From e05dba69ce8ebc2c481ba1b1e6815fac62ac517f Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 25 Oct 2023 22:12:03 +0200 Subject: [PATCH] chore: rewrite all error messages for consistency (#5176) Co-authored-by: Roman Krasiuk --- bin/reth/src/args/secret_key.rs | 2 +- bin/reth/src/args/utils.rs | 8 +- bin/reth/src/init.rs | 2 +- crates/consensus/beacon/src/engine/error.rs | 6 +- .../consensus/beacon/src/engine/hooks/mod.rs | 4 +- crates/consensus/beacon/src/engine/mod.rs | 2 +- .../interfaces/src/blockchain_tree/error.rs | 28 ++--- crates/interfaces/src/consensus.rs | 74 +++++++------ crates/interfaces/src/db.rs | 45 ++++---- crates/interfaces/src/executor.rs | 67 +++++++----- crates/interfaces/src/p2p/error.rs | 32 +++--- crates/interfaces/src/p2p/headers/error.rs | 2 +- crates/interfaces/src/provider.rs | 95 ++++++++-------- crates/net/discv4/src/error.rs | 12 +-- crates/net/discv4/src/proto.rs | 38 ++++--- crates/net/dns/src/error.rs | 16 +-- crates/net/ecies/src/error.rs | 6 +- crates/net/eth-wire/src/disconnect.rs | 27 +++-- crates/net/eth-wire/src/errors/eth.rs | 10 +- crates/net/eth-wire/src/errors/p2p.rs | 2 +- crates/net/network-api/src/error.rs | 2 +- crates/net/network/src/error.rs | 6 +- crates/net/network/src/session/mod.rs | 2 +- crates/net/network/src/transactions.rs | 4 +- crates/payload/basic/src/lib.rs | 6 +- crates/payload/builder/src/error.rs | 4 +- crates/primitives/src/block.rs | 6 +- crates/primitives/src/constants/eip4844.rs | 6 +- crates/primitives/src/integer_list.rs | 4 +- crates/primitives/src/net.rs | 6 +- crates/primitives/src/prune/segment.rs | 4 +- crates/primitives/src/transaction/eip4844.rs | 16 +-- crates/primitives/src/transaction/error.rs | 30 +++--- crates/prune/src/error.rs | 4 +- .../src/tracing/builder/geth.rs | 7 +- .../src/tracing/builder/parity.rs | 7 +- .../revm-inspectors/src/tracing/js/mod.rs | 8 +- crates/revm/src/processor.rs | 6 +- crates/revm/src/state_change.rs | 91 ++++++++-------- crates/rpc/ipc/src/client.rs | 6 +- crates/rpc/rpc-builder/src/cors.rs | 2 +- crates/rpc/rpc-builder/src/error.rs | 12 ++- crates/rpc/rpc-engine-api/src/error.rs | 24 +++-- .../rpc-types/src/eth/engine/forkchoice.rs | 4 +- .../rpc/rpc-types/src/eth/engine/payload.rs | 14 +-- crates/rpc/rpc/src/blocking_pool.rs | 2 +- crates/rpc/rpc/src/eth/api/pending_block.rs | 6 +- crates/rpc/rpc/src/eth/error.rs | 71 ++++++------ crates/rpc/rpc/src/eth/filter.rs | 2 +- crates/rpc/rpc/src/layers/auth_layer.rs | 2 +- crates/rpc/rpc/src/layers/jwt_secret.rs | 10 +- crates/snapshot/src/error.rs | 4 +- crates/stages/src/error.rs | 33 +++--- crates/stages/src/stages/sender_recovery.rs | 6 +- crates/stages/src/stages/total_difficulty.rs | 2 +- crates/stages/src/test_utils/runner.rs | 6 +- .../storage/db/src/implementation/mdbx/mod.rs | 15 +-- crates/storage/db/src/tables/codecs/scale.rs | 3 +- crates/storage/db/src/tables/mod.rs | 70 ++++++------ .../storage/db/src/tables/models/accounts.rs | 3 +- .../db/src/tables/models/integer_list.rs | 2 +- crates/storage/db/src/tables/models/mod.rs | 16 +-- .../db/src/tables/models/sharded_key.rs | 2 +- .../src/tables/models/storage_sharded_key.rs | 2 +- crates/storage/db/src/version.rs | 9 +- crates/storage/nippy-jar/src/error.rs | 22 ++-- crates/transaction-pool/src/error.rs | 101 ++++++++++-------- crates/transaction-pool/src/noop.rs | 8 +- crates/transaction-pool/src/pool/mod.rs | 8 +- crates/transaction-pool/src/pool/txpool.rs | 60 ++++++----- crates/transaction-pool/src/validate/mod.rs | 2 +- crates/transaction-pool/tests/it/blobs.rs | 8 +- testing/ef-tests/src/result.rs | 14 +-- 73 files changed, 649 insertions(+), 599 deletions(-) diff --git a/bin/reth/src/args/secret_key.rs b/bin/reth/src/args/secret_key.rs index 7ff36bfb3b..9ecb1792eb 100644 --- a/bin/reth/src/args/secret_key.rs +++ b/bin/reth/src/args/secret_key.rs @@ -15,7 +15,7 @@ pub enum SecretKeyError { SecretKeyDecodeError(#[from] SecretKeyBaseError), #[error(transparent)] SecretKeyFsPathError(#[from] FsPathError), - #[error("Failed to access key file {secret_file:?}: {error}")] + #[error("failed to access key file {secret_file:?}: {error}")] FailedToAccessKeyFile { error: io::Error, secret_file: PathBuf }, } diff --git a/bin/reth/src/args/utils.rs b/bin/reth/src/args/utils.rs index 3a59556aab..b0035f1c64 100644 --- a/bin/reth/src/args/utils.rs +++ b/bin/reth/src/args/utils.rs @@ -63,16 +63,16 @@ pub fn hash_or_num_value_parser(value: &str) -> eyre::Result = Result; #[derive(Debug, thiserror::Error)] pub enum BeaconConsensusEngineError { /// Pipeline channel closed. - #[error("Pipeline channel closed")] + #[error("pipeline channel closed")] PipelineChannelClosed, /// Pipeline error. #[error(transparent)] Pipeline(#[from] Box), /// Pruner channel closed. - #[error("Pruner channel closed")] + #[error("pruner channel closed")] PrunerChannelClosed, /// Hook error. #[error(transparent)] @@ -50,7 +50,7 @@ impl From for BeaconConsensusEngineError { #[derive(Debug, thiserror::Error)] pub enum BeaconForkChoiceUpdateError { /// Thrown when a forkchoice update resulted in an error. - #[error("Forkchoice update error: {0}")] + #[error("forkchoice update error: {0}")] ForkchoiceUpdateError(#[from] ForkchoiceUpdateError), /// Internal errors, for example, error while reading from the database. #[error(transparent)] diff --git a/crates/consensus/beacon/src/engine/hooks/mod.rs b/crates/consensus/beacon/src/engine/hooks/mod.rs index a619e99900..3b4144c383 100644 --- a/crates/consensus/beacon/src/engine/hooks/mod.rs +++ b/crates/consensus/beacon/src/engine/hooks/mod.rs @@ -102,13 +102,13 @@ pub enum EngineHookAction {} #[derive(Debug, thiserror::Error)] pub enum EngineHookError { /// Hook channel closed. - #[error("Hook channel closed")] + #[error("hook channel closed")] ChannelClosed, /// Common error. Wrapper around [RethError]. #[error(transparent)] Common(#[from] RethError), /// An internal error occurred. - #[error("Internal hook error occurred.")] + #[error(transparent)] Internal(#[from] Box), } diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index 496b47d1d2..8ed944fc96 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -868,7 +868,7 @@ where head_block.total_difficulty = self.blockchain.header_td_by_number(head_block.number)?.ok_or_else(|| { RethError::Provider(ProviderError::TotalDifficultyNotFound { - number: head_block.number, + block_number: head_block.number, }) })?; self.sync_state_updater.update_status(head_block); diff --git a/crates/interfaces/src/blockchain_tree/error.rs b/crates/interfaces/src/blockchain_tree/error.rs index 695902fb0c..43dedf40b8 100644 --- a/crates/interfaces/src/blockchain_tree/error.rs +++ b/crates/interfaces/src/blockchain_tree/error.rs @@ -11,37 +11,37 @@ use reth_primitives::{BlockHash, BlockNumber, SealedBlock}; #[allow(missing_docs)] pub enum BlockchainTreeError { /// Thrown if the block number is lower than the last finalized block number. - #[error("Block number is lower than the last finalized block number #{last_finalized}")] + #[error("block number is lower than the last finalized block number #{last_finalized}")] PendingBlockIsFinalized { /// The block number of the last finalized block. last_finalized: BlockNumber, }, /// Thrown if no side chain could be found for the block. - #[error("BlockChainId can't be found in BlockchainTree with internal index {chain_id}")] + #[error("blockChainId can't be found in BlockchainTree with internal index {chain_id}")] BlockSideChainIdConsistency { /// The internal identifier for the side chain. chain_id: u64, }, /// Thrown if a canonical chain header cannot be found. - #[error("Canonical chain header #{block_hash} can't be found ")] + #[error("canonical chain header {block_hash} can't be found")] CanonicalChain { /// The block hash of the missing canonical chain header. block_hash: BlockHash, }, /// Thrown if a block number cannot be found in the blockchain tree chain. - #[error("Block number #{block_number} not found in blockchain tree chain")] + #[error("block number #{block_number} not found in blockchain tree chain")] BlockNumberNotFoundInChain { /// The block number that could not be found. block_number: BlockNumber, }, /// Thrown if a block hash cannot be found in the blockchain tree chain. - #[error("Block hash {block_hash} not found in blockchain tree chain")] + #[error("block hash {block_hash} not found in blockchain tree chain")] BlockHashNotFoundInChain { /// The block hash that could not be found. block_hash: BlockHash, }, // Thrown if the block failed to buffer - #[error("Block with hash {block_hash:?} failed to buffer")] + #[error("block with hash {block_hash} failed to buffer")] BlockBufferingFailed { /// The block hash of the block that failed to buffer. block_hash: BlockHash, @@ -62,10 +62,10 @@ pub enum CanonicalError { #[error(transparent)] BlockchainTree(#[from] BlockchainTreeError), /// Error indicating a transaction reverted during execution. - #[error("Transaction error on revert: {inner:?}")] + #[error("transaction error on revert: {inner}")] CanonicalRevert { inner: String }, /// Error indicating a transaction failed to commit during execution. - #[error("Transaction error on commit: {inner:?}")] + #[error("transaction error on commit: {inner}")] CanonicalCommit { inner: String }, } @@ -190,23 +190,23 @@ impl InsertBlockErrorData { #[derive(Debug, thiserror::Error)] pub enum InsertBlockErrorKind { /// Failed to recover senders for the block - #[error("Failed to recover senders for block")] + #[error("failed to recover senders for block")] SenderRecovery, /// Block violated consensus rules. #[error(transparent)] - Consensus(ConsensusError), + Consensus(#[from] ConsensusError), /// Block execution failed. #[error(transparent)] - Execution(BlockExecutionError), + Execution(#[from] BlockExecutionError), /// Block violated tree invariants. #[error(transparent)] Tree(#[from] BlockchainTreeError), /// An internal error occurred, like interacting with the database. - #[error("Internal error")] - Internal(Box), + #[error(transparent)] + Internal(#[from] Box), /// Canonical error. #[error(transparent)] - Canonical(CanonicalError), + Canonical(#[from] CanonicalError), /// BlockchainTree error. #[error(transparent)] BlockchainTree(BlockchainTreeError), diff --git a/crates/interfaces/src/consensus.rs b/crates/interfaces/src/consensus.rs index 4e8c1d8e5e..0a68d139ec 100644 --- a/crates/interfaces/src/consensus.rs +++ b/crates/interfaces/src/consensus.rs @@ -82,7 +82,7 @@ pub trait Consensus: Debug + Send + Sync { #[derive(thiserror::Error, Debug, PartialEq, Eq, Clone)] pub enum ConsensusError { /// Error when the gas used in the header exceeds the gas limit. - #[error("Block used gas ({gas_used}) is greater than gas limit ({gas_limit}).")] + #[error("block used gas ({gas_used}) is greater than gas limit ({gas_limit})")] HeaderGasUsedExceedsGasLimit { /// The gas used in the block header. gas_used: u64, @@ -91,7 +91,7 @@ pub enum ConsensusError { }, /// Error when the hash of block ommer is different from the expected hash. - #[error("Block ommer hash ({got:?}) is different from expected: ({expected:?})")] + #[error("block ommer hash ({got}) is different from expected ({expected})")] BodyOmmersHashDiff { /// The actual ommer hash. got: B256, @@ -100,7 +100,7 @@ pub enum ConsensusError { }, /// Error when the state root in the block is different from the expected state root. - #[error("Block state root ({got:?}) is different from expected: ({expected:?})")] + #[error("block state root ({got}) is different from expected ({expected})")] BodyStateRootDiff { /// The actual state root. got: B256, @@ -110,7 +110,7 @@ pub enum ConsensusError { /// Error when the transaction root in the block is different from the expected transaction /// root. - #[error("Block transaction root ({got:?}) is different from expected ({expected:?})")] + #[error("block transaction root ({got}) is different from expected ({expected})")] BodyTransactionRootDiff { /// The actual transaction root. got: B256, @@ -120,7 +120,7 @@ pub enum ConsensusError { /// Error when the withdrawals root in the block is different from the expected withdrawals /// root. - #[error("Block withdrawals root ({got:?}) is different from expected ({expected:?})")] + #[error("block withdrawals root ({got}) is different from expected ({expected})")] BodyWithdrawalsRootDiff { /// The actual withdrawals root. got: B256, @@ -129,7 +129,7 @@ pub enum ConsensusError { }, /// Error when a block with a specific hash and number is already known. - #[error("Block with [hash:{hash:?},number: {number}] is already known.")] + #[error("block with [hash={hash}, number={number}] is already known")] BlockKnown { /// The hash of the known block. hash: BlockHash, @@ -138,7 +138,7 @@ pub enum ConsensusError { }, /// Error when the parent hash of a block is not known. - #[error("Block parent [hash:{hash:?}] is not known.")] + #[error("block parent [hash={hash}] is not known")] ParentUnknown { /// The hash of the unknown parent block. hash: BlockHash, @@ -146,7 +146,7 @@ pub enum ConsensusError { /// Error when the block number does not match the parent block number. #[error( - "Block number {block_number} does not match parent block number {parent_block_number}" + "block number {block_number} does not match parent block number {parent_block_number}" )] ParentBlockNumberMismatch { /// The parent block number. @@ -156,9 +156,7 @@ pub enum ConsensusError { }, /// Error when the parent hash does not match the expected parent hash. - #[error( - "Parent hash {got_parent_hash:?} does not match the expected {expected_parent_hash:?}" - )] + #[error("parent hash {got_parent_hash} does not match the expected {expected_parent_hash}")] ParentHashMismatch { /// The expected parent hash. expected_parent_hash: B256, @@ -167,7 +165,7 @@ pub enum ConsensusError { }, /// Error when the block timestamp is in the past compared to the parent timestamp. - #[error("Block timestamp {timestamp} is in the past compared to the parent timestamp {parent_timestamp}.")] + #[error("block timestamp {timestamp} is in the past compared to the parent timestamp {parent_timestamp}")] TimestampIsInPast { /// The parent block's timestamp. parent_timestamp: u64, @@ -176,7 +174,7 @@ pub enum ConsensusError { }, /// Error when the block timestamp is in the future compared to our clock time. - #[error("Block timestamp {timestamp} is in the future compared to our clock time {present_timestamp}.")] + #[error("block timestamp {timestamp} is in the future compared to our clock time {present_timestamp}")] TimestampIsInFuture { /// The block's timestamp. timestamp: u64, @@ -185,7 +183,7 @@ pub enum ConsensusError { }, /// Error when the child gas limit exceeds the maximum allowed increase. - #[error("Child gas_limit {child_gas_limit} max increase is {parent_gas_limit}/1024.")] + #[error("child gas_limit {child_gas_limit} max increase is {parent_gas_limit}/1024")] GasLimitInvalidIncrease { /// The parent gas limit. parent_gas_limit: u64, @@ -194,7 +192,7 @@ pub enum ConsensusError { }, /// Error when the child gas limit exceeds the maximum allowed decrease. - #[error("Child gas_limit {child_gas_limit} max decrease is {parent_gas_limit}/1024.")] + #[error("child gas_limit {child_gas_limit} max decrease is {parent_gas_limit}/1024")] GasLimitInvalidDecrease { /// The parent gas limit. parent_gas_limit: u64, @@ -203,11 +201,11 @@ pub enum ConsensusError { }, /// Error when the base fee is missing. - #[error("Base fee missing.")] + #[error("base fee missing")] BaseFeeMissing, /// Error when the block's base fee is different from the expected base fee. - #[error("Block base fee ({got}) is different than expected: ({expected}).")] + #[error("block base fee ({got}) is different than expected: ({expected})")] BaseFeeDiff { /// The expected base fee. expected: u64, @@ -216,66 +214,66 @@ pub enum ConsensusError { }, /// Error when there is a transaction signer recovery error. - #[error("Transaction signer recovery error.")] + #[error("transaction signer recovery error")] TransactionSignerRecoveryError, /// Error when the extra data length exceeds the maximum allowed. - #[error("Extra data {len} exceeds max length.")] + #[error("extra data {len} exceeds max length")] ExtraDataExceedsMax { /// The length of the extra data. len: usize, }, /// Error when the difficulty after a merge is not zero. - #[error("Difficulty after merge is not zero")] + #[error("difficulty after merge is not zero")] TheMergeDifficultyIsNotZero, /// Error when the nonce after a merge is not zero. - #[error("Nonce after merge is not zero")] + #[error("nonce after merge is not zero")] TheMergeNonceIsNotZero, /// Error when the ommer root after a merge is not empty. - #[error("Ommer root after merge is not empty")] + #[error("ommer root after merge is not empty")] TheMergeOmmerRootIsNotEmpty, /// Error when the withdrawals root is missing. - #[error("Missing withdrawals root")] + #[error("missing withdrawals root")] WithdrawalsRootMissing, /// Error when an unexpected withdrawals root is encountered. - #[error("Unexpected withdrawals root")] + #[error("unexpected withdrawals root")] WithdrawalsRootUnexpected, /// Error when withdrawals are missing. - #[error("Missing withdrawals")] + #[error("missing withdrawals")] BodyWithdrawalsMissing, /// Error when blob gas used is missing. - #[error("Missing blob gas used")] + #[error("missing blob gas used")] BlobGasUsedMissing, /// Error when unexpected blob gas used is encountered. - #[error("Unexpected blob gas used")] + #[error("unexpected blob gas used")] BlobGasUsedUnexpected, /// Error when excess blob gas is missing. - #[error("Missing excess blob gas")] + #[error("missing excess blob gas")] ExcessBlobGasMissing, /// Error when unexpected excess blob gas is encountered. - #[error("Unexpected excess blob gas")] + #[error("unexpected excess blob gas")] ExcessBlobGasUnexpected, /// Error when the parent beacon block root is missing. - #[error("Missing parent beacon block root")] + #[error("missing parent beacon block root")] ParentBeaconBlockRootMissing, /// Error when an unexpected parent beacon block root is encountered. - #[error("Unexpected parent beacon block root")] + #[error("unexpected parent beacon block root")] ParentBeaconBlockRootUnexpected, /// Error when blob gas used exceeds the maximum allowed. - #[error("Blob gas used {blob_gas_used} exceeds maximum allowance {max_blob_gas_per_block}")] + #[error("blob gas used {blob_gas_used} exceeds maximum allowance {max_blob_gas_per_block}")] BlobGasUsedExceedsMaxBlobGasPerBlock { /// The actual blob gas used. blob_gas_used: u64, @@ -285,7 +283,7 @@ pub enum ConsensusError { /// Error when blob gas used is not a multiple of blob gas per blob. #[error( - "Blob gas used {blob_gas_used} is not a multiple of blob gas per blob {blob_gas_per_blob}" + "blob gas used {blob_gas_used} is not a multiple of blob gas per blob {blob_gas_per_blob}" )] BlobGasUsedNotMultipleOfBlobGasPerBlob { /// The actual blob gas used. @@ -295,7 +293,10 @@ pub enum ConsensusError { }, /// Error when the blob gas used in the header does not match the expected blob gas used. - #[error("Blob gas used in the header {header_blob_gas_used} does not match the expected blob gas used {expected_blob_gas_used}")] + #[error( + "blob gas used in the header {header_blob_gas_used} \ + does not match the expected blob gas used {expected_blob_gas_used}" + )] BlobGasUsedDiff { /// The blob gas used in the header. header_blob_gas_used: u64, @@ -304,7 +305,10 @@ pub enum ConsensusError { }, /// Error when there is an invalid excess blob gas. - #[error("Invalid excess blob gas. Expected: {expected}, got: {got}. Parent excess blob gas: {parent_excess_blob_gas}, parent blob gas used: {parent_blob_gas_used}.")] + #[error( + "invalid excess blob gas. Expected: {expected}, got: {got}. \ + Parent excess blob gas: {parent_excess_blob_gas}, parent blob gas used: {parent_blob_gas_used}" + )] ExcessBlobGasDiff { /// The expected excess blob gas. expected: u64, diff --git a/crates/interfaces/src/db.rs b/crates/interfaces/src/db.rs index 7606e859ff..014b92e279 100644 --- a/crates/interfaces/src/db.rs +++ b/crates/interfaces/src/db.rs @@ -1,14 +1,17 @@ -/// Database error type. It uses i32 to represent an error code. +/// Database error type. #[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)] pub enum DatabaseError { - /// Failed to open database. - #[error("Failed to open database: {0:?}")] - FailedToOpen(i32), - /// Failed to create a table in database. - #[error("Table Creating error code: {0:?}")] - TableCreation(i32), + /// Failed to open the database. + #[error("failed to open the database ({0})")] + Open(i32), + /// Failed to create a table in the database. + #[error("failed to create a table ({0})")] + CreateTable(i32), /// Failed to write a value into a table. - #[error("Database write operation \"{operation:?}\" for key \"{key:?}\" in table \"{table_name}\" ended with error code: {code:?}")] + #[error( + "write operation {operation:?} failed for key \"{key}\" in table {table_name:?} ({code})", + key = reth_primitives::hex::encode(key), + )] Write { /// Database error code code: i32, @@ -20,32 +23,32 @@ pub enum DatabaseError { key: Box<[u8]>, }, /// Failed to read a value from a table. - #[error("Database read error code: {0:?}")] + #[error("failed to read a value from a database table ({0})")] Read(i32), /// Failed to delete a `(key, value)` pair from a table. - #[error("Database delete error code: {0:?}")] + #[error("database delete error code ({0})")] Delete(i32), /// Failed to commit transaction changes into the database. - #[error("Database commit error code: {0:?}")] + #[error("failed to commit transaction changes ({0})")] Commit(i32), /// Failed to initiate a transaction. - #[error("Initialization of transaction errored with code: {0:?}")] - InitTransaction(i32), - /// Failed to initiate a cursor. - #[error("Initialization of cursor errored with code: {0:?}")] + #[error("failed to initialize a transaction ({0})")] + InitTx(i32), + /// Failed to initialize a cursor. + #[error("failed to initialize a cursor ({0})")] InitCursor(i32), /// Failed to decode a key from a table. - #[error("Error decoding value.")] - DecodeError, + #[error("failed to decode a key from a table")] + Decode, /// Failed to get database stats. - #[error("Database stats error code: {0:?}")] + #[error("failed to get stats ({0})")] Stats(i32), /// Failed to use the specified log level, as it's not available. - #[error("Log level is not available: {0:?}")] + #[error("log level {0:?} is not available")] LogLevelUnavailable(LogLevel), } -/// Database write operation type +/// Database write operation type. #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[allow(missing_docs)] pub enum DatabaseWriteOperation { @@ -56,9 +59,9 @@ pub enum DatabaseWriteOperation { Put, } +/// Database log level. #[derive(Debug, PartialEq, Eq, Clone, Copy)] #[cfg_attr(feature = "clap", derive(clap::ValueEnum))] -/// Database log level. pub enum LogLevel { /// Enables logging for critical conditions, i.e. assertion failures. Fatal, diff --git a/crates/interfaces/src/executor.rs b/crates/interfaces/src/executor.rs index 4b6b1c4620..c3b62165cc 100644 --- a/crates/interfaces/src/executor.rs +++ b/crates/interfaces/src/executor.rs @@ -1,34 +1,36 @@ +use crate::RethError; use reth_primitives::{BlockNumHash, Bloom, PruneSegmentError, B256}; +use revm_primitives::EVMError; use thiserror::Error; /// Transaction validation errors -#[allow(missing_docs)] #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum BlockValidationError { /// EVM error with transaction hash and message - #[error("EVM reported invalid transaction ({hash:?}): {message}")] + #[error("EVM reported invalid transaction ({hash}): {error}")] EVM { /// The hash of the transaction hash: B256, - /// Error message - message: String, + /// The EVM error. + #[source] + error: Box>, }, /// Error when recovering the sender for a transaction - #[error("Failed to recover sender for transaction")] + #[error("failed to recover sender for transaction")] SenderRecoveryError, /// Error when incrementing balance in post execution - #[error("Incrementing balance in post execution failed")] + #[error("incrementing balance in post execution failed")] IncrementBalanceFailed, /// Error when receipt root doesn't match expected value - #[error("Receipt root {got:?} is different than expected {expected:?}.")] + #[error("receipt root {got} is different than expected {expected}")] ReceiptRootDiff { /// The actual receipt root - got: B256, + got: Box, /// The expected receipt root - expected: B256, + expected: Box, }, /// Error when header bloom filter doesn't match expected value - #[error("Header bloom filter {got:?} is different than expected {expected:?}.")] + #[error("header bloom filter {got} is different than expected {expected}")] BloomLogDiff { /// The actual bloom filter got: Box, @@ -36,7 +38,7 @@ pub enum BlockValidationError { expected: Box, }, /// Error when transaction gas limit exceeds available block gas - #[error("Transaction gas limit {transaction_gas_limit} is more than blocks available gas {block_available_gas}")] + #[error("transaction gas limit {transaction_gas_limit} is more than blocks available gas {block_available_gas}")] TransactionGasLimitMoreThanAvailableBlockGas { /// The transaction's gas limit transaction_gas_limit: u64, @@ -44,7 +46,10 @@ pub enum BlockValidationError { block_available_gas: u64, }, /// Error when block gas used doesn't match expected value - #[error("Block gas used {got} is different from expected gas used {expected}.\nGas spent by each transaction: {gas_spent_by_tx:?}\n")] + #[error( + "block gas used {got} is different from expected gas used {expected}.\n\ + Gas spent by each transaction: {gas_spent_by_tx:?}" + )] BlockGasUsed { /// The actual gas used got: u64, @@ -54,23 +59,37 @@ pub enum BlockValidationError { gas_spent_by_tx: Vec<(u64, u64)>, }, /// Error for pre-merge block - #[error("Block {hash:?} is pre merge")] + #[error("block {hash} is pre merge")] BlockPreMerge { /// The hash of the block hash: B256, }, - #[error("Missing total difficulty for block {hash:?}")] - MissingTotalDifficulty { hash: B256 }, + /// Error for missing total difficulty + #[error("missing total difficulty for block {hash}")] + MissingTotalDifficulty { + /// The hash of the block + hash: B256, + }, /// Error for EIP-4788 when parent beacon block root is missing - #[error("EIP-4788 Parent beacon block root missing for active Cancun block")] + #[error("EIP-4788 parent beacon block root missing for active Cancun block")] MissingParentBeaconBlockRoot, /// Error for Cancun genesis block when parent beacon block root is not zero - #[error("The parent beacon block root is not zero for Cancun genesis block")] - CancunGenesisParentBeaconBlockRootNotZero, + #[error("the parent beacon block root is not zero for Cancun genesis block: {parent_beacon_block_root}")] + CancunGenesisParentBeaconBlockRootNotZero { + /// The beacon block root + parent_beacon_block_root: B256, + }, + /// EVM error during beacon root contract call + #[error("failed to apply beacon root contract call at {parent_beacon_block_root}: {message}")] + BeaconRootContractCall { + /// The beacon block root + parent_beacon_block_root: Box, + /// The error message. + message: String, + }, } /// BlockExecutor Errors -#[allow(missing_docs)] #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum BlockExecutionError { /// Validation error, transparently wrapping `BlockValidationError` @@ -80,23 +99,23 @@ pub enum BlockExecutionError { #[error(transparent)] Pruning(#[from] PruneSegmentError), /// Error representing a provider error - #[error("Provider error")] + #[error("provider error")] ProviderError, /// Transaction error on revert with inner details - #[error("Transaction error on revert: {inner:?}")] + #[error("transaction error on revert: {inner}")] CanonicalRevert { /// The inner error message inner: String, }, /// Transaction error on commit with inner details - #[error("Transaction error on commit: {inner:?}")] + #[error("transaction error on commit: {inner}")] CanonicalCommit { /// The inner error message inner: String, }, /// Error when appending chain on fork is not possible #[error( - "Appending chain on fork (other_chain_fork:?) is not possible as the tip is {chain_tip:?}" + "appending chain on fork (other_chain_fork:?) is not possible as the tip is {chain_tip:?}" )] AppendChainDoesntConnect { /// The tip of the current chain @@ -107,7 +126,7 @@ pub enum BlockExecutionError { /// Only used for TestExecutor /// /// Note: this is not feature gated for convenience. - #[error("Execution unavailable for tests")] + #[error("execution unavailable for tests")] UnavailableForTest, } diff --git a/crates/interfaces/src/p2p/error.rs b/crates/interfaces/src/p2p/error.rs index 89257e200a..06259f5512 100644 --- a/crates/interfaces/src/p2p/error.rs +++ b/crates/interfaces/src/p2p/error.rs @@ -73,15 +73,15 @@ impl EthResponseValidator for RequestResult> { #[derive(Clone, Debug, Error, Eq, PartialEq)] #[allow(missing_docs)] pub enum RequestError { - #[error("Closed channel to the peer.")] + #[error("closed channel to the peer")] ChannelClosed, - #[error("Connection to a peer dropped while handling the request.")] + #[error("connection to a peer dropped while handling the request")] ConnectionDropped, - #[error("Capability Message is not supported by remote peer.")] + #[error("capability message is not supported by remote peer")] UnsupportedCapability, - #[error("Request timed out while awaiting response.")] + #[error("request timed out while awaiting response")] Timeout, - #[error("Received bad response.")] + #[error("received bad response")] BadResponse, } @@ -119,7 +119,7 @@ pub type DownloadResult = Result; pub enum DownloadError { /* ==================== HEADER ERRORS ==================== */ /// Header validation failed - #[error("Failed to validate header {hash}. Details: {error}.")] + #[error("failed to validate header {hash}: {error}")] HeaderValidation { /// Hash of header failing validation hash: B256, @@ -128,7 +128,7 @@ pub enum DownloadError { error: consensus::ConsensusError, }, /// Received an invalid tip - #[error("Received invalid tip: {received:?}. Expected {expected:?}.")] + #[error("received invalid tip: {received}. Expected {expected}")] InvalidTip { /// The hash of the received tip received: B256, @@ -136,7 +136,7 @@ pub enum DownloadError { expected: B256, }, /// Received a tip with an invalid tip number - #[error("Received invalid tip number: {received:?}. Expected {expected:?}.")] + #[error("received invalid tip number: {received}. Expected {expected}")] InvalidTipNumber { /// The block number of the received tip received: u64, @@ -144,7 +144,7 @@ pub enum DownloadError { expected: u64, }, /// Received a response to a request with unexpected start block - #[error("Headers response starts at unexpected block: {received:?}. Expected {expected:?}.")] + #[error("headers response starts at unexpected block: {received}. Expected {expected}")] HeadersResponseStartBlockMismatch { /// The block number of the received tip received: u64, @@ -152,7 +152,7 @@ pub enum DownloadError { expected: u64, }, /// Received headers with less than expected items. - #[error("Received less headers than expected: {received:?}. Expected {expected:?}.")] + #[error("received less headers than expected: {received}. Expected {expected}")] HeadersResponseTooShort { /// How many headers we received. received: u64, @@ -161,7 +161,7 @@ pub enum DownloadError { }, /* ==================== BODIES ERRORS ==================== */ /// Block validation failed - #[error("Failed to validate body for header {hash}. Details: {error}.")] + #[error("failed to validate body for header {hash}: {error}")] BodyValidation { /// Hash of header failing validation hash: B256, @@ -170,7 +170,7 @@ pub enum DownloadError { error: consensus::ConsensusError, }, /// Received more bodies than requested. - #[error("Received more bodies than requested. Expected: {expected}. Received: {received}")] + #[error("received more bodies than requested. Expected: {expected}. Received: {received}")] TooManyBodies { /// How many bodies we received. received: usize, @@ -178,23 +178,23 @@ pub enum DownloadError { expected: usize, }, /// Headers missing from the database. - #[error("Header missing from the database: {block_number}")] + #[error("header missing from the database: {block_number}")] MissingHeader { /// Missing header block number. block_number: BlockNumber, }, /// Body range invalid - #[error("Requested body range is invalid: {range:?}.")] + #[error("requested body range is invalid: {range:?}")] InvalidBodyRange { /// Invalid block number range. range: RangeInclusive, }, /* ==================== COMMON ERRORS ==================== */ /// Timed out while waiting for request id response. - #[error("Timed out while waiting for response.")] + #[error("timed out while waiting for response")] Timeout, /// Received empty response while expecting non empty - #[error("Received empty response.")] + #[error("received empty response")] EmptyResponse, /// Error while executing the request. #[error(transparent)] diff --git a/crates/interfaces/src/p2p/headers/error.rs b/crates/interfaces/src/p2p/headers/error.rs index 483abc7d2e..ce4f6c46b6 100644 --- a/crates/interfaces/src/p2p/headers/error.rs +++ b/crates/interfaces/src/p2p/headers/error.rs @@ -10,7 +10,7 @@ pub type HeadersDownloaderResult = Result; pub enum HeadersDownloaderError { /// The downloaded header cannot be attached to the local head, /// but is valid otherwise. - #[error("Valid downloaded header cannot be attached to the local head. Details: {error}.")] + #[error("valid downloaded header cannot be attached to the local head: {error}")] DetachedHead { /// The local head we attempted to attach to. local_head: SealedHeader, diff --git a/crates/interfaces/src/provider.rs b/crates/interfaces/src/provider.rs index 68439c0cbb..ec86cf15ef 100644 --- a/crates/interfaces/src/provider.rs +++ b/crates/interfaces/src/provider.rs @@ -1,89 +1,95 @@ use reth_primitives::{Address, BlockHash, BlockHashOrNumber, BlockNumber, TxNumber, B256}; /// Bundled errors variants thrown by various providers. -#[allow(missing_docs)] #[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)] pub enum ProviderError { + /// Database error. #[error(transparent)] Database(#[from] crate::db::DatabaseError), /// The header number was not found for the given block hash. - #[error("Block hash {0:?} does not exist in Headers table")] + #[error("block hash {0:?} does not exist in Headers table")] BlockHashNotFound(BlockHash), /// A block body is missing. - #[error("Block meta not found for block #{0}")] + #[error("block meta not found for block #{0}")] BlockBodyIndicesNotFound(BlockNumber), /// The transition id was found for the given address and storage key, but the changeset was /// not found. - #[error("Storage ChangeSet address: ({address:?} key: {storage_key:?}) for block:#{block_number} does not exist")] + #[error("storage ChangeSet address: ({address:?} key: {storage_key:?}) for block:#{block_number} does not exist")] StorageChangesetNotFound { - /// The block number found for the address and storage key + /// The block number found for the address and storage key. block_number: BlockNumber, - /// The account address + /// The account address. address: Address, - /// The storage key + /// The storage key. storage_key: B256, }, /// The block number was found for the given address, but the changeset was not found. - #[error("Account {address:?} ChangeSet for block #{block_number} does not exist")] + #[error("account {address:?} ChangeSet for block #{block_number} does not exist")] AccountChangesetNotFound { - /// Block number found for the address + /// Block number found for the address. block_number: BlockNumber, - /// The account address + /// The account address. address: Address, }, /// The total difficulty for a block is missing. - #[error("Total difficulty not found for block #{number}")] - TotalDifficultyNotFound { number: BlockNumber }, - /// Thrown when required header related data was not found but was required. - #[error("No header found for {0:?}")] + #[error("total difficulty not found for block #{block_number}")] + TotalDifficultyNotFound { + /// The block number. + block_number: BlockNumber, + }, + /// when required header related data was not found but was required. + #[error("no header found for {0:?}")] HeaderNotFound(BlockHashOrNumber), - /// Thrown we were unable to find a specific block - #[error("Block does not exist {0:?}")] + /// Unable to find a specific block. + #[error("block does not exist {0:?}")] BlockNotFound(BlockHashOrNumber), - /// Thrown we were unable to find the best block - #[error("Best block does not exist")] + /// Unable to find the best block. + #[error("best block does not exist")] BestBlockNotFound, - /// Thrown we were unable to find the finalized block - #[error("Finalized block does not exist")] + /// Unable to find the finalized block. + #[error("finalized block does not exist")] FinalizedBlockNotFound, - /// Thrown we were unable to find the safe block - #[error("Safe block does not exist")] + /// Unable to find the safe block. + #[error("safe block does not exist")] SafeBlockNotFound, - /// Mismatch of sender and transaction - #[error("Mismatch of sender and transaction id {tx_id}")] - MismatchOfTransactionAndSenderId { tx_id: TxNumber }, - /// Block body wrong transaction count - #[error("Stored block indices does not match transaction count")] + /// Mismatch of sender and transaction. + #[error("mismatch of sender and transaction id {tx_id}")] + MismatchOfTransactionAndSenderId { + /// The transaction ID. + tx_id: TxNumber, + }, + /// Block body wrong transaction count. + #[error("stored block indices does not match transaction count")] BlockBodyTransactionCount, - /// Thrown when the cache service task dropped + /// Thrown when the cache service task dropped. #[error("cache service task stopped")] CacheServiceUnavailable, - /// Thrown when we failed to lookup a block for the pending state - #[error("Unknown block hash: {0:}")] + /// Thrown when we failed to lookup a block for the pending state. + #[error("unknown block {0}")] UnknownBlockHash(B256), - /// Thrown when we were unable to find a state for a block hash - #[error("No State found for block hash: {0:}")] + /// Thrown when we were unable to find a state for a block hash. + #[error("no state found for block {0}")] StateForHashNotFound(B256), - /// Unable to compute state root on top of historical block - #[error("Unable to compute state root on top of historical block")] + /// Unable to compute state root on top of historical block. + #[error("unable to compute state root on top of historical block")] StateRootNotAvailableForHistoricalBlock, - /// Unable to find the block number for a given transaction index - #[error("Unable to find the block number for a given transaction index")] + /// Unable to find the block number for a given transaction index. + #[error("unable to find the block number for a given transaction index")] BlockNumberForTransactionIndexNotFound, - /// Root mismatch - #[error("Merkle trie root mismatch at #{block_number} ({block_hash:?}). Got: {got:?}. Expected: {expected:?}")] + /// Root mismatch. + #[error("merkle trie root mismatch at #{block_number} ({block_hash}): got {got}, expected {expected}")] StateRootMismatch { - /// Expected root + /// The expected root. expected: B256, - /// Calculated root + /// The calculated root. got: B256, - /// Block number + /// The block number. block_number: BlockNumber, - /// Block hash + /// The block hash. block_hash: BlockHash, }, /// Root mismatch during unwind - #[error("Unwind merkle trie root mismatch at #{block_number} ({block_hash:?}). Got: {got:?}. Expected: {expected:?}")] + #[error("unwind merkle trie root mismatch at #{block_number} ({block_hash}): got {got}, expected {expected}")] UnwindStateRootMismatch { /// Expected root expected: B256, @@ -94,6 +100,7 @@ pub enum ProviderError { /// Block hash block_hash: BlockHash, }, - #[error("State at block #{0} is pruned")] + /// State is not available for the given block number because it is pruned. + #[error("state at block #{0} is pruned")] StateAtBlockPruned(BlockNumber), } diff --git a/crates/net/discv4/src/error.rs b/crates/net/discv4/src/error.rs index 580f0e23d8..19ab703cbc 100644 --- a/crates/net/discv4/src/error.rs +++ b/crates/net/discv4/src/error.rs @@ -6,15 +6,15 @@ use tokio::sync::{mpsc::error::SendError, oneshot::error::RecvError}; #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] pub enum DecodePacketError { - #[error("Failed to rlp decode: {0:?}")] + #[error("failed to rlp decode: {0}")] Rlp(#[from] alloy_rlp::Error), - #[error("Received packet len too short.")] + #[error("received packet length is too short")] PacketTooShort, - #[error("Hash of the header not equals to the hash of the data.")] + #[error("header/data hash mismatch")] HashMismatch, - #[error("Message id {0} is not supported.")] + #[error("message ID {0} is not supported")] UnknownMessage(u8), - #[error("Failed to recover public key: {0:?}")] + #[error("failed to recover public key: {0}")] Secp256k1(#[from] secp256k1::Error), } @@ -22,7 +22,7 @@ pub enum DecodePacketError { #[derive(Debug, thiserror::Error)] pub enum Discv4Error { /// Failed to send a command over the channel - #[error("Failed to send on a closed channel")] + #[error("failed to send on a closed channel")] Send, /// Failed to receive a command response #[error(transparent)] diff --git a/crates/net/discv4/src/proto.rs b/crates/net/discv4/src/proto.rs index 998ddd8697..0c4816d259 100644 --- a/crates/net/discv4/src/proto.rs +++ b/crates/net/discv4/src/proto.rs @@ -256,26 +256,30 @@ where } } +fn to_alloy_rlp_error(e: rlp::DecoderError) -> RlpError { + match e { + rlp::DecoderError::RlpIsTooShort => RlpError::InputTooShort, + rlp::DecoderError::RlpInvalidLength => RlpError::Overflow, + rlp::DecoderError::RlpExpectedToBeList => RlpError::UnexpectedString, + rlp::DecoderError::RlpExpectedToBeData => RlpError::UnexpectedList, + rlp::DecoderError::RlpDataLenWithZeroPrefix | + rlp::DecoderError::RlpListLenWithZeroPrefix => RlpError::LeadingZero, + rlp::DecoderError::RlpInvalidIndirection => RlpError::NonCanonicalSize, + rlp::DecoderError::RlpIncorrectListLen => { + RlpError::Custom("incorrect list length when decoding rlp") + } + rlp::DecoderError::RlpIsTooBig => RlpError::Custom("rlp is too big"), + rlp::DecoderError::RlpInconsistentLengthAndData => { + RlpError::Custom("inconsistent length and data when decoding rlp") + } + rlp::DecoderError::Custom(s) => RlpError::Custom(s), + } +} + impl Decodable for EnrWrapper { fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let enr = as rlp::Decodable>::decode(&rlp::Rlp::new(buf)) - .map_err(|e| match e { - rlp::DecoderError::RlpIsTooShort => RlpError::InputTooShort, - rlp::DecoderError::RlpInvalidLength => RlpError::Overflow, - rlp::DecoderError::RlpExpectedToBeList => RlpError::UnexpectedString, - rlp::DecoderError::RlpExpectedToBeData => RlpError::UnexpectedList, - rlp::DecoderError::RlpDataLenWithZeroPrefix | - rlp::DecoderError::RlpListLenWithZeroPrefix => RlpError::LeadingZero, - rlp::DecoderError::RlpInvalidIndirection => RlpError::NonCanonicalSize, - rlp::DecoderError::RlpIncorrectListLen => { - RlpError::Custom("incorrect list length when decoding rlp") - } - rlp::DecoderError::RlpIsTooBig => RlpError::Custom("rlp is too big"), - rlp::DecoderError::RlpInconsistentLengthAndData => { - RlpError::Custom("inconsistent length and data when decoding rlp") - } - rlp::DecoderError::Custom(s) => RlpError::Custom(s), - }) + .map_err(to_alloy_rlp_error) .map(EnrWrapper::new); if enr.is_ok() { // Decode was successful, advance buffer diff --git a/crates/net/dns/src/error.rs b/crates/net/dns/src/error.rs index a4469801e2..d24c83ab9d 100644 --- a/crates/net/dns/src/error.rs +++ b/crates/net/dns/src/error.rs @@ -9,17 +9,17 @@ pub(crate) type LookupResult = Result; #[derive(thiserror::Error, Debug)] #[allow(missing_docs)] pub enum ParseDnsEntryError { - #[error("Unknown entry: {0}")] + #[error("unknown entry: {0}")] UnknownEntry(String), - #[error("Field {0} not found.")] + #[error("field {0} not found")] FieldNotFound(&'static str), - #[error("Base64 decoding failed: {0}")] + #[error("base64 decoding failed: {0}")] Base64DecodeError(String), - #[error("Base32 decoding failed: {0}")] + #[error("base32 decoding failed: {0}")] Base32DecodeError(String), #[error("{0}")] RlpDecodeError(String), - #[error("Invalid child hash in branch: {0}")] + #[error("invalid child hash in branch: {0}")] InvalidChildHash(String), #[error("{0}")] Other(String), @@ -31,10 +31,10 @@ pub enum ParseDnsEntryError { pub(crate) enum LookupError { #[error(transparent)] Parse(#[from] ParseDnsEntryError), - #[error("Failed to verify root {0}")] + #[error("failed to verify root {0}")] InvalidRoot(TreeRootEntry), - #[error("Request timed out")] + #[error("request timed out")] RequestTimedOut, - #[error("Entry not found")] + #[error("entry not found")] EntryNotFound, } diff --git a/crates/net/ecies/src/error.rs b/crates/net/ecies/src/error.rs index 1a2a738c4b..ddeb5d2b5f 100644 --- a/crates/net/ecies/src/error.rs +++ b/crates/net/ecies/src/error.rs @@ -7,8 +7,6 @@ pub struct ECIESError { inner: Box, } -// === impl === - impl ECIESError { /// Consumes the type and returns the error enum pub fn into_inner(self) -> ECIESErrorImpl { @@ -38,7 +36,7 @@ impl std::error::Error for ECIESError { #[derive(Debug, Error)] pub enum ECIESErrorImpl { /// Error during IO - #[error("IO error")] + #[error(transparent)] IO(std::io::Error), /// Error when checking the HMAC tag against the tag on the message being decrypted #[error("tag check failure in read_header")] @@ -89,7 +87,7 @@ pub enum ECIESErrorImpl { /// [`Framed`](tokio_util::codec::Framed) is closed by the peer, See /// [ConnectionReset](std::io::ErrorKind::ConnectionReset) and the ecies codec fails to decode /// a message from the (partially filled) buffer. - #[error("Stream closed due to not being readable.")] + #[error("stream closed due to not being readable")] UnreadableStream, } diff --git a/crates/net/eth-wire/src/disconnect.rs b/crates/net/eth-wire/src/disconnect.rs index 8e51cfe4f4..aa3c6d220e 100644 --- a/crates/net/eth-wire/src/disconnect.rs +++ b/crates/net/eth-wire/src/disconnect.rs @@ -50,28 +50,27 @@ pub enum DisconnectReason { impl Display for DisconnectReason { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let message = match self { - DisconnectReason::DisconnectRequested => "Disconnect requested", + DisconnectReason::DisconnectRequested => "disconnect requested", DisconnectReason::TcpSubsystemError => "TCP sub-system error", DisconnectReason::ProtocolBreach => { - "Breach of protocol, e.g. a malformed message, bad RLP, ..." + "breach of protocol, e.g. a malformed message, bad RLP, etc." } - DisconnectReason::UselessPeer => "Useless peer", - DisconnectReason::TooManyPeers => "Too many peers", - DisconnectReason::AlreadyConnected => "Already connected", - DisconnectReason::IncompatibleP2PProtocolVersion => "Incompatible P2P protocol version", + DisconnectReason::UselessPeer => "useless peer", + DisconnectReason::TooManyPeers => "too many peers", + DisconnectReason::AlreadyConnected => "already connected", + DisconnectReason::IncompatibleP2PProtocolVersion => "incompatible P2P protocol version", DisconnectReason::NullNodeIdentity => { - "Null node identity received - this is automatically invalid" + "null node identity received - this is automatically invalid" } - DisconnectReason::ClientQuitting => "Client quitting", - DisconnectReason::UnexpectedHandshakeIdentity => "Unexpected identity in handshake", + DisconnectReason::ClientQuitting => "client quitting", + DisconnectReason::UnexpectedHandshakeIdentity => "unexpected identity in handshake", DisconnectReason::ConnectedToSelf => { - "Identity is the same as this node (i.e. connected to itself)" + "identity is the same as this node (i.e. connected to itself)" } - DisconnectReason::PingTimeout => "Ping timeout", - DisconnectReason::SubprotocolSpecific => "Some other reason specific to a subprotocol", + DisconnectReason::PingTimeout => "ping timeout", + DisconnectReason::SubprotocolSpecific => "some other reason specific to a subprotocol", }; - - write!(f, "{message}") + f.write_str(message) } } diff --git a/crates/net/eth-wire/src/errors/eth.rs b/crates/net/eth-wire/src/errors/eth.rs index e120c61ee8..49c6f49413 100644 --- a/crates/net/eth-wire/src/errors/eth.rs +++ b/crates/net/eth-wire/src/errors/eth.rs @@ -15,7 +15,7 @@ pub enum EthStreamError { ParseVersionError(#[from] ParseVersionError), #[error(transparent)] EthHandshakeError(#[from] EthHandshakeError), - #[error("For {0:?} version, message id({1:?}) is invalid")] + #[error("message id {1:?} is invalid for version {0:?}")] EthInvalidMessageError(EthVersion, EthMessageID), #[error("message size ({0}) exceeds max length (10MB)")] MessageTooBig(usize), @@ -68,12 +68,12 @@ pub enum EthHandshakeError { NoResponse, #[error(transparent)] InvalidFork(#[from] ValidationError), - #[error("mismatched genesis in Status message. expected: {expected:?}, got: {got:?}")] + #[error("mismatched genesis in status message: got {got}, expected {expected}")] MismatchedGenesis { expected: B256, got: B256 }, - #[error("mismatched protocol version in Status message. expected: {expected:?}, got: {got:?}")] + #[error("mismatched protocol version in status message: got {got}, expected {expected}")] MismatchedProtocolVersion { expected: u8, got: u8 }, - #[error("mismatched chain in Status message. expected: {expected:?}, got: {got:?}")] + #[error("mismatched chain in status message: got {got}, expected {expected}")] MismatchedChain { expected: Chain, got: Chain }, - #[error("total difficulty bitlen is too large. maximum: {maximum:?}, got: {got:?}")] + #[error("total difficulty bitlen is too large: got {got}, maximum {maximum}")] TotalDifficultyBitLenTooLarge { maximum: usize, got: usize }, } diff --git a/crates/net/eth-wire/src/errors/p2p.rs b/crates/net/eth-wire/src/errors/p2p.rs index f323a47c1c..b10d3d3475 100644 --- a/crates/net/eth-wire/src/errors/p2p.rs +++ b/crates/net/eth-wire/src/errors/p2p.rs @@ -70,7 +70,7 @@ pub enum P2PHandshakeError { NoResponse, #[error("handshake timed out")] Timeout, - #[error("Disconnected by peer: {0}")] + #[error("disconnected by peer: {0}")] Disconnected(DisconnectReason), #[error("error decoding a message during handshake: {0}")] DecodeError(#[from] alloy_rlp::Error), diff --git a/crates/net/network-api/src/error.rs b/crates/net/network-api/src/error.rs index 71038cf4b0..66e1fd0b07 100644 --- a/crates/net/network-api/src/error.rs +++ b/crates/net/network-api/src/error.rs @@ -5,7 +5,7 @@ use tokio::sync::{mpsc, oneshot}; #[allow(missing_docs)] #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum NetworkError { - #[error("Sender has been dropped")] + #[error("sender has been dropped")] ChannelClosed, } diff --git a/crates/net/network/src/error.rs b/crates/net/network/src/error.rs index 7362f70941..73a8537629 100644 --- a/crates/net/network/src/error.rs +++ b/crates/net/network/src/error.rs @@ -33,7 +33,7 @@ pub enum NetworkError { #[error(transparent)] Io(#[from] io::Error), /// Error when an address is already in use. - #[error("Address {kind} is already in use (os error 98)")] + #[error("address {kind} is already in use (os error 98)")] AddressAlreadyInUse { /// Service kind. kind: ServiceKind, @@ -41,12 +41,12 @@ pub enum NetworkError { error: io::Error, }, /// IO error when creating the discovery service - #[error("Failed to launch discovery service: {0}")] + #[error("failed to launch discovery service: {0}")] Discovery(io::Error), /// Error when setting up the DNS resolver failed /// /// See also [DnsResolver](reth_dns_discovery::DnsResolver::from_system_conf) - #[error("Failed to configure DNS resolver: {0}")] + #[error("failed to configure DNS resolver: {0}")] DnsResolver(#[from] ResolveError), } diff --git a/crates/net/network/src/session/mod.rs b/crates/net/network/src/session/mod.rs index 3dad28b70b..76d52bcac2 100644 --- a/crates/net/network/src/session/mod.rs +++ b/crates/net/network/src/session/mod.rs @@ -710,7 +710,7 @@ impl PendingSessionHandshakeError { /// The error thrown when the max configured limit has been reached and no more connections are /// accepted. #[derive(Debug, Clone, thiserror::Error)] -#[error("Session limit reached {0}")] +#[error("session limit reached {0}")] pub struct ExceedsSessionLimit(pub(crate) u32); /// Starts the authentication process for a connection initiated by a remote peer. diff --git a/crates/net/network/src/transactions.rs b/crates/net/network/src/transactions.rs index cfeebebfe0..0eb6481b32 100644 --- a/crates/net/network/src/transactions.rs +++ b/crates/net/network/src/transactions.rs @@ -811,10 +811,10 @@ where // rules) if err.is_bad_transaction() && !this.network.is_syncing() { trace!(target: "net::tx", ?err, "Bad transaction import"); - this.on_bad_import(*err.hash()); + this.on_bad_import(err.hash); continue } - this.on_good_import(*err.hash()); + this.on_good_import(err.hash); } } } diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index ef015266f8..53f7f64453 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -43,7 +43,6 @@ use revm::{ Database, DatabaseCommit, State, }; use std::{ - fmt::Debug, future::Future, pin::Pin, sync::{atomic::AtomicBool, Arc}, @@ -1042,7 +1041,7 @@ fn commit_withdrawals>( /// /// This uses [apply_beacon_root_contract_call] to ultimately apply the beacon root contract state /// change. -fn pre_block_beacon_root_contract_call( +fn pre_block_beacon_root_contract_call( db: &mut DB, chain_spec: &ChainSpec, block_number: u64, @@ -1051,8 +1050,7 @@ fn pre_block_beacon_root_contract_call( attributes: &PayloadBuilderAttributes, ) -> Result<(), PayloadBuilderError> where - DB: Database + DatabaseCommit, - ::Error: Debug, + DB::Error: std::fmt::Display, { // Configure the environment for the block. let env = Env { diff --git a/crates/payload/builder/src/error.rs b/crates/payload/builder/src/error.rs index bbaf2856f5..aaa37d5ac8 100644 --- a/crates/payload/builder/src/error.rs +++ b/crates/payload/builder/src/error.rs @@ -10,7 +10,7 @@ use tokio::sync::oneshot; #[derive(Debug, thiserror::Error)] pub enum PayloadBuilderError { /// Thrown whe the parent block is missing. - #[error("missing parent block {0:?}")] + #[error("missing parent block {0}")] MissingParentBlock(B256), /// An oneshot channels has been closed. #[error("sender has been dropped")] @@ -22,7 +22,7 @@ pub enum PayloadBuilderError { #[error(transparent)] Internal(#[from] RethError), /// Unrecoverable error during evm execution. - #[error("evm execution error: {0:?}")] + #[error("evm execution error: {0}")] EvmExecutionError(EVMError), /// Thrown if the payload requests withdrawals before Shanghai activation. #[error("withdrawals set before Shanghai activation")] diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 36cfdceaf1..3bd3b53023 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -343,10 +343,10 @@ impl Decodable for BlockHashOrNumber { } #[derive(Debug, thiserror::Error)] -#[error("Failed to parse `{input}` as integer: {pares_int_error} or as hex: {hex_error}")] +#[error("failed to parse {input:?} as a number: {parse_int_error} or hash: {hex_error}")] pub struct ParseBlockHashOrNumberError { input: String, - pares_int_error: ParseIntError, + parse_int_error: ParseIntError, hex_error: crate::hex::FromHexError, } @@ -360,7 +360,7 @@ impl FromStr for BlockHashOrNumber { Ok(val) => Ok(val.into()), Err(hex_error) => Err(ParseBlockHashOrNumberError { input: s.to_string(), - pares_int_error, + parse_int_error: pares_int_error, hex_error, }), }, diff --git a/crates/primitives/src/constants/eip4844.rs b/crates/primitives/src/constants/eip4844.rs index 9d05526331..1265a6cd86 100644 --- a/crates/primitives/src/constants/eip4844.rs +++ b/crates/primitives/src/constants/eip4844.rs @@ -59,11 +59,11 @@ pub fn load_trusted_setup_from_bytes(bytes: &[u8]) -> Result Arbitrary<'a> for IntegerList { #[derive(Debug, thiserror::Error)] pub enum EliasFanoError { /// The provided input is invalid. - #[error("The provided input is invalid.")] + #[error("the provided input is invalid")] InvalidInput, /// Failed to deserialize data into type. - #[error("Failed to deserialize data into type.")] + #[error("failed to deserialize data into type")] FailedDeserialize, } diff --git a/crates/primitives/src/net.rs b/crates/primitives/src/net.rs index eeec5abae0..8b4503b289 100644 --- a/crates/primitives/src/net.rs +++ b/crates/primitives/src/net.rs @@ -183,11 +183,11 @@ fn parse_nodes(nodes: impl IntoIterator>) -> Vec for BlobTransactionValidationError { - fn from(value: kzg::Error) -> Self { - Self::KZGError(value) - } -} - /// A response to `GetPooledTransactions` that includes blob data, their commitments, and their /// corresponding proofs. /// diff --git a/crates/primitives/src/transaction/error.rs b/crates/primitives/src/transaction/error.rs index b45ac8cb08..7542e8f5c8 100644 --- a/crates/primitives/src/transaction/error.rs +++ b/crates/primitives/src/transaction/error.rs @@ -6,49 +6,51 @@ use crate::U256; #[derive(Debug, Clone, Eq, PartialEq, thiserror::Error)] pub enum InvalidTransactionError { /// The sender does not have enough funds to cover the transaction fees - #[error("Sender does not have enough funds ({available_funds:?}) to cover transaction fees: {cost:?}.")] + #[error( + "sender does not have enough funds ({available_funds}) to cover transaction fees: {cost}" + )] InsufficientFunds { cost: U256, available_funds: U256 }, /// The nonce is lower than the account's nonce, or there is a nonce gap present. /// /// This is a consensus error. - #[error("Transaction nonce is not consistent.")] + #[error("transaction nonce is not consistent")] NonceNotConsistent, /// The transaction is before Spurious Dragon and has a chain ID - #[error("Transactions before Spurious Dragon should not have a chain ID.")] + #[error("transactions before Spurious Dragon should not have a chain ID")] OldLegacyChainId, /// The chain ID in the transaction does not match the current network configuration. - #[error("Transaction's chain ID does not match.")] + #[error("transaction's chain ID does not match")] ChainIdMismatch, /// The transaction requires EIP-2930 which is not enabled currently. - #[error("EIP-2930 transactions are disabled.")] + #[error("EIP-2930 transactions are disabled")] Eip2930Disabled, /// The transaction requires EIP-1559 which is not enabled currently. - #[error("EIP-1559 transactions are disabled.")] + #[error("EIP-1559 transactions are disabled")] Eip1559Disabled, /// The transaction requires EIP-4844 which is not enabled currently. - #[error("EIP-4844 transactions are disabled.")] + #[error("EIP-4844 transactions are disabled")] Eip4844Disabled, /// Thrown if a transaction is not supported in the current network configuration. - #[error("Transaction type not supported")] + #[error("transaction type not supported")] TxTypeNotSupported, /// The calculated gas of the transaction exceeds `u64::MAX`. - #[error("Gas overflow (maximum of u64)")] + #[error("gas overflow (maximum of u64)")] GasUintOverflow, /// The transaction is specified to use less gas than required to start the /// invocation. - #[error("Intrinsic gas too low")] + #[error("intrinsic gas too low")] GasTooLow, /// The transaction gas exceeds the limit - #[error("Intrinsic gas too high")] + #[error("intrinsic gas too high")] GasTooHigh, /// Thrown to ensure no one is able to specify a transaction with a tip higher than the total /// fee cap. - #[error("Max priority fee per gas higher than max fee per gas")] + #[error("max priority fee per gas higher than max fee per gas")] TipAboveFeeCap, /// Thrown post London if the transaction's fee is less than the base fee of the block - #[error("Max fee per gas less than block base fee")] + #[error("max fee per gas less than block base fee")] FeeCapTooLow, /// Thrown if the sender of a transaction is a contract. - #[error("Transaction signer has bytecode set.")] + #[error("transaction signer has bytecode set")] SignerAccountHasBytecode, } diff --git a/crates/prune/src/error.rs b/crates/prune/src/error.rs index 360fd61c5a..e12320bc8f 100644 --- a/crates/prune/src/error.rs +++ b/crates/prune/src/error.rs @@ -9,10 +9,10 @@ pub enum PrunerError { #[error(transparent)] PruneSegment(#[from] PruneSegmentError), - #[error("Inconsistent data: {0}")] + #[error("inconsistent data: {0}")] InconsistentData(&'static str), - #[error("An interface error occurred.")] + #[error(transparent)] Interface(#[from] RethError), #[error(transparent)] diff --git a/crates/revm/revm-inspectors/src/tracing/builder/geth.rs b/crates/revm/revm-inspectors/src/tracing/builder/geth.rs index 7dea00a98d..388e65aba4 100644 --- a/crates/revm/revm-inspectors/src/tracing/builder/geth.rs +++ b/crates/revm/revm-inspectors/src/tracing/builder/geth.rs @@ -179,15 +179,12 @@ impl GethTraceBuilder { /// * `state` - The state post-transaction execution. /// * `diff_mode` - if prestate is in diff or prestate mode. /// * `db` - The database to fetch state pre-transaction execution. - pub fn geth_prestate_traces( + pub fn geth_prestate_traces( &self, ResultAndState { state, .. }: &ResultAndState, prestate_config: PreStateConfig, db: DB, - ) -> Result - where - DB: DatabaseRef, - { + ) -> Result { // loads the code from the account or the database // Geth always includes the contract code in the prestate. However, // the code hash will be KECCAK_EMPTY if the account is an EOA. Therefore diff --git a/crates/revm/revm-inspectors/src/tracing/builder/parity.rs b/crates/revm/revm-inspectors/src/tracing/builder/parity.rs index 2b6aa9bf47..0c3179776b 100644 --- a/crates/revm/revm-inspectors/src/tracing/builder/parity.rs +++ b/crates/revm/revm-inspectors/src/tracing/builder/parity.rs @@ -179,15 +179,12 @@ impl ParityTraceBuilder { /// Note: this is considered a convenience method that takes the state map of /// [ResultAndState] after inspecting a transaction /// with the [TracingInspector](crate::tracing::TracingInspector). - pub fn into_trace_results_with_state( + pub fn into_trace_results_with_state( self, res: &ResultAndState, trace_types: &HashSet, db: DB, - ) -> Result - where - DB: DatabaseRef, - { + ) -> Result { let ResultAndState { ref result, ref state } = res; let breadth_first_addresses = if trace_types.contains(&TraceType::VmTrace) { diff --git a/crates/revm/revm-inspectors/src/tracing/js/mod.rs b/crates/revm/revm-inspectors/src/tracing/js/mod.rs index 2824c9065b..803f79fa7f 100644 --- a/crates/revm/revm-inspectors/src/tracing/js/mod.rs +++ b/crates/revm/revm-inspectors/src/tracing/js/mod.rs @@ -511,9 +511,9 @@ struct CallStackItem { pub enum JsInspectorError { #[error(transparent)] JsError(#[from] JsError), - #[error("Failed to eval js code: {0}")] + #[error("failed to evaluate JS code: {0}")] EvalCode(JsError), - #[error("The evaluated code is not a JS object")] + #[error("the evaluated code is not a JS object")] ExpectedJsObject, #[error("trace object must expose a function result()")] ResultFunctionMissing, @@ -521,8 +521,8 @@ pub enum JsInspectorError { FaultFunctionMissing, #[error("setup object must be a function")] SetupFunctionNotCallable, - #[error("Failed to call setup(): {0}")] + #[error("failed to call setup(): {0}")] SetupCallFailed(JsError), - #[error("Invalid JSON config: {0}")] + #[error("invalid JSON config: {0}")] InvalidJsonConfig(JsError), } diff --git a/crates/revm/src/processor.rs b/crates/revm/src/processor.rs index de86e2e332..c23fcbed34 100644 --- a/crates/revm/src/processor.rs +++ b/crates/revm/src/processor.rs @@ -268,7 +268,7 @@ impl<'a> EVMProcessor<'a> { // main execution. self.evm.transact() }; - out.map_err(|e| BlockValidationError::EVM { hash, message: format!("{e:?}") }.into()) + out.map_err(|e| BlockValidationError::EVM { hash, error: e.into() }.into()) } /// Runs the provided transactions and commits their state to the run-time database. @@ -534,8 +534,8 @@ pub fn verify_receipt<'a>( let receipts_root = reth_primitives::proofs::calculate_receipt_root(&receipts_with_bloom); if receipts_root != expected_receipts_root { return Err(BlockValidationError::ReceiptRootDiff { - got: receipts_root, - expected: expected_receipts_root, + got: Box::new(receipts_root), + expected: Box::new(expected_receipts_root), } .into()) } diff --git a/crates/revm/src/state_change.rs b/crates/revm/src/state_change.rs index 20a162acbd..6fe24790f4 100644 --- a/crates/revm/src/state_change.rs +++ b/crates/revm/src/state_change.rs @@ -4,8 +4,8 @@ use reth_primitives::{ constants::SYSTEM_ADDRESS, revm::env::fill_tx_env_with_beacon_root_contract_call, Address, ChainSpec, Header, Withdrawal, B256, U256, }; -use revm::{primitives::ResultAndState, Database, DatabaseCommit, EVM}; -use std::{collections::HashMap, fmt::Debug}; +use revm::{Database, DatabaseCommit, EVM}; +use std::collections::HashMap; /// Collect all balance changes at the end of the block. /// @@ -61,51 +61,58 @@ pub fn apply_beacon_root_contract_call( chain_spec: &ChainSpec, block_timestamp: u64, block_number: u64, - block_parent_beacon_block_root: Option, + parent_beacon_block_root: Option, evm: &mut EVM, ) -> Result<(), BlockExecutionError> where - ::Error: Debug, + DB::Error: std::fmt::Display, { - if chain_spec.is_cancun_active_at_timestamp(block_timestamp) { - // if the block number is zero (genesis block) then the parent beacon block root must - // be 0x0 and no system transaction may occur as per EIP-4788 - if block_number == 0 { - if block_parent_beacon_block_root != Some(B256::ZERO) { - return Err(BlockValidationError::CancunGenesisParentBeaconBlockRootNotZero.into()) - } - } else { - let parent_beacon_block_root = block_parent_beacon_block_root.ok_or( - BlockExecutionError::from(BlockValidationError::MissingParentBeaconBlockRoot), - )?; - - // get previous env - let previous_env = evm.env.clone(); - - // modify env for pre block call - fill_tx_env_with_beacon_root_contract_call(&mut evm.env, parent_beacon_block_root); - - let ResultAndState { mut state, .. } = match evm.transact() { - Ok(res) => res, - Err(e) => { - evm.env = previous_env; - return Err(BlockExecutionError::from(BlockValidationError::EVM { - hash: Default::default(), - message: format!("{e:?}"), - })) - } - }; - - state.remove(&SYSTEM_ADDRESS); - state.remove(&evm.env.block.coinbase); - - let db = evm.db().expect("db to not be moved"); - db.commit(state); - - // re-set the previous env - evm.env = previous_env; - } + if !chain_spec.is_cancun_active_at_timestamp(block_timestamp) { + return Ok(()) } + + let parent_beacon_block_root = + parent_beacon_block_root.ok_or(BlockValidationError::MissingParentBeaconBlockRoot)?; + + // if the block number is zero (genesis block) then the parent beacon block root must + // be 0x0 and no system transaction may occur as per EIP-4788 + if block_number == 0 { + if parent_beacon_block_root != B256::ZERO { + return Err(BlockValidationError::CancunGenesisParentBeaconBlockRootNotZero { + parent_beacon_block_root, + } + .into()) + } + return Ok(()) + } + + // get previous env + let previous_env = evm.env.clone(); + + // modify env for pre block call + fill_tx_env_with_beacon_root_contract_call(&mut evm.env, parent_beacon_block_root); + + let mut state = match evm.transact() { + Ok(res) => res.state, + Err(e) => { + evm.env = previous_env; + return Err(BlockValidationError::BeaconRootContractCall { + parent_beacon_block_root: Box::new(parent_beacon_block_root), + message: e.to_string(), + } + .into()) + } + }; + + state.remove(&SYSTEM_ADDRESS); + state.remove(&evm.env.block.coinbase); + + let db = evm.db().expect("db to not be moved"); + db.commit(state); + + // re-set the previous env + evm.env = previous_env; + Ok(()) } diff --git a/crates/rpc/ipc/src/client.rs b/crates/rpc/ipc/src/client.rs index 61a8381fcc..640c0e3a34 100644 --- a/crates/rpc/ipc/src/client.rs +++ b/crates/rpc/ipc/src/client.rs @@ -120,13 +120,13 @@ impl IpcTransportClientBuilder { #[allow(missing_docs)] pub enum IpcError { /// Operation not supported - #[error("Operation not supported")] + #[error("operation not supported")] NotSupported, /// Stream was closed - #[error("Stream closed")] + #[error("stream closed")] Closed, /// Thrown when failed to establish a socket connection. - #[error("Failed to connect to socket {path}: {err}")] + #[error("failed to connect to socket {path}: {err}")] FailedToConnect { /// The path of the socket. path: PathBuf, diff --git a/crates/rpc/rpc-builder/src/cors.rs b/crates/rpc/rpc-builder/src/cors.rs index 7b7492c86d..73e755f9fa 100644 --- a/crates/rpc/rpc-builder/src/cors.rs +++ b/crates/rpc/rpc-builder/src/cors.rs @@ -6,7 +6,7 @@ use tower_http::cors::{AllowOrigin, Any, CorsLayer}; pub(crate) enum CorsDomainError { #[error("{domain} is an invalid header value")] InvalidHeader { domain: String }, - #[error("Wildcard origin (`*`) cannot be passed as part of a list: {input}")] + #[error("wildcard origin (`*`) cannot be passed as part of a list: {input}")] WildCardNotAllowed { input: String }, } diff --git a/crates/rpc/rpc-builder/src/error.rs b/crates/rpc/rpc-builder/src/error.rs index d1689c089a..5b13e78824 100644 --- a/crates/rpc/rpc-builder/src/error.rs +++ b/crates/rpc/rpc-builder/src/error.rs @@ -35,7 +35,7 @@ pub enum RpcError { #[error(transparent)] RpcError(#[from] JsonRpseeError), /// Address already in use. - #[error("Address {kind} is already in use (os error 98)")] + #[error("address {kind} is already in use (os error 98)")] AddressAlreadyInUse { /// Server kind. kind: ServerKind, @@ -74,7 +74,10 @@ impl RpcError { #[derive(Debug, thiserror::Error)] pub enum WsHttpSamePortError { /// Ws and http server configured on same port but with different cors domains. - #[error("CORS domains for http and ws are different, but they are on the same port: http: {http_cors_domains:?}, ws: {ws_cors_domains:?}")] + #[error( + "CORS domains for HTTP and WS are different, but they are on the same port: \ + HTTP: {http_cors_domains:?}, WS: {ws_cors_domains:?}" + )] ConflictingCorsDomains { /// Http cors domains. http_cors_domains: Option, @@ -82,7 +85,10 @@ pub enum WsHttpSamePortError { ws_cors_domains: Option, }, /// Ws and http server configured on same port but with different modules. - #[error("Different api modules for http and ws on the same port is currently not supported: http: {http_modules:?}, ws: {ws_modules:?}")] + #[error( + "different API modules for HTTP and WS on the same port is currently not supported: \ + HTTP: {http_modules:?}, WS: {ws_modules:?}" + )] ConflictingModules { /// Http modules. http_modules: Vec, diff --git a/crates/rpc/rpc-engine-api/src/error.rs b/crates/rpc/rpc-engine-api/src/error.rs index 8ec5466088..59aeb15076 100644 --- a/crates/rpc/rpc-engine-api/src/error.rs +++ b/crates/rpc/rpc-engine-api/src/error.rs @@ -16,24 +16,26 @@ pub const REQUEST_TOO_LARGE_CODE: i32 = -38004; /// Error returned by [`EngineApi`][crate::EngineApi] /// -/// Note: This is a high-fidelity error type which can be converted to an RPC error that adheres to the spec: +/// Note: This is a high-fidelity error type which can be converted to an RPC error that adheres to +/// the [Engine API spec](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md#errors). #[derive(Error, Debug)] pub enum EngineApiError { - /// Unknown payload requested. + // **IMPORTANT**: keep error messages in sync with the Engine API spec linked above. + /// Payload does not exist / is not available. #[error("Unknown payload")] UnknownPayload, /// The payload body request length is too large. - #[error("Payload request too large: {len}")] + #[error("payload request too large: {len}")] PayloadRequestTooLarge { /// The length that was requested. len: u64, }, /// Thrown if engine_getPayloadBodiesByRangeV1 contains an invalid range - #[error("invalid start or count, start: {start} count: {count}")] + #[error("invalid start ({start}) or count ({count})")] InvalidBodiesRange { /// Start of the range start: u64, - /// requested number of items + /// Requested number of items count: u64, }, /// Thrown if `PayloadAttributes` provided in engine_forkchoiceUpdated before V3 contains a @@ -44,10 +46,10 @@ pub enum EngineApiError { #[error("withdrawals not supported in V1")] WithdrawalsNotSupportedInV1, /// Thrown if engine_forkchoiceUpdated contains no withdrawals after Shanghai - #[error("no withdrawals post-shanghai")] + #[error("no withdrawals post-Shanghai")] NoWithdrawalsPostShanghai, /// Thrown if engine_forkchoiceUpdated contains withdrawals before Shanghai - #[error("withdrawals pre-shanghai")] + #[error("withdrawals pre-Shanghai")] HasWithdrawalsPreShanghai, /// Thrown if the `PayloadAttributes` provided in engine_forkchoiceUpdated contains no parent /// beacon block root after Cancun @@ -59,7 +61,8 @@ pub enum EngineApiError { UnsupportedFork, /// Terminal total difficulty mismatch during transition configuration exchange. #[error( - "Invalid transition terminal total difficulty. Execution: {execution}. Consensus: {consensus}" + "invalid transition terminal total difficulty: \ + execution: {execution}, consensus: {consensus}" )] TerminalTD { /// Execution terminal total difficulty value. @@ -69,7 +72,8 @@ pub enum EngineApiError { }, /// Terminal block hash mismatch during transition configuration exchange. #[error( - "Invalid transition terminal block hash. Execution: {execution:?}. Consensus: {consensus:?}" + "invalid transition terminal block hash: \ + execution: {execution:?}, consensus: {consensus}" )] TerminalBlockHash { /// Execution terminal block hash. `None` if block number is not found in the database. @@ -85,7 +89,7 @@ pub enum EngineApiError { NewPayload(#[from] BeaconOnNewPayloadError), /// Encountered an internal error. #[error(transparent)] - Internal(Box), + Internal(#[from] Box), /// Fetching the payload failed #[error(transparent)] GetPayloadError(#[from] PayloadBuilderError), diff --git a/crates/rpc/rpc-types/src/eth/engine/forkchoice.rs b/crates/rpc/rpc-types/src/eth/engine/forkchoice.rs index 9aad006103..aae2e76ed5 100644 --- a/crates/rpc/rpc-types/src/eth/engine/forkchoice.rs +++ b/crates/rpc/rpc-types/src/eth/engine/forkchoice.rs @@ -40,10 +40,10 @@ pub enum ForkchoiceUpdateError { /// [PayloadAttributes](crate::engine::PayloadAttributes). /// /// This is returned as an error because the payload attributes are invalid and the payload is not valid, See - #[error("Invalid payload attributes")] + #[error("invalid payload attributes")] UpdatedInvalidPayloadAttributes, /// The given [ForkchoiceState] is invalid or inconsistent. - #[error("Invalid forkchoice state")] + #[error("invalid forkchoice state")] InvalidState, /// Thrown when a forkchoice final block does not exist in the database. #[error("final block not available in database")] diff --git a/crates/rpc/rpc-types/src/eth/engine/payload.rs b/crates/rpc/rpc-types/src/eth/engine/payload.rs index bfb0a6b07b..07aef13cf5 100644 --- a/crates/rpc/rpc-types/src/eth/engine/payload.rs +++ b/crates/rpc/rpc-types/src/eth/engine/payload.rs @@ -341,22 +341,22 @@ impl From for ExecutionPayload { #[derive(thiserror::Error, Debug)] pub enum PayloadError { /// Invalid payload extra data. - #[error("Invalid payload extra data: {0}")] + #[error("invalid payload extra data: {0}")] ExtraData(Bytes), /// Invalid payload base fee. - #[error("Invalid payload base fee: {0}")] + #[error("invalid payload base fee: {0}")] BaseFee(U256), /// Invalid payload blob gas used. - #[error("Invalid payload blob gas used: {0}")] + #[error("invalid payload blob gas used: {0}")] BlobGasUsed(U256), /// Invalid payload excess blob gas. - #[error("Invalid payload excess blob gas: {0}")] + #[error("invalid payload excess blob gas: {0}")] ExcessBlobGas(U256), /// Pre-cancun Payload has blob transactions. - #[error("Invalid payload, pre-Cancun payload has blob transactions")] + #[error("pre-Cancun payload has blob transactions")] PreCancunBlockWithBlobTransactions, /// Invalid payload block hash. - #[error("blockhash mismatch, want {consensus}, got {execution}")] + #[error("block hash mismatch: want {consensus}, got {execution}")] BlockHash { /// The block hash computed from the payload. execution: B256, @@ -364,7 +364,7 @@ pub enum PayloadError { consensus: B256, }, /// Expected blob versioned hashes do not match the given transactions. - #[error("Expected blob versioned hashes do not match the given transactions")] + #[error("expected blob versioned hashes do not match the given transactions")] InvalidVersionedHashes, /// Encountered decoding error. #[error(transparent)] diff --git a/crates/rpc/rpc/src/blocking_pool.rs b/crates/rpc/rpc/src/blocking_pool.rs index ef3dbe7d7a..cfd0c90748 100644 --- a/crates/rpc/rpc/src/blocking_pool.rs +++ b/crates/rpc/rpc/src/blocking_pool.rs @@ -145,7 +145,7 @@ impl Future for BlockingTaskHandle { /// /// This should only happen #[derive(Debug, Default, thiserror::Error)] -#[error("Tokio channel dropped while awaiting result")] +#[error("tokio channel dropped while awaiting result")] #[non_exhaustive] pub struct TokioBlockingTaskError; diff --git a/crates/rpc/rpc/src/eth/api/pending_block.rs b/crates/rpc/rpc/src/eth/api/pending_block.rs index 396c8de4e6..a1625e0c69 100644 --- a/crates/rpc/rpc/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc/src/eth/api/pending_block.rs @@ -1,7 +1,6 @@ //! Support for building a pending block via local txpool. use crate::eth::error::{EthApiError, EthResult}; -use core::fmt::Debug; use reth_primitives::{ constants::{eip4844::MAX_DATA_GAS_PER_BLOCK, BEACON_NONCE}, proofs, @@ -248,7 +247,7 @@ impl PendingBlockEnv { /// /// This uses [apply_beacon_root_contract_call] to ultimately apply the beacon root contract state /// change. -fn pre_block_beacon_root_contract_call( +fn pre_block_beacon_root_contract_call( db: &mut DB, chain_spec: &ChainSpec, block_number: u64, @@ -257,8 +256,7 @@ fn pre_block_beacon_root_contract_call( parent_beacon_block_root: Option, ) -> EthResult<()> where - DB: Database + DatabaseCommit, - ::Error: Debug, + DB::Error: std::fmt::Display, { // Configure the environment for the block. let env = Env { diff --git a/crates/rpc/rpc/src/eth/error.rs b/crates/rpc/rpc/src/eth/error.rs index 998469ecbd..b22ab5c041 100644 --- a/crates/rpc/rpc/src/eth/error.rs +++ b/crates/rpc/rpc/src/eth/error.rs @@ -11,7 +11,8 @@ use reth_primitives::{Address, Bytes, U256}; use reth_revm::tracing::js::JsInspectorError; use reth_rpc_types::{error::EthRpcErrorCode, BlockError, CallInputError}; use reth_transaction_pool::error::{ - Eip4844PoolTransactionError, InvalidPoolTransactionError, PoolError, PoolTransactionError, + Eip4844PoolTransactionError, InvalidPoolTransactionError, PoolError, PoolErrorKind, + PoolTransactionError, }; use revm::primitives::{EVMError, ExecutionResult, Halt, OutOfGasError}; use revm_primitives::InvalidHeader; @@ -25,29 +26,29 @@ pub type EthResult = Result; #[allow(missing_docs)] pub enum EthApiError { /// When a raw transaction is empty - #[error("Empty transaction data")] + #[error("empty transaction data")] EmptyRawTransactionData, - #[error("Failed to decode signed transaction")] + #[error("failed to decode signed transaction")] FailedToDecodeSignedTransaction, - #[error("Invalid transaction signature")] + #[error("invalid transaction signature")] InvalidTransactionSignature, #[error(transparent)] PoolError(RpcPoolError), - #[error("Unknown block number")] + #[error("unknown block number")] UnknownBlockNumber, /// Thrown when querying for `finalized` or `safe` block before the merge transition is /// finalized, - #[error("Unknown block")] + #[error("unknown block")] UnknownSafeOrFinalizedBlock, - #[error("Unknown block or tx index")] + #[error("unknown block or tx index")] UnknownBlockOrTxIndex, - #[error("Invalid block range")] + #[error("invalid block range")] InvalidBlockRange, /// An internal error where prevrandao is not set in the evm's environment - #[error("Prevrandao not in th EVM's environment after merge")] + #[error("prevrandao not in the EVM's environment after merge")] PrevrandaoNotSet, /// Excess_blob_gas is not set for Cancun and above. - #[error("Excess blob gas missing th EVM's environment after Cancun")] + #[error("excess blob gas missing the EVM's environment after Cancun")] ExcessBlobGasNotSet, /// Thrown when a call or transaction request (`eth_call`, `eth_estimateGas`, /// `eth_sendTransaction`) contains conflicting fields (legacy, EIP-1559) @@ -265,38 +266,38 @@ pub enum RpcInvalidTransactionError { #[error("sender not an eoa")] SenderNoEOA, /// Thrown during estimate if caller has insufficient funds to cover the tx. - #[error("Out of gas: gas required exceeds allowance: {0:?}")] + #[error("out of gas: gas required exceeds allowance: {0:?}")] BasicOutOfGas(U256), /// As BasicOutOfGas but thrown when gas exhausts during memory expansion. - #[error("Out of gas: gas exhausts during memory expansion: {0:?}")] + #[error("out of gas: gas exhausts during memory expansion: {0:?}")] MemoryOutOfGas(U256), /// As BasicOutOfGas but thrown when gas exhausts during precompiled contract execution. - #[error("Out of gas: gas exhausts during precompiled contract execution: {0:?}")] + #[error("out of gas: gas exhausts during precompiled contract execution: {0:?}")] PrecompileOutOfGas(U256), /// revm's Type cast error, U256 casts down to a u64 with overflow - #[error("Out of gas: revm's Type cast error, U256 casts down to a u64 with overflow {0:?}")] + #[error("out of gas: revm's Type cast error, U256 casts down to a u64 with overflow {0:?}")] InvalidOperandOutOfGas(U256), /// Thrown if executing a transaction failed during estimate/call #[error("{0}")] Revert(RevertError), - /// Unspecific evm halt error + /// Unspecific EVM halt error. #[error("EVM error {0:?}")] EvmHalt(Halt), /// Invalid chain id set for the transaction. - #[error("Invalid chain id")] + #[error("invalid chain ID")] InvalidChainId, /// The transaction is before Spurious Dragon and has a chain ID - #[error("Transactions before Spurious Dragon should not have a chain ID.")] + #[error("transactions before Spurious Dragon should not have a chain ID")] OldLegacyChainId, /// The transitions is before Berlin and has access list - #[error("Transactions before Berlin should not have access list")] + #[error("transactions before Berlin should not have access list")] AccessListNotSupported, /// `max_fee_per_blob_gas` is not supported for blocks before the Cancun hardfork. - #[error("max_fee_per_blob_gas is not supported for blocks before the Cancun hardfork.")] + #[error("max_fee_per_blob_gas is not supported for blocks before the Cancun hardfork")] MaxFeePerBlobGasNotSupported, /// `blob_hashes`/`blob_versioned_hashes` is not supported for blocks before the Cancun /// hardfork. - #[error("blob_versioned_hashes is not supported for blocks before the Cancun hardfork.")] + #[error("blob_versioned_hashes is not supported for blocks before the Cancun hardfork")] BlobVersionedHashesNotSupported, /// Block `blob_gas_price` is greater than tx-specified `max_fee_per_blob_gas` after Cancun. #[error("max fee per blob gas less than block blob gas fee")] @@ -527,7 +528,7 @@ pub enum RpcPoolError { #[error(transparent)] Invalid(#[from] RpcInvalidTransactionError), /// Custom pool error - #[error("{0:?}")] + #[error(transparent)] PoolTransactionError(Box), /// Eip-4844 related error #[error(transparent)] @@ -553,15 +554,15 @@ impl From for ErrorObject<'static> { impl From for RpcPoolError { fn from(err: PoolError) -> RpcPoolError { - match err { - PoolError::ReplacementUnderpriced(_) => RpcPoolError::ReplaceUnderpriced, - PoolError::FeeCapBelowMinimumProtocolFeeCap(_, _) => RpcPoolError::Underpriced, - PoolError::SpammerExceededCapacity(_, _) => RpcPoolError::TxPoolOverflow, - PoolError::DiscardedOnInsert(_) => RpcPoolError::TxPoolOverflow, - PoolError::InvalidTransaction(_, err) => err.into(), - PoolError::Other(_, err) => RpcPoolError::Other(err), - PoolError::AlreadyImported(_) => RpcPoolError::AlreadyKnown, - PoolError::ExistingConflictingTransactionType(_, _, _) => { + match err.kind { + PoolErrorKind::ReplacementUnderpriced => RpcPoolError::ReplaceUnderpriced, + PoolErrorKind::FeeCapBelowMinimumProtocolFeeCap(_) => RpcPoolError::Underpriced, + PoolErrorKind::SpammerExceededCapacity(_) => RpcPoolError::TxPoolOverflow, + PoolErrorKind::DiscardedOnInsert => RpcPoolError::TxPoolOverflow, + PoolErrorKind::InvalidTransaction(err) => err.into(), + PoolErrorKind::Other(err) => RpcPoolError::Other(err), + PoolErrorKind::AlreadyImported => RpcPoolError::AlreadyKnown, + PoolErrorKind::ExistingConflictingTransactionType(_, _) => { RpcPoolError::AddressAlreadyReserved } } @@ -600,19 +601,19 @@ impl From for EthApiError { #[derive(Debug, thiserror::Error)] pub enum SignError { /// Error occured while trying to sign data. - #[error("Could not sign")] + #[error("could not sign")] CouldNotSign, /// Signer for requested account not found. - #[error("Unknown account")] + #[error("unknown account")] NoAccount, /// TypedData has invalid format. - #[error("Given typed data is not valid")] + #[error("given typed data is not valid")] InvalidTypedData, /// Invalid transaction request in `sign_transaction`. - #[error("Invalid transaction request")] + #[error("invalid transaction request")] InvalidTransactionRequest, /// No chain ID was given. - #[error("No chainid")] + #[error("no chainid")] NoChainId, } diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 5b0cc631ba..d895d7cf9a 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -513,7 +513,7 @@ enum FilterKind { pub enum FilterError { #[error("filter not found")] FilterNotFound(FilterId), - #[error("Query exceeds max results {0}")] + #[error("query exceeds max results {0}")] QueryExceedsMaxResults(usize), #[error(transparent)] EthAPIError(#[from] EthApiError), diff --git a/crates/rpc/rpc/src/layers/auth_layer.rs b/crates/rpc/rpc/src/layers/auth_layer.rs index 838fb678dd..0a3a529d19 100644 --- a/crates/rpc/rpc/src/layers/auth_layer.rs +++ b/crates/rpc/rpc/src/layers/auth_layer.rs @@ -233,7 +233,7 @@ mod tests { let jwt = "this jwt has serious encoding problems".to_string(); let (status, body) = send_request(Some(jwt)).await; assert_eq!(status, StatusCode::UNAUTHORIZED); - assert_eq!(body, "JWT decoding error Error(InvalidToken)".to_string()); + assert_eq!(body, "JWT decoding error: Error(InvalidToken)".to_string()); } async fn send_request(jwt: Option) -> (StatusCode, String) { diff --git a/crates/rpc/rpc/src/layers/jwt_secret.rs b/crates/rpc/rpc/src/layers/jwt_secret.rs index f0c0df0bae..af5d92c381 100644 --- a/crates/rpc/rpc/src/layers/jwt_secret.rs +++ b/crates/rpc/rpc/src/layers/jwt_secret.rs @@ -20,19 +20,19 @@ pub enum JwtError { JwtSecretHexDecodeError(#[from] hex::FromHexError), #[error("JWT key is expected to have a length of {0} digits. {1} digits key provided")] InvalidLength(usize, usize), - #[error("Unsupported signature algorithm. Only HS256 is supported")] + #[error("unsupported signature algorithm. Only HS256 is supported")] UnsupportedSignatureAlgorithm, - #[error("The provided signature is invalid")] + #[error("provided signature is invalid")] InvalidSignature, - #[error("The iat (issued-at) claim is not within +-60 seconds from the current time")] + #[error("IAT (issued-at) claim is not within ±60 seconds from the current time")] InvalidIssuanceTimestamp, #[error("Authorization header is missing or invalid")] MissingOrInvalidAuthorizationHeader, - #[error("JWT decoding error {0}")] + #[error("JWT decoding error: {0}")] JwtDecodingError(String), #[error(transparent)] JwtFsPathError(#[from] FsPathError), - #[error("An I/O error occurred: {0}")] + #[error(transparent)] IOError(#[from] std::io::Error), } diff --git a/crates/snapshot/src/error.rs b/crates/snapshot/src/error.rs index 4bdea3e8fc..20da642bee 100644 --- a/crates/snapshot/src/error.rs +++ b/crates/snapshot/src/error.rs @@ -7,10 +7,10 @@ use thiserror::Error; #[derive(Error, Debug)] #[allow(missing_docs)] pub enum SnapshotterError { - #[error("Inconsistent data: {0}")] + #[error("inconsistent data: {0}")] InconsistentData(&'static str), - #[error("An interface error occurred.")] + #[error(transparent)] Interface(#[from] RethError), #[error(transparent)] diff --git a/crates/stages/src/error.rs b/crates/stages/src/error.rs index 9bc50e5c4b..b44a8a14f8 100644 --- a/crates/stages/src/error.rs +++ b/crates/stages/src/error.rs @@ -11,18 +11,18 @@ use tokio::sync::mpsc::error::SendError; #[derive(Error, Debug)] pub enum BlockErrorKind { /// The block encountered a validation error. - #[error("Validation error: {0}")] - Validation(#[source] consensus::ConsensusError), + #[error("validation error: {0}")] + Validation(#[from] consensus::ConsensusError), /// The block encountered an execution error. - #[error("Execution error: {0}")] - Execution(#[source] executor::BlockExecutionError), + #[error("execution error: {0}")] + Execution(#[from] executor::BlockExecutionError), } /// A stage execution error. #[derive(Error, Debug)] pub enum StageError { /// The stage encountered an error related to a block. - #[error("Stage encountered a block error in block {number}: {error}.", number = block.number)] + #[error("stage encountered an error in block #{number}: {error}", number = block.number)] Block { /// The block that caused the error. block: SealedHeader, @@ -33,7 +33,9 @@ pub enum StageError { /// The stage encountered a downloader error where the responses cannot be attached to the /// current head. #[error( - "Stage encountered inconsistent chain. Downloaded header #{header_number} ({header_hash:?}) is detached from local head #{head_number} ({head_hash:?}). Details: {error}.", + "stage encountered inconsistent chain: \ + downloaded header #{header_number} ({header_hash}) is detached from \ + local head #{head_number} ({head_hash}): {error}", header_number = header.number, header_hash = header.hash, head_number = local_head.number, @@ -45,26 +47,27 @@ pub enum StageError { /// The header we attempted to attach. header: SealedHeader, /// The error that occurred when attempting to attach the header. + #[source] error: Box, }, /// The stage encountered a database error. - #[error("An internal database error occurred: {0}")] + #[error("internal database error occurred: {0}")] Database(#[from] DbError), /// Invalid pruning configuration #[error(transparent)] PruningConfiguration(#[from] reth_primitives::PruneSegmentError), /// Invalid checkpoint passed to the stage - #[error("Invalid stage checkpoint: {0}")] + #[error("invalid stage checkpoint: {0}")] StageCheckpoint(u64), /// Download channel closed - #[error("Download channel closed")] + #[error("download channel closed")] ChannelClosed, /// The stage encountered a database integrity error. - #[error("A database integrity error occurred: {0}")] + #[error("database integrity error occurred: {0}")] DatabaseIntegrity(#[from] ProviderError), /// Invalid download response. Applicable for stages which /// rely on external downloaders - #[error("Invalid download response: {0}")] + #[error("invalid download response: {0}")] Download(#[from] DownloadError), /// Internal error #[error(transparent)] @@ -101,16 +104,16 @@ impl StageError { #[derive(Error, Debug)] pub enum PipelineError { /// The pipeline encountered an irrecoverable error in one of the stages. - #[error("A stage encountered an irrecoverable error.")] + #[error(transparent)] Stage(#[from] StageError), /// The pipeline encountered a database error. - #[error("A database error occurred.")] + #[error(transparent)] Database(#[from] DbError), /// The pipeline encountered an irrecoverable error in one of the stages. - #[error("An interface error occurred.")] + #[error(transparent)] Interface(#[from] RethError), /// The pipeline encountered an error while trying to send an event. - #[error("The pipeline encountered an error while trying to send an event.")] + #[error("pipeline encountered an error while trying to send an event")] Channel(#[from] SendError), /// The stage encountered an internal error. #[error(transparent)] diff --git a/crates/stages/src/stages/sender_recovery.rs b/crates/stages/src/stages/sender_recovery.rs index f7c6ec148f..4105e810a2 100644 --- a/crates/stages/src/stages/sender_recovery.rs +++ b/crates/stages/src/stages/sender_recovery.rs @@ -228,14 +228,16 @@ fn stage_checkpoint( #[error(transparent)] enum SenderRecoveryStageError { /// A transaction failed sender recovery - FailedRecovery(FailedSenderRecoveryError), + #[error(transparent)] + FailedRecovery(#[from] FailedSenderRecoveryError), /// A different type of stage error occurred + #[error(transparent)] StageError(#[from] StageError), } #[derive(Error, Debug)] -#[error("Sender recovery failed for transaction {tx}.")] +#[error("sender recovery failed for transaction {tx}")] struct FailedSenderRecoveryError { /// The transaction that failed sender recovery tx: TxNumber, diff --git a/crates/stages/src/stages/total_difficulty.rs b/crates/stages/src/stages/total_difficulty.rs index 9fbb9bca3f..5a923e9d18 100644 --- a/crates/stages/src/stages/total_difficulty.rs +++ b/crates/stages/src/stages/total_difficulty.rs @@ -72,7 +72,7 @@ impl Stage for TotalDifficultyStage { let last_header_number = input.checkpoint().block_number; let last_entry = cursor_td .seek_exact(last_header_number)? - .ok_or(ProviderError::TotalDifficultyNotFound { number: last_header_number })?; + .ok_or(ProviderError::TotalDifficultyNotFound { block_number: last_header_number })?; let mut td: U256 = last_entry.1.into(); debug!(target: "sync::stages::total_difficulty", ?td, block_number = last_header_number, "Last total difficulty entry"); diff --git a/crates/stages/src/test_utils/runner.rs b/crates/stages/src/test_utils/runner.rs index d49e24ca69..190ea3b53a 100644 --- a/crates/stages/src/test_utils/runner.rs +++ b/crates/stages/src/test_utils/runner.rs @@ -9,11 +9,11 @@ use tokio::sync::oneshot; #[derive(thiserror::Error, Debug)] pub(crate) enum TestRunnerError { - #[error("Database error occurred.")] + #[error(transparent)] Database(#[from] DatabaseError), - #[error("Internal runner error occurred.")] + #[error(transparent)] Internal(#[from] Box), - #[error("Internal interface error occurred.")] + #[error(transparent)] Interface(#[from] RethError), } diff --git a/crates/storage/db/src/implementation/mdbx/mod.rs b/crates/storage/db/src/implementation/mdbx/mod.rs index ea82ed4285..7c0f6051fe 100644 --- a/crates/storage/db/src/implementation/mdbx/mod.rs +++ b/crates/storage/db/src/implementation/mdbx/mod.rs @@ -46,15 +46,11 @@ impl<'a, E: EnvironmentKind> DatabaseGAT<'a> for Env { impl Database for Env { fn tx(&self) -> Result<>::TX, DatabaseError> { - Ok(Tx::new( - self.inner.begin_ro_txn().map_err(|e| DatabaseError::InitTransaction(e.into()))?, - )) + Ok(Tx::new(self.inner.begin_ro_txn().map_err(|e| DatabaseError::InitTx(e.into()))?)) } fn tx_mut(&self) -> Result<>::TXMut, DatabaseError> { - Ok(Tx::new( - self.inner.begin_rw_txn().map_err(|e| DatabaseError::InitTransaction(e.into()))?, - )) + Ok(Tx::new(self.inner.begin_rw_txn().map_err(|e| DatabaseError::InitTx(e.into()))?)) } } @@ -120,15 +116,14 @@ impl Env { } } - let env = - Env { inner: inner_env.open(path).map_err(|e| DatabaseError::FailedToOpen(e.into()))? }; + let env = Env { inner: inner_env.open(path).map_err(|e| DatabaseError::Open(e.into()))? }; Ok(env) } /// Creates all the defined tables, if necessary. pub fn create_tables(&self) -> Result<(), DatabaseError> { - let tx = self.inner.begin_rw_txn().map_err(|e| DatabaseError::InitTransaction(e.into()))?; + let tx = self.inner.begin_rw_txn().map_err(|e| DatabaseError::InitTx(e.into()))?; for table in Tables::ALL { let flags = match table.table_type() { @@ -137,7 +132,7 @@ impl Env { }; tx.create_db(Some(table.name()), flags) - .map_err(|e| DatabaseError::TableCreation(e.into()))?; + .map_err(|e| DatabaseError::CreateTable(e.into()))?; } tx.commit().map_err(|e| DatabaseError::Commit(e.into()))?; diff --git a/crates/storage/db/src/tables/codecs/scale.rs b/crates/storage/db/src/tables/codecs/scale.rs index 6d42325b03..a837dadef9 100644 --- a/crates/storage/db/src/tables/codecs/scale.rs +++ b/crates/storage/db/src/tables/codecs/scale.rs @@ -31,8 +31,7 @@ where T: ScaleValue + parity_scale_codec::Decode + Sync + Send + std::fmt::Debug, { fn decompress>(value: B) -> Result { - parity_scale_codec::Decode::decode(&mut value.as_ref()) - .map_err(|_| DatabaseError::DecodeError) + parity_scale_codec::Decode::decode(&mut value.as_ref()).map_err(|_| DatabaseError::Decode) } } diff --git a/crates/storage/db/src/tables/mod.rs b/crates/storage/db/src/tables/mod.rs index 7171f137c6..b9502153dd 100644 --- a/crates/storage/db/src/tables/mod.rs +++ b/crates/storage/db/src/tables/mod.rs @@ -187,29 +187,22 @@ tables!([ (PruneCheckpoints, TableType::Table) ]); -#[macro_export] /// Macro to declare key value table. +#[macro_export] macro_rules! table { ($(#[$docs:meta])+ ( $table_name:ident ) $key:ty | $value:ty) => { $(#[$docs])+ /// - #[doc = concat!("Takes [`", stringify!($key), "`] as a key and returns [`", stringify!($value), "`]")] + #[doc = concat!("Takes [`", stringify!($key), "`] as a key and returns [`", stringify!($value), "`].")] #[derive(Clone, Copy, Debug, Default)] pub struct $table_name; impl $crate::table::Table for $table_name { - const NAME: &'static str = $table_name::const_name(); + const NAME: &'static str = stringify!($table_name); type Key = $key; type Value = $value; } - impl $table_name { - #[doc=concat!("Return ", stringify!($table_name), " as it is present inside the database.")] - pub const fn const_name() -> &'static str { - stringify!($table_name) - } - } - impl std::fmt::Display for $table_name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", stringify!($table_name)) @@ -225,7 +218,7 @@ macro_rules! dupsort { table!( $(#[$docs])+ /// - #[doc = concat!("`DUPSORT` table with subkey being: [`", stringify!($subkey), "`].")] + #[doc = concat!("`DUPSORT` table with subkey being: [`", stringify!($subkey), "`]")] ( $table_name ) $key | $value ); impl DupSort for $table_name { @@ -430,37 +423,36 @@ pub type StageId = String; #[cfg(test)] mod tests { + use super::*; use std::str::FromStr; - use crate::*; - const TABLES: [(TableType, &str); NUM_TABLES] = [ - (TableType::Table, CanonicalHeaders::const_name()), - (TableType::Table, HeaderTD::const_name()), - (TableType::Table, HeaderNumbers::const_name()), - (TableType::Table, Headers::const_name()), - (TableType::Table, BlockBodyIndices::const_name()), - (TableType::Table, BlockOmmers::const_name()), - (TableType::Table, BlockWithdrawals::const_name()), - (TableType::Table, TransactionBlock::const_name()), - (TableType::Table, Transactions::const_name()), - (TableType::Table, TxHashNumber::const_name()), - (TableType::Table, Receipts::const_name()), - (TableType::Table, PlainAccountState::const_name()), - (TableType::DupSort, PlainStorageState::const_name()), - (TableType::Table, Bytecodes::const_name()), - (TableType::Table, AccountHistory::const_name()), - (TableType::Table, StorageHistory::const_name()), - (TableType::DupSort, AccountChangeSet::const_name()), - (TableType::DupSort, StorageChangeSet::const_name()), - (TableType::Table, HashedAccount::const_name()), - (TableType::DupSort, HashedStorage::const_name()), - (TableType::Table, AccountsTrie::const_name()), - (TableType::DupSort, StoragesTrie::const_name()), - (TableType::Table, TxSenders::const_name()), - (TableType::Table, SyncStage::const_name()), - (TableType::Table, SyncStageProgress::const_name()), - (TableType::Table, PruneCheckpoints::const_name()), + (TableType::Table, CanonicalHeaders::NAME), + (TableType::Table, HeaderTD::NAME), + (TableType::Table, HeaderNumbers::NAME), + (TableType::Table, Headers::NAME), + (TableType::Table, BlockBodyIndices::NAME), + (TableType::Table, BlockOmmers::NAME), + (TableType::Table, BlockWithdrawals::NAME), + (TableType::Table, TransactionBlock::NAME), + (TableType::Table, Transactions::NAME), + (TableType::Table, TxHashNumber::NAME), + (TableType::Table, Receipts::NAME), + (TableType::Table, PlainAccountState::NAME), + (TableType::DupSort, PlainStorageState::NAME), + (TableType::Table, Bytecodes::NAME), + (TableType::Table, AccountHistory::NAME), + (TableType::Table, StorageHistory::NAME), + (TableType::DupSort, AccountChangeSet::NAME), + (TableType::DupSort, StorageChangeSet::NAME), + (TableType::Table, HashedAccount::NAME), + (TableType::DupSort, HashedStorage::NAME), + (TableType::Table, AccountsTrie::NAME), + (TableType::DupSort, StoragesTrie::NAME), + (TableType::Table, TxSenders::NAME), + (TableType::Table, SyncStage::NAME), + (TableType::Table, SyncStageProgress::NAME), + (TableType::Table, PruneCheckpoints::NAME), ]; #[test] diff --git a/crates/storage/db/src/tables/models/accounts.rs b/crates/storage/db/src/tables/models/accounts.rs index c3b8e60677..57533f5778 100644 --- a/crates/storage/db/src/tables/models/accounts.rs +++ b/crates/storage/db/src/tables/models/accounts.rs @@ -116,8 +116,7 @@ impl Encode for BlockNumberAddress { impl Decode for BlockNumberAddress { fn decode>(value: B) -> Result { let value = value.as_ref(); - let num = - u64::from_be_bytes(value[..8].try_into().map_err(|_| DatabaseError::DecodeError)?); + let num = u64::from_be_bytes(value[..8].try_into().map_err(|_| DatabaseError::Decode)?); let hash = Address::from_slice(&value[8..]); Ok(BlockNumberAddress((num, hash))) diff --git a/crates/storage/db/src/tables/models/integer_list.rs b/crates/storage/db/src/tables/models/integer_list.rs index 203957e783..94746a1211 100644 --- a/crates/storage/db/src/tables/models/integer_list.rs +++ b/crates/storage/db/src/tables/models/integer_list.rs @@ -19,6 +19,6 @@ impl Compress for IntegerList { impl Decompress for IntegerList { fn decompress>(value: B) -> Result { - IntegerList::from_bytes(value.as_ref()).map_err(|_| DatabaseError::DecodeError) + IntegerList::from_bytes(value.as_ref()).map_err(|_| DatabaseError::Decode) } } diff --git a/crates/storage/db/src/tables/models/mod.rs b/crates/storage/db/src/tables/models/mod.rs index 0db59058a0..507151797d 100644 --- a/crates/storage/db/src/tables/models/mod.rs +++ b/crates/storage/db/src/tables/models/mod.rs @@ -23,8 +23,7 @@ pub use sharded_key::ShardedKey; macro_rules! impl_uints { ($($name:tt),+) => { $( - impl Encode for $name - { + impl Encode for $name { type Encoded = [u8; std::mem::size_of::<$name>()]; fn encode(self) -> Self::Encoded { @@ -32,12 +31,11 @@ macro_rules! impl_uints { } } - impl Decode for $name - { + impl Decode for $name { fn decode>(value: B) -> Result { Ok( $name::from_be_bytes( - value.as_ref().try_into().map_err(|_| $crate::DatabaseError::DecodeError)? + value.as_ref().try_into().map_err(|_| $crate::DatabaseError::Decode)? ) ) } @@ -50,6 +48,7 @@ impl_uints!(u64, u32, u16, u8); impl Encode for Vec { type Encoded = Vec; + fn encode(self) -> Self::Encoded { self } @@ -63,6 +62,7 @@ impl Decode for Vec { impl Encode for Address { type Encoded = [u8; 20]; + fn encode(self) -> Self::Encoded { self.0 .0 } @@ -76,6 +76,7 @@ impl Decode for Address { impl Encode for B256 { type Encoded = [u8; 32]; + fn encode(self) -> Self::Encoded { self.0 } @@ -83,12 +84,13 @@ impl Encode for B256 { impl Decode for B256 { fn decode>(value: B) -> Result { - Ok(B256::from_slice(value.as_ref())) + Ok(B256::new(value.as_ref().try_into().map_err(|_| DatabaseError::Decode)?)) } } impl Encode for String { type Encoded = Vec; + fn encode(self) -> Self::Encoded { self.into_bytes() } @@ -96,7 +98,7 @@ impl Encode for String { impl Decode for String { fn decode>(value: B) -> Result { - String::from_utf8(value.as_ref().to_vec()).map_err(|_| DatabaseError::DecodeError) + String::from_utf8(value.as_ref().to_vec()).map_err(|_| DatabaseError::Decode) } } diff --git a/crates/storage/db/src/tables/models/sharded_key.rs b/crates/storage/db/src/tables/models/sharded_key.rs index 5dedd349eb..9c0664da44 100644 --- a/crates/storage/db/src/tables/models/sharded_key.rs +++ b/crates/storage/db/src/tables/models/sharded_key.rs @@ -69,7 +69,7 @@ where let tx_num_index = value.len() - 8; let highest_tx_number = u64::from_be_bytes( - value[tx_num_index..].try_into().map_err(|_| DatabaseError::DecodeError)?, + value[tx_num_index..].try_into().map_err(|_| DatabaseError::Decode)?, ); let key = T::decode(&value[..tx_num_index])?; diff --git a/crates/storage/db/src/tables/models/storage_sharded_key.rs b/crates/storage/db/src/tables/models/storage_sharded_key.rs index a5fd89b379..e0d9faa1f0 100644 --- a/crates/storage/db/src/tables/models/storage_sharded_key.rs +++ b/crates/storage/db/src/tables/models/storage_sharded_key.rs @@ -63,7 +63,7 @@ impl Decode for StorageShardedKey { let tx_num_index = value.len() - 8; let highest_tx_number = u64::from_be_bytes( - value[tx_num_index..].try_into().map_err(|_| DatabaseError::DecodeError)?, + value[tx_num_index..].try_into().map_err(|_| DatabaseError::Decode)?, ); let address = Address::decode(&value[..20])?; let storage_key = B256::decode(&value[20..52])?; diff --git a/crates/storage/db/src/version.rs b/crates/storage/db/src/version.rs index db61744590..380c170c54 100644 --- a/crates/storage/db/src/version.rs +++ b/crates/storage/db/src/version.rs @@ -15,14 +15,13 @@ pub const DB_VERSION: u64 = 1; #[allow(missing_docs)] #[derive(thiserror::Error, Debug)] pub enum DatabaseVersionError { - #[error("Unable to determine the version of the database, file is missing.")] + #[error("unable to determine the version of the database, file is missing")] MissingFile, - #[error("Unable to determine the version of the database, file is malformed.")] + #[error("unable to determine the version of the database, file is malformed")] MalformedFile, #[error( - "Breaking database change detected. \ - Your database version (v{version}) is incompatible with the latest database version (v{}).", - DB_VERSION.to_string() + "breaking database change detected: your database version (v{version}) \ + is incompatible with the latest database version (v{DB_VERSION})" )] VersionMismatch { version: u64 }, #[error("IO error occurred while reading {path}: {err}")] diff --git a/crates/storage/nippy-jar/src/error.rs b/crates/storage/nippy-jar/src/error.rs index b17d3d2163..20513c414a 100644 --- a/crates/storage/nippy-jar/src/error.rs +++ b/crates/storage/nippy-jar/src/error.rs @@ -13,28 +13,28 @@ pub enum NippyJarError { Bincode(#[from] Box), #[error(transparent)] EliasFano(#[from] anyhow::Error), - #[error("Compression was enabled, but it's not ready yet.")] + #[error("compression was enabled, but it's not ready yet")] CompressorNotReady, - #[error("Decompression was enabled, but it's not ready yet.")] + #[error("decompression was enabled, but it's not ready yet")] DecompressorNotReady, - #[error("Number of columns does not match. {0} != {1}")] + #[error("number of columns does not match: {0} != {1}")] ColumnLenMismatch(usize, usize), - #[error("UnexpectedMissingValue row: {0} col:{1}")] + #[error("unexpected missing value: row:col {0}:{1}")] UnexpectedMissingValue(u64, u64), #[error(transparent)] FilterError(#[from] cuckoofilter::CuckooError), - #[error("NippyJar initialized without filter.")] + #[error("nippy jar initialized without filter")] FilterMissing, - #[error("Filter has reached max capacity.")] + #[error("filter has reached max capacity")] FilterMaxCapacity, - #[error("Cuckoo was not properly initialized after loaded.")] + #[error("cuckoo was not properly initialized after loaded")] FilterCuckooNotLoaded, - #[error("Perfect hashing function doesn't have any keys added.")] + #[error("perfect hashing function doesn't have any keys added")] PHFMissingKeys, - #[error("NippyJar initialized without perfect hashing function.")] + #[error("nippy jar initialized without perfect hashing function")] PHFMissing, - #[error("NippyJar was built without an index.")] + #[error("nippy jar was built without an index")] UnsupportedFilterQuery, - #[error("Compression or decompression requires a bigger destination output.")] + #[error("compression or decompression requires a bigger destination output")] OutputTooSmall, } diff --git a/crates/transaction-pool/src/error.rs b/crates/transaction-pool/src/error.rs index 01ced749e2..51e0cf22e5 100644 --- a/crates/transaction-pool/src/error.rs +++ b/crates/transaction-pool/src/error.rs @@ -17,52 +17,65 @@ pub trait PoolTransactionError: std::error::Error + Send + Sync { fn is_bad_transaction(&self) -> bool; } -/// All errors the Transaction pool can throw. +// Needed for `#[error(transparent)]` +impl std::error::Error for Box { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + (**self).source() + } +} + +/// Transaction pool error. #[derive(Debug, thiserror::Error)] -pub enum PoolError { +#[error("[{hash}]: {kind}")] +pub struct PoolError { + /// The transaction hash that caused the error. + pub hash: TxHash, + /// The error kind. + pub kind: PoolErrorKind, +} + +/// Transaction pool error kind. +#[derive(Debug, thiserror::Error)] +pub enum PoolErrorKind { /// Same transaction already imported - #[error("[{0:?}] Already imported")] - AlreadyImported(TxHash), + #[error("already imported")] + AlreadyImported, /// Thrown if a replacement transaction's gas price is below the already imported transaction - #[error("[{0:?}]: insufficient gas price to replace existing transaction.")] - ReplacementUnderpriced(TxHash), + #[error("insufficient gas price to replace existing transaction")] + ReplacementUnderpriced, /// The fee cap of the transaction is below the minimum fee cap determined by the protocol - #[error("[{0:?}] Transaction feeCap {1} below chain minimum.")] - FeeCapBelowMinimumProtocolFeeCap(TxHash, u128), + #[error("transaction feeCap {0} below chain minimum")] + FeeCapBelowMinimumProtocolFeeCap(u128), /// Thrown when the number of unique transactions of a sender exceeded the slot capacity. - #[error("{0:?} identified as spammer. Transaction {1:?} rejected.")] - SpammerExceededCapacity(Address, TxHash), + #[error("rejected due to {0} being identified as a spammer")] + SpammerExceededCapacity(Address), /// Thrown when a new transaction is added to the pool, but then immediately discarded to /// respect the size limits of the pool. - #[error("[{0:?}] Transaction discarded outright due to pool size constraints.")] - DiscardedOnInsert(TxHash), + #[error("transaction discarded outright due to pool size constraints")] + DiscardedOnInsert, /// Thrown when the transaction is considered invalid. - #[error("[{0:?}] {1:?}")] - InvalidTransaction(TxHash, InvalidPoolTransactionError), + #[error(transparent)] + InvalidTransaction(#[from] InvalidPoolTransactionError), /// Thrown if the mutual exclusivity constraint (blob vs normal transaction) is violated. - #[error("[{1:?}] Transaction type {2} conflicts with existing transaction for {0:?}")] - ExistingConflictingTransactionType(Address, TxHash, u8), + #[error("transaction type {1} conflicts with existing transaction for {0}")] + ExistingConflictingTransactionType(Address, u8), /// Any other error that occurred while inserting/validating a transaction. e.g. IO database /// error - #[error("[{0:?}] {1:?}")] - Other(TxHash, Box), + #[error(transparent)] + Other(#[from] Box), } // === impl PoolError === impl PoolError { - /// Returns the hash of the transaction that resulted in this error. - pub fn hash(&self) -> &TxHash { - match self { - PoolError::AlreadyImported(hash) => hash, - PoolError::ReplacementUnderpriced(hash) => hash, - PoolError::FeeCapBelowMinimumProtocolFeeCap(hash, _) => hash, - PoolError::SpammerExceededCapacity(_, hash) => hash, - PoolError::DiscardedOnInsert(hash) => hash, - PoolError::InvalidTransaction(hash, _) => hash, - PoolError::Other(hash, _) => hash, - PoolError::ExistingConflictingTransactionType(_, hash, _) => hash, - } + /// Creates a new pool error. + pub fn new(hash: TxHash, kind: impl Into) -> Self { + Self { hash, kind: kind.into() } + } + + /// Creates a new pool error with the `Other` kind. + pub fn other(hash: TxHash, error: impl Into>) -> Self { + Self { hash, kind: PoolErrorKind::Other(error.into()) } } /// Returns `true` if the error was caused by a transaction that is considered bad in the @@ -79,42 +92,42 @@ impl PoolError { /// erroneous transaction. #[inline] pub fn is_bad_transaction(&self) -> bool { - match self { - PoolError::AlreadyImported(_) => { + match &self.kind { + PoolErrorKind::AlreadyImported => { // already imported but not bad false } - PoolError::ReplacementUnderpriced(_) => { + PoolErrorKind::ReplacementUnderpriced => { // already imported but not bad false } - PoolError::FeeCapBelowMinimumProtocolFeeCap(_, _) => { + PoolErrorKind::FeeCapBelowMinimumProtocolFeeCap(_) => { // fee cap of the tx below the technical minimum determined by the protocol, see // [MINIMUM_PROTOCOL_FEE_CAP](reth_primitives::constants::MIN_PROTOCOL_BASE_FEE) // although this transaction will always be invalid, we do not want to penalize the // sender because this check simply could not be implemented by the client false } - PoolError::SpammerExceededCapacity(_, _) => { + PoolErrorKind::SpammerExceededCapacity(_) => { // the sender exceeded the slot capacity, we should not penalize the peer for // sending the tx because we don't know if all the transactions are sent from the // same peer, there's also a chance that old transactions haven't been cleared yet // (pool lags behind) and old transaction still occupy a slot in the pool false } - PoolError::DiscardedOnInsert(_) => { + PoolErrorKind::DiscardedOnInsert => { // valid tx but dropped due to size constraints false } - PoolError::InvalidTransaction(_, err) => { + PoolErrorKind::InvalidTransaction(err) => { // transaction rejected because it violates constraints err.is_bad_transaction() } - PoolError::Other(_, _) => { + PoolErrorKind::Other(_) => { // internal error unrelated to the transaction false } - PoolError::ExistingConflictingTransactionType(_, _, _) => { + PoolErrorKind::ExistingConflictingTransactionType(_, _) => { // this is not a protocol error but an implementation error since the pool enforces // exclusivity (blob vs normal tx) for all senders false @@ -150,7 +163,7 @@ pub enum Eip4844PoolTransactionError { /// /// This error is thrown on validation if a valid blob transaction arrives with a nonce that /// would introduce gap in the nonce sequence. - #[error("Nonce too high.")] + #[error("nonce too high")] Eip4844NonceGap, } @@ -164,16 +177,16 @@ pub enum InvalidPoolTransactionError { Consensus(#[from] InvalidTransactionError), /// Thrown when a new transaction is added to the pool, but then immediately discarded to /// respect the size limits of the pool. - #[error("Transaction's gas limit {0} exceeds block's gas limit {1}.")] + #[error("transaction's gas limit {0} exceeds block's gas limit {1}")] ExceedsGasLimit(u64, u64), /// Thrown when a new transaction is added to the pool, but then immediately discarded to /// respect the max_init_code_size. - #[error("Transaction's size {0} exceeds max_init_code_size {1}.")] + #[error("transaction's size {0} exceeds max_init_code_size {1}")] ExceedsMaxInitCodeSize(usize, usize), /// Thrown if the input data of a transaction is greater /// than some meaningful limit a user might use. This is not a consensus error /// making the transaction invalid, rather a DOS protection. - #[error("Input data too large")] + #[error("input data too large")] OversizedData(usize, usize), /// Thrown if the transaction's fee is below the minimum fee #[error("transaction underpriced")] @@ -185,7 +198,7 @@ pub enum InvalidPoolTransactionError { #[error(transparent)] Eip4844(#[from] Eip4844PoolTransactionError), /// Any other error that occurred while inserting/validating that is transaction specific - #[error("{0:?}")] + #[error(transparent)] Other(Box), /// The transaction is specified to use less gas than required to start the /// invocation. diff --git a/crates/transaction-pool/src/noop.rs b/crates/transaction-pool/src/noop.rs index 0ba41a6fab..13efe283cd 100644 --- a/crates/transaction-pool/src/noop.rs +++ b/crates/transaction-pool/src/noop.rs @@ -51,7 +51,7 @@ impl TransactionPool for NoopTransactionPool { transaction: Self::Transaction, ) -> PoolResult { let hash = *transaction.hash(); - Err(PoolError::Other(hash, Box::new(NoopInsertError::new(transaction)))) + Err(PoolError::other(hash, Box::new(NoopInsertError::new(transaction)))) } async fn add_transaction( @@ -60,7 +60,7 @@ impl TransactionPool for NoopTransactionPool { transaction: Self::Transaction, ) -> PoolResult { let hash = *transaction.hash(); - Err(PoolError::Other(hash, Box::new(NoopInsertError::new(transaction)))) + Err(PoolError::other(hash, Box::new(NoopInsertError::new(transaction)))) } async fn add_transactions( @@ -72,7 +72,7 @@ impl TransactionPool for NoopTransactionPool { .into_iter() .map(|transaction| { let hash = *transaction.hash(); - Err(PoolError::Other(hash, Box::new(NoopInsertError::new(transaction)))) + Err(PoolError::other(hash, Box::new(NoopInsertError::new(transaction)))) }) .collect()) } @@ -264,7 +264,7 @@ impl Default for MockTransactionValidator { /// An error that contains the transaction that failed to be inserted into the noop pool. #[derive(Debug, Clone, thiserror::Error)] -#[error("Can't insert transaction into the noop pool that does nothing.")] +#[error("can't insert transaction into the noop pool that does nothing")] pub struct NoopInsertError { tx: EthPooledTransaction, } diff --git a/crates/transaction-pool/src/pool/mod.rs b/crates/transaction-pool/src/pool/mod.rs index 6c7a00a051..55f4cbb1ba 100644 --- a/crates/transaction-pool/src/pool/mod.rs +++ b/crates/transaction-pool/src/pool/mod.rs @@ -66,7 +66,7 @@ //! category (2.) and become pending. use crate::{ - error::{PoolError, PoolResult}, + error::{PoolError, PoolErrorKind, PoolResult}, identifier::{SenderId, SenderIdentifiers, TransactionId}, pool::{ listener::PoolEventBroadcast, @@ -449,12 +449,12 @@ where TransactionValidationOutcome::Invalid(tx, err) => { let mut listener = self.event_listener.write(); listener.discarded(tx.hash()); - Err(PoolError::InvalidTransaction(*tx.hash(), err)) + Err(PoolError::new(*tx.hash(), err)) } TransactionValidationOutcome::Error(tx_hash, err) => { let mut listener = self.event_listener.write(); listener.discarded(&tx_hash); - Err(PoolError::Other(tx_hash, err)) + Err(PoolError::other(tx_hash, err)) } } } @@ -498,7 +498,7 @@ where .into_iter() .map(|res| match res { Ok(ref hash) if discarded.contains(hash) => { - Err(PoolError::DiscardedOnInsert(*hash)) + Err(PoolError::new(*hash, PoolErrorKind::DiscardedOnInsert)) } other => other, }) diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 8e5027bff7..8dbe28db3e 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -1,7 +1,7 @@ //! The internal transaction pool implementation. use crate::{ config::TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, - error::{Eip4844PoolTransactionError, InvalidPoolTransactionError, PoolError}, + error::{Eip4844PoolTransactionError, InvalidPoolTransactionError, PoolError, PoolErrorKind}, identifier::{SenderId, TransactionId}, metrics::TxPoolMetrics, pool::{ @@ -414,7 +414,7 @@ impl TxPool { on_chain_nonce: u64, ) -> PoolResult> { if self.contains(tx.hash()) { - return Err(PoolError::AlreadyImported(*tx.hash())) + return Err(PoolError::new(*tx.hash(), PoolErrorKind::AlreadyImported)) } // Update sender info with balance and nonce @@ -452,42 +452,50 @@ impl TxPool { self.metrics.invalid_transactions.increment(1); match err { InsertErr::Underpriced { existing, transaction: _ } => { - Err(PoolError::ReplacementUnderpriced(existing)) + Err(PoolError::new(existing, PoolErrorKind::ReplacementUnderpriced)) } - InsertErr::FeeCapBelowMinimumProtocolFeeCap { transaction, fee_cap } => Err( - PoolError::FeeCapBelowMinimumProtocolFeeCap(*transaction.hash(), fee_cap), - ), - InsertErr::ExceededSenderTransactionsCapacity { transaction } => { - Err(PoolError::SpammerExceededCapacity( - transaction.sender(), + InsertErr::FeeCapBelowMinimumProtocolFeeCap { transaction, fee_cap } => { + Err(PoolError::new( *transaction.hash(), + PoolErrorKind::FeeCapBelowMinimumProtocolFeeCap(fee_cap), + )) + } + InsertErr::ExceededSenderTransactionsCapacity { transaction } => { + Err(PoolError::new( + *transaction.hash(), + PoolErrorKind::SpammerExceededCapacity(transaction.sender()), )) } InsertErr::TxGasLimitMoreThanAvailableBlockGas { transaction, block_gas_limit, tx_gas_limit, - } => Err(PoolError::InvalidTransaction( + } => Err(PoolError::new( *transaction.hash(), - InvalidPoolTransactionError::ExceedsGasLimit(block_gas_limit, tx_gas_limit), + PoolErrorKind::InvalidTransaction( + InvalidPoolTransactionError::ExceedsGasLimit( + block_gas_limit, + tx_gas_limit, + ), + ), )), - InsertErr::BlobTxHasNonceGap { transaction } => { - Err(PoolError::InvalidTransaction( - *transaction.hash(), + InsertErr::BlobTxHasNonceGap { transaction } => Err(PoolError::new( + *transaction.hash(), + PoolErrorKind::InvalidTransaction( Eip4844PoolTransactionError::Eip4844NonceGap.into(), - )) - } - InsertErr::Overdraft { transaction } => Err(PoolError::InvalidTransaction( - *transaction.hash(), - InvalidPoolTransactionError::Overdraft, + ), )), - InsertErr::TxTypeConflict { transaction } => { - Err(PoolError::ExistingConflictingTransactionType( + InsertErr::Overdraft { transaction } => Err(PoolError::new( + *transaction.hash(), + PoolErrorKind::InvalidTransaction(InvalidPoolTransactionError::Overdraft), + )), + InsertErr::TxTypeConflict { transaction } => Err(PoolError::new( + *transaction.hash(), + PoolErrorKind::ExistingConflictingTransactionType( transaction.sender(), - *transaction.hash(), transaction.tx_type(), - )) - } + ), + )), } } } @@ -1828,8 +1836,8 @@ mod tests { let tx = MockTransaction::eip1559().inc_price().inc_limit(); let tx = f.validated(tx); pool.add_transaction(tx.clone(), on_chain_balance, on_chain_nonce).unwrap(); - match pool.add_transaction(tx, on_chain_balance, on_chain_nonce).unwrap_err() { - PoolError::AlreadyImported(_) => {} + match pool.add_transaction(tx, on_chain_balance, on_chain_nonce).unwrap_err().kind { + PoolErrorKind::AlreadyImported => {} _ => unreachable!(), } } diff --git a/crates/transaction-pool/src/validate/mod.rs b/crates/transaction-pool/src/validate/mod.rs index 7df86d51a9..6f62720680 100644 --- a/crates/transaction-pool/src/validate/mod.rs +++ b/crates/transaction-pool/src/validate/mod.rs @@ -347,6 +347,6 @@ impl fmt::Debug for ValidPoolTransaction { #[derive(thiserror::Error, Debug)] pub enum TransactionValidatorError { /// Failed to communicate with the validation service. - #[error("Validation service unreachable")] + #[error("validation service unreachable")] ValidationServiceUnreachable, } diff --git a/crates/transaction-pool/tests/it/blobs.rs b/crates/transaction-pool/tests/it/blobs.rs index cdcce9de3d..26b7795d1a 100644 --- a/crates/transaction-pool/tests/it/blobs.rs +++ b/crates/transaction-pool/tests/it/blobs.rs @@ -1,7 +1,7 @@ //! Blob transaction tests use reth_transaction_pool::{ - error::PoolError, + error::PoolErrorKind, test_utils::{testing_pool, MockTransaction, MockTransactionFactory}, TransactionOrigin, TransactionPool, }; @@ -29,10 +29,10 @@ async fn blobs_exclusive() { let res = txpool.add_transaction(TransactionOrigin::External, eip1559_tx.clone()).await.unwrap_err(); - match res { - PoolError::ExistingConflictingTransactionType(addr, hash, tx_type) => { + assert_eq!(res.hash, eip1559_tx.get_hash()); + match res.kind { + PoolErrorKind::ExistingConflictingTransactionType(addr, tx_type) => { assert_eq!(addr, eip1559_tx.get_sender()); - assert_eq!(hash, eip1559_tx.get_hash()); assert_eq!(tx_type, eip1559_tx.tx_type()); } _ => unreachable!(), diff --git a/testing/ef-tests/src/result.rs b/testing/ef-tests/src/result.rs index e0d6ec5012..c7a893c4cb 100644 --- a/testing/ef-tests/src/result.rs +++ b/testing/ef-tests/src/result.rs @@ -15,13 +15,13 @@ use thiserror::Error; #[non_exhaustive] pub enum Error { /// The test was skipped - #[error("Test was skipped")] + #[error("test was skipped")] Skipped, /// No post state found in test - #[error("No post state found for validation")] + #[error("no post state found for validation")] MissingPostState, /// An IO error occurred - #[error("An error occurred interacting with the file system at {path}: {error}")] + #[error("an error occurred interacting with the file system at {path}: {error}")] Io { /// The path to the file or directory path: PathBuf, @@ -30,7 +30,7 @@ pub enum Error { error: std::io::Error, }, /// A deserialization error occurred - #[error("An error occurred deserializing the test at {path}: {error}")] + #[error("an error occurred deserializing the test at {path}: {error}")] CouldNotDeserialize { /// The path to the file we wanted to deserialize path: PathBuf, @@ -42,13 +42,13 @@ pub enum Error { #[error(transparent)] Database(#[from] DatabaseError), /// A test assertion failed. - #[error("Test failed: {0}")] + #[error("test failed: {0}")] Assertion(String), /// An error internally in reth occurred. - #[error("Test failed: {0}")] + #[error("test failed: {0}")] RethError(#[from] RethError), /// An error occurred while decoding RLP. - #[error("An error occurred deserializing RLP")] + #[error("an error occurred deserializing RLP: {0}")] RlpDecodeError(#[from] alloy_rlp::Error), }