2018-06-04 10:19:50 +02:00
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
2016-08-08 17:25:15 +02:00
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! RPC Error codes and error objects
use std ::fmt ;
2018-01-11 17:49:10 +01:00
2017-01-30 21:08:36 +01:00
use ethcore ::account_provider ::{ SignError as AccountError } ;
2018-04-19 11:52:54 +02:00
use ethcore ::error ::{ Error as EthcoreError , ErrorKind , CallError } ;
2018-08-13 09:47:10 +02:00
use ethcore ::client ::BlockId ;
2017-10-05 12:35:01 +02:00
use jsonrpc_core ::{ futures , Error , ErrorCode , Value } ;
2018-01-11 17:49:10 +01:00
use rlp ::DecoderError ;
use transaction ::Error as TransactionError ;
2018-04-09 16:14:33 +02:00
use ethcore_private_tx ::Error as PrivateTransactionError ;
2018-04-21 11:41:09 +02:00
use vm ::Error as VMError ;
2018-09-12 11:47:01 +02:00
use light ::on_demand ::error ::{ Error as OnDemandError , ErrorKind as OnDemandErrorKind } ;
2016-08-08 17:25:15 +02:00
mod codes {
// NOTE [ToDr] Codes from [-32099, -32000]
pub const UNSUPPORTED_REQUEST : i64 = - 32000 ;
pub const NO_WORK : i64 = - 32001 ;
pub const NO_AUTHOR : i64 = - 32002 ;
2016-08-23 17:07:00 +02:00
pub const NO_NEW_WORK : i64 = - 32003 ;
2017-07-12 08:52:18 +02:00
pub const NO_WORK_REQUIRED : i64 = - 32004 ;
2016-08-08 17:25:15 +02:00
pub const UNKNOWN_ERROR : i64 = - 32009 ;
pub const TRANSACTION_ERROR : i64 = - 32010 ;
2016-10-09 11:45:12 +02:00
pub const EXECUTION_ERROR : i64 = - 32015 ;
2017-01-12 11:06:12 +01:00
pub const EXCEPTION_ERROR : i64 = - 32016 ;
2017-03-10 10:25:13 +01:00
pub const DATABASE_ERROR : i64 = - 32017 ;
2016-08-08 17:25:15 +02:00
pub const ACCOUNT_LOCKED : i64 = - 32020 ;
pub const PASSWORD_INVALID : i64 = - 32021 ;
pub const ACCOUNT_ERROR : i64 = - 32023 ;
2018-04-09 16:14:33 +02:00
pub const PRIVATE_ERROR : i64 = - 32024 ;
2016-08-08 17:25:15 +02:00
pub const REQUEST_REJECTED : i64 = - 32040 ;
2016-09-01 12:00:00 +02:00
pub const REQUEST_REJECTED_LIMIT : i64 = - 32041 ;
pub const REQUEST_NOT_FOUND : i64 = - 32042 ;
2016-10-15 14:44:08 +02:00
pub const ENCRYPTION_ERROR : i64 = - 32055 ;
2017-04-08 13:35:23 +02:00
pub const ENCODING_ERROR : i64 = - 32058 ;
2016-09-27 16:27:06 +02:00
pub const FETCH_ERROR : i64 = - 32060 ;
2017-02-09 21:12:28 +01:00
pub const NO_LIGHT_PEERS : i64 = - 32065 ;
2017-02-17 12:00:33 +01:00
pub const DEPRECATED : i64 = - 32070 ;
2016-08-08 17:25:15 +02:00
}
2016-11-10 11:27:05 +01:00
pub fn unimplemented ( details : Option < String > ) -> Error {
2016-08-08 17:25:15 +02:00
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
message : " This request is not implemented yet. Please create an issue on Github repo. " . into ( ) ,
2016-11-10 11:27:05 +01:00
data : details . map ( Value ::String ) ,
2016-08-08 17:25:15 +02:00
}
}
2017-02-17 21:38:43 +01:00
pub fn light_unimplemented ( details : Option < String > ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
message : " This request is unsupported for light clients. " . into ( ) ,
data : details . map ( Value ::String ) ,
}
}
2017-08-15 12:11:34 +02:00
pub fn unsupported < T : Into < String > > ( msg : T , details : Option < T > ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
message : msg . into ( ) ,
data : details . map ( Into ::into ) . map ( Value ::String ) ,
}
}
2016-08-08 17:25:15 +02:00
pub fn request_not_found ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::REQUEST_NOT_FOUND ) ,
message : " Request not found. " . into ( ) ,
data : None ,
}
}
pub fn request_rejected ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::REQUEST_REJECTED ) ,
message : " Request has been rejected. " . into ( ) ,
data : None ,
}
}
2016-09-01 12:00:00 +02:00
pub fn request_rejected_limit ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::REQUEST_REJECTED_LIMIT ) ,
message : " Request has been rejected because of queue limit. " . into ( ) ,
data : None ,
}
}
2016-08-08 17:25:15 +02:00
2018-08-25 23:06:01 +02:00
pub fn request_rejected_param_limit ( limit : u64 , items_desc : & str ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::REQUEST_REJECTED_LIMIT ) ,
message : format ! ( " Requested data size exceeds limit of {} {}. " , limit , items_desc ) ,
data : None ,
}
}
2016-08-08 17:25:15 +02:00
pub fn account < T : fmt ::Debug > ( error : & str , details : T ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::ACCOUNT_ERROR ) ,
message : error . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , details ) ) ) ,
}
}
2017-03-10 10:25:13 +01:00
/// Internal error signifying a logic error in code.
/// Should not be used when function can just fail
/// because of invalid parameters or incomplete node state.
2016-08-08 17:25:15 +02:00
pub fn internal < T : fmt ::Debug > ( error : & str , data : T ) -> Error {
Error {
code : ErrorCode ::InternalError ,
message : format ! ( " Internal error occurred: {} " , error ) ,
data : Some ( Value ::String ( format! ( " {:?} " , data ) ) ) ,
}
}
pub fn invalid_params < T : fmt ::Debug > ( param : & str , details : T ) -> Error {
Error {
code : ErrorCode ::InvalidParams ,
message : format ! ( " Couldn't parse parameters: {} " , param ) ,
data : Some ( Value ::String ( format! ( " {:?} " , details ) ) ) ,
}
}
2016-10-09 11:45:12 +02:00
pub fn execution < T : fmt ::Debug > ( data : T ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::EXECUTION_ERROR ) ,
message : " Transaction execution error. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , data ) ) ) ,
}
}
2016-08-08 17:25:15 +02:00
pub fn state_pruned ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
message : " This request is not supported because your node is running with state pruning. Run with --pruning=archive. " . into ( ) ,
2017-07-12 08:52:18 +02:00
data : None ,
2016-08-08 17:25:15 +02:00
}
}
2017-02-26 13:10:50 +01:00
pub fn state_corrupt ( ) -> Error {
internal ( " State corrupt " , " " )
}
2017-01-12 11:06:12 +01:00
pub fn exceptional ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::EXCEPTION_ERROR ) ,
message : " The execution failed due to an exception. " . into ( ) ,
2017-07-12 08:52:18 +02:00
data : None ,
2017-01-12 11:06:12 +01:00
}
}
2016-08-08 17:25:15 +02:00
pub fn no_work ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::NO_WORK ) ,
message : " Still syncing. " . into ( ) ,
2017-07-12 08:52:18 +02:00
data : None ,
2016-08-08 17:25:15 +02:00
}
}
2016-08-23 17:07:00 +02:00
pub fn no_new_work ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::NO_NEW_WORK ) ,
message : " Work has not changed. " . into ( ) ,
2017-07-12 08:52:18 +02:00
data : None ,
2016-08-23 17:07:00 +02:00
}
}
2016-08-08 17:25:15 +02:00
pub fn no_author ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::NO_AUTHOR ) ,
message : " Author not configured. Run Parity with --author to configure. " . into ( ) ,
2017-07-12 08:52:18 +02:00
data : None ,
}
}
pub fn no_work_required ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::NO_WORK_REQUIRED ) ,
message : " External work is only required for Proof of Work engines. " . into ( ) ,
data : None ,
2016-08-08 17:25:15 +02:00
}
}
2016-10-31 12:57:48 +01:00
pub fn not_enough_data ( ) -> Error {
Error {
2017-03-14 13:04:32 +01:00
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
2016-10-31 12:57:48 +01:00
message : " The node does not have enough data to compute the given statistic. " . into ( ) ,
2017-03-14 13:04:32 +01:00
data : None ,
2016-10-31 12:57:48 +01:00
}
}
2016-09-21 12:44:49 +02:00
pub fn token ( e : String ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::UNKNOWN_ERROR ) ,
message : " There was an error when saving your authorization tokens. " . into ( ) ,
data : Some ( Value ::String ( e ) ) ,
}
}
2016-08-08 17:25:15 +02:00
pub fn signer_disabled ( ) -> Error {
Error {
2017-03-14 13:04:32 +01:00
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
2016-08-08 17:25:15 +02:00
message : " Trusted Signer is disabled. This API is not available. " . into ( ) ,
2017-03-14 13:04:32 +01:00
data : None ,
2016-08-08 17:25:15 +02:00
}
}
2017-05-24 12:24:07 +02:00
pub fn ws_disabled ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
message : " WebSockets Server is disabled. This API is not available. " . into ( ) ,
2017-03-14 13:04:32 +01:00
data : None ,
2016-10-24 12:21:15 +02:00
}
}
2016-11-02 19:43:21 +01:00
pub fn network_disabled ( ) -> Error {
Error {
2017-03-14 13:04:32 +01:00
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
2016-11-02 19:43:21 +01:00
message : " Network is disabled or not yet up. " . into ( ) ,
2017-03-14 13:04:32 +01:00
data : None ,
2016-11-02 19:43:21 +01:00
}
}
2017-07-04 17:01:06 +02:00
pub fn encryption < T : fmt ::Debug > ( error : T ) -> Error {
2016-10-15 14:44:08 +02:00
Error {
code : ErrorCode ::ServerError ( codes ::ENCRYPTION_ERROR ) ,
message : " Encryption error. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , error ) ) ) ,
}
2017-03-10 10:25:13 +01:00
}
2017-07-04 17:01:06 +02:00
pub fn encoding < T : fmt ::Debug > ( error : T ) -> Error {
2017-04-08 13:35:23 +02:00
Error {
code : ErrorCode ::ServerError ( codes ::ENCODING_ERROR ) ,
message : " Encoding error. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , error ) ) ) ,
}
}
2017-07-04 17:01:06 +02:00
pub fn database < T : fmt ::Debug > ( error : T ) -> Error {
2017-03-10 10:25:13 +01:00
Error {
code : ErrorCode ::ServerError ( codes ::DATABASE_ERROR ) ,
message : " Database error. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , error ) ) ) ,
}
2016-10-15 14:44:08 +02:00
}
2017-07-04 17:01:06 +02:00
pub fn fetch < T : fmt ::Debug > ( error : T ) -> Error {
2016-09-27 16:27:06 +02:00
Error {
code : ErrorCode ::ServerError ( codes ::FETCH_ERROR ) ,
message : " Error while fetching content. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , error ) ) ) ,
}
}
2017-07-04 17:01:06 +02:00
pub fn signing ( error : AccountError ) -> Error {
2016-08-08 17:25:15 +02:00
Error {
code : ErrorCode ::ServerError ( codes ::ACCOUNT_LOCKED ) ,
message : " Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , error ) ) ) ,
}
}
2017-07-04 17:01:06 +02:00
pub fn password ( error : AccountError ) -> Error {
2016-08-08 17:25:15 +02:00
Error {
code : ErrorCode ::ServerError ( codes ::PASSWORD_INVALID ) ,
message : " Account password is invalid or account does not exist. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , error ) ) ) ,
}
}
2018-04-09 16:14:33 +02:00
pub fn private_message ( error : PrivateTransactionError ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::PRIVATE_ERROR ) ,
message : " Private transactions call failed. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , error ) ) ) ,
}
}
pub fn private_message_block_id_not_supported ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::PRIVATE_ERROR ) ,
message : " Pending block id not supported. " . into ( ) ,
data : None ,
}
}
2018-04-19 11:52:54 +02:00
pub fn transaction_message ( error : & TransactionError ) -> String {
2018-01-11 17:49:10 +01:00
use self ::TransactionError ::* ;
2016-08-08 17:25:15 +02:00
2018-04-19 11:52:54 +02:00
match * error {
2016-11-16 17:54:54 +01:00
AlreadyImported = > " Transaction with the same hash was already imported. " . into ( ) ,
Old = > " Transaction nonce is too low. Try incrementing the nonce. " . into ( ) ,
TooCheapToReplace = > {
" Transaction gas price is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce. " . into ( )
} ,
LimitReached = > {
" There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee. " . into ( )
} ,
InsufficientGas { minimal , got } = > {
format! ( " Transaction gas is too low. There is not enough gas to cover minimal cost of the transaction (minimal: {} , got: {} ). Try increasing supplied gas. " , minimal , got )
} ,
InsufficientGasPrice { minimal , got } = > {
format! ( " Transaction gas price is too low. It does not satisfy your node's minimal gas price (minimal: {} , got: {} ). Try increasing the gas price. " , minimal , got )
} ,
InsufficientBalance { balance , cost } = > {
2016-12-19 16:27:03 +01:00
format! ( " Insufficient funds. The account you tried to send transaction from does not have enough funds. Required {} and got: {} . " , cost , balance )
2016-11-16 17:54:54 +01:00
} ,
GasLimitExceeded { limit , got } = > {
format! ( " Transaction cost exceeds current gas limit. Limit: {} , got: {} . Try decreasing supplied gas. " , limit , got )
} ,
2018-04-19 11:52:54 +02:00
InvalidSignature ( ref sig ) = > format! ( " Invalid signature: {} " , sig ) ,
2017-08-21 13:46:58 +02:00
InvalidChainId = > " Invalid chain id. " . into ( ) ,
2016-11-16 17:54:54 +01:00
InvalidGasLimit ( _ ) = > " Supplied gas is beyond limit. " . into ( ) ,
SenderBanned = > " Sender is banned in local queue. " . into ( ) ,
RecipientBanned = > " Recipient is banned in local queue. " . into ( ) ,
CodeBanned = > " Code is banned in local queue. " . into ( ) ,
2017-09-05 11:39:50 +02:00
NotAllowed = > " Transaction is not permitted. " . into ( ) ,
2018-04-27 15:02:45 +02:00
TooBig = > " Transaction is too big, see chain specification for the limit. " . into ( ) ,
InvalidRlp ( ref descr ) = > format! ( " Invalid RLP data: {} " , descr ) ,
2016-11-16 17:54:54 +01:00
}
}
2018-01-11 17:49:10 +01:00
pub fn transaction < T : Into < EthcoreError > > ( error : T ) -> Error {
let error = error . into ( ) ;
2018-04-19 11:52:54 +02:00
if let ErrorKind ::Transaction ( ref e ) = * error . kind ( ) {
2016-08-08 17:25:15 +02:00
Error {
code : ErrorCode ::ServerError ( codes ::TRANSACTION_ERROR ) ,
2016-11-16 17:54:54 +01:00
message : transaction_message ( e ) ,
2016-08-08 17:25:15 +02:00
data : None ,
}
} else {
Error {
code : ErrorCode ::ServerError ( codes ::UNKNOWN_ERROR ) ,
message : " Unknown error when sending transaction. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , error ) ) ) ,
}
}
}
2018-05-09 12:05:56 +02:00
pub fn decode < T : Into < EthcoreError > > ( error : T ) -> Error {
let error = error . into ( ) ;
match * error . kind ( ) {
ErrorKind ::Decoder ( ref dec_err ) = > rlp ( dec_err . clone ( ) ) ,
_ = > Error {
code : ErrorCode ::InternalError ,
message : " decoding error " . into ( ) ,
data : None ,
}
}
}
2017-07-04 17:01:06 +02:00
pub fn rlp ( error : DecoderError ) -> Error {
2016-11-04 18:33:10 +01:00
Error {
code : ErrorCode ::InvalidParams ,
message : " Invalid RLP. " . into ( ) ,
data : Some ( Value ::String ( format! ( " {:?} " , error ) ) ) ,
}
}
2017-07-04 17:01:06 +02:00
pub fn call ( error : CallError ) -> Error {
2016-10-09 11:45:12 +02:00
match error {
CallError ::StatePruned = > state_pruned ( ) ,
2017-02-26 13:10:50 +01:00
CallError ::StateCorrupt = > state_corrupt ( ) ,
2017-01-12 11:06:12 +01:00
CallError ::Exceptional = > exceptional ( ) ,
2016-10-09 11:45:12 +02:00
CallError ::Execution ( e ) = > execution ( e ) ,
CallError ::TransactionNotFound = > internal ( " {}, this should not be the case with eth_call, most likely a bug. " , CallError ::TransactionNotFound ) ,
}
}
2016-12-23 18:46:17 +01:00
2018-04-21 11:41:09 +02:00
pub fn vm ( error : & VMError , output : & [ u8 ] ) -> Error {
use rustc_hex ::ToHex ;
let data = match error {
& VMError ::Reverted = > format! ( " {} 0x {} " , VMError ::Reverted , output . to_hex ( ) ) ,
error = > format! ( " {} " , error ) ,
} ;
Error {
code : ErrorCode ::ServerError ( codes ::EXECUTION_ERROR ) ,
message : " VM execution error. " . into ( ) ,
data : Some ( Value ::String ( data ) ) ,
}
}
2016-12-23 18:46:17 +01:00
pub fn unknown_block ( ) -> Error {
Error {
2017-03-14 13:04:32 +01:00
code : ErrorCode ::InvalidParams ,
2016-12-23 18:46:17 +01:00
message : " Unknown block number " . into ( ) ,
data : None ,
}
}
2017-02-09 21:12:28 +01:00
pub fn no_light_peers ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::NO_LIGHT_PEERS ) ,
message : " No light peers who can serve data " . into ( ) ,
data : None ,
}
}
2017-02-17 12:00:33 +01:00
2018-04-13 17:34:27 +02:00
pub fn deprecated < S : Into < String > , T : Into < Option < S > > > ( message : T ) -> Error {
2017-02-17 12:00:33 +01:00
Error {
code : ErrorCode ::ServerError ( codes ::DEPRECATED ) ,
message : " Method deprecated " . into ( ) ,
2018-04-13 17:34:27 +02:00
data : message . into ( ) . map ( Into ::into ) . map ( Value ::String ) ,
2017-02-17 12:00:33 +01:00
}
}
2017-04-03 11:37:07 +02:00
2018-04-10 10:36:14 +02:00
pub fn filter_not_found ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
message : " Filter not found " . into ( ) ,
data : None ,
}
}
2018-08-13 09:47:10 +02:00
pub fn filter_block_not_found ( id : BlockId ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) , // Specified in EIP-234.
message : " One of the blocks specified in filter (fromBlock, toBlock or blockHash) cannot be found " . into ( ) ,
data : Some ( Value ::String ( match id {
BlockId ::Hash ( hash ) = > format! ( " 0x {:x} " , hash ) ,
BlockId ::Number ( number ) = > format! ( " 0x {:x} " , number ) ,
BlockId ::Earliest = > " earliest " . to_string ( ) ,
BlockId ::Latest = > " latest " . to_string ( ) ,
} ) ) ,
}
}
2018-09-12 11:47:01 +02:00
pub fn on_demand_error ( err : OnDemandError ) -> Error {
match err {
OnDemandError ( OnDemandErrorKind ::ChannelCanceled ( e ) , _ ) = > on_demand_cancel ( e ) ,
OnDemandError ( OnDemandErrorKind ::MaxAttemptReach ( _ ) , _ ) = > max_attempts_reached ( & err ) ,
OnDemandError ( OnDemandErrorKind ::TimeoutOnNewPeers ( _ , _ ) , _ ) = > timeout_new_peer ( & err ) ,
_ = > on_demand_others ( & err ) ,
}
}
2017-04-03 11:37:07 +02:00
// on-demand sender cancelled.
2017-10-05 12:35:01 +02:00
pub fn on_demand_cancel ( _cancel : futures ::sync ::oneshot ::Canceled ) -> Error {
2017-04-03 11:37:07 +02:00
internal ( " on-demand sender cancelled " , " " )
}
2018-09-12 11:47:01 +02:00
pub fn max_attempts_reached ( err : & OnDemandError ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::REQUEST_NOT_FOUND ) ,
message : err . to_string ( ) ,
data : None ,
}
}
pub fn timeout_new_peer ( err : & OnDemandError ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::NO_LIGHT_PEERS ) ,
message : err . to_string ( ) ,
data : None ,
}
}
pub fn on_demand_others ( err : & OnDemandError ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::UNKNOWN_ERROR ) ,
message : err . to_string ( ) ,
data : None ,
}
}