openethereum/crates/rpc/src/v1/helpers/errors.rs

546 lines
18 KiB
Rust
Raw Normal View History

2020-09-22 14:53:52 +02:00
// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of OpenEthereum.
2020-09-22 14:53:52 +02:00
// OpenEthereum 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.
2020-09-22 14:53:52 +02:00
// OpenEthereum 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
2020-09-22 14:53:52 +02:00
// along with OpenEthereum. If not, see <http://www.gnu.org/licenses/>.
//! RPC Error codes and error objects
use std::fmt;
2020-08-05 06:08:03 +02:00
use ethcore::{
client::{BlockChainClient, BlockId},
error::{CallError, Error as EthcoreError, ErrorKind},
};
2020-08-13 18:25:19 +02:00
use jsonrpc_core::{Error, ErrorCode, Result as RpcResult, Value};
2020-08-05 06:08:03 +02:00
use rlp::DecoderError;
use types::{blockchain_info::BlockChainInfo, transaction::Error as TransactionError};
use v1::{impls::EthClientOptions, types::BlockNumber};
use vm::Error as VMError;
mod codes {
2020-08-05 06:08:03 +02:00
// NOTE [ToDr] Codes from [-32099, -32000]
pub const UNSUPPORTED_REQUEST: i64 = -32000;
pub const NO_WORK: i64 = -32001;
pub const NO_AUTHOR: i64 = -32002;
pub const NO_NEW_WORK: i64 = -32003;
pub const NO_WORK_REQUIRED: i64 = -32004;
pub const CANNOT_SUBMIT_WORK: i64 = -32005;
pub const UNKNOWN_ERROR: i64 = -32009;
pub const TRANSACTION_ERROR: i64 = -32010;
pub const EXECUTION_ERROR: i64 = -32015;
pub const EXCEPTION_ERROR: i64 = -32016;
pub const DATABASE_ERROR: i64 = -32017;
#[cfg(any(test, feature = "accounts"))]
pub const ACCOUNT_LOCKED: i64 = -32020;
#[cfg(any(test, feature = "accounts"))]
pub const PASSWORD_INVALID: i64 = -32021;
pub const ACCOUNT_ERROR: i64 = -32023;
pub const REQUEST_REJECTED: i64 = -32040;
pub const REQUEST_REJECTED_LIMIT: i64 = -32041;
pub const REQUEST_NOT_FOUND: i64 = -32042;
pub const ENCRYPTION_ERROR: i64 = -32055;
2020-08-24 14:18:03 +02:00
#[cfg(any(test, feature = "accounts"))]
2020-08-05 06:08:03 +02:00
pub const ENCODING_ERROR: i64 = -32058;
pub const FETCH_ERROR: i64 = -32060;
pub const NO_PEERS: i64 = -32066;
pub const DEPRECATED: i64 = -32070;
pub const EXPERIMENTAL_RPC: i64 = -32071;
pub const CANNOT_RESTART: i64 = -32080;
}
pub fn unimplemented(details: Option<String>) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "This request is not implemented yet. Please create an issue on Github repo."
.into(),
data: details.map(Value::String),
}
}
pub fn unsupported<T: Into<String>>(msg: T, details: Option<T>) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: msg.into(),
data: details.map(Into::into).map(Value::String),
}
}
pub fn request_not_found() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::REQUEST_NOT_FOUND),
message: "Request not found.".into(),
data: None,
}
}
pub fn request_rejected() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::REQUEST_REJECTED),
message: "Request has been rejected.".into(),
data: None,
}
}
pub fn request_rejected_limit() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::REQUEST_REJECTED_LIMIT),
message: "Request has been rejected because of queue limit.".into(),
data: None,
}
}
pub fn account<T: fmt::Debug>(error: &str, details: T) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::ACCOUNT_ERROR),
message: error.into(),
data: Some(Value::String(format!("{:?}", details))),
}
}
pub fn cannot_restart() -> Error {
2020-08-05 06:08:03 +02:00
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(),
data: None,
}
}
/// 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.
pub fn internal<T: fmt::Debug>(error: &str, data: T) -> Error {
2020-08-05 06:08:03 +02:00
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 {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::InvalidParams,
message: format!("Couldn't parse parameters: {}", param),
data: Some(Value::String(format!("{:?}", details))),
}
}
pub fn execution<T: fmt::Debug>(data: T) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::EXECUTION_ERROR),
message: "Transaction execution error.".into(),
data: Some(Value::String(format!("{:?}", data))),
}
}
pub fn state_pruned() -> Error {
2020-08-05 06:08:03 +02:00
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(),
data: None,
}
}
pub fn state_corrupt() -> Error {
2020-08-05 06:08:03 +02:00
internal("State corrupt", "")
}
pub fn exceptional<T: fmt::Display>(data: T) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::EXCEPTION_ERROR),
message: "The execution failed due to an exception.".into(),
data: Some(Value::String(data.to_string())),
}
}
pub fn no_work() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::NO_WORK),
message: "Still syncing.".into(),
data: None,
}
}
pub fn no_new_work() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::NO_NEW_WORK),
message: "Work has not changed.".into(),
data: None,
}
}
pub fn no_author() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::NO_AUTHOR),
message: "Author not configured. Run Parity with --author to configure.".into(),
data: None,
}
}
pub fn no_work_required() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::NO_WORK_REQUIRED),
message: "External work is only required for Proof of Work engines.".into(),
data: None,
}
}
pub fn cannot_submit_work(err: EthcoreError) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::CANNOT_SUBMIT_WORK),
message: "Cannot submit work.".into(),
data: Some(Value::String(err.to_string())),
}
}
pub fn unavailable_block(no_ancient_block: bool, by_hash: bool) -> Error {
2020-08-05 06:08:03 +02:00
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,
}
2020-08-05 06:08:03 +02:00
} 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,
}
2020-08-05 06:08:03 +02:00
} 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,
}
2020-08-05 06:08:03 +02:00
}
}
pub fn check_block_number_existence<'a, T, C>(
2020-08-05 06:08:03 +02:00
client: &'a C,
num: BlockNumber,
options: EthClientOptions,
) -> impl Fn(Option<T>) -> RpcResult<Option<T>> + 'a
where
C: BlockChainClient,
{
2020-08-05 06:08:03 +02:00
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
if block_number < client.chain_info().best_block_number
&& !options.allow_missing_blocks
{
return Err(unavailable_block(options.no_ancient_blocks, false));
}
}
}
Ok(response)
}
}
pub fn check_block_gap<'a, T, C>(
2020-08-05 06:08:03 +02:00
client: &'a C,
options: EthClientOptions,
) -> impl Fn(Option<T>) -> RpcResult<Option<T>> + 'a
2020-08-05 06:08:03 +02:00
where
C: BlockChainClient,
{
2020-08-05 06:08:03 +02:00
move |response| {
if response.is_none() && !options.allow_missing_blocks {
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() {
return Err(unavailable_block(options.no_ancient_blocks, true));
}
}
Ok(response)
}
}
pub fn not_enough_data() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "The node does not have enough data to compute the given statistic.".into(),
data: None,
}
}
pub fn token(e: String) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::UNKNOWN_ERROR),
message: "There was an error when saving your authorization tokens.".into(),
data: Some(Value::String(e)),
}
}
pub fn signer_disabled() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "Trusted Signer is disabled. This API is not available.".into(),
data: None,
}
}
pub fn ws_disabled() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "WebSockets Server is disabled. This API is not available.".into(),
data: None,
}
2016-10-24 12:21:15 +02:00
}
pub fn network_disabled() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "Network is disabled or not yet up.".into(),
data: None,
}
}
pub fn encryption<T: fmt::Debug>(error: T) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::ENCRYPTION_ERROR),
message: "Encryption error.".into(),
data: Some(Value::String(format!("{:?}", error))),
}
}
pub fn database<T: fmt::Debug>(error: T) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::DATABASE_ERROR),
message: "Database error.".into(),
data: Some(Value::String(format!("{:?}", error))),
}
}
pub fn fetch<T: fmt::Debug>(error: T) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::FETCH_ERROR),
message: "Error while fetching content.".into(),
data: Some(Value::String(format!("{:?}", error))),
}
}
#[cfg(any(test, feature = "accounts"))]
pub fn invalid_call_data<T: fmt::Display>(error: T) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::ENCODING_ERROR),
message: format!("{}", error),
data: None,
}
}
#[cfg(any(test, feature = "accounts"))]
pub fn signing(error: ::accounts::SignError) -> Error {
2020-08-05 06:08:03 +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))),
}
}
#[cfg(any(test, feature = "accounts"))]
pub fn password(error: ::accounts::SignError) -> Error {
2020-08-05 06:08:03 +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))),
}
}
pub fn transaction_message(error: &TransactionError) -> String {
2020-08-05 06:08:03 +02:00
use self::TransactionError::*;
2020-08-05 06:08:03 +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 { 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())
)
}
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()
}
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)
}
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)
}
Sunce86/eip 1559 (#393) * eip1559 hard fork activation * eip1559 hard fork activation 2 * added new transaction type for eip1559 * added base fee field to block header * fmt fix * added base fee calculation. added block header validation against base fee * fmt * temporarily added modified transaction pool * tx pool fix of PendingIterator * tx pool fix of UnorderedIterator * tx pool added test for set_scoring * transaction pool changes * added tests for eip1559 transaction and eip1559 receipt * added test for eip1559 transaction execution * block gas limit / block gas target handling * base fee verification moved out of engine * calculate_base_fee moved to EthereumMachine * handling of base_fee_per_gas as part of seal * handling of base_fee_per_gas changed. Different encoding/decoding of block header * eip1559 transaction execution - gas price handling * eip1559 transaction execution - verification, fee burning * effectiveGasPrice removed from the receipt payload (specs) * added support for 1559 txs in tx pool verification * added Aleut test network configuration * effective_tip_scaled replaced by typed_gas_price * eip 3198 - Basefee opcode * rpc - updated structs Block and Header * rpc changes for 1559 * variable renaming according to spec * - typed_gas_price renamed to effective_gas_price - elasticity_multiplier definition moved to update_schedule() * calculate_base_fee simplified * Evm environment context temporary fix for gas limit * fmt fix * fixed fake_sign::sign_call * temporary fix for GASLIMIT opcode to provide gas_target actually * gas_target removed from block header according to spec change: https://github.com/ethereum/EIPs/pull/3566 * tx pool verification fix * env_info base fee changed to Option * fmt fix * pretty format * updated ethereum tests * cache_pending refresh on each update of score * code review fixes * fmt fix * code review fix - changed handling of eip1559_base_fee_max_change_denominator * code review fix - modification.gas_price * Skip gas_limit_bump for Aura * gas_limit calculation changed to target ceil * gas_limit calculation will target ceil on 1559 activation block * transaction verification updated according spec: https://github.com/ethereum/EIPs/pull/3594 * updated json tests * ethereum json tests fix for base_fee
2021-06-04 12:12:24 +02:00
GasPriceLowerThanBaseFee { gas_price, base_fee} => {
format!("Transaction max gas price is lower then the required base fee (gas_price: {}, base_fee: {}). Try increasing the max gas price.", gas_price, base_fee)
}
2016-11-16 17:54:54 +01:00
InsufficientBalance { balance, cost } => {
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)
}
InvalidSignature(ref sig) => format!("Invalid signature: {}", sig),
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(),
TooBig => "Transaction is too big, see chain specification for the limit.".into(),
InvalidRlp(ref descr) => format!("Invalid RLP data: {}", descr),
TransactionTypeNotEnabled => format!("Transaction type is not enabled for current block"),
2016-11-16 17:54:54 +01:00
}
}
pub fn transaction<T: Into<EthcoreError>>(error: T) -> Error {
2020-08-05 06:08:03 +02:00
let error = error.into();
if let ErrorKind::Transaction(ref e) = *error.kind() {
Error {
code: ErrorCode::ServerError(codes::TRANSACTION_ERROR),
message: transaction_message(e),
data: None,
}
} else {
Error {
code: ErrorCode::ServerError(codes::UNKNOWN_ERROR),
message: "Unknown error when sending transaction.".into(),
data: Some(Value::String(format!("{:?}", error))),
}
}
}
pub fn decode<T: Into<EthcoreError>>(error: T) -> Error {
2020-08-05 06:08:03 +02:00
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,
},
}
}
pub fn rlp(error: DecoderError) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::InvalidParams,
message: "Invalid RLP.".into(),
data: Some(Value::String(format!("{:?}", error))),
}
}
pub fn call(error: CallError) -> Error {
2020-08-05 06:08:03 +02:00
match error {
CallError::StatePruned => state_pruned(),
CallError::StateCorrupt => state_corrupt(),
CallError::Exceptional(e) => exceptional(e),
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
pub fn vm(error: &VMError, output: &[u8]) -> Error {
2020-08-05 06:08:03 +02:00
use rustc_hex::ToHex;
2020-08-05 06:08:03 +02:00
let data = match error {
&VMError::Reverted => format!("{} 0x{}", VMError::Reverted, output.to_hex()),
error => format!("{}", error),
};
2020-08-05 06:08:03 +02:00
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 {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::InvalidParams,
message: "Unknown block number".into(),
data: None,
}
2016-12-23 18:46:17 +01:00
}
2017-02-09 21:12:28 +01:00
New Transaction Queue implementation (#8074) * Implementation of Verifier, Scoring and Ready. * Queue in progress. * TransactionPool. * Prepare for txpool release. * Miner refactor [WiP] * WiP reworking miner. * Make it compile. * Add some docs. * Split blockchain access to a separate file. * Work on miner API. * Fix ethcore tests. * Refactor miner interface for sealing/work packages. * Implement next nonce. * RPC compiles. * Implement couple of missing methdods for RPC. * Add transaction queue listeners. * Compiles! * Clean-up and parallelize. * Get rid of RefCell in header. * Revert "Get rid of RefCell in header." This reverts commit 0f2424c9b7319a786e1565ea2a8a6d801a21b4fb. * Override Sync requirement. * Fix status display. * Unify logging. * Extract some cheap checks. * Measurements and optimizations. * Fix scoring bug, heap size of bug and add cache * Disable tx queueing and parallel verification. * Make ethcore and ethcore-miner compile again. * Make RPC compile again. * Bunch of txpool tests. * Migrate transaction queue tests. * Nonce Cap * Nonce cap cache and tests. * Remove stale future transactions from the queue. * Optimize scoring and write some tests. * Simple penalization. * Clean up and support for different scoring algorithms. * Add CLI parameters for the new queue. * Remove banning queue. * Disable debug build. * Change per_sender limit to be 1% instead of 5% * Avoid cloning when propagating transactions. * Remove old todo. * Post-review fixes. * Fix miner options default. * Implement back ready transactions for light client. * Get rid of from_pending_block * Pass rejection reason. * Add more details to drop. * Rollback heap size of. * Avoid cloning hashes when propagating and include more details on rejection. * Fix tests. * Introduce nonces cache. * Remove uneccessary hashes allocation. * Lower the mem limit. * Re-enable parallel verification. * Add miner log. Don't check the type if not below min_gas_price. * Add more traces, fix disabling miner. * Fix creating pending blocks twice on AuRa authorities. * Fix tests. * re-use pending blocks in AuRa * Use reseal_min_period to prevent too frequent update_sealing. * Fix log to contain hash not sender. * Optimize local transactions. * Fix aura tests. * Update locks comments. * Get rid of unsafe Sync impl. * Review fixes. * Remove excessive matches. * Fix compilation errors. * Use new pool in private transactions. * Fix private-tx test. * Fix secret store tests. * Actually use gas_floor_target * Fix config tests. * Fix pool tests. * Address grumbles.
2018-04-13 17:34:27 +02:00
pub fn deprecated<S: Into<String>, T: Into<Option<S>>>(message: T) -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::DEPRECATED),
message: "Method deprecated".into(),
data: message.into().map(Into::into).map(Value::String),
}
}
pub fn filter_not_found() -> Error {
2020-08-05 06:08:03 +02:00
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "Filter not found".into(),
data: None,
}
}
pub fn filter_block_not_found(id: BlockId) -> Error {
2020-08-05 06:08:03 +02:00
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(),
})),
}
}
pub fn status_error(has_peers: bool) -> Error {
2020-08-05 06:08:03 +02:00
if has_peers {
no_work()
} else {
Error {
code: ErrorCode::ServerError(codes::NO_PEERS),
message: "Node is not connected to any peers.".into(),
data: None,
}
}
}
/// Returns a descriptive error in case experimental RPCs are not enabled.
pub fn require_experimental(allow_experimental_rpcs: bool, eip: &str) -> Result<(), Error> {
2020-08-05 06:08:03 +02:00
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))),
})
2020-08-05 06:08:03 +02:00
}
}
/// returns an error for when require_canonical was specified in RPC for EIP-1898
pub fn invalid_input() -> Error {
Error {
// UNSUPPORTED_REQUEST shares the same error code for EIP-1898
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "Invalid input".into(),
data: None,
}
}