feat: abstract over Evm::Error (#14085)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Arsenii Kulikov
2025-01-30 17:02:20 +04:00
committed by GitHub
parent 6b13409812
commit 98a021ee7d
40 changed files with 298 additions and 247 deletions

3
Cargo.lock generated
View File

@ -7515,7 +7515,6 @@ dependencies = [
"reth-consensus", "reth-consensus",
"reth-prune-types", "reth-prune-types",
"reth-storage-errors", "reth-storage-errors",
"revm-primitives",
"thiserror 2.0.11", "thiserror 2.0.11",
] ]
@ -8321,6 +8320,7 @@ dependencies = [
"reth-primitives-traits", "reth-primitives-traits",
"reth-provider", "reth-provider",
"reth-revm", "reth-revm",
"reth-rpc-eth-types",
"reth-rpc-server-types", "reth-rpc-server-types",
"reth-rpc-types-compat", "reth-rpc-types-compat",
"reth-tasks", "reth-tasks",
@ -8503,7 +8503,6 @@ dependencies = [
"reth-chainspec", "reth-chainspec",
"reth-errors", "reth-errors",
"reth-primitives", "reth-primitives",
"revm-primitives",
"serde", "serde",
"thiserror 2.0.11", "thiserror 2.0.11",
"tokio", "tokio",

View File

@ -14,7 +14,7 @@ use reth_errors::{BlockExecutionError, BlockValidationError, RethError, RethResu
use reth_ethereum_forks::EthereumHardforks; use reth_ethereum_forks::EthereumHardforks;
use reth_evm::{ use reth_evm::{
state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller, state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller,
ConfigureEvm, Evm, ConfigureEvm, Evm, EvmError,
}; };
use reth_payload_primitives::EngineApiMessageVersion; use reth_payload_primitives::EngineApiMessageVersion;
use reth_payload_validator::ExecutionPayloadValidator; use reth_payload_validator::ExecutionPayloadValidator;
@ -29,7 +29,6 @@ use reth_revm::{
DatabaseCommit, DatabaseCommit,
}; };
use reth_rpc_types_compat::engine::payload::block_to_payload; use reth_rpc_types_compat::engine::payload::block_to_payload;
use revm_primitives::EVMError;
use std::{ use std::{
collections::VecDeque, collections::VecDeque,
future::Future, future::Future,
@ -328,8 +327,8 @@ where
let tx_env = evm_config.tx_env(&tx_recovered, tx_recovered.signer()); let tx_env = evm_config.tx_env(&tx_recovered, tx_recovered.signer());
let exec_result = match evm.transact(tx_env) { let exec_result = match evm.transact(tx_env) {
Ok(result) => result, Ok(result) => result,
error @ Err(EVMError::Transaction(_) | EVMError::Header(_)) => { Err(err) if err.is_invalid_tx_err() => {
trace!(target: "engine::stream::reorg", hash = %tx.tx_hash(), ?error, "Error executing transaction from next block"); trace!(target: "engine::stream::reorg", hash = %tx.tx_hash(), ?err, "Error executing transaction from next block");
continue continue
} }
// Treat error as fatal // Treat error as fatal

View File

@ -7,7 +7,6 @@ use crate::{
use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloc::{boxed::Box, sync::Arc, vec::Vec};
use alloy_consensus::{BlockHeader, Transaction}; use alloy_consensus::{BlockHeader, Transaction};
use alloy_eips::{eip6110, eip7685::Requests}; use alloy_eips::{eip6110, eip7685::Requests};
use core::fmt::Display;
use reth_chainspec::{ChainSpec, EthereumHardfork, EthereumHardforks, MAINNET}; use reth_chainspec::{ChainSpec, EthereumHardfork, EthereumHardforks, MAINNET};
use reth_consensus::ConsensusError; use reth_consensus::ConsensusError;
use reth_ethereum_consensus::validate_block_post_execution; use reth_ethereum_consensus::validate_block_post_execution;
@ -15,19 +14,15 @@ use reth_evm::{
execute::{ execute::{
balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError,
BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput, BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput,
ProviderError,
}, },
state_change::post_block_balance_increments, state_change::post_block_balance_increments,
system_calls::{OnStateHook, SystemCaller}, system_calls::{OnStateHook, SystemCaller},
ConfigureEvm, Evm, ConfigureEvm, Database, Evm,
}; };
use reth_primitives::{EthPrimitives, Receipt, RecoveredBlock}; use reth_primitives::{EthPrimitives, Receipt, RecoveredBlock};
use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_primitives_traits::{BlockBody, SignedTransaction};
use reth_revm::db::State; use reth_revm::db::State;
use revm_primitives::{ use revm_primitives::{db::DatabaseCommit, ResultAndState};
db::{Database, DatabaseCommit},
ResultAndState,
};
/// Factory for [`EthExecutionStrategy`]. /// Factory for [`EthExecutionStrategy`].
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -71,12 +66,11 @@ where
{ {
type Primitives = EthPrimitives; type Primitives = EthPrimitives;
type Strategy<DB: Database<Error: Into<ProviderError> + Display>> = type Strategy<DB: Database> = EthExecutionStrategy<DB, EvmConfig>;
EthExecutionStrategy<DB, EvmConfig>;
fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB> fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
let state = let state =
State::builder().with_database(db).with_bundle_update().without_state_clear().build(); State::builder().with_database(db).with_bundle_update().without_state_clear().build();
@ -113,7 +107,7 @@ where
impl<DB, EvmConfig> BlockExecutionStrategy for EthExecutionStrategy<DB, EvmConfig> impl<DB, EvmConfig> BlockExecutionStrategy for EthExecutionStrategy<DB, EvmConfig>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
EvmConfig: ConfigureEvm< EvmConfig: ConfigureEvm<
Header = alloy_consensus::Header, Header = alloy_consensus::Header,
Transaction = reth_primitives::TransactionSigned, Transaction = reth_primitives::TransactionSigned,
@ -163,11 +157,10 @@ where
// Execute transaction. // Execute transaction.
let result_and_state = evm.transact(tx_env).map_err(move |err| { let result_and_state = evm.transact(tx_env).map_err(move |err| {
let new_err = err.map_db_err(|e| e.into());
// Ensure hash is calculated for error log, if not already done // Ensure hash is calculated for error log, if not already done
BlockValidationError::EVM { BlockValidationError::EVM {
hash: transaction.recalculate_hash(), hash: transaction.recalculate_hash(),
error: Box::new(new_err), error: Box::new(err),
} }
})?; })?;
self.system_caller.on_state(&result_and_state.state); self.system_caller.on_state(&result_and_state.state);
@ -307,7 +300,7 @@ mod tests {
use reth_primitives::{Account, Block, BlockBody, Transaction}; use reth_primitives::{Account, Block, BlockBody, Transaction};
use reth_primitives_traits::{crypto::secp256k1::public_key_to_address, Block as _}; use reth_primitives_traits::{crypto::secp256k1::public_key_to_address, Block as _};
use reth_revm::{ use reth_revm::{
database::StateProviderDatabase, test_utils::StateProviderTest, TransitionState, database::StateProviderDatabase, test_utils::StateProviderTest, Database, TransitionState,
}; };
use reth_testing_utils::generators::{self, sign_tx_with_key_pair}; use reth_testing_utils::generators::{self, sign_tx_with_key_pair};
use revm_primitives::{address, EvmState, BLOCKHASH_SERVE_WINDOW}; use revm_primitives::{address, EvmState, BLOCKHASH_SERVE_WINDOW};
@ -393,7 +386,7 @@ mod tests {
); );
assert!(matches!( assert!(matches!(
err.as_validation().unwrap().clone(), err.as_validation().unwrap(),
BlockValidationError::MissingParentBeaconBlockRoot BlockValidationError::MissingParentBeaconBlockRoot
)); ));

View File

@ -22,10 +22,10 @@ use alloy_consensus::{BlockHeader, Header};
use alloy_primitives::{Address, U256}; use alloy_primitives::{Address, U256};
use core::{convert::Infallible, fmt::Debug}; use core::{convert::Infallible, fmt::Debug};
use reth_chainspec::ChainSpec; use reth_chainspec::ChainSpec;
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Evm, NextBlockEnvAttributes}; use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Database, Evm, NextBlockEnvAttributes};
use reth_primitives::TransactionSigned; use reth_primitives::TransactionSigned;
use reth_primitives_traits::transaction::execute::FillTxEnv; use reth_primitives_traits::transaction::execute::FillTxEnv;
use reth_revm::{inspector_handle_register, Database, EvmBuilder}; use reth_revm::{inspector_handle_register, EvmBuilder};
use revm_primitives::{ use revm_primitives::{
AnalysisKind, BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, CfgEnvWithHandlerCfg, EVMError, AnalysisKind, BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, CfgEnvWithHandlerCfg, EVMError,
HandlerCfg, ResultAndState, SpecId, TxEnv, TxKind, HandlerCfg, ResultAndState, SpecId, TxEnv, TxKind,
@ -237,6 +237,7 @@ impl ConfigureEvmEnv for EthEvmConfig {
impl ConfigureEvm for EthEvmConfig { impl ConfigureEvm for EthEvmConfig {
type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>; type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>;
type EvmError<DBError: core::error::Error + Send + Sync + 'static> = EVMError<DBError>;
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> { fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg { let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {

View File

@ -22,7 +22,8 @@ use reth_basic_payload_builder::{
use reth_chainspec::{ChainSpec, ChainSpecProvider}; use reth_chainspec::{ChainSpec, ChainSpecProvider};
use reth_errors::RethError; use reth_errors::RethError;
use reth_evm::{ use reth_evm::{
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, Evm, NextBlockEnvAttributes, env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, Evm, EvmError, InvalidTxError,
NextBlockEnvAttributes,
}; };
use reth_evm_ethereum::{eip6110::parse_deposits_from_receipts, EthEvmConfig}; use reth_evm_ethereum::{eip6110::parse_deposits_from_receipts, EthEvmConfig};
use reth_execution_types::ExecutionOutcome; use reth_execution_types::ExecutionOutcome;
@ -44,7 +45,7 @@ use reth_transaction_pool::{
}; };
use revm::{ use revm::{
db::{states::bundle_state::BundleRetention, State}, db::{states::bundle_state::BundleRetention, State},
primitives::{EVMError, InvalidTransaction, ResultAndState}, primitives::ResultAndState,
DatabaseCommit, DatabaseCommit,
}; };
use std::sync::Arc; use std::sync::Arc;
@ -276,30 +277,25 @@ where
let ResultAndState { result, state } = match evm.transact(tx_env) { let ResultAndState { result, state } = match evm.transact(tx_env) {
Ok(res) => res, Ok(res) => res,
Err(err) => { Err(err) => {
match err { if let Some(err) = err.as_invalid_tx_err() {
EVMError::Transaction(err) => { if err.is_nonce_too_low() {
if matches!(err, InvalidTransaction::NonceTooLow { .. }) { // if the nonce is too low, we can skip this transaction
// if the nonce is too low, we can skip this transaction trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction");
trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction"); } else {
} else { // if the transaction is invalid, we can skip it and all of its
// if the transaction is invalid, we can skip it and all of its // descendants
// descendants trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants");
trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants"); best_txs.mark_invalid(
best_txs.mark_invalid( &pool_tx,
&pool_tx, InvalidPoolTransactionError::Consensus(
InvalidPoolTransactionError::Consensus( InvalidTransactionError::TxTypeNotSupported,
InvalidTransactionError::TxTypeNotSupported, ),
), );
);
}
continue
}
err => {
// this is an error that we should treat as fatal for this attempt
return Err(PayloadBuilderError::EvmExecutionError(err))
} }
continue
} }
// this is an error that we should treat as fatal for this attempt
return Err(PayloadBuilderError::evm(err))
} }
}; };

View File

@ -19,7 +19,6 @@ reth-prune-types.workspace = true
alloy-primitives.workspace = true alloy-primitives.workspace = true
alloy-rlp.workspace = true alloy-rlp.workspace = true
alloy-eips.workspace = true alloy-eips.workspace = true
revm-primitives.workspace = true
nybbles.workspace = true nybbles.workspace = true
thiserror.workspace = true thiserror.workspace = true
@ -30,7 +29,6 @@ std = [
"reth-consensus/std", "reth-consensus/std",
"alloy-eips/std", "alloy-eips/std",
"alloy-primitives/std", "alloy-primitives/std",
"revm-primitives/std",
"alloy-rlp/std", "alloy-rlp/std",
"thiserror/std", "thiserror/std",
"nybbles/std", "nybbles/std",

View File

@ -20,14 +20,13 @@ use alloy_primitives::B256;
use reth_consensus::ConsensusError; use reth_consensus::ConsensusError;
use reth_prune_types::PruneSegmentError; use reth_prune_types::PruneSegmentError;
use reth_storage_errors::provider::ProviderError; use reth_storage_errors::provider::ProviderError;
use revm_primitives::EVMError;
use thiserror::Error; use thiserror::Error;
pub mod trie; pub mod trie;
pub use trie::*; pub use trie::*;
/// Transaction validation errors /// Transaction validation errors
#[derive(Error, Clone, Debug)] #[derive(Error, Debug)]
pub enum BlockValidationError { pub enum BlockValidationError {
/// EVM error with transaction hash and message /// EVM error with transaction hash and message
#[error("EVM reported invalid transaction ({hash}): {error}")] #[error("EVM reported invalid transaction ({hash}): {error}")]
@ -35,7 +34,7 @@ pub enum BlockValidationError {
/// The hash of the transaction /// The hash of the transaction
hash: B256, hash: B256,
/// The EVM error. /// The EVM error.
error: Box<EVMError<ProviderError>>, error: Box<dyn core::error::Error + Send + Sync>,
}, },
/// Error when recovering the sender for a transaction /// Error when recovering the sender for a transaction
#[error("failed to recover sender for transaction")] #[error("failed to recover sender for transaction")]

View File

@ -1,13 +1,10 @@
//! Helper type that represents one of two possible executor types //! Helper type that represents one of two possible executor types
use core::fmt::Display;
use crate::{ use crate::{
execute::{BatchExecutor, BlockExecutorProvider, Executor}, execute::{BatchExecutor, BlockExecutorProvider, Executor},
system_calls::OnStateHook, system_calls::OnStateHook,
Database,
}; };
use reth_storage_errors::provider::ProviderError;
use revm_primitives::db::Database;
// re-export Either // re-export Either
pub use futures_util::future::Either; pub use futures_util::future::Either;
@ -20,15 +17,13 @@ where
{ {
type Primitives = A::Primitives; type Primitives = A::Primitives;
type Executor<DB: Database<Error: Into<ProviderError> + Display>> = type Executor<DB: Database> = Either<A::Executor<DB>, B::Executor<DB>>;
Either<A::Executor<DB>, B::Executor<DB>>;
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> = type BatchExecutor<DB: Database> = Either<A::BatchExecutor<DB>, B::BatchExecutor<DB>>;
Either<A::BatchExecutor<DB>, B::BatchExecutor<DB>>;
fn executor<DB>(&self, db: DB) -> Self::Executor<DB> fn executor<DB>(&self, db: DB) -> Self::Executor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
match self { match self {
Self::Left(a) => Either::Left(a.executor(db)), Self::Left(a) => Either::Left(a.executor(db)),
@ -38,7 +33,7 @@ where
fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB> fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
match self { match self {
Self::Left(a) => Either::Left(a.batch_executor(db)), Self::Left(a) => Either::Left(a.batch_executor(db)),
@ -51,7 +46,7 @@ impl<A, B, DB> Executor<DB> for Either<A, B>
where where
A: Executor<DB>, A: Executor<DB>,
B: for<'a> Executor<DB, Input<'a> = A::Input<'a>, Output = A::Output, Error = A::Error>, B: for<'a> Executor<DB, Input<'a> = A::Input<'a>, Output = A::Output, Error = A::Error>,
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
type Input<'a> = A::Input<'a>; type Input<'a> = A::Input<'a>;
type Output = A::Output; type Output = A::Output;
@ -97,7 +92,7 @@ impl<A, B, DB> BatchExecutor<DB> for Either<A, B>
where where
A: BatchExecutor<DB>, A: BatchExecutor<DB>,
B: for<'a> BatchExecutor<DB, Input<'a> = A::Input<'a>, Output = A::Output, Error = A::Error>, B: for<'a> BatchExecutor<DB, Input<'a> = A::Input<'a>, Output = A::Output, Error = A::Error>,
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
type Input<'a> = A::Input<'a>; type Input<'a> = A::Input<'a>;
type Output = A::Output; type Output = A::Output;

49
crates/evm/src/error.rs Normal file
View File

@ -0,0 +1,49 @@
use revm_primitives::{EVMError, InvalidTransaction};
/// Abstraction over transaction validation error.
pub trait InvalidTxError: core::error::Error + Send + Sync + 'static {
/// Returns whether the error cause by transaction having a nonce lower than expected.
fn is_nonce_too_low(&self) -> bool;
}
impl InvalidTxError for InvalidTransaction {
fn is_nonce_too_low(&self) -> bool {
matches!(self, Self::NonceTooLow { .. })
}
}
/// Abstraction over errors that can occur during EVM execution.
///
/// It's assumed that errors can occur either because of an invalid transaction, meaning that other
/// transaction might still result in successful execution, or because of a general EVM
/// misconfiguration.
///
/// If caller occurs a error different from [`EvmError::InvalidTransaction`], it should most likely
/// be treated as fatal error flagging some EVM misconfiguration.
pub trait EvmError: core::error::Error + Send + Sync + 'static {
/// Errors which might occur as a result of an invalid transaction. i.e unrelated to general EVM
/// configuration.
type InvalidTransaction: InvalidTxError;
/// Returns the [`EvmError::InvalidTransaction`] if the error is an invalid transaction error.
fn as_invalid_tx_err(&self) -> Option<&Self::InvalidTransaction>;
/// Returns `true` if the error is an invalid transaction error.
fn is_invalid_tx_err(&self) -> bool {
self.as_invalid_tx_err().is_some()
}
}
impl<DBError> EvmError for EVMError<DBError>
where
DBError: core::error::Error + Send + Sync + 'static,
{
type InvalidTransaction = InvalidTransaction;
fn as_invalid_tx_err(&self) -> Option<&Self::InvalidTransaction> {
match self {
Self::Transaction(err) => Some(err),
_ => None,
}
}
}

View File

@ -8,14 +8,13 @@ pub use reth_execution_errors::{
pub use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome}; pub use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome};
pub use reth_storage_errors::provider::ProviderError; pub use reth_storage_errors::provider::ProviderError;
use crate::system_calls::OnStateHook; use crate::{system_calls::OnStateHook, Database};
use alloc::{boxed::Box, vec::Vec}; use alloc::{boxed::Box, vec::Vec};
use alloy_eips::eip7685::Requests; use alloy_eips::eip7685::Requests;
use alloy_primitives::{ use alloy_primitives::{
map::{DefaultHashBuilder, HashMap}, map::{DefaultHashBuilder, HashMap},
Address, Address,
}; };
use core::fmt::Display;
use reth_consensus::ConsensusError; use reth_consensus::ConsensusError;
use reth_primitives::{NodePrimitives, Receipt, RecoveredBlock}; use reth_primitives::{NodePrimitives, Receipt, RecoveredBlock};
use reth_revm::batch::BlockBatchRecord; use reth_revm::batch::BlockBatchRecord;
@ -23,7 +22,7 @@ use revm::{
db::{states::bundle_state::BundleRetention, BundleState}, db::{states::bundle_state::BundleRetention, BundleState},
State, State,
}; };
use revm_primitives::{db::Database, Account, AccountStatus, EvmState}; use revm_primitives::{Account, AccountStatus, EvmState};
/// A general purpose executor trait that executes an input (e.g. block) and produces an output /// A general purpose executor trait that executes an input (e.g. block) and produces an output
/// (e.g. state changes and receipts). /// (e.g. state changes and receipts).
@ -134,7 +133,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static {
/// ///
/// It is not expected to validate the state trie root, this must be done by the caller using /// It is not expected to validate the state trie root, this must be done by the caller using
/// the returned state. /// the returned state.
type Executor<DB: Database<Error: Into<ProviderError> + Display>>: for<'a> Executor< type Executor<DB: Database>: for<'a> Executor<
DB, DB,
Input<'a> = &'a RecoveredBlock<<Self::Primitives as NodePrimitives>::Block>, Input<'a> = &'a RecoveredBlock<<Self::Primitives as NodePrimitives>::Block>,
Output = BlockExecutionOutput<<Self::Primitives as NodePrimitives>::Receipt>, Output = BlockExecutionOutput<<Self::Primitives as NodePrimitives>::Receipt>,
@ -142,7 +141,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static {
>; >;
/// An executor that can execute a batch of blocks given a database. /// An executor that can execute a batch of blocks given a database.
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>>: for<'a> BatchExecutor< type BatchExecutor<DB: Database>: for<'a> BatchExecutor<
DB, DB,
Input<'a> = &'a RecoveredBlock<<Self::Primitives as NodePrimitives>::Block>, Input<'a> = &'a RecoveredBlock<<Self::Primitives as NodePrimitives>::Block>,
Output = ExecutionOutcome<<Self::Primitives as NodePrimitives>::Receipt>, Output = ExecutionOutcome<<Self::Primitives as NodePrimitives>::Receipt>,
@ -154,7 +153,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static {
/// This is used to execute a single block and get the changed state. /// This is used to execute a single block and get the changed state.
fn executor<DB>(&self, db: DB) -> Self::Executor<DB> fn executor<DB>(&self, db: DB) -> Self::Executor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>; DB: Database;
/// Creates a new batch executor with the given database and pruning modes. /// Creates a new batch executor with the given database and pruning modes.
/// ///
@ -162,7 +161,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static {
/// during historical sync which involves executing multiple blocks in sequence. /// during historical sync which involves executing multiple blocks in sequence.
fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB> fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>; DB: Database;
} }
/// Helper type for the output of executing a block. /// Helper type for the output of executing a block.
@ -177,13 +176,13 @@ pub struct ExecuteOutput<R = Receipt> {
/// Defines the strategy for executing a single block. /// Defines the strategy for executing a single block.
pub trait BlockExecutionStrategy { pub trait BlockExecutionStrategy {
/// Database this strategy operates on. /// Database this strategy operates on.
type DB: Database; type DB: revm::Database;
/// Primitive types used by the strategy. /// Primitive types used by the strategy.
type Primitives: NodePrimitives; type Primitives: NodePrimitives;
/// The error type returned by this strategy's methods. /// The error type returned by this strategy's methods.
type Error: From<ProviderError> + core::error::Error; type Error: core::error::Error;
/// Applies any necessary changes before executing the block's transactions. /// Applies any necessary changes before executing the block's transactions.
fn apply_pre_execution_changes( fn apply_pre_execution_changes(
@ -236,7 +235,7 @@ pub trait BlockExecutionStrategyFactory: Send + Sync + Clone + Unpin + 'static {
type Primitives: NodePrimitives; type Primitives: NodePrimitives;
/// Associated strategy type. /// Associated strategy type.
type Strategy<DB: Database<Error: Into<ProviderError> + Display>>: BlockExecutionStrategy< type Strategy<DB: Database>: BlockExecutionStrategy<
DB = DB, DB = DB,
Primitives = Self::Primitives, Primitives = Self::Primitives,
Error = BlockExecutionError, Error = BlockExecutionError,
@ -245,7 +244,7 @@ pub trait BlockExecutionStrategyFactory: Send + Sync + Clone + Unpin + 'static {
/// Creates a strategy using the give database. /// Creates a strategy using the give database.
fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB> fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>; DB: Database;
} }
impl<F> Clone for BasicBlockExecutorProvider<F> impl<F> Clone for BasicBlockExecutorProvider<F>
@ -276,15 +275,13 @@ where
{ {
type Primitives = F::Primitives; type Primitives = F::Primitives;
type Executor<DB: Database<Error: Into<ProviderError> + Display>> = type Executor<DB: Database> = BasicBlockExecutor<F::Strategy<DB>>;
BasicBlockExecutor<F::Strategy<DB>>;
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> = type BatchExecutor<DB: Database> = BasicBatchExecutor<F::Strategy<DB>>;
BasicBatchExecutor<F::Strategy<DB>>;
fn executor<DB>(&self, db: DB) -> Self::Executor<DB> fn executor<DB>(&self, db: DB) -> Self::Executor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
let strategy = self.strategy_factory.create_strategy(db); let strategy = self.strategy_factory.create_strategy(db);
BasicBlockExecutor::new(strategy) BasicBlockExecutor::new(strategy)
@ -292,7 +289,7 @@ where
fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB> fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
let strategy = self.strategy_factory.create_strategy(db); let strategy = self.strategy_factory.create_strategy(db);
let batch_record = BlockBatchRecord::default(); let batch_record = BlockBatchRecord::default();
@ -318,7 +315,7 @@ impl<S> BasicBlockExecutor<S> {
impl<S, DB> Executor<DB> for BasicBlockExecutor<S> impl<S, DB> Executor<DB> for BasicBlockExecutor<S>
where where
S: BlockExecutionStrategy<DB = DB>, S: BlockExecutionStrategy<DB = DB>,
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
type Input<'a> = &'a RecoveredBlock<<S::Primitives as NodePrimitives>::Block>; type Input<'a> = &'a RecoveredBlock<<S::Primitives as NodePrimitives>::Block>;
type Output = BlockExecutionOutput<<S::Primitives as NodePrimitives>::Receipt>; type Output = BlockExecutionOutput<<S::Primitives as NodePrimitives>::Receipt>;
@ -401,7 +398,7 @@ where
impl<S, DB> BatchExecutor<DB> for BasicBatchExecutor<S> impl<S, DB> BatchExecutor<DB> for BasicBatchExecutor<S>
where where
S: BlockExecutionStrategy<DB = DB, Error = BlockExecutionError>, S: BlockExecutionStrategy<DB = DB, Error = BlockExecutionError>,
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
type Input<'a> = &'a RecoveredBlock<<S::Primitives as NodePrimitives>::Block>; type Input<'a> = &'a RecoveredBlock<<S::Primitives as NodePrimitives>::Block>;
type Output = ExecutionOutcome<<S::Primitives as NodePrimitives>::Receipt>; type Output = ExecutionOutcome<<S::Primitives as NodePrimitives>::Receipt>;
@ -495,19 +492,19 @@ mod tests {
impl BlockExecutorProvider for TestExecutorProvider { impl BlockExecutorProvider for TestExecutorProvider {
type Primitives = EthPrimitives; type Primitives = EthPrimitives;
type Executor<DB: Database<Error: Into<ProviderError> + Display>> = TestExecutor<DB>; type Executor<DB: Database> = TestExecutor<DB>;
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> = TestExecutor<DB>; type BatchExecutor<DB: Database> = TestExecutor<DB>;
fn executor<DB>(&self, _db: DB) -> Self::Executor<DB> fn executor<DB>(&self, _db: DB) -> Self::Executor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
TestExecutor(PhantomData) TestExecutor(PhantomData)
} }
fn batch_executor<DB>(&self, _db: DB) -> Self::BatchExecutor<DB> fn batch_executor<DB>(&self, _db: DB) -> Self::BatchExecutor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
TestExecutor(PhantomData) TestExecutor(PhantomData)
} }
@ -585,12 +582,11 @@ mod tests {
impl BlockExecutionStrategyFactory for TestExecutorStrategyFactory { impl BlockExecutionStrategyFactory for TestExecutorStrategyFactory {
type Primitives = EthPrimitives; type Primitives = EthPrimitives;
type Strategy<DB: Database<Error: Into<ProviderError> + Display>> = type Strategy<DB: Database> = TestExecutorStrategy<DB, TestEvmConfig>;
TestExecutorStrategy<DB, TestEvmConfig>;
fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB> fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
let state = State::builder() let state = State::builder()
.with_database(db) .with_database(db)

View File

@ -22,12 +22,15 @@ use alloy_eips::eip2930::AccessList;
use alloy_primitives::{Address, Bytes, B256, U256}; use alloy_primitives::{Address, Bytes, B256, U256};
use core::fmt::Debug; use core::fmt::Debug;
use reth_primitives_traits::{BlockHeader, SignedTransaction}; use reth_primitives_traits::{BlockHeader, SignedTransaction};
use revm::{Database, DatabaseCommit, GetInspector}; use revm::{DatabaseCommit, GetInspector};
use revm_primitives::{BlockEnv, EVMError, ResultAndState, TxEnv, TxKind}; use revm_primitives::{BlockEnv, ResultAndState, TxEnv, TxKind};
pub mod either; pub mod either;
/// EVM environment configuration. /// EVM environment configuration.
pub mod env; pub mod env;
/// EVM error types.
mod error;
pub use error::*;
pub mod execute; pub mod execute;
pub use env::EvmEnv; pub use env::EvmEnv;
@ -82,6 +85,9 @@ pub trait Evm {
Ok(result) Ok(result)
} }
} }
/// Helper trait to bound [`revm::Database::Error`] with common requirements.
pub trait Database: revm::Database<Error: core::error::Error + Send + Sync + 'static> {}
impl<T> Database for T where T: revm::Database<Error: core::error::Error + Send + Sync + 'static> {}
/// Trait for configuring the EVM for executing full blocks. /// Trait for configuring the EVM for executing full blocks.
pub trait ConfigureEvm: ConfigureEvmEnv { pub trait ConfigureEvm: ConfigureEvmEnv {
@ -89,9 +95,12 @@ pub trait ConfigureEvm: ConfigureEvmEnv {
type Evm<'a, DB: Database + 'a, I: 'a>: Evm< type Evm<'a, DB: Database + 'a, I: 'a>: Evm<
Tx = Self::TxEnv, Tx = Self::TxEnv,
DB = DB, DB = DB,
Error = EVMError<DB::Error>, Error = Self::EvmError<DB::Error>,
>; >;
/// The error type returned by the EVM.
type EvmError<DBError: core::error::Error + Send + Sync + 'static>: EvmError;
/// Returns a new EVM with the given database configured with the given environment settings, /// Returns a new EVM with the given database configured with the given environment settings,
/// including the spec id and transaction environment. /// including the spec id and transaction environment.
/// ///
@ -137,6 +146,7 @@ where
&'b T: ConfigureEvmEnv<Header = T::Header, TxEnv = T::TxEnv, Spec = T::Spec>, &'b T: ConfigureEvmEnv<Header = T::Header, TxEnv = T::TxEnv, Spec = T::Spec>,
{ {
type Evm<'a, DB: Database + 'a, I: 'a> = T::Evm<'a, DB, I>; type Evm<'a, DB: Database + 'a, I: 'a> = T::Evm<'a, DB, I>;
type EvmError<DBError: core::error::Error + Send + Sync + 'static> = T::EvmError<DBError>;
fn evm_for_block<DB: Database>(&self, db: DB, header: &Self::Header) -> Self::Evm<'_, DB, ()> { fn evm_for_block<DB: Database>(&self, db: DB, header: &Self::Header) -> Self::Evm<'_, DB, ()> {
(*self).evm_for_block(db, header) (*self).evm_for_block(db, header)

View File

@ -1,16 +1,14 @@
//! A no operation block executor implementation. //! A no operation block executor implementation.
use core::fmt::Display;
use reth_execution_errors::BlockExecutionError; use reth_execution_errors::BlockExecutionError;
use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome}; use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome};
use reth_primitives::{NodePrimitives, RecoveredBlock}; use reth_primitives::{NodePrimitives, RecoveredBlock};
use reth_storage_errors::provider::ProviderError;
use revm::State; use revm::State;
use revm_primitives::db::Database;
use crate::{ use crate::{
execute::{BatchExecutor, BlockExecutorProvider, Executor}, execute::{BatchExecutor, BlockExecutorProvider, Executor},
system_calls::OnStateHook, system_calls::OnStateHook,
Database,
}; };
const UNAVAILABLE_FOR_NOOP: &str = "execution unavailable for noop"; const UNAVAILABLE_FOR_NOOP: &str = "execution unavailable for noop";
@ -23,20 +21,20 @@ pub struct NoopBlockExecutorProvider<P>(core::marker::PhantomData<P>);
impl<P: NodePrimitives> BlockExecutorProvider for NoopBlockExecutorProvider<P> { impl<P: NodePrimitives> BlockExecutorProvider for NoopBlockExecutorProvider<P> {
type Primitives = P; type Primitives = P;
type Executor<DB: Database<Error: Into<ProviderError> + Display>> = Self; type Executor<DB: Database> = Self;
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> = Self; type BatchExecutor<DB: Database> = Self;
fn executor<DB>(&self, _: DB) -> Self::Executor<DB> fn executor<DB>(&self, _: DB) -> Self::Executor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
Self::default() Self::default()
} }
fn batch_executor<DB>(&self, _: DB) -> Self::BatchExecutor<DB> fn batch_executor<DB>(&self, _: DB) -> Self::BatchExecutor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
Self::default() Self::default()
} }

View File

@ -1,6 +1,6 @@
//! System contract call functions. //! System contract call functions.
use crate::{ConfigureEvm, Evm, EvmEnv}; use crate::{ConfigureEvm, Database, Evm, EvmEnv};
use alloc::{boxed::Box, sync::Arc}; use alloc::{boxed::Box, sync::Arc};
use alloy_consensus::BlockHeader; use alloy_consensus::BlockHeader;
use alloy_eips::{ use alloy_eips::{
@ -10,7 +10,7 @@ use alloy_primitives::Bytes;
use core::fmt::Display; use core::fmt::Display;
use reth_chainspec::EthereumHardforks; use reth_chainspec::EthereumHardforks;
use reth_execution_errors::BlockExecutionError; use reth_execution_errors::BlockExecutionError;
use revm::{Database, DatabaseCommit}; use revm::DatabaseCommit;
use revm_primitives::{EvmState, B256}; use revm_primitives::{EvmState, B256};
mod eip2935; mod eip2935;
@ -260,7 +260,6 @@ where
) -> Result<Bytes, BlockExecutionError> ) -> Result<Bytes, BlockExecutionError>
where where
DB: Database + DatabaseCommit, DB: Database + DatabaseCommit,
DB::Error: Display,
{ {
let evm_config = self.evm_config.clone(); let evm_config = self.evm_config.clone();
let mut evm = evm_config.evm_with_env(db, evm_env.clone()); let mut evm = evm_config.evm_with_env(db, evm_env.clone());

View File

@ -6,16 +6,15 @@ use crate::{
BlockExecutionStrategy, BlockExecutorProvider, Executor, BlockExecutionStrategy, BlockExecutorProvider, Executor,
}, },
system_calls::OnStateHook, system_calls::OnStateHook,
Database,
}; };
use alloy_eips::eip7685::Requests; use alloy_eips::eip7685::Requests;
use parking_lot::Mutex; use parking_lot::Mutex;
use reth_execution_errors::BlockExecutionError; use reth_execution_errors::BlockExecutionError;
use reth_execution_types::ExecutionOutcome; use reth_execution_types::ExecutionOutcome;
use reth_primitives::{EthPrimitives, NodePrimitives, Receipt, Receipts, RecoveredBlock}; use reth_primitives::{EthPrimitives, NodePrimitives, Receipt, Receipts, RecoveredBlock};
use reth_storage_errors::provider::ProviderError;
use revm::State; use revm::State;
use revm_primitives::db::Database; use std::sync::Arc;
use std::{fmt::Display, sync::Arc};
/// A [`BlockExecutorProvider`] that returns mocked execution results. /// A [`BlockExecutorProvider`] that returns mocked execution results.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
@ -33,20 +32,20 @@ impl MockExecutorProvider {
impl BlockExecutorProvider for MockExecutorProvider { impl BlockExecutorProvider for MockExecutorProvider {
type Primitives = EthPrimitives; type Primitives = EthPrimitives;
type Executor<DB: Database<Error: Into<ProviderError> + Display>> = Self; type Executor<DB: Database> = Self;
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> = Self; type BatchExecutor<DB: Database> = Self;
fn executor<DB>(&self, _: DB) -> Self::Executor<DB> fn executor<DB>(&self, _: DB) -> Self::Executor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
self.clone() self.clone()
} }
fn batch_executor<DB>(&self, _: DB) -> Self::BatchExecutor<DB> fn batch_executor<DB>(&self, _: DB) -> Self::BatchExecutor<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
self.clone() self.clone()
} }

View File

@ -7,7 +7,6 @@ use crate::{
use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloc::{boxed::Box, sync::Arc, vec::Vec};
use alloy_consensus::{BlockHeader, Eip658Value, Receipt, Transaction as _}; use alloy_consensus::{BlockHeader, Eip658Value, Receipt, Transaction as _};
use alloy_eips::eip7685::Requests; use alloy_eips::eip7685::Requests;
use core::fmt::Display;
use op_alloy_consensus::OpDepositReceipt; use op_alloy_consensus::OpDepositReceipt;
use reth_chainspec::EthereumHardforks; use reth_chainspec::EthereumHardforks;
use reth_consensus::ConsensusError; use reth_consensus::ConsensusError;
@ -15,11 +14,10 @@ use reth_evm::{
execute::{ execute::{
balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError,
BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput, BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput,
ProviderError,
}, },
state_change::post_block_balance_increments, state_change::post_block_balance_increments,
system_calls::{OnStateHook, SystemCaller}, system_calls::{OnStateHook, SystemCaller},
ConfigureEvmFor, Evm, ConfigureEvmFor, Database, Evm,
}; };
use reth_optimism_chainspec::OpChainSpec; use reth_optimism_chainspec::OpChainSpec;
use reth_optimism_consensus::validate_block_post_execution; use reth_optimism_consensus::validate_block_post_execution;
@ -29,7 +27,7 @@ use reth_optimism_primitives::{
}; };
use reth_primitives::{NodePrimitives, RecoveredBlock}; use reth_primitives::{NodePrimitives, RecoveredBlock};
use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_primitives_traits::{BlockBody, SignedTransaction};
use reth_revm::{Database, State}; use reth_revm::State;
use revm_primitives::{db::DatabaseCommit, ResultAndState}; use revm_primitives::{db::DatabaseCommit, ResultAndState};
use tracing::trace; use tracing::trace;
@ -76,12 +74,11 @@ where
EvmConfig: ConfigureEvmFor<N> + Clone + Unpin + Sync + Send + 'static, EvmConfig: ConfigureEvmFor<N> + Clone + Unpin + Sync + Send + 'static,
{ {
type Primitives = N; type Primitives = N;
type Strategy<DB: Database<Error: Into<ProviderError> + Display>> = type Strategy<DB: Database> = OpExecutionStrategy<DB, N, EvmConfig>;
OpExecutionStrategy<DB, N, EvmConfig>;
fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB> fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
let state = let state =
State::builder().with_database(db).with_bundle_update().without_state_clear().build(); State::builder().with_database(db).with_bundle_update().without_state_clear().build();
@ -131,7 +128,7 @@ where
impl<DB, N, EvmConfig> BlockExecutionStrategy for OpExecutionStrategy<DB, N, EvmConfig> impl<DB, N, EvmConfig> BlockExecutionStrategy for OpExecutionStrategy<DB, N, EvmConfig>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
N: NodePrimitives< N: NodePrimitives<
BlockHeader = alloy_consensus::Header, BlockHeader = alloy_consensus::Header,
SignedTx: OpTransaction, SignedTx: OpTransaction,
@ -214,11 +211,10 @@ where
// Execute transaction. // Execute transaction.
let result_and_state = evm.transact(tx_env).map_err(move |err| { let result_and_state = evm.transact(tx_env).map_err(move |err| {
let new_err = err.map_db_err(|e| e.into());
// Ensure hash is calculated for error log, if not already done // Ensure hash is calculated for error log, if not already done
BlockValidationError::EVM { BlockValidationError::EVM {
hash: transaction.recalculate_hash(), hash: transaction.recalculate_hash(),
error: Box::new(new_err), error: Box::new(err),
} }
})?; })?;

View File

@ -18,14 +18,14 @@ use alloy_eips::eip7840::BlobParams;
use alloy_primitives::{Address, U256}; use alloy_primitives::{Address, U256};
use core::fmt::Debug; use core::fmt::Debug;
use op_alloy_consensus::EIP1559ParamError; use op_alloy_consensus::EIP1559ParamError;
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Evm, NextBlockEnvAttributes}; use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Database, Evm, NextBlockEnvAttributes};
use reth_optimism_chainspec::OpChainSpec; use reth_optimism_chainspec::OpChainSpec;
use reth_optimism_primitives::OpTransactionSigned; use reth_optimism_primitives::OpTransactionSigned;
use reth_primitives_traits::FillTxEnv; use reth_primitives_traits::FillTxEnv;
use reth_revm::{ use reth_revm::{
inspector_handle_register, inspector_handle_register,
primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
Database, EvmBuilder, GetInspector, EvmBuilder, GetInspector,
}; };
mod config; mod config;
@ -224,6 +224,7 @@ impl ConfigureEvmEnv for OpEvmConfig {
impl ConfigureEvm for OpEvmConfig { impl ConfigureEvm for OpEvmConfig {
type Evm<'a, DB: Database + 'a, I: 'a> = OpEvm<'a, I, DB>; type Evm<'a, DB: Database + 'a, I: 'a> = OpEvm<'a, I, DB>;
type EvmError<DBError: core::error::Error + Send + Sync + 'static> = EVMError<DBError>;
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> { fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg { let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {

View File

@ -33,6 +33,7 @@ reth-revm = { workspace = true, features = ["std"] }
reth-trie-db.workspace = true reth-trie-db.workspace = true
reth-rpc-server-types.workspace = true reth-rpc-server-types.workspace = true
reth-rpc-types-compat.workspace = true reth-rpc-types-compat.workspace = true
reth-rpc-eth-types.workspace = true
reth-tasks = { workspace = true, optional = true } reth-tasks = { workspace = true, optional = true }
# op-reth # op-reth

View File

@ -9,7 +9,9 @@ use crate::{
use op_alloy_consensus::OpPooledTransaction; use op_alloy_consensus::OpPooledTransaction;
use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig};
use reth_chainspec::{EthChainSpec, Hardforks}; use reth_chainspec::{EthChainSpec, Hardforks};
use reth_evm::{execute::BasicBlockExecutorProvider, ConfigureEvmEnv, ConfigureEvmFor}; use reth_evm::{
execute::BasicBlockExecutorProvider, ConfigureEvm, ConfigureEvmEnv, ConfigureEvmFor,
};
use reth_network::{NetworkConfig, NetworkHandle, NetworkManager, NetworkPrimitives, PeersInfo}; use reth_network::{NetworkConfig, NetworkHandle, NetworkManager, NetworkPrimitives, PeersInfo};
use reth_node_api::{AddOnsContext, FullNodeComponents, NodeAddOns, PrimitivesTy, TxTy}; use reth_node_api::{AddOnsContext, FullNodeComponents, NodeAddOns, PrimitivesTy, TxTy};
use reth_node_builder::{ use reth_node_builder::{
@ -32,10 +34,11 @@ use reth_optimism_primitives::{OpPrimitives, OpReceipt, OpTransactionSigned};
use reth_optimism_rpc::{ use reth_optimism_rpc::{
miner::{MinerApiExtServer, OpMinerExtApi}, miner::{MinerApiExtServer, OpMinerExtApi},
witness::{DebugExecutionWitnessApiServer, OpDebugWitnessApi}, witness::{DebugExecutionWitnessApiServer, OpDebugWitnessApi},
OpEthApi, SequencerClient, OpEthApi, OpEthApiError, SequencerClient,
}; };
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
use reth_provider::{CanonStateSubscriptions, EthStorage}; use reth_provider::{CanonStateSubscriptions, EthStorage};
use reth_rpc_eth_types::error::FromEvmError;
use reth_rpc_server_types::RethRpcModule; use reth_rpc_server_types::RethRpcModule;
use reth_tracing::tracing::{debug, info}; use reth_tracing::tracing::{debug, info};
use reth_transaction_pool::{ use reth_transaction_pool::{
@ -193,6 +196,7 @@ where
>, >,
Evm: ConfigureEvmEnv<TxEnv = TxEnv>, Evm: ConfigureEvmEnv<TxEnv = TxEnv>,
>, >,
OpEthApiError: FromEvmError<N::Evm>,
{ {
type Handle = RpcHandle<N, OpEthApi<N>>; type Handle = RpcHandle<N, OpEthApi<N>>;
@ -241,8 +245,9 @@ where
Storage = OpStorage, Storage = OpStorage,
Engine = OpEngineTypes, Engine = OpEngineTypes,
>, >,
Evm: ConfigureEvmEnv<TxEnv = TxEnv>, Evm: ConfigureEvm<TxEnv = TxEnv>,
>, >,
OpEthApiError: FromEvmError<N::Evm>,
{ {
type EthApi = OpEthApi<N>; type EthApi = OpEthApi<N>;

View File

@ -17,8 +17,8 @@ use reth_basic_payload_builder::*;
use reth_chain_state::{ExecutedBlock, ExecutedBlockWithTrieUpdates}; use reth_chain_state::{ExecutedBlock, ExecutedBlockWithTrieUpdates};
use reth_chainspec::{ChainSpecProvider, EthereumHardforks}; use reth_chainspec::{ChainSpecProvider, EthereumHardforks};
use reth_evm::{ use reth_evm::{
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm, env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Database, Evm,
NextBlockEnvAttributes, EvmError, InvalidTxError, NextBlockEnvAttributes,
}; };
use reth_execution_types::ExecutionOutcome; use reth_execution_types::ExecutionOutcome;
use reth_optimism_chainspec::OpChainSpec; use reth_optimism_chainspec::OpChainSpec;
@ -42,8 +42,8 @@ use reth_transaction_pool::{
}; };
use revm::{ use revm::{
db::{states::bundle_state::BundleRetention, State}, db::{states::bundle_state::BundleRetention, State},
primitives::{EVMError, InvalidTransaction, ResultAndState}, primitives::ResultAndState,
Database, DatabaseCommit, DatabaseCommit,
}; };
use std::{fmt::Display, sync::Arc}; use std::{fmt::Display, sync::Arc};
use tracing::{debug, trace, warn}; use tracing::{debug, trace, warn};
@ -818,16 +818,12 @@ where
let ResultAndState { result, state } = match evm.transact(tx_env) { let ResultAndState { result, state } = match evm.transact(tx_env) {
Ok(res) => res, Ok(res) => res,
Err(err) => { Err(err) => {
match err { if err.is_invalid_tx_err() {
EVMError::Transaction(err) => { trace!(target: "payload_builder", %err, ?sequencer_tx, "Error in sequencer transaction, skipping.");
trace!(target: "payload_builder", %err, ?sequencer_tx, "Error in sequencer transaction, skipping."); continue
continue
}
err => {
// this is an error that we should treat as fatal for this attempt
return Err(PayloadBuilderError::EvmExecutionError(err))
}
} }
// this is an error that we should treat as fatal for this attempt
return Err(PayloadBuilderError::EvmExecutionError(Box::new(err)))
} }
}; };
@ -915,25 +911,21 @@ where
let ResultAndState { result, state } = match evm.transact(tx_env) { let ResultAndState { result, state } = match evm.transact(tx_env) {
Ok(res) => res, Ok(res) => res,
Err(err) => { Err(err) => {
match err { if let Some(err) = err.as_invalid_tx_err() {
EVMError::Transaction(err) => { if err.is_nonce_too_low() {
if matches!(err, InvalidTransaction::NonceTooLow { .. }) { // if the nonce is too low, we can skip this transaction
// if the nonce is too low, we can skip this transaction trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction");
trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction"); } else {
} else { // if the transaction is invalid, we can skip it and all of its
// if the transaction is invalid, we can skip it and all of its // descendants
// descendants trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants");
trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants"); best_txs.mark_invalid(tx.signer(), tx.nonce());
best_txs.mark_invalid(tx.signer(), tx.nonce()); }
}
continue continue
}
err => {
// this is an error that we should treat as fatal for this attempt
return Err(PayloadBuilderError::EvmExecutionError(err))
}
} }
// this is an error that we should treat as fatal for this attempt
return Err(PayloadBuilderError::EvmExecutionError(Box::new(err)))
} }
}; };

View File

@ -6,7 +6,7 @@ use reth_optimism_evm::OpBlockExecutionError;
use reth_rpc_eth_api::AsEthApiError; use reth_rpc_eth_api::AsEthApiError;
use reth_rpc_eth_types::EthApiError; use reth_rpc_eth_types::EthApiError;
use reth_rpc_server_types::result::{internal_rpc_err, rpc_err}; use reth_rpc_server_types::result::{internal_rpc_err, rpc_err};
use revm::primitives::{InvalidTransaction, OptimismInvalidTransaction}; use revm::primitives::{EVMError, InvalidTransaction, OptimismInvalidTransaction};
/// Optimism specific errors, that extend [`EthApiError`]. /// Optimism specific errors, that extend [`EthApiError`].
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@ -119,3 +119,12 @@ impl From<BlockError> for OpEthApiError {
Self::Eth(error.into()) Self::Eth(error.into())
} }
} }
impl<DB> From<EVMError<DB>> for OpEthApiError
where
EthApiError: From<EVMError<DB>>,
{
fn from(error: EVMError<DB>) -> Self {
Self::Eth(error.into())
}
}

View File

@ -40,8 +40,7 @@ where
let excess_blob_gas = block.excess_blob_gas(); let excess_blob_gas = block.excess_blob_gas();
let timestamp = block.timestamp(); let timestamp = block.timestamp();
let mut l1_block_info = let mut l1_block_info = reth_optimism_evm::extract_l1_info(block.body())?;
reth_optimism_evm::extract_l1_info(block.body()).map_err(OpEthApiError::from)?;
return block return block
.body() .body()

View File

@ -6,7 +6,7 @@ use reth_evm::ConfigureEvm;
use reth_provider::ProviderHeader; use reth_provider::ProviderHeader;
use reth_rpc_eth_api::{ use reth_rpc_eth_api::{
helpers::{estimate::EstimateCall, Call, EthCall, LoadBlock, LoadState, SpawnBlocking}, helpers::{estimate::EstimateCall, Call, EthCall, LoadBlock, LoadState, SpawnBlocking},
FromEthApiError, FullEthApiTypes, IntoEthApiError, FromEthApiError, FromEvmError, FullEthApiTypes, IntoEthApiError,
}; };
use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError}; use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError};
use revm::primitives::{BlockEnv, OptimismFields, TxEnv}; use revm::primitives::{BlockEnv, OptimismFields, TxEnv};
@ -28,8 +28,10 @@ where
impl<N> Call for OpEthApi<N> impl<N> Call for OpEthApi<N>
where where
Self: LoadState<Evm: ConfigureEvm<Header = ProviderHeader<Self::Provider>, TxEnv = TxEnv>> Self: LoadState<
+ SpawnBlocking, Evm: ConfigureEvm<Header = ProviderHeader<Self::Provider>, TxEnv = TxEnv>,
Error: FromEvmError<Self::Evm>,
> + SpawnBlocking,
Self::Error: From<OpEthApiError>, Self::Error: From<OpEthApiError>,
N: OpNodeCore, N: OpNodeCore,
{ {

View File

@ -30,7 +30,7 @@ use reth_rpc_eth_api::{
AddDevSigners, EthApiSpec, EthFees, EthSigner, EthState, LoadBlock, LoadFee, LoadState, AddDevSigners, EthApiSpec, EthFees, EthSigner, EthState, LoadBlock, LoadFee, LoadState,
SpawnBlocking, Trace, SpawnBlocking, Trace,
}, },
EthApiTypes, RpcNodeCore, RpcNodeCoreExt, EthApiTypes, FromEvmError, RpcNodeCore, RpcNodeCoreExt,
}; };
use reth_rpc_eth_types::{EthStateCache, FeeHistoryCache, GasPriceOracle}; use reth_rpc_eth_types::{EthStateCache, FeeHistoryCache, GasPriceOracle};
use reth_tasks::{ use reth_tasks::{
@ -252,6 +252,7 @@ where
Header = ProviderHeader<Self::Provider>, Header = ProviderHeader<Self::Provider>,
Transaction = ProviderTx<Self::Provider>, Transaction = ProviderTx<Self::Provider>,
>, >,
Error: FromEvmError<Self::Evm>,
>, >,
N: OpNodeCore, N: OpNodeCore,
{ {

View File

@ -21,7 +21,7 @@ use reth_provider::{
}; };
use reth_rpc_eth_api::{ use reth_rpc_eth_api::{
helpers::{LoadPendingBlock, SpawnBlocking}, helpers::{LoadPendingBlock, SpawnBlocking},
EthApiTypes, FromEthApiError, RpcNodeCore, EthApiTypes, FromEthApiError, FromEvmError, RpcNodeCore,
}; };
use reth_rpc_eth_types::{EthApiError, PendingBlock}; use reth_rpc_eth_types::{EthApiError, PendingBlock};
use reth_transaction_pool::{PoolTransaction, TransactionPool}; use reth_transaction_pool::{PoolTransaction, TransactionPool};
@ -34,6 +34,7 @@ where
NetworkTypes: Network< NetworkTypes: Network<
HeaderResponse = alloy_rpc_types_eth::Header<ProviderHeader<Self::Provider>>, HeaderResponse = alloy_rpc_types_eth::Header<ProviderHeader<Self::Provider>>,
>, >,
Error: FromEvmError<Self::Evm>,
>, >,
N: RpcNodeCore< N: RpcNodeCore<
Provider: BlockReaderIdExt< Provider: BlockReaderIdExt<

View File

@ -18,8 +18,6 @@ reth-errors.workspace = true
reth-primitives.workspace = true reth-primitives.workspace = true
reth-chain-state.workspace = true reth-chain-state.workspace = true
revm-primitives.workspace = true
# alloy # alloy
alloy-eips.workspace = true alloy-eips.workspace = true
alloy-primitives.workspace = true alloy-primitives.workspace = true
@ -39,7 +37,6 @@ default = ["std"]
std = [ std = [
"reth-chainspec/std", "reth-chainspec/std",
"reth-primitives/std", "reth-primitives/std",
"revm-primitives/std",
"alloy-eips/std", "alloy-eips/std",
"alloy-primitives/std", "alloy-primitives/std",
"alloy-rpc-types-engine/std", "alloy-rpc-types-engine/std",

View File

@ -4,7 +4,6 @@ use alloc::boxed::Box;
use alloy_primitives::B256; use alloy_primitives::B256;
use alloy_rpc_types_engine::ForkchoiceUpdateError; use alloy_rpc_types_engine::ForkchoiceUpdateError;
use reth_errors::{ProviderError, RethError}; use reth_errors::{ProviderError, RethError};
use revm_primitives::EVMError;
use tokio::sync::oneshot; use tokio::sync::oneshot;
/// Possible error variants during payload building. /// Possible error variants during payload building.
@ -27,13 +26,21 @@ pub enum PayloadBuilderError {
Internal(#[from] RethError), Internal(#[from] RethError),
/// Unrecoverable error during evm execution. /// Unrecoverable error during evm execution.
#[error("evm execution error: {0}")] #[error("evm execution error: {0}")]
EvmExecutionError(EVMError<ProviderError>), EvmExecutionError(Box<dyn core::error::Error + Send + Sync>),
/// Any other payload building errors. /// Any other payload building errors.
#[error(transparent)] #[error(transparent)]
Other(Box<dyn core::error::Error + Send + Sync>), Other(Box<dyn core::error::Error + Send + Sync>),
} }
impl PayloadBuilderError { impl PayloadBuilderError {
/// Create a new EVM error from a boxed error.
pub fn evm<E>(error: E) -> Self
where
E: core::error::Error + Send + Sync + 'static,
{
Self::EvmExecutionError(Box::new(error))
}
/// Create a new error from a boxed error. /// Create a new error from a boxed error.
pub fn other<E>(error: E) -> Self pub fn other<E>(error: E) -> Self
where where

View File

@ -17,7 +17,8 @@ use alloy_rpc_types_eth::{
}; };
use futures::Future; use futures::Future;
use reth_chainspec::EthChainSpec; use reth_chainspec::EthChainSpec;
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Evm, TransactionEnv}; use reth_errors::ProviderError;
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Database, Evm, TransactionEnv};
use reth_node_api::BlockBody; use reth_node_api::BlockBody;
use reth_primitives_traits::SignedTransaction; use reth_primitives_traits::SignedTransaction;
use reth_provider::{BlockIdReader, ChainSpecProvider, ProviderHeader}; use reth_provider::{BlockIdReader, ChainSpecProvider, ProviderHeader};
@ -36,7 +37,7 @@ use reth_rpc_eth_types::{
simulate::{self, EthSimulateError}, simulate::{self, EthSimulateError},
EthApiError, RevertError, RpcInvalidTransactionError, StateCacheDb, EthApiError, RevertError, RpcInvalidTransactionError, StateCacheDb,
}; };
use revm::{Database, DatabaseCommit, GetInspector}; use revm::{DatabaseCommit, GetInspector};
use revm_inspectors::{access_list::AccessListInspector, transfer::TransferInspector}; use revm_inspectors::{access_list::AccessListInspector, transfer::TransferInspector};
use tracing::trace; use tracing::trace;
@ -473,7 +474,10 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
/// Executes code on state. /// Executes code on state.
pub trait Call: pub trait Call:
LoadState<Evm: ConfigureEvm<Header = ProviderHeader<Self::Provider>>> + SpawnBlocking LoadState<
Evm: ConfigureEvm<Header = ProviderHeader<Self::Provider>>,
Error: FromEvmError<Self::Evm>,
> + SpawnBlocking
{ {
/// Returns default gas limit to use for `eth_call` and tracing RPC methods. /// Returns default gas limit to use for `eth_call` and tracing RPC methods.
/// ///
@ -508,8 +512,7 @@ pub trait Call:
Self::Error, Self::Error,
> >
where where
DB: Database, DB: Database<Error = ProviderError>,
EthApiError: From<DB::Error>,
{ {
let mut evm = self.evm_config().evm_with_env(db, evm_env.clone()); let mut evm = self.evm_config().evm_with_env(db, evm_env.clone());
let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?; let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?;
@ -534,8 +537,7 @@ pub trait Call:
Self::Error, Self::Error,
> >
where where
DB: Database, DB: Database<Error = ProviderError>,
EthApiError: From<DB::Error>,
{ {
let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector); let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector);
let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?; let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?;
@ -704,8 +706,7 @@ pub trait Call:
target_tx_hash: B256, target_tx_hash: B256,
) -> Result<usize, Self::Error> ) -> Result<usize, Self::Error>
where where
DB: Database + DatabaseCommit, DB: Database<Error = ProviderError> + DatabaseCommit,
EthApiError: From<DB::Error>,
I: IntoIterator<Item = (&'a Address, &'a <Self::Evm as ConfigureEvmEnv>::Transaction)>, I: IntoIterator<Item = (&'a Address, &'a <Self::Evm as ConfigureEvmEnv>::Transaction)>,
<Self::Evm as ConfigureEvmEnv>::Transaction: SignedTransaction, <Self::Evm as ConfigureEvmEnv>::Transaction: SignedTransaction,
{ {

View File

@ -6,7 +6,8 @@ use alloy_primitives::U256;
use alloy_rpc_types_eth::{state::StateOverride, transaction::TransactionRequest, BlockId}; use alloy_rpc_types_eth::{state::StateOverride, transaction::TransactionRequest, BlockId};
use futures::Future; use futures::Future;
use reth_chainspec::MIN_TRANSACTION_GAS; use reth_chainspec::MIN_TRANSACTION_GAS;
use reth_evm::{env::EvmEnv, ConfigureEvmEnv, TransactionEnv}; use reth_errors::ProviderError;
use reth_evm::{env::EvmEnv, ConfigureEvmEnv, Database, TransactionEnv};
use reth_provider::StateProvider; use reth_provider::StateProvider;
use reth_revm::{ use reth_revm::{
database::StateProviderDatabase, database::StateProviderDatabase,
@ -18,7 +19,7 @@ use reth_rpc_eth_types::{
EthApiError, RevertError, RpcInvalidTransactionError, EthApiError, RevertError, RpcInvalidTransactionError,
}; };
use reth_rpc_server_types::constants::gas_oracle::{CALL_STIPEND_GAS, ESTIMATE_GAS_ERROR_RATIO}; use reth_rpc_server_types::constants::gas_oracle::{CALL_STIPEND_GAS, ESTIMATE_GAS_ERROR_RATIO};
use revm_primitives::{db::Database, TxKind}; use revm_primitives::TxKind;
use tracing::trace; use tracing::trace;
/// Gas execution estimates /// Gas execution estimates
@ -286,7 +287,7 @@ pub trait EstimateCall: Call {
db: &mut DB, db: &mut DB,
) -> Self::Error ) -> Self::Error
where where
DB: Database, DB: Database<Error = ProviderError>,
EthApiError: From<DB::Error>, EthApiError: From<DB::Error>,
{ {
let req_gas_limit = tx_env.gas_limit(); let req_gas_limit = tx_env.gas_limit();

View File

@ -13,7 +13,8 @@ use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_errors::RethError; use reth_errors::RethError;
use reth_evm::{ use reth_evm::{
env::EvmEnv, state_change::post_block_withdrawals_balance_increments, env::EvmEnv, state_change::post_block_withdrawals_balance_increments,
system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm, NextBlockEnvAttributes, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm, EvmError, InvalidTxError,
NextBlockEnvAttributes,
}; };
use reth_primitives::{InvalidTransactionError, RecoveredBlock}; use reth_primitives::{InvalidTransactionError, RecoveredBlock};
use reth_primitives_traits::Receipt; use reth_primitives_traits::Receipt;
@ -23,7 +24,7 @@ use reth_provider::{
}; };
use reth_revm::{ use reth_revm::{
database::StateProviderDatabase, database::StateProviderDatabase,
primitives::{BlockEnv, EVMError, ExecutionResult, InvalidTransaction, ResultAndState}, primitives::{BlockEnv, ExecutionResult, ResultAndState},
}; };
use reth_rpc_eth_types::{EthApiError, PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin}; use reth_rpc_eth_types::{EthApiError, PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin};
use reth_transaction_pool::{ use reth_transaction_pool::{
@ -43,6 +44,7 @@ pub trait LoadPendingBlock:
NetworkTypes: Network< NetworkTypes: Network<
HeaderResponse = alloy_rpc_types_eth::Header<ProviderHeader<Self::Provider>>, HeaderResponse = alloy_rpc_types_eth::Header<ProviderHeader<Self::Provider>>,
>, >,
Error: FromEvmError<Self::Evm>,
> + RpcNodeCore< > + RpcNodeCore<
Provider: BlockReaderIdExt<Receipt: Receipt> Provider: BlockReaderIdExt<Receipt: Receipt>
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks> + ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
@ -334,27 +336,23 @@ pub trait LoadPendingBlock:
let ResultAndState { result, state } = match evm.transact(tx_env) { let ResultAndState { result, state } = match evm.transact(tx_env) {
Ok(res) => res, Ok(res) => res,
Err(err) => { Err(err) => {
match err { if let Some(err) = err.as_invalid_tx_err() {
EVMError::Transaction(err) => { if err.is_nonce_too_low() {
if matches!(err, InvalidTransaction::NonceTooLow { .. }) { // if the nonce is too low, we can skip this transaction
// if the nonce is too low, we can skip this transaction } else {
} else { // if the transaction is invalid, we can skip it and all of its
// if the transaction is invalid, we can skip it and all of its // descendants
// descendants best_txs.mark_invalid(
best_txs.mark_invalid( &pool_tx,
&pool_tx, InvalidPoolTransactionError::Consensus(
InvalidPoolTransactionError::Consensus( InvalidTransactionError::TxTypeNotSupported,
InvalidTransactionError::TxTypeNotSupported, ),
), );
);
}
continue
}
err => {
// this is an error that we should treat as fatal for this attempt
return Err(Self::Error::from_evm_err(err))
} }
continue
} }
// this is an error that we should treat as fatal for this attempt
return Err(Self::Error::from_evm_err(err));
} }
}; };
// drop evm to release db reference. // drop evm to release db reference.

View File

@ -7,7 +7,10 @@ use alloy_primitives::B256;
use alloy_rpc_types_eth::{BlockId, TransactionInfo}; use alloy_rpc_types_eth::{BlockId, TransactionInfo};
use futures::Future; use futures::Future;
use reth_chainspec::ChainSpecProvider; use reth_chainspec::ChainSpecProvider;
use reth_evm::{env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm}; use reth_errors::ProviderError;
use reth_evm::{
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Database, Evm,
};
use reth_primitives::RecoveredBlock; use reth_primitives::RecoveredBlock;
use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_primitives_traits::{BlockBody, SignedTransaction};
use reth_provider::{BlockReader, ProviderBlock, ProviderHeader, ProviderTx}; use reth_provider::{BlockReader, ProviderBlock, ProviderHeader, ProviderTx};
@ -16,7 +19,7 @@ use reth_rpc_eth_types::{
cache::db::{StateCacheDb, StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper}, cache::db::{StateCacheDb, StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper},
EthApiError, EthApiError,
}; };
use revm::{db::CacheDB, Database, DatabaseCommit, GetInspector, Inspector}; use revm::{db::CacheDB, DatabaseCommit, GetInspector, Inspector};
use revm_inspectors::tracing::{TracingInspector, TracingInspectorConfig}; use revm_inspectors::tracing::{TracingInspector, TracingInspectorConfig};
use revm_primitives::{EvmState, ExecutionResult, ResultAndState}; use revm_primitives::{EvmState, ExecutionResult, ResultAndState};
use std::{fmt::Display, sync::Arc}; use std::{fmt::Display, sync::Arc};
@ -29,6 +32,7 @@ pub trait Trace:
Header = ProviderHeader<Self::Provider>, Header = ProviderHeader<Self::Provider>,
Transaction = ProviderTx<Self::Provider>, Transaction = ProviderTx<Self::Provider>,
>, >,
Error: FromEvmError<Self::Evm>,
> >
{ {
/// Executes the [`EvmEnv`] against the given [Database] without committing state /// Executes the [`EvmEnv`] against the given [Database] without committing state
@ -48,8 +52,7 @@ pub trait Trace:
Self::Error, Self::Error,
> >
where where
DB: Database, DB: Database<Error = ProviderError>,
EthApiError: From<DB::Error>,
I: GetInspector<DB>, I: GetInspector<DB>,
{ {
let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector); let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector);

View File

@ -11,7 +11,7 @@ use reth_provider::{ProviderTx, ReceiptProvider, TransactionsProvider};
use reth_rpc_types_compat::TransactionCompat; use reth_rpc_types_compat::TransactionCompat;
use reth_transaction_pool::{PoolTransaction, TransactionPool}; use reth_transaction_pool::{PoolTransaction, TransactionPool};
use crate::{AsEthApiError, FromEthApiError, FromEvmError, RpcNodeCore}; use crate::{AsEthApiError, FromEthApiError, RpcNodeCore};
/// Network specific `eth` API types. /// Network specific `eth` API types.
pub trait EthApiTypes: Send + Sync + Clone { pub trait EthApiTypes: Send + Sync + Clone {
@ -19,7 +19,6 @@ pub trait EthApiTypes: Send + Sync + Clone {
type Error: Into<jsonrpsee_types::error::ErrorObject<'static>> type Error: Into<jsonrpsee_types::error::ErrorObject<'static>>
+ FromEthApiError + FromEthApiError
+ AsEthApiError + AsEthApiError
+ FromEvmError
+ Error + Error
+ Send + Send
+ Sync; + Sync;

View File

@ -1,7 +1,8 @@
//! Helper traits to wrap generic l1 errors, in network specific error type configured in //! Helper traits to wrap generic l1 errors, in network specific error type configured in
//! `reth_rpc_eth_api::EthApiTypes`. //! `reth_rpc_eth_api::EthApiTypes`.
use revm_primitives::EVMError; use reth_errors::ProviderError;
use reth_evm::ConfigureEvm;
use crate::EthApiError; use crate::EthApiError;
@ -79,21 +80,16 @@ impl AsEthApiError for EthApiError {
} }
/// Helper trait to convert from revm errors. /// Helper trait to convert from revm errors.
pub trait FromEvmError: From<EthApiError> { pub trait FromEvmError<Evm: ConfigureEvm>: From<Evm::EvmError<ProviderError>> {
/// Converts from a revm error. /// Converts from EVM error to this type.
fn from_evm_err<E>(err: EVMError<E>) -> Self fn from_evm_err(err: Evm::EvmError<ProviderError>) -> Self {
where err.into()
EthApiError: From<E>;
}
impl<T> FromEvmError for T
where
T: From<EthApiError>,
{
fn from_evm_err<E>(err: EVMError<E>) -> Self
where
EthApiError: From<E>,
{
err.into_eth_err()
} }
} }
impl<T, Evm> FromEvmError<Evm> for T
where
T: From<Evm::EvmError<ProviderError>>,
Evm: ConfigureEvm,
{
}

View File

@ -651,8 +651,9 @@ where
let ExecutionWitnessRecord { hashed_state, codes, keys } = witness_record; let ExecutionWitnessRecord { hashed_state, codes, keys } = witness_record;
let state = let state = state_provider
state_provider.witness(Default::default(), hashed_state).map_err(Into::into)?; .witness(Default::default(), hashed_state)
.map_err(EthApiError::from)?;
Ok(ExecutionWitness { state: state.into_iter().collect(), codes, keys }) Ok(ExecutionWitness { state: state.into_iter().collect(), codes, keys })
}) })
.await .await

View File

@ -7,7 +7,7 @@ use reth_evm::ConfigureEvm;
use reth_provider::{BlockReader, ProviderHeader}; use reth_provider::{BlockReader, ProviderHeader};
use reth_rpc_eth_api::{ use reth_rpc_eth_api::{
helpers::{estimate::EstimateCall, Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking}, helpers::{estimate::EstimateCall, Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking},
FromEthApiError, FullEthApiTypes, IntoEthApiError, FromEthApiError, FromEvmError, FullEthApiTypes, IntoEthApiError,
}; };
use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError}; use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError};
use revm_primitives::{BlockEnv, TxEnv, TxKind, U256}; use revm_primitives::{BlockEnv, TxEnv, TxKind, U256};
@ -21,8 +21,10 @@ where
impl<Provider, Pool, Network, EvmConfig> Call for EthApi<Provider, Pool, Network, EvmConfig> impl<Provider, Pool, Network, EvmConfig> Call for EthApi<Provider, Pool, Network, EvmConfig>
where where
Self: LoadState<Evm: ConfigureEvm<TxEnv = TxEnv, Header = ProviderHeader<Self::Provider>>> Self: LoadState<
+ SpawnBlocking, Evm: ConfigureEvm<TxEnv = TxEnv, Header = ProviderHeader<Self::Provider>>,
Error: FromEvmError<Self::Evm>,
> + SpawnBlocking,
EvmConfig: ConfigureEvm<Header = Header>, EvmConfig: ConfigureEvm<Header = Header>,
Provider: BlockReader, Provider: BlockReader,
{ {

View File

@ -13,7 +13,7 @@ use reth_provider::{
}; };
use reth_rpc_eth_api::{ use reth_rpc_eth_api::{
helpers::{LoadPendingBlock, SpawnBlocking}, helpers::{LoadPendingBlock, SpawnBlocking},
RpcNodeCore, FromEvmError, RpcNodeCore,
}; };
use reth_rpc_eth_types::PendingBlock; use reth_rpc_eth_types::PendingBlock;
use reth_transaction_pool::{PoolTransaction, TransactionPool}; use reth_transaction_pool::{PoolTransaction, TransactionPool};
@ -26,6 +26,7 @@ impl<Provider, Pool, Network, EvmConfig> LoadPendingBlock
where where
Self: SpawnBlocking< Self: SpawnBlocking<
NetworkTypes: alloy_network::Network<HeaderResponse = alloy_rpc_types_eth::Header>, NetworkTypes: alloy_network::Network<HeaderResponse = alloy_rpc_types_eth::Header>,
Error: FromEvmError<Self::Evm>,
> + RpcNodeCore< > + RpcNodeCore<
Provider: BlockReaderIdExt< Provider: BlockReaderIdExt<
Transaction = reth_primitives::TransactionSigned, Transaction = reth_primitives::TransactionSigned,

View File

@ -2,7 +2,10 @@
use reth_evm::ConfigureEvm; use reth_evm::ConfigureEvm;
use reth_provider::{BlockReader, ProviderHeader, ProviderTx}; use reth_provider::{BlockReader, ProviderHeader, ProviderTx};
use reth_rpc_eth_api::helpers::{LoadState, Trace}; use reth_rpc_eth_api::{
helpers::{LoadState, Trace},
FromEvmError,
};
use crate::EthApi; use crate::EthApi;
@ -14,6 +17,7 @@ where
Header = ProviderHeader<Self::Provider>, Header = ProviderHeader<Self::Provider>,
Transaction = ProviderTx<Self::Provider>, Transaction = ProviderTx<Self::Provider>,
>, >,
Error: FromEvmError<Self::Evm>,
>, >,
Provider: BlockReader, Provider: BlockReader,
{ {

View File

@ -14,7 +14,7 @@ use reth_revm::database::StateProviderDatabase;
use reth_rpc_api::MevSimApiServer; use reth_rpc_api::MevSimApiServer;
use reth_rpc_eth_api::{ use reth_rpc_eth_api::{
helpers::{Call, EthTransactions, LoadPendingBlock}, helpers::{Call, EthTransactions, LoadPendingBlock},
FromEthApiError, FromEthApiError, FromEvmError,
}; };
use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError}; use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError};
use reth_tasks::pool::BlockingTaskGuard; use reth_tasks::pool::BlockingTaskGuard;
@ -307,7 +307,7 @@ where
let ResultAndState { result, state } = evm let ResultAndState { result, state } = evm
.transact(eth_api.evm_config().tx_env(&item.tx, item.signer)) .transact(eth_api.evm_config().tx_env(&item.tx, item.signer))
.map_err(EthApiError::from_eth_err)?; .map_err(Eth::Error::from_evm_err)?;
if !result.is_success() && !item.can_revert { if !result.is_success() && !item.can_revert {
return Err(EthApiError::InvalidParams( return Err(EthApiError::InvalidParams(

View File

@ -11,10 +11,9 @@ use reth::{
api::{ConfigureEvm, NodeTypesWithEngine}, api::{ConfigureEvm, NodeTypesWithEngine},
builder::{components::ExecutorBuilder, BuilderContext, FullNodeTypes}, builder::{components::ExecutorBuilder, BuilderContext, FullNodeTypes},
cli::Cli, cli::Cli,
providers::ProviderError,
revm::{ revm::{
primitives::{address, Address}, primitives::{address, Address},
Database, DatabaseCommit, State, DatabaseCommit, State,
}, },
}; };
use reth_chainspec::{ChainSpec, EthereumHardforks}; use reth_chainspec::{ChainSpec, EthereumHardforks};
@ -23,7 +22,7 @@ use reth_evm::{
BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, ExecuteOutput, BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, ExecuteOutput,
InternalBlockExecutionError, InternalBlockExecutionError,
}, },
Evm, Database, Evm,
}; };
use reth_evm_ethereum::EthEvmConfig; use reth_evm_ethereum::EthEvmConfig;
use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode}; use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode};
@ -90,11 +89,11 @@ pub struct CustomExecutorStrategyFactory {
impl BlockExecutionStrategyFactory for CustomExecutorStrategyFactory { impl BlockExecutionStrategyFactory for CustomExecutorStrategyFactory {
type Primitives = EthPrimitives; type Primitives = EthPrimitives;
type Strategy<DB: Database<Error: Into<ProviderError> + Display>> = CustomExecutorStrategy<DB>; type Strategy<DB: Database> = CustomExecutorStrategy<DB>;
fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB> fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
let state = let state =
State::builder().with_database(db).with_bundle_update().without_state_clear().build(); State::builder().with_database(db).with_bundle_update().without_state_clear().build();
@ -108,7 +107,7 @@ impl BlockExecutionStrategyFactory for CustomExecutorStrategyFactory {
pub struct CustomExecutorStrategy<DB> pub struct CustomExecutorStrategy<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
/// The chainspec /// The chainspec
chain_spec: Arc<ChainSpec>, chain_spec: Arc<ChainSpec>,
@ -120,7 +119,7 @@ where
impl<DB> BlockExecutionStrategy for CustomExecutorStrategy<DB> impl<DB> BlockExecutionStrategy for CustomExecutorStrategy<DB>
where where
DB: Database<Error: Into<ProviderError> + Display>, DB: Database,
{ {
type DB = DB; type DB = DB;
type Primitives = EthPrimitives; type Primitives = EthPrimitives;

View File

@ -15,15 +15,17 @@ use reth::{
handler::register::EvmHandler, handler::register::EvmHandler,
inspector_handle_register, inspector_handle_register,
precompile::{Precompile, PrecompileOutput, PrecompileSpecId}, precompile::{Precompile, PrecompileOutput, PrecompileSpecId},
primitives::{CfgEnvWithHandlerCfg, Env, HandlerCfg, PrecompileResult, SpecId, TxEnv}, primitives::{
ContextPrecompiles, Database, EvmBuilder, GetInspector, CfgEnvWithHandlerCfg, EVMError, Env, HandlerCfg, PrecompileResult, SpecId, TxEnv,
},
ContextPrecompiles, EvmBuilder, GetInspector,
}, },
rpc::types::engine::PayloadAttributes, rpc::types::engine::PayloadAttributes,
tasks::TaskManager, tasks::TaskManager,
transaction_pool::{PoolTransaction, TransactionPool}, transaction_pool::{PoolTransaction, TransactionPool},
}; };
use reth_chainspec::{Chain, ChainSpec}; use reth_chainspec::{Chain, ChainSpec};
use reth_evm::env::EvmEnv; use reth_evm::{env::EvmEnv, Database};
use reth_evm_ethereum::{EthEvm, EthEvmConfig}; use reth_evm_ethereum::{EthEvm, EthEvmConfig};
use reth_node_api::{ use reth_node_api::{
ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NextBlockEnvAttributes, NodeTypes, ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NextBlockEnvAttributes, NodeTypes,
@ -109,6 +111,7 @@ impl ConfigureEvmEnv for MyEvmConfig {
impl ConfigureEvm for MyEvmConfig { impl ConfigureEvm for MyEvmConfig {
type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>; type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>;
type EvmError<DBError: core::error::Error + Send + Sync + 'static> = EVMError<DBError>;
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> { fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg { let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {

View File

@ -14,15 +14,15 @@ use reth::{
inspector_handle_register, inspector_handle_register,
precompile::{Precompile, PrecompileSpecId}, precompile::{Precompile, PrecompileSpecId},
primitives::{ primitives::{
CfgEnvWithHandlerCfg, Env, HandlerCfg, PrecompileResult, SpecId, StatefulPrecompileMut, CfgEnvWithHandlerCfg, EVMError, Env, HandlerCfg, PrecompileResult, SpecId,
TxEnv, StatefulPrecompileMut, TxEnv,
}, },
ContextPrecompile, ContextPrecompiles, Database, EvmBuilder, GetInspector, ContextPrecompile, ContextPrecompiles, EvmBuilder, GetInspector,
}, },
tasks::TaskManager, tasks::TaskManager,
}; };
use reth_chainspec::{Chain, ChainSpec}; use reth_chainspec::{Chain, ChainSpec};
use reth_evm::env::EvmEnv; use reth_evm::{env::EvmEnv, Database};
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NodeTypes}; use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NodeTypes};
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
use reth_node_ethereum::{ use reth_node_ethereum::{
@ -173,6 +173,7 @@ impl ConfigureEvmEnv for MyEvmConfig {
impl ConfigureEvm for MyEvmConfig { impl ConfigureEvm for MyEvmConfig {
type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>; type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>;
type EvmError<DBError: core::error::Error + Send + Sync + 'static> = EVMError<DBError>;
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> { fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg { let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {