diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index ddac38d04dc0..841427bc3f81 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -6,10 +6,7 @@ use eyre::OptionExt; use pretty_assertions::Comparison; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_engine_primitives::InvalidBlockHook; -use reth_evm::{ - system_calls::{apply_beacon_root_contract_call, apply_blockhashes_contract_call}, - ConfigureEvm, -}; +use reth_evm::{system_calls::SystemCaller, ConfigureEvm}; use reth_primitives::{Header, Receipt, SealedBlockWithSenders, SealedHeader}; use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory}; use reth_revm::{ @@ -87,23 +84,10 @@ where EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()), ); + let mut system_caller = SystemCaller::new(&self.evm_config, self.provider.chain_spec()); + // Apply pre-block system contract calls. - apply_beacon_root_contract_call( - &self.evm_config, - self.provider.chain_spec().as_ref(), - block.timestamp, - block.number, - block.parent_beacon_block_root, - &mut evm, - )?; - apply_blockhashes_contract_call( - &self.evm_config, - &self.provider.chain_spec(), - block.timestamp, - block.number, - block.parent_hash, - &mut evm, - )?; + system_caller.apply_pre_execution_changes(&block.clone().unseal(), &mut evm)?; // Re-execute all of the transactions in the block to load all touched accounts into // the cache DB. diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 9c5ccaeff7d9..bd7b1b95642a 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -10,7 +10,7 @@ use reth_beacon_consensus::{BeaconEngineMessage, BeaconOnNewPayloadError, OnFork use reth_engine_primitives::EngineTypes; use reth_errors::{BlockExecutionError, BlockValidationError, RethError, RethResult}; use reth_ethereum_forks::EthereumHardforks; -use reth_evm::{system_calls::apply_beacon_root_contract_call, ConfigureEvm}; +use reth_evm::{system_calls::SystemCaller, ConfigureEvm}; use reth_payload_validator::ExecutionPayloadValidator; use reth_primitives::{proofs, Block, BlockBody, Header, Receipt, Receipts}; use reth_provider::{BlockReader, ExecutionOutcome, ProviderError, StateProviderFactory}; @@ -286,9 +286,9 @@ where let mut evm = evm_config.evm_with_env(&mut state, env); // apply eip-4788 pre block contract call - apply_beacon_root_contract_call( - evm_config, - chain_spec, + let mut system_caller = SystemCaller::new(evm_config, chain_spec); + + system_caller.apply_beacon_root_contract_call( reorg_target.timestamp, reorg_target.number, reorg_target.parent_beacon_block_root, diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 668c01f69fa4..f1d7de115d57 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -14,10 +14,7 @@ use reth_evm::{ BatchExecutor, BlockExecutionError, BlockExecutionInput, BlockExecutionOutput, BlockExecutorProvider, BlockValidationError, Executor, ProviderError, }, - system_calls::{ - apply_beacon_root_contract_call, apply_blockhashes_contract_call, - apply_consolidation_requests_contract_call, apply_withdrawal_requests_contract_call, - }, + system_calls::SystemCaller, ConfigureEvm, }; use reth_execution_types::ExecutionOutcome; @@ -142,23 +139,9 @@ where DB: Database, DB::Error: Into + Display, { - // apply pre execution changes - apply_beacon_root_contract_call( - &self.evm_config, - &self.chain_spec, - block.timestamp, - block.number, - block.parent_beacon_block_root, - &mut evm, - )?; - apply_blockhashes_contract_call( - &self.evm_config, - &self.chain_spec, - block.timestamp, - block.number, - block.parent_hash, - &mut evm, - )?; + let mut system_caller = SystemCaller::new(&self.evm_config, &self.chain_spec); + + system_caller.apply_pre_execution_changes(block, &mut evm)?; // execute transactions let mut cumulative_gas_used = 0; @@ -212,15 +195,9 @@ where let deposit_requests = crate::eip6110::parse_deposits_from_receipts(&self.chain_spec, &receipts)?; - // Collect all EIP-7685 requests - let withdrawal_requests = - apply_withdrawal_requests_contract_call(&self.evm_config, &mut evm)?; - - // Collect all EIP-7251 requests - let consolidation_requests = - apply_consolidation_requests_contract_call(&self.evm_config, &mut evm)?; + let post_execution_requests = system_caller.apply_post_execution_changes(&mut evm)?; - [deposit_requests, withdrawal_requests, consolidation_requests].concat() + [deposit_requests, post_execution_requests].concat() } else { vec![] }; diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 4665c2ff8c63..5d2fcde2f7e5 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -17,14 +17,7 @@ use reth_basic_payload_builder::{ use reth_chain_state::ExecutedBlock; use reth_chainspec::ChainSpec; use reth_errors::RethError; -use reth_evm::{ - system_calls::{ - post_block_consolidation_requests_contract_call, - post_block_withdrawal_requests_contract_call, pre_block_beacon_root_contract_call, - pre_block_blockhashes_contract_call, - }, - ConfigureEvm, NextBlockEnvAttributes, -}; +use reth_evm::{system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes}; use reth_evm_ethereum::{eip6110::parse_deposits_from_receipts, EthEvmConfig}; use reth_execution_types::ExecutionOutcome; use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes}; @@ -167,29 +160,28 @@ where let block_number = initialized_block_env.number.to::(); + let mut system_caller = SystemCaller::new(&evm_config, chain_spec.clone()); + // apply eip-4788 pre block contract call - pre_block_beacon_root_contract_call( - &mut db, - &evm_config, - &chain_spec, - &initialized_cfg, - &initialized_block_env, - attributes.parent_beacon_block_root, - ) - .map_err(|err| { - warn!(target: "payload_builder", - parent_hash=%parent_block.hash(), - %err, - "failed to apply beacon root contract call for payload" - ); - PayloadBuilderError::Internal(err.into()) - })?; + system_caller + .pre_block_beacon_root_contract_call( + &mut db, + &initialized_cfg, + &initialized_block_env, + attributes.parent_beacon_block_root, + ) + .map_err(|err| { + warn!(target: "payload_builder", + parent_hash=%parent_block.hash(), + %err, + "failed to apply beacon root contract call for payload" + ); + PayloadBuilderError::Internal(err.into()) + })?; // apply eip-2935 blockhashes update - pre_block_blockhashes_contract_call( + system_caller.pre_block_blockhashes_contract_call( &mut db, - &evm_config, - &chain_spec, &initialized_cfg, &initialized_block_env, parent_block.hash(), @@ -320,20 +312,20 @@ where { let deposit_requests = parse_deposits_from_receipts(&chain_spec, receipts.iter().flatten()) .map_err(|err| PayloadBuilderError::Internal(RethError::Execution(err.into())))?; - let withdrawal_requests = post_block_withdrawal_requests_contract_call( - &evm_config, - &mut db, - &initialized_cfg, - &initialized_block_env, - ) - .map_err(|err| PayloadBuilderError::Internal(err.into()))?; - let consolidation_requests = post_block_consolidation_requests_contract_call( - &evm_config, - &mut db, - &initialized_cfg, - &initialized_block_env, - ) - .map_err(|err| PayloadBuilderError::Internal(err.into()))?; + let withdrawal_requests = system_caller + .post_block_withdrawal_requests_contract_call( + &mut db, + &initialized_cfg, + &initialized_block_env, + ) + .map_err(|err| PayloadBuilderError::Internal(err.into()))?; + let consolidation_requests = system_caller + .post_block_consolidation_requests_contract_call( + &mut db, + &initialized_cfg, + &initialized_block_env, + ) + .map_err(|err| PayloadBuilderError::Internal(err.into()))?; let requests = [deposit_requests, withdrawal_requests, consolidation_requests].concat(); let requests_root = calculate_requests_root(&requests); diff --git a/crates/evm/src/system_calls/eip2935.rs b/crates/evm/src/system_calls/eip2935.rs index 9dcec89f4db3..edb71c8b4e06 100644 --- a/crates/evm/src/system_calls/eip2935.rs +++ b/crates/evm/src/system_calls/eip2935.rs @@ -5,52 +5,11 @@ use alloy_eips::eip2935::HISTORY_STORAGE_ADDRESS; use crate::ConfigureEvm; use alloy_primitives::B256; -use core::fmt::Display; use reth_chainspec::EthereumHardforks; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; use reth_primitives::Header; -use revm::{interpreter::Host, Database, DatabaseCommit, Evm}; -use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState}; - -/// Apply the [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) pre block contract call. -/// -/// This constructs a new [`Evm`] with the given database and environment ([`CfgEnvWithHandlerCfg`] -/// and [`BlockEnv`]) to execute the pre block contract call. -/// -/// This uses [`apply_blockhashes_contract_call`] to ultimately apply the -/// blockhash contract state change. -pub fn pre_block_blockhashes_contract_call( - db: &mut DB, - evm_config: &EvmConfig, - chain_spec: impl EthereumHardforks, - initialized_cfg: &CfgEnvWithHandlerCfg, - initialized_block_env: &BlockEnv, - parent_block_hash: B256, -) -> Result<(), BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: Display, - EvmConfig: ConfigureEvm
, -{ - // Apply the pre-block EIP-2935 contract call - let mut evm_pre_block = Evm::builder() - .with_db(db) - .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( - initialized_cfg.clone(), - initialized_block_env.clone(), - Default::default(), - )) - .build(); - - apply_blockhashes_contract_call( - evm_config, - chain_spec, - initialized_block_env.timestamp.to(), - initialized_block_env.number.to(), - parent_block_hash, - &mut evm_pre_block, - ) -} +use revm::{interpreter::Host, Database, Evm}; +use revm_primitives::ResultAndState; /// Applies the pre-block call to the [EIP-2935] blockhashes contract, using the given block, /// chain specification, and EVM. @@ -65,7 +24,7 @@ where /// /// [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935 #[inline] -pub fn transact_blockhashes_contract_call( +pub(crate) fn transact_blockhashes_contract_call( evm_config: &EvmConfig, chain_spec: impl EthereumHardforks, block_timestamp: u64, @@ -115,38 +74,3 @@ where Ok(Some(res)) } - -/// Applies the pre-block call to the [EIP-2935] blockhashes contract, using the given block, -/// chain specification, and EVM and commits the relevant state changes. -/// -/// If Prague is not activated, or the block is the genesis block, then this is a no-op, and no -/// state changes are made. -/// -/// [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935 -#[inline] -pub fn apply_blockhashes_contract_call( - evm_config: &EvmConfig, - chain_spec: impl EthereumHardforks, - block_timestamp: u64, - block_number: u64, - parent_block_hash: B256, - evm: &mut Evm<'_, EXT, DB>, -) -> Result<(), BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, -{ - if let Some(res) = transact_blockhashes_contract_call( - evm_config, - chain_spec, - block_timestamp, - block_number, - parent_block_hash, - evm, - )? { - evm.context.evm.db.commit(res.state); - } - - Ok(()) -} diff --git a/crates/evm/src/system_calls/eip4788.rs b/crates/evm/src/system_calls/eip4788.rs index 6352a53070f6..bc535809680f 100644 --- a/crates/evm/src/system_calls/eip4788.rs +++ b/crates/evm/src/system_calls/eip4788.rs @@ -7,49 +7,8 @@ use alloy_primitives::B256; use reth_chainspec::EthereumHardforks; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; use reth_primitives::Header; -use revm::{interpreter::Host, Database, DatabaseCommit, Evm}; -use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState}; - -/// Apply the [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) pre block contract call. -/// -/// This constructs a new [`Evm`] with the given DB, and environment -/// ([`CfgEnvWithHandlerCfg`] and [`BlockEnv`]) to execute the pre block contract call. -/// -/// This uses [`apply_beacon_root_contract_call`] to ultimately apply the beacon root contract state -/// change. -pub fn pre_block_beacon_root_contract_call( - db: &mut DB, - evm_config: &EvmConfig, - chain_spec: impl EthereumHardforks, - initialized_cfg: &CfgEnvWithHandlerCfg, - initialized_block_env: &BlockEnv, - parent_beacon_block_root: Option, -) -> Result<(), BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, -{ - // apply pre-block EIP-4788 contract call - let mut evm_pre_block = Evm::builder() - .with_db(db) - .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( - initialized_cfg.clone(), - initialized_block_env.clone(), - Default::default(), - )) - .build(); - - // initialize a block from the env, because the pre block call needs the block itself - apply_beacon_root_contract_call( - evm_config, - chain_spec, - initialized_block_env.timestamp.to(), - initialized_block_env.number.to(), - parent_beacon_block_root, - &mut evm_pre_block, - ) -} +use revm::{interpreter::Host, Database, Evm}; +use revm_primitives::ResultAndState; /// Applies the pre-block call to the [EIP-4788] beacon block root contract, using the given block, /// chain spec, EVM. @@ -61,7 +20,7 @@ where /// /// [EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788 #[inline] -pub fn transact_beacon_root_contract_call( +pub(crate) fn transact_beacon_root_contract_call( evm_config: &EvmConfig, chain_spec: &Spec, block_timestamp: u64, @@ -125,38 +84,3 @@ where Ok(Some(res)) } - -/// Applies the pre-block call to the [EIP-4788] beacon block root contract, using the given block, -/// chain spec, EVM. -/// -/// If Cancun is not activated or the block is the genesis block, then this is a no-op, and no -/// state changes are made. -/// -/// [EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788 -#[inline] -pub fn apply_beacon_root_contract_call( - evm_config: &EvmConfig, - chain_spec: impl EthereumHardforks, - block_timestamp: u64, - block_number: u64, - parent_beacon_block_root: Option, - evm: &mut Evm<'_, EXT, DB>, -) -> Result<(), BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, -{ - if let Some(res) = transact_beacon_root_contract_call( - evm_config, - &chain_spec, - block_timestamp, - block_number, - parent_beacon_block_root, - evm, - )? { - evm.context.evm.db.commit(res.state); - } - - Ok(()) -} diff --git a/crates/evm/src/system_calls/eip7002.rs b/crates/evm/src/system_calls/eip7002.rs index b84bcbc9a631..9af944e42a53 100644 --- a/crates/evm/src/system_calls/eip7002.rs +++ b/crates/evm/src/system_calls/eip7002.rs @@ -1,48 +1,12 @@ //! [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) system call implementation. -use alloc::{boxed::Box, format, string::ToString, vec::Vec}; -use core::fmt::Display; - use crate::ConfigureEvm; +use alloc::{boxed::Box, format, string::ToString, vec::Vec}; use alloy_eips::eip7002::{WithdrawalRequest, WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS}; use alloy_primitives::{bytes::Buf, Address, Bytes, FixedBytes}; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; use reth_primitives::{Header, Request}; -use revm::{interpreter::Host, Database, DatabaseCommit, Evm}; -use revm_primitives::{ - BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, ResultAndState, -}; - -/// Apply the [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) post block contract call. -/// -/// This constructs a new [Evm] with the given DB, and environment -/// ([`CfgEnvWithHandlerCfg`] and [`BlockEnv`]) to execute the post block contract call. -/// -/// This uses [`apply_withdrawal_requests_contract_call`] to ultimately calculate the -/// [requests](Request). -pub fn post_block_withdrawal_requests_contract_call( - evm_config: &EvmConfig, - db: &mut DB, - initialized_cfg: &CfgEnvWithHandlerCfg, - initialized_block_env: &BlockEnv, -) -> Result, BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: Display, - EvmConfig: ConfigureEvm
, -{ - // apply post-block EIP-7002 contract call - let mut evm_post_block = Evm::builder() - .with_db(db) - .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( - initialized_cfg.clone(), - initialized_block_env.clone(), - Default::default(), - )) - .build(); - - // initialize a block from the env, because the post block call needs the block itself - apply_withdrawal_requests_contract_call(evm_config, &mut evm_post_block) -} +use revm::{interpreter::Host, Database, Evm}; +use revm_primitives::{ExecutionResult, ResultAndState}; /// Applies the post-block call to the EIP-7002 withdrawal requests contract. /// @@ -50,7 +14,7 @@ where /// /// Note: this does not commit the state changes to the database, it only transact the call. #[inline] -pub fn transact_withdrawal_requests_contract_call( +pub(crate) fn transact_withdrawal_requests_contract_call( evm_config: &EvmConfig, evm: &mut Evm<'_, EXT, DB>, ) -> Result @@ -98,29 +62,6 @@ where Ok(res) } -/// Applies the post-block call to the EIP-7002 withdrawal requests contract. -/// -/// If Prague is not active at the given timestamp, then this is a no-op, and an empty vector is -/// returned. Otherwise, the withdrawal requests are returned. -#[inline] -pub fn apply_withdrawal_requests_contract_call( - evm_config: &EvmConfig, - evm: &mut Evm<'_, EXT, DB>, -) -> Result, BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, -{ - let ResultAndState { result, state } = - transact_withdrawal_requests_contract_call(evm_config, evm)?; - - // commit the state - evm.context.evm.db.commit(state); - - post_commit(result) -} - /// Parses the withdrawal requests from the execution output. #[inline] pub(crate) fn post_commit(result: ExecutionResult) -> Result, BlockExecutionError> { diff --git a/crates/evm/src/system_calls/eip7251.rs b/crates/evm/src/system_calls/eip7251.rs index df122293be70..f09d4be81afc 100644 --- a/crates/evm/src/system_calls/eip7251.rs +++ b/crates/evm/src/system_calls/eip7251.rs @@ -1,48 +1,12 @@ //! [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) system call implementation. -use alloc::{boxed::Box, format, string::ToString, vec::Vec}; -use core::fmt::Display; - use crate::ConfigureEvm; +use alloc::{boxed::Box, format, string::ToString, vec::Vec}; use alloy_eips::eip7251::{ConsolidationRequest, CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS}; use alloy_primitives::{bytes::Buf, Address, Bytes, FixedBytes}; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; use reth_primitives::{Header, Request}; -use revm::{interpreter::Host, Database, DatabaseCommit, Evm}; -use revm_primitives::{ - BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, ResultAndState, -}; - -/// Apply the [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) post block contract call. -/// -/// This constructs a new [Evm] with the given DB, and environment -/// ([`CfgEnvWithHandlerCfg`] and [`BlockEnv`]) to execute the post block contract call. -/// -/// This uses [`apply_consolidation_requests_contract_call`] to ultimately calculate the -/// [requests](Request). -pub fn post_block_consolidation_requests_contract_call( - evm_config: &EvmConfig, - db: &mut DB, - initialized_cfg: &CfgEnvWithHandlerCfg, - initialized_block_env: &BlockEnv, -) -> Result, BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: Display, - EvmConfig: ConfigureEvm
, -{ - // apply post-block EIP-7251 contract call - let mut evm_post_block = Evm::builder() - .with_db(db) - .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( - initialized_cfg.clone(), - initialized_block_env.clone(), - Default::default(), - )) - .build(); - - // initialize a block from the env, because the post block call needs the block itself - apply_consolidation_requests_contract_call(evm_config, &mut evm_post_block) -} +use revm::{interpreter::Host, Database, Evm}; +use revm_primitives::{ExecutionResult, ResultAndState}; /// Applies the post-block call to the EIP-7251 consolidation requests contract. /// @@ -51,7 +15,7 @@ where /// /// Note: this does not commit the state changes to the database, it only transact the call. #[inline] -pub fn transact_consolidation_requests_contract_call( +pub(crate) fn transact_consolidation_requests_contract_call( evm_config: &EvmConfig, evm: &mut Evm<'_, EXT, DB>, ) -> Result @@ -100,29 +64,6 @@ where Ok(res) } -/// Applies the post-block call to the EIP-7251 consolidation requests contract. -/// -/// If Prague is not active at the given timestamp, then this is a no-op, and an empty vector is -/// returned. Otherwise, the consolidation requests are returned. -#[inline] -pub fn apply_consolidation_requests_contract_call( - evm_config: &EvmConfig, - evm: &mut Evm<'_, EXT, DB>, -) -> Result, BlockExecutionError> -where - DB: Database + DatabaseCommit, - DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, -{ - let ResultAndState { result, state } = - transact_consolidation_requests_contract_call(evm_config, evm)?; - - // commit the state - evm.context.evm.db.commit(state); - - post_commit(result) -} - /// Parses the consolidation requests from the execution output. #[inline] pub(crate) fn post_commit(result: ExecutionResult) -> Result, BlockExecutionError> { diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 2e2df10ad049..ce5fec42184c 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -10,16 +10,9 @@ use revm::{Database, DatabaseCommit, Evm}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, B256}; mod eip2935; -pub use eip2935::*; - mod eip4788; -pub use eip4788::*; - mod eip7002; -pub use eip7002::*; - mod eip7251; -pub use eip7251::*; /// A hook that is called after each state change. pub trait OnStateHook { diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 6a3ff8a8e445..28f8cdf4ed25 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -10,7 +10,7 @@ use reth_evm::{ BatchExecutor, BlockExecutionError, BlockExecutionInput, BlockExecutionOutput, BlockExecutorProvider, BlockValidationError, Executor, ProviderError, }, - system_calls::apply_beacon_root_contract_call, + system_calls::SystemCaller, ConfigureEvm, }; use reth_execution_types::ExecutionOutcome; @@ -119,10 +119,10 @@ where where DB: Database + Display>, { + let mut system_caller = SystemCaller::new(&self.evm_config, &self.chain_spec); + // apply pre execution changes - apply_beacon_root_contract_call( - &self.evm_config, - &self.chain_spec, + system_caller.apply_beacon_root_contract_call( block.timestamp, block.number, block.parent_beacon_block_root, diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 0f1a1e224d45..5e9c1b5d18be 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -6,10 +6,7 @@ use alloy_primitives::U256; use reth_basic_payload_builder::*; use reth_chain_state::ExecutedBlock; use reth_chainspec::{ChainSpecProvider, EthereumHardforks}; -use reth_evm::{ - system_calls::pre_block_beacon_root_contract_call, ConfigureEvm, ConfigureEvmEnv, - NextBlockEnvAttributes, -}; +use reth_evm::{system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; use reth_execution_types::ExecutionOutcome; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; @@ -204,22 +201,23 @@ where ); // apply eip-4788 pre block contract call - pre_block_beacon_root_contract_call( - &mut db, - &evm_config, - &chain_spec, - &initialized_cfg, - &initialized_block_env, - attributes.payload_attributes.parent_beacon_block_root, - ) - .map_err(|err| { - warn!(target: "payload_builder", - parent_hash=%parent_block.hash(), - %err, - "failed to apply beacon root contract call for payload" - ); - PayloadBuilderError::Internal(err.into()) - })?; + let mut system_caller = SystemCaller::new(&evm_config, &chain_spec); + + system_caller + .pre_block_beacon_root_contract_call( + &mut db, + &initialized_cfg, + &initialized_block_env, + attributes.payload_attributes.parent_beacon_block_root, + ) + .map_err(|err| { + warn!(target: "payload_builder", + parent_hash=%parent_block.hash(), + %err, + "failed to apply beacon root contract call for payload" + ); + PayloadBuilderError::Internal(err.into()) + })?; // Ensure that the create2deployer is force-deployed at the canyon transition. Optimism // blocks will always have at least a single transaction in them (the L1 info transaction), diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index cee8fb2a56f9..8014851e3f93 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -4,14 +4,12 @@ use std::time::{Duration, Instant}; use crate::{EthApiTypes, FromEthApiError, FromEvmError}; + use alloy_primitives::{BlockNumber, B256, U256}; use alloy_rpc_types::BlockNumberOrTag; use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; -use reth_evm::{ - system_calls::{pre_block_beacon_root_contract_call, pre_block_blockhashes_contract_call}, - ConfigureEvm, ConfigureEvmEnv, -}; +use reth_evm::{system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv}; use reth_execution_types::ExecutionOutcome; use reth_primitives::{ constants::{eip4844::MAX_DATA_GAS_PER_BLOCK, BEACON_NONCE, EMPTY_ROOT_HASH}, @@ -262,31 +260,27 @@ pub trait LoadPendingBlock: EthApiTypes { let chain_spec = self.provider().chain_spec(); + let evm_config = self.evm_config().clone(); + let mut system_caller = SystemCaller::new(&evm_config, chain_spec.clone()); + let parent_beacon_block_root = if origin.is_actual_pending() { // apply eip-4788 pre block contract call if we got the block from the CL with the real // parent beacon block root - pre_block_beacon_root_contract_call( - &mut db, - self.evm_config(), - chain_spec.as_ref(), - &cfg, - &block_env, - origin.header().parent_beacon_block_root, - ) - .map_err(|err| EthApiError::Internal(err.into()))?; + system_caller + .pre_block_beacon_root_contract_call( + &mut db, + &cfg, + &block_env, + origin.header().parent_beacon_block_root, + ) + .map_err(|err| EthApiError::Internal(err.into()))?; origin.header().parent_beacon_block_root } else { None }; - pre_block_blockhashes_contract_call( - &mut db, - self.evm_config(), - chain_spec.as_ref(), - &cfg, - &block_env, - origin.header().hash(), - ) - .map_err(|err| EthApiError::Internal(err.into()))?; + system_caller + .pre_block_blockhashes_contract_call(&mut db, &cfg, &block_env, origin.header().hash()) + .map_err(|err| EthApiError::Internal(err.into()))?; let mut receipts = Vec::new();