reth_execution_errors/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
//! Commonly used error types used when doing block execution.
#![doc(
html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
)]
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::{boxed::Box, string::String};
use alloy_eips::BlockNumHash;
use alloy_primitives::B256;
use reth_consensus::ConsensusError;
use reth_prune_types::PruneSegmentError;
use reth_storage_errors::provider::ProviderError;
use revm_primitives::EVMError;
use thiserror::Error;
pub mod trie;
pub use trie::*;
/// Transaction validation errors
#[derive(Error, PartialEq, Eq, Clone, Debug)]
pub enum BlockValidationError {
/// EVM error with transaction hash and message
#[error("EVM reported invalid transaction ({hash}): {error}")]
EVM {
/// The hash of the transaction
hash: B256,
/// The EVM error.
error: Box<EVMError<ProviderError>>,
},
/// Error when recovering the sender for a transaction
#[error("failed to recover sender for transaction")]
SenderRecoveryError,
/// Error when incrementing balance in post execution
#[error("incrementing balance in post execution failed")]
IncrementBalanceFailed,
/// Error when the state root does not match the expected value.
#[error(transparent)]
StateRoot(#[from] 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}"
)]
TransactionGasLimitMoreThanAvailableBlockGas {
/// The transaction's gas limit
transaction_gas_limit: u64,
/// The available block gas
block_available_gas: u64,
},
/// Error for pre-merge block
#[error("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}")]
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")]
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}"
)]
CancunGenesisParentBeaconBlockRootNotZero {
/// The beacon block root
parent_beacon_block_root: B256,
},
/// 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}")]
BeaconRootContractCall {
/// The beacon block root
parent_beacon_block_root: Box<B256>,
/// The error message.
message: String,
},
/// EVM error during [EIP-2935] blockhash contract call.
///
/// [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935
#[error("failed to apply blockhash contract call: {message}")]
BlockHashContractCall {
/// The error message.
message: String,
},
/// 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}")]
WithdrawalRequestsContractCall {
/// The error message.
message: String,
},
/// 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}")]
ConsolidationRequestsContractCall {
/// The error message.
message: String,
},
/// 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}")]
DepositRequestDecode(String),
}
/// `BlockExecutor` Errors
#[derive(Error, Debug)]
pub enum BlockExecutionError {
/// Validation error, transparently wrapping [`BlockValidationError`]
#[error(transparent)]
Validation(#[from] BlockValidationError),
/// Consensus error, transparently wrapping [`ConsensusError`]
#[error(transparent)]
Consensus(#[from] ConsensusError),
/// Internal, i.e. non consensus or validation related Block Executor Errors
#[error(transparent)]
Internal(#[from] InternalBlockExecutionError),
}
impl BlockExecutionError {
/// Create a new [`BlockExecutionError::Internal`] variant, containing a
/// [`InternalBlockExecutionError::Other`] error.
#[cfg(feature = "std")]
pub fn other<E>(error: E) -> Self
where
E: core::error::Error + Send + Sync + 'static,
{
Self::Internal(InternalBlockExecutionError::other(error))
}
/// Create a new [`BlockExecutionError::Internal`] variant, containing a
/// [`InternalBlockExecutionError::Other`] error with the given message.
#[cfg(feature = "std")]
pub fn msg(msg: impl std::fmt::Display) -> Self {
Self::Internal(InternalBlockExecutionError::msg(msg))
}
/// Returns the inner `BlockValidationError` if the error is a validation error.
pub const fn as_validation(&self) -> Option<&BlockValidationError> {
match self {
Self::Validation(err) => Some(err),
_ => None,
}
}
/// Returns `true` if the error is a state root error.
pub const fn is_state_root_error(&self) -> bool {
matches!(self, Self::Validation(BlockValidationError::StateRoot(_)))
}
}
impl From<ProviderError> for BlockExecutionError {
fn from(error: ProviderError) -> Self {
InternalBlockExecutionError::from(error).into()
}
}
/// Internal (i.e., not validation or consensus related) `BlockExecutor` Errors
#[derive(Error, Debug)]
pub enum InternalBlockExecutionError {
/// Pruning error, transparently wrapping [`PruneSegmentError`]
#[error(transparent)]
Pruning(#[from] 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:?}"
)]
AppendChainDoesntConnect {
/// The tip of the current chain
chain_tip: Box<BlockNumHash>,
/// The fork on the other chain
other_chain_fork: Box<BlockNumHash>,
},
/// Error when fetching latest block state.
#[error(transparent)]
LatestBlock(#[from] ProviderError),
/// Arbitrary Block Executor Errors
#[error(transparent)]
Other(Box<dyn core::error::Error + Send + Sync>),
}
impl InternalBlockExecutionError {
/// Create a new [`InternalBlockExecutionError::Other`] variant.
#[cfg(feature = "std")]
pub fn other<E>(error: E) -> Self
where
E: core::error::Error + Send + Sync + 'static,
{
Self::Other(Box::new(error))
}
/// Create a new [`InternalBlockExecutionError::Other`] from a given message.
#[cfg(feature = "std")]
pub fn msg(msg: impl std::fmt::Display) -> Self {
Self::Other(msg.to_string().into())
}
}