diff --git a/Cargo.lock b/Cargo.lock index 2ce9de38b..ee50ce50e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7306,12 +7306,12 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", + "derive_more", "nybbles", "reth-consensus", "reth-prune-types", "reth-storage-errors", "revm-primitives", - "thiserror-no-std", ] [[package]] diff --git a/crates/evm/execution-errors/Cargo.toml b/crates/evm/execution-errors/Cargo.toml index fdf6cf683..fd57c9f21 100644 --- a/crates/evm/execution-errors/Cargo.toml +++ b/crates/evm/execution-errors/Cargo.toml @@ -22,9 +22,9 @@ alloy-eips.workspace = true revm-primitives.workspace = true nybbles.workspace = true -thiserror-no-std = { workspace = true, default-features = false } +derive_more.workspace = true [features] default = ["std"] -std = ["thiserror-no-std/std"] \ No newline at end of file +std = [] \ No newline at end of file diff --git a/crates/evm/execution-errors/src/lib.rs b/crates/evm/execution-errors/src/lib.rs index bfa366f30..ba6258e18 100644 --- a/crates/evm/execution-errors/src/lib.rs +++ b/crates/evm/execution-errors/src/lib.rs @@ -11,43 +11,44 @@ #[cfg(not(feature = "std"))] extern crate alloc; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, string::String}; use alloy_eips::BlockNumHash; use alloy_primitives::B256; +use derive_more::Display; use reth_consensus::ConsensusError; use reth_prune_types::PruneSegmentError; use reth_storage_errors::provider::ProviderError; use revm_primitives::EVMError; -#[cfg(not(feature = "std"))] -use alloc::{boxed::Box, string::String}; - pub mod trie; pub use trie::*; /// Transaction validation errors -#[derive(thiserror_no_std::Error, Debug, Clone, PartialEq, Eq)] +#[derive(Clone, Debug, Display, Eq, PartialEq)] pub enum BlockValidationError { /// EVM error with transaction hash and message - #[error("EVM reported invalid transaction ({hash}): {error}")] + #[display(fmt = "EVM reported invalid transaction ({hash}): {error}")] EVM { /// The hash of the transaction hash: B256, /// The EVM error. - #[source] error: Box>, }, /// Error when recovering the sender for a transaction - #[error("failed to recover sender for transaction")] + #[display(fmt = "failed to recover sender for transaction")] SenderRecoveryError, /// Error when incrementing balance in post execution - #[error("incrementing balance in post execution failed")] + #[display(fmt = "incrementing balance in post execution failed")] IncrementBalanceFailed, /// Error when the state root does not match the expected value. - #[error(transparent)] - StateRoot(#[from] StateRootError), + // #[from(ignore)] + StateRoot(StateRootError), /// 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}")] + #[display( + fmt = "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, @@ -55,22 +56,24 @@ pub enum BlockValidationError { block_available_gas: u64, }, /// Error for pre-merge block - #[error("block {hash} is pre merge")] + #[display(fmt = "block {hash} is pre merge")] BlockPreMerge { /// The hash of the block hash: B256, }, /// Error for missing total difficulty - #[error("missing total difficulty for block {hash}")] + #[display(fmt = "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")] + #[display(fmt = "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: {parent_beacon_block_root}")] + #[display( + fmt = "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, @@ -78,7 +81,9 @@ pub enum BlockValidationError { /// EVM error during [EIP-4788] beacon root contract call. /// /// [EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788 - #[error("failed to apply beacon root contract call at {parent_beacon_block_root}: {message}")] + #[display( + fmt = "failed to apply beacon root contract call at {parent_beacon_block_root}: {message}" + )] BeaconRootContractCall { /// The beacon block root parent_beacon_block_root: Box, @@ -88,12 +93,11 @@ pub enum BlockValidationError { /// Provider error during the [EIP-2935] block hash account loading. /// /// [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935 - #[error(transparent)] - BlockHashAccountLoadingFailed(#[from] ProviderError), + BlockHashAccountLoadingFailed(ProviderError), /// EVM error during withdrawal requests contract call [EIP-7002] /// /// [EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 - #[error("failed to apply withdrawal requests contract call: {message}")] + #[display(fmt = "failed to apply withdrawal requests contract call: {message}")] WithdrawalRequestsContractCall { /// The error message. message: String, @@ -101,7 +105,7 @@ pub enum BlockValidationError { /// EVM error during consolidation requests contract call [EIP-7251] /// /// [EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 - #[error("failed to apply consolidation requests contract call: {message}")] + #[display(fmt = "failed to apply consolidation requests contract call: {message}")] ConsolidationRequestsContractCall { /// The error message. message: String, @@ -109,34 +113,36 @@ pub enum BlockValidationError { /// Error when decoding deposit requests from receipts [EIP-6110] /// /// [EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 - #[error("failed to decode deposit requests from receipts: {0}")] + #[display(fmt = "failed to decode deposit requests from receipts: {_0}")] DepositRequestDecode(String), } +impl From for BlockValidationError { + fn from(error: StateRootError) -> Self { + Self::StateRoot(error) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for BlockValidationError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::EVM { error, .. } => std::error::Error::source(error), + Self::StateRoot(source) => std::error::Error::source(source), + _ => Option::None, + } + } +} + /// `BlockExecutor` Errors -#[derive(thiserror_no_std::Error, Debug)] +#[derive(Debug, Display)] pub enum BlockExecutionError { /// Validation error, transparently wrapping [`BlockValidationError`] - #[error(transparent)] - Validation(#[from] BlockValidationError), + Validation(BlockValidationError), /// Consensus error, transparently wrapping [`ConsensusError`] - #[error(transparent)] - Consensus(#[from] ConsensusError), + Consensus(ConsensusError), /// Internal, i.e. non consensus or validation related Block Executor Errors - #[error(transparent)] - Internal(#[from] InternalBlockExecutionError), -} - -impl From for BlockExecutionError { - fn from(value: ProviderError) -> Self { - InternalBlockExecutionError::from(value).into() - } -} - -impl From for BlockExecutionError { - fn from(value: PruneSegmentError) -> Self { - InternalBlockExecutionError::from(value).into() - } + Internal(InternalBlockExecutionError), } impl BlockExecutionError { @@ -171,15 +177,49 @@ impl BlockExecutionError { } } +impl From for BlockExecutionError { + fn from(error: BlockValidationError) -> Self { + Self::Validation(error) + } +} + +impl From for BlockExecutionError { + fn from(error: ConsensusError) -> Self { + Self::Consensus(error) + } +} + +impl From for BlockExecutionError { + fn from(error: InternalBlockExecutionError) -> Self { + Self::Internal(error) + } +} + +impl From for BlockExecutionError { + fn from(error: ProviderError) -> Self { + InternalBlockExecutionError::from(error).into() + } +} + +#[cfg(feature = "std")] +impl std::error::Error for BlockExecutionError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Validation(source) => std::error::Error::source(source), + Self::Consensus(source) => std::error::Error::source(source), + Self::Internal(source) => std::error::Error::source(source), + } + } +} + /// Internal (i.e., not validation or consensus related) `BlockExecutor` Errors -#[derive(thiserror_no_std::Error, Debug)] +#[derive(Display, Debug)] pub enum InternalBlockExecutionError { /// Pruning error, transparently wrapping [`PruneSegmentError`] - #[error(transparent)] - Pruning(#[from] PruneSegmentError), + Pruning(PruneSegmentError), /// 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:?}" + #[display( + fmt = "appending chain on fork (other_chain_fork:?) is not possible as the tip is {chain_tip:?}" )] AppendChainDoesntConnect { /// The tip of the current chain @@ -188,11 +228,9 @@ pub enum InternalBlockExecutionError { other_chain_fork: Box, }, /// Error when fetching latest block state. - #[error(transparent)] - LatestBlock(#[from] ProviderError), + LatestBlock(ProviderError), /// Arbitrary Block Executor Errors #[cfg(feature = "std")] - #[error(transparent)] Other(Box), } @@ -212,3 +250,26 @@ impl InternalBlockExecutionError { Self::Other(msg.to_string().into()) } } + +impl From for InternalBlockExecutionError { + fn from(error: PruneSegmentError) -> Self { + Self::Pruning(error) + } +} + +impl From for InternalBlockExecutionError { + fn from(error: ProviderError) -> Self { + Self::LatestBlock(error) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for InternalBlockExecutionError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Pruning(source) => std::error::Error::source(source), + Self::LatestBlock(source) => std::error::Error::source(source), + _ => Option::None, + } + } +} diff --git a/crates/evm/execution-errors/src/trie.rs b/crates/evm/execution-errors/src/trie.rs index cb822b047..ccf9ea23c 100644 --- a/crates/evm/execution-errors/src/trie.rs +++ b/crates/evm/execution-errors/src/trie.rs @@ -1,19 +1,42 @@ //! Errors when computing the state root. use alloy_primitives::B256; +use derive_more::Display; use nybbles::Nibbles; use reth_storage_errors::{db::DatabaseError, provider::ProviderError}; -use thiserror_no_std::Error; + +#[cfg(not(feature = "std"))] +use alloc::string::ToString; /// State root errors. -#[derive(Error, Debug, PartialEq, Eq, Clone)] +#[derive(Display, Debug, PartialEq, Eq, Clone)] pub enum StateRootError { /// Internal database error. - #[error(transparent)] - Database(#[from] DatabaseError), + Database(DatabaseError), /// Storage root error. - #[error(transparent)] - StorageRootError(#[from] StorageRootError), + StorageRootError(StorageRootError), +} + +impl From for StateRootError { + fn from(error: DatabaseError) -> Self { + Self::Database(error) + } +} + +impl From for StateRootError { + fn from(error: StorageRootError) -> Self { + Self::StorageRootError(error) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for StateRootError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Database(source) => std::error::Error::source(source), + Self::StorageRootError(source) => std::error::Error::source(source), + } + } } impl From for DatabaseError { @@ -26,11 +49,16 @@ impl From for DatabaseError { } /// Storage root error. -#[derive(Error, PartialEq, Eq, Clone, Debug)] +#[derive(Display, PartialEq, Eq, Clone, Debug)] pub enum StorageRootError { /// Internal database error. - #[error(transparent)] - Database(#[from] DatabaseError), + Database(DatabaseError), +} + +impl From for StorageRootError { + fn from(error: DatabaseError) -> Self { + Self::Database(error) + } } impl From for DatabaseError { @@ -41,15 +69,34 @@ impl From for DatabaseError { } } +#[cfg(feature = "std")] +impl std::error::Error for StorageRootError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Database(source) => std::error::Error::source(source), + } + } +} + /// State proof errors. -#[derive(Error, Debug, PartialEq, Eq, Clone)] +#[derive(Display, Debug, PartialEq, Eq, Clone)] pub enum StateProofError { /// Internal database error. - #[error(transparent)] - Database(#[from] DatabaseError), + Database(DatabaseError), /// RLP decoding error. - #[error(transparent)] - Rlp(#[from] alloy_rlp::Error), + Rlp(alloy_rlp::Error), +} + +impl From for StateProofError { + fn from(error: DatabaseError) -> Self { + Self::Database(error) + } +} + +impl From for StateProofError { + fn from(error: alloy_rlp::Error) -> Self { + Self::Rlp(error) + } } impl From for ProviderError { @@ -61,28 +108,59 @@ impl From for ProviderError { } } +#[cfg(feature = "std")] +impl std::error::Error for StateProofError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Database(source) => std::error::Error::source(source), + Self::Rlp(source) => std::error::Error::source(source), + } + } +} + /// Trie witness errors. -#[derive(Error, Debug, PartialEq, Eq, Clone)] +#[derive(Display, Debug, PartialEq, Eq, Clone)] pub enum TrieWitnessError { /// Error gather proofs. - #[error(transparent)] - Proof(#[from] StateProofError), + Proof(StateProofError), /// RLP decoding error. - #[error(transparent)] - Rlp(#[from] alloy_rlp::Error), + Rlp(alloy_rlp::Error), /// Missing storage multiproof. - #[error("missing storage multiproof for {0}")] + #[display(fmt = "missing storage multiproof for {_0}")] MissingStorageMultiProof(B256), /// Missing account. - #[error("missing account {0}")] + #[display(fmt = "missing account {_0}")] MissingAccount(B256), /// Missing target node. - #[error("target node missing from proof {0:?}")] + #[display(fmt = "target node missing from proof {_0:?}")] MissingTargetNode(Nibbles), } -impl From for ProviderError { - fn from(value: TrieWitnessError) -> Self { - Self::TrieWitnessError(value.to_string()) +impl From for TrieWitnessError { + fn from(error: StateProofError) -> Self { + Self::Proof(error) + } +} + +impl From for TrieWitnessError { + fn from(error: alloy_rlp::Error) -> Self { + Self::Rlp(error) + } +} + +impl From for ProviderError { + fn from(error: TrieWitnessError) -> Self { + Self::TrieWitnessError(error.to_string()) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for TrieWitnessError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Proof(source) => std::error::Error::source(source), + Self::Rlp(source) => std::error::Error::source(source), + _ => Option::None, + } } }