2020-09-22 14:53:52 +02:00
// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of OpenEthereum.
2016-08-08 17:25:15 +02:00
2020-09-22 14:53:52 +02:00
// OpenEthereum is free software: you can redistribute it and/or modify
2016-08-08 17:25:15 +02:00
// 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.
2020-09-22 14:53:52 +02:00
// OpenEthereum is distributed in the hope that it will be useful,
2016-08-08 17:25:15 +02:00
// 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
2020-09-22 14:53:52 +02:00
// along with OpenEthereum. If not, see <http://www.gnu.org/licenses/>.
2016-08-08 17:25:15 +02:00
//! RPC Error codes and error objects
use std ::fmt ;
2018-01-11 17:49:10 +01:00
2018-04-19 11:52:54 +02:00
use ethcore ::{
client ::{ BlockChainClient , BlockId } ,
error ::{ CallError , Error as EthcoreError , ErrorKind } ,
2018-11-26 19:58:27 +01:00
} ;
2020-08-13 18:25:19 +02:00
use jsonrpc_core ::{ Error , ErrorCode , Result as RpcResult , Value } ;
2018-11-26 19:58:27 +01:00
use rlp ::DecoderError ;
2019-01-04 14:05:46 +01:00
use types ::{ blockchain_info ::BlockChainInfo , transaction ::Error as TransactionError } ;
2019-05-10 13:48:52 +02:00
use v1 ::{ impls ::EthClientOptions , types ::BlockNumber } ;
2018-04-09 16:14:33 +02:00
use vm ::Error as VMError ;
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 ;
2018-10-02 21:02:48 +02:00
pub const CANNOT_SUBMIT_WORK : i64 = - 32005 ;
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 ;
2019-02-14 15:54:44 +01:00
#[ cfg(any(test, feature = " accounts " )) ]
2016-08-08 17:25:15 +02:00
pub const ACCOUNT_LOCKED : i64 = - 32020 ;
2019-02-14 15:54:44 +01:00
#[ cfg(any(test, feature = " accounts " )) ]
2016-08-08 17:25:15 +02:00
pub const PASSWORD_INVALID : i64 = - 32021 ;
pub const ACCOUNT_ERROR : i64 = - 32023 ;
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 ;
2020-08-24 14:18:03 +02:00
#[ cfg(any(test, feature = " accounts " )) ]
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 ;
2018-11-07 09:30:34 +01:00
pub const NO_PEERS : i64 = - 32066 ;
2017-02-17 12:00:33 +01:00
pub const DEPRECATED : i64 = - 32070 ;
2018-11-16 14:00:34 +01:00
pub const EXPERIMENTAL_RPC : i64 = - 32071 ;
2019-03-04 20:24:53 +01:00
pub const CANNOT_RESTART : i64 = - 32080 ;
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-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
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 ) ) ) ,
}
}
2019-03-04 20:24:53 +01:00
pub fn cannot_restart ( ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::CANNOT_RESTART ) ,
2020-09-22 14:53:52 +02:00
message : " OpenEthereum could not be restarted. This feature is disabled in development mode and if the binary name isn't openethereum. " . into ( ) ,
2019-03-04 20:24:53 +01:00
data : None ,
}
}
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 " , " " )
}
2019-03-27 08:01:05 +01:00
pub fn exceptional < T : fmt ::Display > ( data : T ) -> Error {
2017-01-12 11:06:12 +01:00
Error {
code : ErrorCode ::ServerError ( codes ::EXCEPTION_ERROR ) ,
message : " The execution failed due to an exception. " . into ( ) ,
2019-03-27 08:01:05 +01:00
data : Some ( Value ::String ( data . to_string ( ) ) ) ,
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
}
}
2018-10-02 21:02:48 +02:00
pub fn cannot_submit_work ( err : EthcoreError ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::CANNOT_SUBMIT_WORK ) ,
message : " Cannot submit work. " . into ( ) ,
data : Some ( Value ::String ( err . to_string ( ) ) ) ,
}
}
2019-05-10 13:48:52 +02:00
pub fn unavailable_block ( no_ancient_block : bool , by_hash : bool ) -> Error {
if no_ancient_block {
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
message : " Looks like you disabled ancient block download, unfortunately the information you're \
trying to fetch doesn ' t exist in the db and is probably in the ancient blocks . " .into(),
data : None ,
}
} else if by_hash {
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
message : " Block information is incomplete while ancient block sync is still in progress, before \
it ' s finished we can ' t determine the existence of requested item . " .into(),
data : None ,
}
} else {
Error {
code : ErrorCode ::ServerError ( codes ::UNSUPPORTED_REQUEST ) ,
message : " Requested block number is in a range that is not available yet, because the ancient block sync is still in progress. " . into ( ) ,
data : None ,
}
2018-11-26 19:58:27 +01:00
}
}
pub fn check_block_number_existence < ' a , T , C > (
client : & ' a C ,
num : BlockNumber ,
2019-05-10 13:48:52 +02:00
options : EthClientOptions ,
2018-11-26 19:58:27 +01:00
) -> impl Fn ( Option < T > ) -> RpcResult < Option < T > > + ' a
where
C : BlockChainClient ,
{
move | response | {
if response . is_none ( ) {
if let BlockNumber ::Num ( block_number ) = num {
// tried to fetch block number and got nothing even though the block number is
// less than the latest block number
2019-05-10 13:48:52 +02:00
if block_number < client . chain_info ( ) . best_block_number
& & ! options . allow_missing_blocks
{
return Err ( unavailable_block ( options . no_ancient_blocks , false ) ) ;
2018-11-26 19:58:27 +01:00
}
}
2020-08-05 06:08:03 +02:00
}
2018-11-26 19:58:27 +01:00
Ok ( response )
}
}
pub fn check_block_gap < ' a , T , C > (
client : & ' a C ,
2019-05-10 13:48:52 +02:00
options : EthClientOptions ,
2018-11-26 19:58:27 +01:00
) -> impl Fn ( Option < T > ) -> RpcResult < Option < T > > + ' a
where
C : BlockChainClient ,
{
move | response | {
2019-05-10 13:48:52 +02:00
if response . is_none ( ) & & ! options . allow_missing_blocks {
2018-11-26 19:58:27 +01:00
let BlockChainInfo {
ancient_block_hash , ..
} = client . chain_info ( ) ;
// block information was requested, but unfortunately we couldn't find it and there
// are gaps in the database ethcore/src/blockchain/blockchain.rs
if ancient_block_hash . is_some ( ) {
2019-05-10 13:48:52 +02:00
return Err ( unavailable_block ( options . no_ancient_blocks , true ) ) ;
2018-11-26 19:58:27 +01:00
}
2020-08-05 06:08:03 +02:00
}
2018-11-26 19:58:27 +01:00
Ok ( response )
}
}
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 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 ) ) ) ,
}
}
2019-02-14 15:54:44 +01:00
#[ cfg(any(test, feature = " accounts " )) ]
2018-10-30 22:12:42 +01:00
pub fn invalid_call_data < T : fmt ::Display > ( error : T ) -> Error {
Error {
code : ErrorCode ::ServerError ( codes ::ENCODING_ERROR ) ,
message : format ! ( " {} " , error ) ,
data : None ,
}
}
2019-02-07 14:34:24 +01:00
#[ cfg(any(test, feature = " accounts " )) ]
pub fn signing ( error : ::accounts ::SignError ) -> Error {
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 ) ) ) ,
}
}
#[ cfg(any(test, feature = " accounts " )) ]
pub fn password ( error : ::accounts ::SignError ) -> 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-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 ( ) ,
2019-09-12 18:43:53 +02:00
TooCheapToReplace { prev , new } = > {
format! ( " 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. " ,
new . map ( | gas | format! ( " {} wei " , gas ) ) . unwrap_or ( " supplied " . into ( ) ) ,
prev . map ( | gas | format! ( " with gas price: {} wei " , gas ) ) . unwrap_or ( " " . into ( ) )
)
2018-11-26 19:58:27 +01:00
}
2016-11-16 17:54:54 +01:00
LimitReached = > {
" There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee. " . into ( )
2018-11-26 19:58:27 +01:00
}
2016-11-16 17:54:54 +01:00
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 )
2018-11-26 19:58:27 +01:00
}
2016-11-16 17:54:54 +01:00
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 )
2018-11-26 19:58:27 +01:00
}
2016-11-16 17:54:54 +01:00
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 )
2018-11-26 19:58:27 +01:00
}
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-11-26 19:58:27 +01:00
}
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 ( ) ,
2019-03-27 08:01:05 +01:00
CallError ::Exceptional ( e ) = > exceptional ( e ) ,
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
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-11-07 09:30:34 +01:00
pub fn status_error ( has_peers : bool ) -> Error {
if has_peers {
no_work ( )
} else {
Error {
code : ErrorCode ::ServerError ( codes ::NO_PEERS ) ,
message : " Node is not connected to any peers. " . into ( ) ,
data : None ,
}
}
}
2018-11-16 14:00:34 +01:00
/// Returns a descriptive error in case experimental RPCs are not enabled.
pub fn require_experimental ( allow_experimental_rpcs : bool , eip : & str ) -> Result < ( ) , Error > {
if allow_experimental_rpcs {
Ok ( ( ) )
} else {
Err ( Error {
code : ErrorCode ::ServerError ( codes ::EXPERIMENTAL_RPC ) ,
message : format ! ( " This method is not part of the official RPC API yet (EIP-{}). Run with `--jsonrpc-experimental` to enable it. " , eip ) ,
data : Some ( Value ::String ( format! ( " See EIP: https://eips.ethereum.org/EIPS/eip- {} " , eip ) ) ) ,
} )
}
}