diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index ce1a2cf6d8e2..595f93e58dcd 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -265,7 +265,7 @@ impl> Command { EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db); let block_execution_output = - executor.execute((&block_with_senders.clone().unseal(), U256::MAX).into())?; + executor.execute(&block_with_senders.clone().unseal())?; let execution_outcome = ExecutionOutcome::from((block_execution_output, block.number)); debug!(target: "reth::cli", ?execution_outcome, "Executed block"); diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index 58b86648b901..ff75fccc8ddd 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -24,9 +24,8 @@ use reth_node_ethereum::EthExecutorProvider; use reth_primitives::BlockExt; use reth_provider::{ providers::ProviderNodeTypes, AccountExtReader, ChainSpecProvider, DatabaseProviderFactory, - HashedPostStateProvider, HashingWriter, HeaderProvider, LatestStateProviderRef, - OriginalValuesKnown, ProviderFactory, StageCheckpointReader, StateWriter, StorageLocation, - StorageReader, + HashedPostStateProvider, HashingWriter, LatestStateProviderRef, OriginalValuesKnown, + ProviderFactory, StageCheckpointReader, StateWriter, StorageLocation, StorageReader, }; use reth_revm::database::StateProviderDatabase; use reth_stages::StageId; @@ -148,19 +147,12 @@ impl> Command { let db = StateProviderDatabase::new(&state_provider); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db); - - let merkle_block_td = - provider.header_td_by_number(merkle_block_number)?.unwrap_or_default(); let block_execution_output = executor.execute( - ( - &block - .clone() - .unseal::>() - .with_recovered_senders() - .ok_or(BlockValidationError::SenderRecoveryError)?, - merkle_block_td + block.difficulty, - ) - .into(), + &block + .clone() + .unseal::>() + .with_recovered_senders() + .ok_or(BlockValidationError::SenderRecoveryError)?, )?; let execution_outcome = ExecutionOutcome::from((block_execution_output, block.number)); diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index 16a1f1112726..13f93c51d6ca 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -164,7 +164,7 @@ impl> Command { let mut executor = executor_provider.batch_executor(StateProviderDatabase::new( LatestStateProviderRef::new(&provider_rw), )); - executor.execute_and_verify_one((&sealed_block.clone().unseal(), td).into())?; + executor.execute_and_verify_one(&sealed_block.clone().unseal())?; let execution_outcome = executor.finalize(); provider_rw.write_state( diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 64bff767126a..e2d96c289831 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -397,7 +397,6 @@ where .header_td(&block.parent_hash)? .ok_or_else(|| BlockchainTreeError::CanonicalChain { block_hash: block.parent_hash })?; - // Pass the parent total difficulty to short-circuit unnecessary calculations. if !self .externals .provider_factory @@ -1037,6 +1036,7 @@ where }) }, )?; + if !self .externals .provider_factory diff --git a/crates/blockchain-tree/src/chain.rs b/crates/blockchain-tree/src/chain.rs index 4002fae1ac91..e607d00d2d9b 100644 --- a/crates/blockchain-tree/src/chain.rs +++ b/crates/blockchain-tree/src/chain.rs @@ -6,7 +6,7 @@ use super::externals::TreeExternals; use crate::BundleStateDataRef; use alloy_eips::ForkBlock; -use alloy_primitives::{BlockHash, BlockNumber, U256}; +use alloy_primitives::{BlockHash, BlockNumber}; use reth_blockchain_tree_api::{ error::{BlockchainTreeError, InsertBlockErrorKind}, BlockAttachment, BlockValidationKind, @@ -209,7 +209,7 @@ impl AppendableChain { let block_hash = block.hash(); let block = block.unseal(); - let state = executor.execute((&block, U256::MAX).into())?; + let state = executor.execute(&block)?; externals.consensus.validate_block_post_execution( &block, PostExecutionInput::new(&state.receipts, &state.requests), diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index b8ab45e8539d..d2e15a83a0a6 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -240,6 +240,12 @@ impl ChainSpec { self.chain == Chain::optimism_mainnet() } + /// Returns the known paris block, if it exists. + #[inline] + pub fn paris_block(&self) -> Option { + self.paris_block_and_final_difficulty.map(|(block, _)| block) + } + /// Get the genesis block specification. /// /// To get the header for the genesis block, use [`Self::genesis_header`] instead. @@ -389,7 +395,7 @@ impl ChainSpec { /// Returns the hardfork display helper. pub fn display_hardforks(&self) -> DisplayHardforks { - DisplayHardforks::new(&self, self.paris_block_and_final_difficulty.map(|(block, _)| block)) + DisplayHardforks::new(&self) } /// Get the fork id for the given hardfork. @@ -603,12 +609,20 @@ impl From for ChainSpec { .filter_map(|(hardfork, opt)| opt.map(|block| (hardfork, ForkCondition::Block(block)))) .collect::>(); - // Paris + // We expect no new networks to be configured with the merge, so we ignore the TTD field + // and merge netsplit block from external genesis files. All existing networks that have + // merged should have a static ChainSpec already (namely mainnet and sepolia). let paris_block_and_final_difficulty = if let Some(ttd) = genesis.config.terminal_total_difficulty { hardforks.push(( EthereumHardfork::Paris.boxed(), ForkCondition::TTD { + // NOTE: this will not work properly if the merge is not activated at + // genesis, and there is no merge netsplit block + activation_block_number: genesis + .config + .merge_netsplit_block + .unwrap_or_default(), total_difficulty: ttd, fork_block: genesis.config.merge_netsplit_block, }, @@ -765,10 +779,10 @@ impl ChainSpecBuilder { /// Enable the Paris hardfork at the given TTD. /// /// Does not set the merge netsplit block. - pub fn paris_at_ttd(self, ttd: U256) -> Self { + pub fn paris_at_ttd(self, ttd: U256, activation_block_number: BlockNumber) -> Self { self.with_fork( EthereumHardfork::Paris, - ForkCondition::TTD { total_difficulty: ttd, fork_block: None }, + ForkCondition::TTD { activation_block_number, total_difficulty: ttd, fork_block: None }, ) } @@ -846,7 +860,11 @@ impl ChainSpecBuilder { self = self.london_activated(); self.hardforks.insert( EthereumHardfork::Paris, - ForkCondition::TTD { fork_block: Some(0), total_difficulty: U256::ZERO }, + ForkCondition::TTD { + activation_block_number: 0, + total_difficulty: U256::ZERO, + fork_block: None, + }, ); self } @@ -888,8 +906,8 @@ impl ChainSpecBuilder { pub fn build(self) -> ChainSpec { let paris_block_and_final_difficulty = { self.hardforks.get(EthereumHardfork::Paris).and_then(|cond| { - if let ForkCondition::TTD { fork_block, total_difficulty } = cond { - fork_block.map(|fork_block| (fork_block, total_difficulty)) + if let ForkCondition::TTD { total_difficulty, activation_block_number, .. } = cond { + Some((activation_block_number, total_difficulty)) } else { None } @@ -1133,6 +1151,7 @@ Post-merge hard forks (timestamp based): .with_fork( EthereumHardfork::Paris, ForkCondition::TTD { + activation_block_number: 101, fork_block: Some(101), total_difficulty: U256::from(10_790_000), }, @@ -1166,6 +1185,7 @@ Post-merge hard forks (timestamp based): // Fork::ConditionTTD test case without a new chain spec to demonstrate ChainSpec::satisfy // is independent of ChainSpec for this(these - including ForkCondition::Block) match arm(s) let fork_cond_ttd_no_new_spec = fork_cond_block_only_case.satisfy(ForkCondition::TTD { + activation_block_number: 101, fork_block: None, total_difficulty: U256::from(10_790_000), }); diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index 3d70888fdad3..8d31e3d40ad2 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -2460,7 +2460,7 @@ mod tests { .chain(MAINNET.chain) .genesis(MAINNET.genesis.clone()) .london_activated() - .paris_at_ttd(U256::from(3)) + .paris_at_ttd(U256::from(3), 3) .build(), ); diff --git a/crates/consensus/common/src/calc.rs b/crates/consensus/common/src/calc.rs index e30c5b715f5a..584e90f04d93 100644 --- a/crates/consensus/common/src/calc.rs +++ b/crates/consensus/common/src/calc.rs @@ -1,6 +1,6 @@ use alloy_consensus::constants::ETH_TO_WEI; -use alloy_primitives::{BlockNumber, U256}; -use reth_chainspec::{EthereumHardfork, Hardforks}; +use alloy_primitives::BlockNumber; +use reth_chainspec::{EthereumHardfork, EthereumHardforks, Hardforks}; /// Calculates the base block reward. /// @@ -21,13 +21,11 @@ use reth_chainspec::{EthereumHardfork, Hardforks}; /// - Definition: [Yellow Paper][yp] (page 15, 11.3) /// /// [yp]: https://ethereum.github.io/yellowpaper/paper.pdf -pub fn base_block_reward( - chain_spec: impl Hardforks, +pub fn base_block_reward( + chain_spec: &ChainSpec, block_number: BlockNumber, - block_difficulty: U256, - total_difficulty: U256, ) -> Option { - if chain_spec.fork(EthereumHardfork::Paris).active_at_ttd(total_difficulty, block_difficulty) { + if chain_spec.is_paris_active_at_block(block_number).is_some_and(|active| active) { None } else { Some(base_block_reward_pre_merge(chain_spec, block_number)) @@ -62,12 +60,9 @@ pub fn base_block_reward_pre_merge(chain_spec: impl Hardforks, block_number: Blo /// # /// // This is block 126 on mainnet. /// let block_number = 126; -/// let block_difficulty = U256::from(18_145_285_642usize); -/// let total_difficulty = U256::from(2_235_668_675_900usize); /// let number_of_ommers = 1; /// -/// let reward = base_block_reward(&*MAINNET, block_number, block_difficulty, total_difficulty) -/// .map(|reward| block_reward(reward, 1)); +/// let reward = base_block_reward(&*MAINNET, block_number).map(|reward| block_reward(reward, 1)); /// /// // The base block reward is 5 ETH, and the ommer inclusion reward is 1/32th of 5 ETH. /// assert_eq!(reward.unwrap(), ETH_TO_WEI * 5 + ((ETH_TO_WEI * 5) >> 5)); @@ -113,6 +108,7 @@ pub const fn ommer_reward( #[cfg(test)] mod tests { use super::*; + use alloy_primitives::U256; use reth_chainspec::MAINNET; #[test] @@ -126,11 +122,11 @@ mod tests { // Petersburg ((7280000, U256::ZERO), Some(ETH_TO_WEI * 2)), // Merge - ((10000000, U256::from(58_750_000_000_000_000_000_000_u128)), None), + ((15537394, U256::from(58_750_000_000_000_000_000_000_u128)), None), ]; - for ((block_number, td), expected_reward) in cases { - assert_eq!(base_block_reward(&*MAINNET, block_number, U256::ZERO, td), expected_reward); + for ((block_number, _td), expected_reward) in cases { + assert_eq!(base_block_reward(&*MAINNET, block_number), expected_reward); } } diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index 01fdb7cf3b14..2b634ae5ce71 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -1,5 +1,5 @@ use alloy_consensus::BlockHeader; -use alloy_primitives::{keccak256, B256, U256}; +use alloy_primitives::{keccak256, B256}; use alloy_rpc_types_debug::ExecutionWitness; use eyre::OptionExt; use pretty_assertions::Comparison; @@ -79,7 +79,7 @@ where // Setup environment for the execution. let EvmEnv { cfg_env_with_handler_cfg, block_env } = - self.evm_config.cfg_and_block_env(block.header(), U256::MAX); + self.evm_config.cfg_and_block_env(block.header()); // Setup EVM let mut evm = self.evm_config.evm_with_env( @@ -116,7 +116,6 @@ where let balance_increments = post_block_balance_increments( self.provider.chain_spec().as_ref(), &block.clone().unseal().block, - U256::MAX, ); // increment balances diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 35907800ce3a..eb3798692e5e 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -2261,11 +2261,7 @@ where // }; let state_hook = Box::new(|_state: &EvmState| {}); - let output = self.metrics.executor.execute_metered( - executor, - (&block, U256::MAX).into(), - state_hook, - )?; + let output = self.metrics.executor.execute_metered(executor, &block, state_hook)?; trace!(target: "engine::tree", elapsed=?exec_time.elapsed(), ?block_number, "Executed block"); diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 061dd40c4b81..b9b93329a544 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -1,7 +1,6 @@ //! Stream wrapper that simulates reorgs. use alloy_consensus::{Header, Transaction}; -use alloy_primitives::U256; use alloy_rpc_types_engine::{ CancunPayloadFields, ExecutionPayload, ExecutionPayloadSidecar, ForkchoiceState, PayloadStatus, }; @@ -299,7 +298,7 @@ where // Configure environments let EvmEnv { cfg_env_with_handler_cfg, block_env } = - evm_config.cfg_and_block_env(&reorg_target.header, U256::MAX); + evm_config.cfg_and_block_env(&reorg_target.header); let env = EnvWithHandlerCfg::new_with_cfg_env( cfg_env_with_handler_cfg, block_env, diff --git a/crates/ethereum-forks/src/display.rs b/crates/ethereum-forks/src/display.rs index fc606854caa2..f5c6f47a2ea3 100644 --- a/crates/ethereum-forks/src/display.rs +++ b/crates/ethereum-forks/src/display.rs @@ -38,17 +38,12 @@ impl core::fmt::Display for DisplayFork { ForkCondition::Block(at) | ForkCondition::Timestamp(at) => { write!(f, "{name_with_eip:32} @{at}")?; } - ForkCondition::TTD { fork_block, total_difficulty } => { + ForkCondition::TTD { total_difficulty, .. } => { + // All networks that have merged are finalized. write!( f, - "{:32} @{} ({})", - name_with_eip, - total_difficulty, - if fork_block.is_some() { - "network is known to be merged" - } else { - "network is not known to be merged" - } + "{:32} @{} (network is known to be merged)", + name_with_eip, total_difficulty, )?; } ForkCondition::Never => unreachable!(), @@ -141,7 +136,7 @@ impl core::fmt::Display for DisplayHardforks { impl DisplayHardforks { /// Creates a new [`DisplayHardforks`] from an iterator of hardforks. - pub fn new(hardforks: &H, known_paris_block: Option) -> Self { + pub fn new(hardforks: &H) -> Self { let mut pre_merge = Vec::new(); let mut with_merge = Vec::new(); let mut post_merge = Vec::new(); @@ -154,9 +149,12 @@ impl DisplayHardforks { ForkCondition::Block(_) => { pre_merge.push(display_fork); } - ForkCondition::TTD { total_difficulty, .. } => { - display_fork.activated_at = - ForkCondition::TTD { fork_block: known_paris_block, total_difficulty }; + ForkCondition::TTD { activation_block_number, total_difficulty, fork_block } => { + display_fork.activated_at = ForkCondition::TTD { + activation_block_number, + fork_block, + total_difficulty, + }; with_merge.push(display_fork); } ForkCondition::Timestamp(_) => { diff --git a/crates/ethereum-forks/src/forkcondition.rs b/crates/ethereum-forks/src/forkcondition.rs index 89f21221b011..e6be6a9c9a8f 100644 --- a/crates/ethereum-forks/src/forkcondition.rs +++ b/crates/ethereum-forks/src/forkcondition.rs @@ -9,6 +9,12 @@ pub enum ForkCondition { Block(BlockNumber), /// The fork is activated after a total difficulty has been reached. TTD { + /// The activation block number for the merge. + /// + /// This should represent the first post-merge block for the given network. Sepolia and + /// mainnet are the only networks that have merged, and they have both finalized + /// post-merge, so total difficulty is effectively deprecated. + activation_block_number: BlockNumber, /// The block number at which TTD is reached, if it is known. /// /// This should **NOT** be set unless you want this block advertised as [EIP-2124][eip2124] @@ -127,16 +133,22 @@ mod tests { ); // Test if TTD-based condition with known block activates - let fork_condition = - ForkCondition::TTD { fork_block: Some(10), total_difficulty: U256::from(1000) }; + let fork_condition = ForkCondition::TTD { + activation_block_number: 10, + fork_block: Some(10), + total_difficulty: U256::from(1000), + }; assert!( fork_condition.active_at_block(10), "The TTD condition should be active at block 10" ); // Test if TTD-based condition with unknown block does not activate - let fork_condition = - ForkCondition::TTD { fork_block: None, total_difficulty: U256::from(1000) }; + let fork_condition = ForkCondition::TTD { + activation_block_number: 10, + fork_block: None, + total_difficulty: U256::from(1000), + }; assert!( !fork_condition.active_at_block(10), "The TTD condition should not be active at block 10 with an unknown block number" @@ -166,8 +178,11 @@ mod tests { #[test] fn test_active_at_ttd() { // Test if the condition activates at the correct total difficulty - let fork_condition = - ForkCondition::TTD { fork_block: Some(10), total_difficulty: U256::from(1000) }; + let fork_condition = ForkCondition::TTD { + activation_block_number: 10, + fork_block: Some(10), + total_difficulty: U256::from(1000), + }; assert!( fork_condition.active_at_ttd(U256::from(1000000), U256::from(100)), "The TTD condition should be active when the total difficulty matches" @@ -258,26 +273,38 @@ mod tests { ); // Test if the condition activates based on total difficulty and block number - let fork_condition = - ForkCondition::TTD { fork_block: Some(9), total_difficulty: U256::from(900) }; + let fork_condition = ForkCondition::TTD { + activation_block_number: 10, + fork_block: Some(9), + total_difficulty: U256::from(900), + }; assert!( fork_condition.active_at_head(&head), "The condition should be active at the given head total difficulty" ); - let fork_condition = - ForkCondition::TTD { fork_block: None, total_difficulty: U256::from(900) }; + let fork_condition = ForkCondition::TTD { + activation_block_number: 10, + fork_block: None, + total_difficulty: U256::from(900), + }; assert!( fork_condition.active_at_head(&head), "The condition should be active at the given head total difficulty as the block number is unknown" ); - let fork_condition = - ForkCondition::TTD { fork_block: Some(11), total_difficulty: U256::from(900) }; + let fork_condition = ForkCondition::TTD { + activation_block_number: 10, + fork_block: Some(11), + total_difficulty: U256::from(900), + }; assert!( fork_condition.active_at_head(&head), "The condition should be active as the total difficulty is higher" ); - let fork_condition = - ForkCondition::TTD { fork_block: Some(10), total_difficulty: U256::from(9000) }; + let fork_condition = ForkCondition::TTD { + activation_block_number: 10, + fork_block: Some(10), + total_difficulty: U256::from(9000), + }; assert!( fork_condition.active_at_head(&head), "The condition should be active as the total difficulty is higher than head" diff --git a/crates/ethereum-forks/src/hardfork/dev.rs b/crates/ethereum-forks/src/hardfork/dev.rs index 068e290709d2..8a0510a97985 100644 --- a/crates/ethereum-forks/src/hardfork/dev.rs +++ b/crates/ethereum-forks/src/hardfork/dev.rs @@ -26,7 +26,11 @@ pub static DEV_HARDFORKS: LazyLock = LazyLock::new(|| { (EthereumHardfork::London.boxed(), ForkCondition::Block(0)), ( EthereumHardfork::Paris.boxed(), - ForkCondition::TTD { fork_block: None, total_difficulty: U256::ZERO }, + ForkCondition::TTD { + activation_block_number: 0, + fork_block: None, + total_difficulty: U256::ZERO, + }, ), (EthereumHardfork::Shanghai.boxed(), ForkCondition::Timestamp(0)), (EthereumHardfork::Cancun.boxed(), ForkCondition::Timestamp(0)), diff --git a/crates/ethereum-forks/src/hardfork/ethereum.rs b/crates/ethereum-forks/src/hardfork/ethereum.rs index c728f6ed6634..d75c444ead7c 100644 --- a/crates/ethereum-forks/src/hardfork/ethereum.rs +++ b/crates/ethereum-forks/src/hardfork/ethereum.rs @@ -352,6 +352,7 @@ impl EthereumHardfork { ( Self::Paris, ForkCondition::TTD { + activation_block_number: 15537394, fork_block: None, total_difficulty: uint!(58_750_000_000_000_000_000_000_U256), }, @@ -379,6 +380,7 @@ impl EthereumHardfork { ( Self::Paris, ForkCondition::TTD { + activation_block_number: 1735371, fork_block: Some(1735371), total_difficulty: uint!(17_000_000_000_000_000_U256), }, @@ -403,7 +405,14 @@ impl EthereumHardfork { (Self::MuirGlacier, ForkCondition::Block(0)), (Self::Berlin, ForkCondition::Block(0)), (Self::London, ForkCondition::Block(0)), - (Self::Paris, ForkCondition::TTD { fork_block: Some(0), total_difficulty: U256::ZERO }), + ( + Self::Paris, + ForkCondition::TTD { + activation_block_number: 0, + fork_block: Some(0), + total_difficulty: U256::ZERO, + }, + ), (Self::Shanghai, ForkCondition::Timestamp(1696000704)), (Self::Cancun, ForkCondition::Timestamp(1707305664)), ] diff --git a/crates/ethereum-forks/src/hardforks/ethereum.rs b/crates/ethereum-forks/src/hardforks/ethereum.rs index 086d2d3b46ec..f43d37a7e1f1 100644 --- a/crates/ethereum-forks/src/hardforks/ethereum.rs +++ b/crates/ethereum-forks/src/hardforks/ethereum.rs @@ -50,8 +50,8 @@ pub trait EthereumHardforks: Hardforks { fn is_paris_active_at_block(&self, block_number: u64) -> Option { match self.fork(EthereumHardfork::Paris) { ForkCondition::Block(paris_block) => Some(block_number >= paris_block), - ForkCondition::TTD { fork_block, .. } => { - fork_block.map(|paris_block| block_number >= paris_block) + ForkCondition::TTD { activation_block_number, .. } => { + Some(block_number >= activation_block_number) } _ => None, } diff --git a/crates/ethereum-forks/src/head.rs b/crates/ethereum-forks/src/head.rs index bd05cc3a772e..1b867bcb852f 100644 --- a/crates/ethereum-forks/src/head.rs +++ b/crates/ethereum-forks/src/head.rs @@ -23,6 +23,7 @@ pub struct Head { /// The timestamp of the head block. pub timestamp: u64, } + impl Head { /// Creates a new `Head` instance. pub const fn new( diff --git a/crates/ethereum/evm/src/config.rs b/crates/ethereum/evm/src/config.rs index 9d6b6d8796ce..40e024715f1f 100644 --- a/crates/ethereum/evm/src/config.rs +++ b/crates/ethereum/evm/src/config.rs @@ -32,7 +32,7 @@ pub fn revm_spec(chain_spec: &ChainSpec, block: &Head) -> revm_primitives::SpecI revm_primitives::CANCUN } else if chain_spec.fork(EthereumHardfork::Shanghai).active_at_head(block) { revm_primitives::SHANGHAI - } else if chain_spec.fork(EthereumHardfork::Paris).active_at_head(block) { + } else if chain_spec.is_paris_active_at_block(block.number).is_some_and(|active| active) { revm_primitives::MERGE } else if chain_spec.fork(EthereumHardfork::London).active_at_head(block) { revm_primitives::LONDON @@ -166,19 +166,7 @@ mod tests { &Head { total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128), difficulty: U256::from(10_u128), - ..Default::default() - } - ), - revm_primitives::MERGE - ); - // TTD trumps the block number - assert_eq!( - revm_spec( - &MAINNET, - &Head { - number: 15537394 - 10, - total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128), - difficulty: U256::from(10_u128), + number: 15537394, ..Default::default() } ), diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 2955fdabc7b2..116dd2c00ecd 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -26,7 +26,7 @@ use reth_primitives::{BlockWithSenders, EthPrimitives, Receipt}; use reth_revm::db::State; use revm_primitives::{ db::{Database, DatabaseCommit}, - EnvWithHandlerCfg, ResultAndState, U256, + EnvWithHandlerCfg, ResultAndState, }; /// Factory for [`EthExecutionStrategy`]. @@ -123,13 +123,9 @@ where /// # Caution /// /// This does not initialize the tx environment. - fn evm_env_for_block( - &self, - header: &alloy_consensus::Header, - total_difficulty: U256, - ) -> EnvWithHandlerCfg { + fn evm_env_for_block(&self, header: &alloy_consensus::Header) -> EnvWithHandlerCfg { let EvmEnv { cfg_env_with_handler_cfg, block_env } = - self.evm_config.cfg_and_block_env(header, total_difficulty); + self.evm_config.cfg_and_block_env(header); EnvWithHandlerCfg::new_with_cfg_env(cfg_env_with_handler_cfg, block_env, Default::default()) } } @@ -151,17 +147,13 @@ where self.tx_env_overrides = Some(tx_env_overrides); } - fn apply_pre_execution_changes( - &mut self, - block: &BlockWithSenders, - total_difficulty: U256, - ) -> Result<(), Self::Error> { + fn apply_pre_execution_changes(&mut self, block: &BlockWithSenders) -> Result<(), Self::Error> { // Set state clear flag if the block is after the Spurious Dragon hardfork. let state_clear_flag = (*self.chain_spec).is_spurious_dragon_active_at_block(block.header.number); self.state.set_state_clear_flag(state_clear_flag); - let env = self.evm_env_for_block(&block.header, total_difficulty); + let env = self.evm_env_for_block(&block.header); let mut evm = self.evm_config.evm_with_env(&mut self.state, env); self.system_caller.apply_pre_execution_changes(&block.block, &mut evm)?; @@ -172,9 +164,8 @@ where fn execute_transactions( &mut self, block: &BlockWithSenders, - total_difficulty: U256, ) -> Result, Self::Error> { - let env = self.evm_env_for_block(&block.header, total_difficulty); + let env = self.evm_env_for_block(&block.header); let mut evm = self.evm_config.evm_with_env(&mut self.state, env); let mut cumulative_gas_used = 0; @@ -234,10 +225,9 @@ where fn apply_post_execution_changes( &mut self, block: &BlockWithSenders, - total_difficulty: U256, receipts: &[Receipt], ) -> Result { - let env = self.evm_env_for_block(&block.header, total_difficulty); + let env = self.evm_env_for_block(&block.header); let mut evm = self.evm_config.evm_with_env(&mut self.state, env); let requests = if self.chain_spec.is_prague_active_at_timestamp(block.timestamp) { @@ -258,8 +248,7 @@ where }; drop(evm); - let mut balance_increments = - post_block_balance_increments(&self.chain_spec, &block.block, total_difficulty); + let mut balance_increments = post_block_balance_increments(&self.chain_spec, &block.block); // Irregular state change at Ethereum DAO hardfork if self.chain_spec.fork(EthereumHardfork::Dao).transitions_at_block(block.number) { @@ -337,7 +326,7 @@ mod tests { eip7002::{WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, WITHDRAWAL_REQUEST_PREDEPLOY_CODE}, eip7685::EMPTY_REQUESTS_HASH, }; - use alloy_primitives::{b256, fixed_bytes, keccak256, Bytes, TxKind, B256}; + use alloy_primitives::{b256, fixed_bytes, keccak256, Bytes, TxKind, B256, U256}; use reth_chainspec::{ChainSpecBuilder, ForkCondition}; use reth_evm::execute::{ BasicBlockExecutorProvider, BatchExecutor, BlockExecutorProvider, Executor, @@ -421,23 +410,13 @@ mod tests { // attempt to execute a block without parent beacon block root, expect err let err = executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { - header: header.clone(), - body: BlockBody { - transactions: vec![], - ommers: vec![], - withdrawals: None, - }, - }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { + header: header.clone(), + body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None }, + }, + vec![], + )) .expect_err( "Executing cancun block without parent beacon block root field should fail", ); @@ -452,23 +431,13 @@ mod tests { // Now execute a block with the fixed header, ensure that it does not fail executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { - header: header.clone(), - body: BlockBody { - transactions: vec![], - ommers: vec![], - withdrawals: None, - }, - }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { + header: header.clone(), + body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None }, + }, + vec![], + )) .unwrap(); // check the actual storage of the contract - it should be: @@ -522,23 +491,13 @@ mod tests { // attempt to execute an empty block with parent beacon block root, this should not fail provider .batch_executor(StateProviderDatabase::new(&db)) - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { - header, - body: BlockBody { - transactions: vec![], - ommers: vec![], - withdrawals: None, - }, - }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { + header, + body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None }, + }, + vec![], + )) .expect( "Executing a block with no transactions while cancun is active should not fail", ); @@ -576,23 +535,13 @@ mod tests { // attempt to execute an empty block with parent beacon block root, this should not fail executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { - header, - body: BlockBody { - transactions: vec![], - ommers: vec![], - withdrawals: None, - }, - }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { + header, + body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None }, + }, + vec![], + )) .expect( "Executing a block with no transactions while cancun is active should not fail", ); @@ -622,16 +571,10 @@ mod tests { // attempt to execute the genesis block with non-zero parent beacon block root, expect err header.parent_beacon_block_root = Some(B256::with_last_byte(0x69)); let _err = executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header: header.clone(), body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header: header.clone(), body: Default::default() }, + vec![], + )) .expect_err( "Executing genesis cancun block with non-zero parent beacon block root field should fail", @@ -643,16 +586,10 @@ mod tests { // now try to process the genesis block again, this time ensuring that a system contract // call does not occur executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header, body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + )) .unwrap(); // there is no system contract call so there should be NO STORAGE CHANGES @@ -697,16 +634,10 @@ mod tests { // Now execute a block with the fixed header, ensure that it does not fail executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header: header.clone(), body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header: header.clone(), body: Default::default() }, + vec![], + )) .unwrap(); // check the actual storage of the contract - it should be: @@ -773,16 +704,10 @@ mod tests { // attempt to execute an empty block, this should not fail executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header, body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + )) .expect( "Executing a block with no transactions while Prague is active should not fail", ); @@ -816,16 +741,10 @@ mod tests { // attempt to execute genesis block, this should not fail executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header, body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + )) .expect( "Executing a block with no transactions while Prague is active should not fail", ); @@ -866,16 +785,10 @@ mod tests { // attempt to execute the fork activation block, this should not fail executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header, body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + )) .expect( "Executing a block with no transactions while Prague is active should not fail", ); @@ -922,16 +835,10 @@ mod tests { // attempt to execute the fork activation block, this should not fail executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header, body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + )) .expect( "Executing a block with no transactions while Prague is active should not fail", ); @@ -970,16 +877,10 @@ mod tests { // attempt to execute the genesis block, this should not fail executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header, body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + )) .expect( "Executing a block with no transactions while Prague is active should not fail", ); @@ -1005,16 +906,10 @@ mod tests { let header_hash = header.hash_slow(); executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header, body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + )) .expect( "Executing a block with no transactions while Prague is active should not fail", ); @@ -1043,16 +938,10 @@ mod tests { }; executor - .execute_and_verify_one( - ( - &BlockWithSenders::new_unchecked( - Block { header, body: Default::default() }, - vec![], - ), - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + )) .expect( "Executing a block with no transactions while Prague is active should not fail", ); @@ -1133,16 +1022,9 @@ mod tests { let BlockExecutionOutput { receipts, requests, .. } = executor .execute( - ( - &Block { - header, - body: BlockBody { transactions: vec![tx], ..Default::default() }, - } + &Block { header, body: BlockBody { transactions: vec![tx], ..Default::default() } } .with_recovered_senders() .unwrap(), - U256::ZERO, - ) - .into(), ) .unwrap(); @@ -1216,13 +1098,9 @@ mod tests { // Execute the block and capture the result let exec_result = executor.execute( - ( - &Block { header, body: BlockBody { transactions: vec![tx], ..Default::default() } } - .with_recovered_senders() - .unwrap(), - U256::ZERO, - ) - .into(), + &Block { header, body: BlockBody { transactions: vec![tx], ..Default::default() } } + .with_recovered_senders() + .unwrap(), ); // Check if the execution result is an error and assert the specific error type @@ -1282,7 +1160,7 @@ mod tests { let tx_clone = tx.clone(); let _output = executor - .execute_with_state_hook((block, U256::ZERO).into(), move |state: &EvmState| { + .execute_with_state_hook(block, move |state: &EvmState| { if let Some(account) = state.get(&withdrawal_recipient) { let _ = tx_clone.send(account.info.balance); } diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index 1c92dae65d9b..502bb89524e3 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -109,19 +109,15 @@ impl ConfigureEvmEnv for EthEvmConfig { env.block.basefee = U256::ZERO; } - fn fill_cfg_env( - &self, - cfg_env: &mut CfgEnvWithHandlerCfg, - header: &Header, - total_difficulty: U256, - ) { + fn fill_cfg_env(&self, cfg_env: &mut CfgEnvWithHandlerCfg, header: &Header) { let spec_id = config::revm_spec( self.chain_spec(), &Head { number: header.number, timestamp: header.timestamp, difficulty: header.difficulty, - total_difficulty, + // NOTE: this does nothing within revm_spec + total_difficulty: U256::MIN, hash: Default::default(), }, ); @@ -226,14 +222,10 @@ mod tests { .shanghai_activated() .build(); - // Define the total difficulty as zero (default) - let total_difficulty = U256::ZERO; - // Use the `EthEvmConfig` to fill the `cfg_env` and `block_env` based on the ChainSpec, // Header, and total difficulty let EvmEnv { cfg_env_with_handler_cfg, .. } = - EthEvmConfig::new(Arc::new(chain_spec.clone())) - .cfg_and_block_env(&header, total_difficulty); + EthEvmConfig::new(Arc::new(chain_spec.clone())).cfg_and_block_env(&header); // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the // ChainSpec diff --git a/crates/evm/execution-types/src/execute.rs b/crates/evm/execution-types/src/execute.rs index ae5ad2c0b7c5..6d2a4c035ca9 100644 --- a/crates/evm/execution-types/src/execute.rs +++ b/crates/evm/execution-types/src/execute.rs @@ -1,29 +1,6 @@ use alloy_eips::eip7685::Requests; -use alloy_primitives::U256; use revm::db::BundleState; -/// A helper type for ethereum block inputs that consists of a block and the total difficulty. -#[derive(Debug)] -pub struct BlockExecutionInput<'a, Block> { - /// The block to execute. - pub block: &'a Block, - /// The total difficulty of the block. - pub total_difficulty: U256, -} - -impl<'a, Block> BlockExecutionInput<'a, Block> { - /// Creates a new input. - pub const fn new(block: &'a Block, total_difficulty: U256) -> Self { - Self { block, total_difficulty } - } -} - -impl<'a, Block> From<(&'a Block, U256)> for BlockExecutionInput<'a, Block> { - fn from((block, total_difficulty): (&'a Block, U256)) -> Self { - Self::new(block, total_difficulty) - } -} - /// The output of an ethereum block. /// /// Contains the state changes, transaction receipts, and total gas used in the block. diff --git a/crates/evm/src/execute.rs b/crates/evm/src/execute.rs index 8c3e0108fcc3..9a9f65375918 100644 --- a/crates/evm/src/execute.rs +++ b/crates/evm/src/execute.rs @@ -5,7 +5,7 @@ use alloy_consensus::BlockHeader; pub use reth_execution_errors::{ BlockExecutionError, BlockValidationError, InternalBlockExecutionError, }; -pub use reth_execution_types::{BlockExecutionInput, BlockExecutionOutput, ExecutionOutcome}; +pub use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome}; use reth_primitives_traits::Block as _; pub use reth_storage_errors::provider::ProviderError; @@ -25,7 +25,7 @@ use revm::{ db::{states::bundle_state::BundleRetention, BundleState}, State, }; -use revm_primitives::{db::Database, Account, AccountStatus, EvmState, U256}; +use revm_primitives::{db::Database, Account, AccountStatus, EvmState}; /// A general purpose executor trait that executes an input (e.g. block) and produces an output /// (e.g. state changes and receipts). @@ -151,10 +151,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { /// the returned state. type Executor + Display>>: for<'a> Executor< DB, - Input<'a> = BlockExecutionInput< - 'a, - BlockWithSenders<::Block>, - >, + Input<'a> = &'a BlockWithSenders<::Block>, Output = BlockExecutionOutput<::Receipt>, Error = BlockExecutionError, >; @@ -162,10 +159,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { /// An executor that can execute a batch of blocks given a database. type BatchExecutor + Display>>: for<'a> BatchExecutor< DB, - Input<'a> = BlockExecutionInput< - 'a, - BlockWithSenders<::Block>, - >, + Input<'a> = &'a BlockWithSenders<::Block>, Output = ExecutionOutcome<::Receipt>, Error = BlockExecutionError, >; @@ -213,21 +207,18 @@ pub trait BlockExecutionStrategy { fn apply_pre_execution_changes( &mut self, block: &BlockWithSenders<::Block>, - total_difficulty: U256, ) -> Result<(), Self::Error>; /// Executes all transactions in the block. fn execute_transactions( &mut self, block: &BlockWithSenders<::Block>, - total_difficulty: U256, ) -> Result::Receipt>, Self::Error>; /// Applies any necessary changes after executing the block's transactions. fn apply_post_execution_changes( &mut self, block: &BlockWithSenders<::Block>, - total_difficulty: U256, receipts: &[::Receipt], ) -> Result; @@ -347,8 +338,7 @@ where S: BlockExecutionStrategy, DB: Database + Display>, { - type Input<'a> = - BlockExecutionInput<'a, BlockWithSenders<::Block>>; + type Input<'a> = &'a BlockWithSenders<::Block>; type Output = BlockExecutionOutput<::Receipt>; type Error = S::Error; @@ -356,14 +346,10 @@ where self.strategy.init(env_overrides); } - fn execute(mut self, input: Self::Input<'_>) -> Result { - let BlockExecutionInput { block, total_difficulty } = input; - - self.strategy.apply_pre_execution_changes(block, total_difficulty)?; - let ExecuteOutput { receipts, gas_used } = - self.strategy.execute_transactions(block, total_difficulty)?; - let requests = - self.strategy.apply_post_execution_changes(block, total_difficulty, &receipts)?; + fn execute(mut self, block: Self::Input<'_>) -> Result { + self.strategy.apply_pre_execution_changes(block)?; + let ExecuteOutput { receipts, gas_used } = self.strategy.execute_transactions(block)?; + let requests = self.strategy.apply_post_execution_changes(block, &receipts)?; let state = self.strategy.finish(); Ok(BlockExecutionOutput { state, receipts, requests, gas_used }) @@ -371,19 +357,15 @@ where fn execute_with_state_closure( mut self, - input: Self::Input<'_>, + block: Self::Input<'_>, mut state: F, ) -> Result where F: FnMut(&State), { - let BlockExecutionInput { block, total_difficulty } = input; - - self.strategy.apply_pre_execution_changes(block, total_difficulty)?; - let ExecuteOutput { receipts, gas_used } = - self.strategy.execute_transactions(block, total_difficulty)?; - let requests = - self.strategy.apply_post_execution_changes(block, total_difficulty, &receipts)?; + self.strategy.apply_pre_execution_changes(block)?; + let ExecuteOutput { receipts, gas_used } = self.strategy.execute_transactions(block)?; + let requests = self.strategy.apply_post_execution_changes(block, &receipts)?; state(self.strategy.state_ref()); @@ -394,21 +376,17 @@ where fn execute_with_state_hook( mut self, - input: Self::Input<'_>, + block: Self::Input<'_>, state_hook: H, ) -> Result where H: OnStateHook + 'static, { - let BlockExecutionInput { block, total_difficulty } = input; - self.strategy.with_state_hook(Some(Box::new(state_hook))); - self.strategy.apply_pre_execution_changes(block, total_difficulty)?; - let ExecuteOutput { receipts, gas_used } = - self.strategy.execute_transactions(block, total_difficulty)?; - let requests = - self.strategy.apply_post_execution_changes(block, total_difficulty, &receipts)?; + self.strategy.apply_pre_execution_changes(block)?; + let ExecuteOutput { receipts, gas_used } = self.strategy.execute_transactions(block)?; + let requests = self.strategy.apply_post_execution_changes(block, &receipts)?; let state = self.strategy.finish(); @@ -447,23 +425,18 @@ where S: BlockExecutionStrategy, DB: Database + Display>, { - type Input<'a> = - BlockExecutionInput<'a, BlockWithSenders<::Block>>; + type Input<'a> = &'a BlockWithSenders<::Block>; type Output = ExecutionOutcome<::Receipt>; type Error = BlockExecutionError; - fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> { - let BlockExecutionInput { block, total_difficulty } = input; - + fn execute_and_verify_one(&mut self, block: Self::Input<'_>) -> Result<(), Self::Error> { if self.batch_record.first_block().is_none() { self.batch_record.set_first_block(block.header().number()); } - self.strategy.apply_pre_execution_changes(block, total_difficulty)?; - let ExecuteOutput { receipts, .. } = - self.strategy.execute_transactions(block, total_difficulty)?; - let requests = - self.strategy.apply_post_execution_changes(block, total_difficulty, &receipts)?; + self.strategy.apply_pre_execution_changes(block)?; + let ExecuteOutput { receipts, .. } = self.strategy.execute_transactions(block)?; + let requests = self.strategy.apply_post_execution_changes(block, &receipts)?; self.strategy.validate_block_post_execution(block, &receipts, &requests)?; @@ -575,7 +548,7 @@ mod tests { struct TestExecutor(PhantomData); impl Executor for TestExecutor { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = &'a BlockWithSenders; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -607,7 +580,7 @@ mod tests { } impl BatchExecutor for TestExecutor { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = &'a BlockWithSenders; type Output = ExecutionOutcome; type Error = BlockExecutionError; @@ -689,7 +662,6 @@ mod tests { fn apply_pre_execution_changes( &mut self, _block: &BlockWithSenders, - _total_difficulty: U256, ) -> Result<(), Self::Error> { Ok(()) } @@ -697,7 +669,6 @@ mod tests { fn execute_transactions( &mut self, _block: &BlockWithSenders, - _total_difficulty: U256, ) -> Result, Self::Error> { Ok(self.execute_transactions_result.clone()) } @@ -705,7 +676,6 @@ mod tests { fn apply_post_execution_changes( &mut self, _block: &BlockWithSenders, - _total_difficulty: U256, _receipts: &[Receipt], ) -> Result { Ok(self.apply_post_execution_changes_result.clone()) @@ -743,7 +713,7 @@ mod tests { let provider = TestExecutorProvider; let db = CacheDB::>::default(); let executor = provider.executor(db); - let _ = executor.execute(BlockExecutionInput::new(&Default::default(), U256::ZERO)); + let _ = executor.execute(&Default::default()); } #[test] @@ -766,7 +736,7 @@ mod tests { let provider = BasicBlockExecutorProvider::new(strategy_factory); let db = CacheDB::>::default(); let executor = provider.executor(db); - let result = executor.execute(BlockExecutionInput::new(&Default::default(), U256::ZERO)); + let result = executor.execute(&Default::default()); assert!(result.is_ok()); let block_execution_output = result.unwrap(); @@ -792,11 +762,10 @@ mod tests { // if we want to apply tx env overrides the executor must be mut. let mut executor = provider.executor(db); // execute consumes the executor, so we can only call it once. - // let result = executor.execute(BlockExecutionInput::new(&Default::default(), U256::ZERO)); executor.init(Box::new(|tx_env: &mut TxEnv| { tx_env.nonce.take(); })); - let result = executor.execute(BlockExecutionInput::new(&Default::default(), U256::ZERO)); + let result = executor.execute(&Default::default()); assert!(result.is_ok()); } diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 51d493295ac2..0c17b3acf712 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -145,9 +145,9 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { ); /// Returns a [`CfgEnvWithHandlerCfg`] for the given header. - fn cfg_env(&self, header: &Self::Header, total_difficulty: U256) -> CfgEnvWithHandlerCfg { + fn cfg_env(&self, header: &Self::Header) -> CfgEnvWithHandlerCfg { let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default()); - self.fill_cfg_env(&mut cfg, header, total_difficulty); + self.fill_cfg_env(&mut cfg, header); cfg } @@ -155,12 +155,7 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { /// /// This __must__ set the corresponding spec id in the handler cfg, based on timestamp or total /// difficulty - fn fill_cfg_env( - &self, - cfg_env: &mut CfgEnvWithHandlerCfg, - header: &Self::Header, - total_difficulty: U256, - ); + fn fill_cfg_env(&self, cfg_env: &mut CfgEnvWithHandlerCfg, header: &Self::Header); /// Fill [`BlockEnv`] field according to the chain spec and given header fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool) { @@ -184,10 +179,10 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { } /// Creates a new [`EvmEnv`] for the given header. - fn cfg_and_block_env(&self, header: &Self::Header, total_difficulty: U256) -> EvmEnv { + fn cfg_and_block_env(&self, header: &Self::Header) -> EvmEnv { let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default()); let mut block_env = BlockEnv::default(); - self.fill_cfg_and_block_env(&mut cfg, &mut block_env, header, total_difficulty); + self.fill_cfg_and_block_env(&mut cfg, &mut block_env, header); EvmEnv::new(cfg, block_env) } @@ -200,9 +195,8 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, header: &Self::Header, - total_difficulty: U256, ) { - self.fill_cfg_env(cfg, header, total_difficulty); + self.fill_cfg_env(cfg, header); let after_merge = cfg.handler_cfg.spec_id >= SpecId::MERGE; self.fill_block_env(block_env, header, after_merge); } diff --git a/crates/evm/src/metrics.rs b/crates/evm/src/metrics.rs index 1f21cb4d3a41..242ddfe5b79a 100644 --- a/crates/evm/src/metrics.rs +++ b/crates/evm/src/metrics.rs @@ -5,7 +5,7 @@ use crate::{execute::Executor, system_calls::OnStateHook}; use alloy_consensus::BlockHeader; use metrics::{Counter, Gauge, Histogram}; -use reth_execution_types::{BlockExecutionInput, BlockExecutionOutput}; +use reth_execution_types::BlockExecutionOutput; use reth_metrics::Metrics; use reth_primitives::BlockWithSenders; use revm_primitives::EvmState; @@ -97,13 +97,13 @@ impl ExecutorMetrics { pub fn execute_metered<'a, E, DB, O, Error, B>( &self, executor: E, - input: BlockExecutionInput<'a, BlockWithSenders>, + input: &'a BlockWithSenders, state_hook: Box, ) -> Result, Error> where E: Executor< DB, - Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, + Input<'a> = &'a BlockWithSenders, Output = BlockExecutionOutput, Error = Error, >, @@ -114,11 +114,8 @@ impl ExecutorMetrics { // be accessible. let wrapper = MeteredStateHook { metrics: self.clone(), inner_hook: state_hook }; - // Store reference to block for metered - let block = input.block; - // Use metered to execute and track timing/gas metrics - let output = self.metered(block, || executor.execute_with_state_hook(input, wrapper))?; + let output = self.metered(input, || executor.execute_with_state_hook(input, wrapper))?; // Update the metrics for the number of accounts, storage slots and bytecodes updated let accounts = output.state.state.len(); @@ -134,16 +131,12 @@ impl ExecutorMetrics { } /// Execute the given block and update metrics for the execution. - pub fn metered_one( - &self, - input: BlockExecutionInput<'_, BlockWithSenders>, - f: F, - ) -> R + pub fn metered_one(&self, input: &BlockWithSenders, f: F) -> R where - F: FnOnce(BlockExecutionInput<'_, BlockWithSenders>) -> R, + F: FnOnce(&BlockWithSenders) -> R, B: reth_primitives_traits::Block, { - self.metered(input.block, || f(input)) + self.metered(input, || f(input)) } } @@ -165,7 +158,7 @@ mod tests { impl Executor<()> for MockExecutor { type Input<'a> - = BlockExecutionInput<'a, BlockWithSenders> + = &'a BlockWithSenders where Self: 'a; type Output = BlockExecutionOutput<()>; @@ -236,11 +229,7 @@ mod tests { fn test_executor_metrics_hook_metrics_recorded() { let snapshotter = setup_test_recorder(); let metrics = ExecutorMetrics::default(); - - let input = BlockExecutionInput { - block: &BlockWithSenders::default(), - total_difficulty: Default::default(), - }; + let input = BlockWithSenders::default(); let (tx, _rx) = mpsc::channel(); let expected_output = 42; @@ -266,7 +255,7 @@ mod tests { state }; let executor = MockExecutor { state }; - let _result = metrics.execute_metered(executor, input, state_hook).unwrap(); + let _result = metrics.execute_metered(executor, &input, state_hook).unwrap(); let snapshot = snapshotter.snapshot().into_vec(); @@ -289,11 +278,7 @@ mod tests { #[test] fn test_executor_metrics_hook_called() { let metrics = ExecutorMetrics::default(); - - let input = BlockExecutionInput { - block: &BlockWithSenders::default(), - total_difficulty: Default::default(), - }; + let input = BlockWithSenders::default(); let (tx, rx) = mpsc::channel(); let expected_output = 42; @@ -302,7 +287,7 @@ mod tests { let state = EvmState::default(); let executor = MockExecutor { state }; - let _result = metrics.execute_metered(executor, input, state_hook).unwrap(); + let _result = metrics.execute_metered(executor, &input, state_hook).unwrap(); let actual_output = rx.try_recv().unwrap(); assert_eq!(actual_output, expected_output); diff --git a/crates/evm/src/noop.rs b/crates/evm/src/noop.rs index 816a4c835644..66041840ae77 100644 --- a/crates/evm/src/noop.rs +++ b/crates/evm/src/noop.rs @@ -3,7 +3,7 @@ use alloy_primitives::BlockNumber; use core::fmt::Display; use reth_execution_errors::BlockExecutionError; -use reth_execution_types::{BlockExecutionInput, BlockExecutionOutput, ExecutionOutcome}; +use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome}; use reth_primitives::{BlockWithSenders, NodePrimitives}; use reth_prune_types::PruneModes; use reth_storage_errors::provider::ProviderError; @@ -45,7 +45,7 @@ impl BlockExecutorProvider for NoopBlockExecutorProvider

{ } impl Executor for NoopBlockExecutorProvider

{ - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = &'a BlockWithSenders; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -77,7 +77,7 @@ impl Executor for NoopBlockExecutorProvider

{ } impl BatchExecutor for NoopBlockExecutorProvider

{ - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = &'a BlockWithSenders; type Output = ExecutionOutcome; type Error = BlockExecutionError; diff --git a/crates/evm/src/state_change.rs b/crates/evm/src/state_change.rs index 5104c466399b..af14705d1686 100644 --- a/crates/evm/src/state_change.rs +++ b/crates/evm/src/state_change.rs @@ -2,7 +2,7 @@ use alloy_consensus::BlockHeader; use alloy_eips::eip4895::Withdrawal; -use alloy_primitives::{map::HashMap, Address, U256}; +use alloy_primitives::{map::HashMap, Address}; use reth_chainspec::EthereumHardforks; use reth_consensus_common::calc; use reth_primitives_traits::BlockBody; @@ -15,7 +15,6 @@ use reth_primitives_traits::BlockBody; pub fn post_block_balance_increments( chain_spec: &ChainSpec, block: &Block, - total_difficulty: U256, ) -> HashMap where ChainSpec: EthereumHardforks, @@ -24,12 +23,7 @@ where let mut balance_increments = HashMap::default(); // Add block rewards if they are enabled. - if let Some(base_block_reward) = calc::base_block_reward( - chain_spec, - block.header().number(), - block.header().difficulty(), - total_difficulty, - ) { + if let Some(base_block_reward) = calc::base_block_reward(chain_spec, block.header().number()) { // Ommer rewards if let Some(ommers) = block.body().ommers() { for ommer in ommers { diff --git a/crates/evm/src/test_utils.rs b/crates/evm/src/test_utils.rs index 1fb9fd7075de..a3c230af1198 100644 --- a/crates/evm/src/test_utils.rs +++ b/crates/evm/src/test_utils.rs @@ -3,15 +3,15 @@ use crate::{ env::EvmEnv, execute::{ - BasicBatchExecutor, BasicBlockExecutor, BatchExecutor, BlockExecutionInput, - BlockExecutionOutput, BlockExecutionStrategy, BlockExecutorProvider, Executor, + BasicBatchExecutor, BasicBlockExecutor, BatchExecutor, BlockExecutionOutput, + BlockExecutionStrategy, BlockExecutorProvider, Executor, }, provider::EvmEnvProvider, system_calls::OnStateHook, ConfigureEvmEnv, }; use alloy_eips::eip7685::Requests; -use alloy_primitives::{BlockNumber, U256}; +use alloy_primitives::BlockNumber; use parking_lot::Mutex; use reth_execution_errors::BlockExecutionError; use reth_execution_types::ExecutionOutcome; @@ -33,7 +33,7 @@ impl EvmEnvProvider where EvmConfig: ConfigureEvmEnv

, { - Ok(evm_config.cfg_and_block_env(header, U256::MAX)) + Ok(evm_config.cfg_and_block_env(header)) } } @@ -73,7 +73,7 @@ impl BlockExecutorProvider for MockExecutorProvider { } impl Executor for MockExecutorProvider { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = &'a BlockWithSenders; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -115,7 +115,7 @@ impl Executor for MockExecutorProvider { } impl BatchExecutor for MockExecutorProvider { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = &'a BlockWithSenders; type Output = ExecutionOutcome; type Error = BlockExecutionError; diff --git a/crates/exex/exex/src/backfill/job.rs b/crates/exex/exex/src/backfill/job.rs index 0a2be83d6f61..0bd4ce5f2b7d 100644 --- a/crates/exex/exex/src/backfill/job.rs +++ b/crates/exex/exex/src/backfill/job.rs @@ -90,11 +90,6 @@ where // Fetch the block let fetch_block_start = Instant::now(); - let td = self - .provider - .header_td_by_number(block_number)? - .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))?; - // we need the block's transactions along with their hashes let block = self .provider @@ -116,7 +111,7 @@ where let (unsealed_header, hash) = block.header.split(); let block = P::Block::new(unsealed_header, block.body).with_senders_unchecked(senders); - executor.execute_and_verify_one((&block, td).into())?; + executor.execute_and_verify_one(&block)?; execution_duration += execute_start.elapsed(); // TODO(alexey): report gas metrics using `block.header.gas_used` @@ -199,11 +194,6 @@ where BlockWithSenders, BlockExecutionOutput<::Receipt>, )> { - let td = self - .provider - .header_td_by_number(block_number)? - .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))?; - // Fetch the block with senders for execution. let block_with_senders = self .provider @@ -217,7 +207,7 @@ where trace!(target: "exex::backfill", number = block_number, txs = block_with_senders.block.body().transactions().len(), "Executing block"); - let block_execution_output = executor.execute((&block_with_senders, td).into())?; + let block_execution_output = executor.execute(&block_with_senders)?; Ok((block_with_senders, block_execution_output)) } diff --git a/crates/exex/exex/src/backfill/test_utils.rs b/crates/exex/exex/src/backfill/test_utils.rs index 6d93314e22bd..eb7598377f2c 100644 --- a/crates/exex/exex/src/backfill/test_utils.rs +++ b/crates/exex/exex/src/backfill/test_utils.rs @@ -5,9 +5,7 @@ use alloy_genesis::{Genesis, GenesisAccount}; use alloy_primitives::{b256, Address, TxKind, U256}; use eyre::OptionExt; use reth_chainspec::{ChainSpec, ChainSpecBuilder, EthereumHardfork, MAINNET, MIN_TRANSACTION_GAS}; -use reth_evm::execute::{ - BatchExecutor, BlockExecutionInput, BlockExecutionOutput, BlockExecutorProvider, Executor, -}; +use reth_evm::execute::{BatchExecutor, BlockExecutionOutput, BlockExecutorProvider, Executor}; use reth_evm_ethereum::execute::EthExecutorProvider; use reth_node_api::FullNodePrimitives; use reth_primitives::{ @@ -71,7 +69,7 @@ where // Execute the block to produce a block execution output let mut block_execution_output = EthExecutorProvider::ethereum(chain_spec) .executor(StateProviderDatabase::new(LatestStateProviderRef::new(&provider))) - .execute(BlockExecutionInput { block, total_difficulty: U256::ZERO })?; + .execute(block)?; block_execution_output.state.reverts.sort(); // Convert the block execution output to an execution outcome for committing to the database @@ -206,10 +204,7 @@ where let executor = EthExecutorProvider::ethereum(chain_spec) .batch_executor(StateProviderDatabase::new(LatestStateProviderRef::new(&provider))); - let mut execution_outcome = executor.execute_and_verify_batch(vec![ - (&block1, U256::ZERO).into(), - (&block2, U256::ZERO).into(), - ])?; + let mut execution_outcome = executor.execute_and_verify_batch(vec![&block1, &block2])?; execution_outcome.state_mut().reverts.sort(); let block1 = block1.seal_slow(); diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index 8e40e1f272e4..5dc4aa930790 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -355,21 +355,15 @@ impl From for OpChainSpec { .filter_map(|(hardfork, opt)| opt.map(|block| (hardfork, ForkCondition::Block(block)))) .collect::>(); - // Paris - let paris_block_and_final_difficulty = - if let Some(ttd) = genesis.config.terminal_total_difficulty { - block_hardforks.push(( - EthereumHardfork::Paris.boxed(), - ForkCondition::TTD { - total_difficulty: ttd, - fork_block: genesis.config.merge_netsplit_block, - }, - )); - - genesis.config.merge_netsplit_block.map(|block| (block, ttd)) - } else { - None - }; + // We set the paris hardfork for OP networks to zero + block_hardforks.push(( + EthereumHardfork::Paris.boxed(), + ForkCondition::TTD { + activation_block_number: 0, + total_difficulty: U256::ZERO, + fork_block: genesis.config.merge_netsplit_block, + }, + )); // Time-based hardforks let time_hardfork_opts = [ @@ -413,7 +407,9 @@ impl From for OpChainSpec { chain: genesis.config.chain_id.into(), genesis, hardforks: ChainHardforks::new(ordered_hardforks), - paris_block_and_final_difficulty, + // We assume no OP network merges, and set the paris block and total difficulty to + // zero + paris_block_and_final_difficulty: Some((0, U256::ZERO)), base_fee_params: optimism_genesis_info.base_fee_params, ..Default::default() }, @@ -1006,10 +1002,10 @@ mod tests { // OpHardfork::Isthmus.boxed(), ]; - assert!(expected_hardforks - .iter() - .zip(hardforks.iter()) - .all(|(expected, actual)| &**expected == *actual)); + for (expected, actual) in expected_hardforks.iter().zip(hardforks.iter()) { + println!("got {expected:?}, {actual:?}"); + assert_eq!(&**expected, &**actual); + } assert_eq!(expected_hardforks.len(), hardforks.len()); } diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index ae16d3f99239..8cc4a2c35525 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -25,7 +25,7 @@ use reth_optimism_forks::OpHardfork; use reth_optimism_primitives::OpPrimitives; use reth_primitives::{BlockWithSenders, Receipt, TransactionSigned, TxType}; use reth_revm::{Database, State}; -use revm_primitives::{db::DatabaseCommit, EnvWithHandlerCfg, ResultAndState, U256}; +use revm_primitives::{db::DatabaseCommit, EnvWithHandlerCfg, ResultAndState}; use tracing::trace; /// Factory for [`OpExecutionStrategy`]. @@ -111,8 +111,8 @@ where /// Configures a new evm configuration and block environment for the given block. /// /// Caution: this does not initialize the tx environment. - fn evm_env_for_block(&self, header: &Header, total_difficulty: U256) -> EnvWithHandlerCfg { - let evm_env = self.evm_config.cfg_and_block_env(header, total_difficulty); + fn evm_env_for_block(&self, header: &Header) -> EnvWithHandlerCfg { + let evm_env = self.evm_config.cfg_and_block_env(header); let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; EnvWithHandlerCfg::new_with_cfg_env(cfg_env_with_handler_cfg, block_env, Default::default()) } @@ -131,17 +131,13 @@ where self.tx_env_overrides = Some(tx_env_overrides); } - fn apply_pre_execution_changes( - &mut self, - block: &BlockWithSenders, - total_difficulty: U256, - ) -> Result<(), Self::Error> { + fn apply_pre_execution_changes(&mut self, block: &BlockWithSenders) -> Result<(), Self::Error> { // Set state clear flag if the block is after the Spurious Dragon hardfork. let state_clear_flag = (*self.chain_spec).is_spurious_dragon_active_at_block(block.header.number); self.state.set_state_clear_flag(state_clear_flag); - let env = self.evm_env_for_block(&block.header, total_difficulty); + let env = self.evm_env_for_block(&block.header); let mut evm = self.evm_config.evm_with_env(&mut self.state, env); self.system_caller.apply_beacon_root_contract_call( @@ -164,9 +160,8 @@ where fn execute_transactions( &mut self, block: &BlockWithSenders, - total_difficulty: U256, ) -> Result, Self::Error> { - let env = self.evm_env_for_block(&block.header, total_difficulty); + let env = self.evm_env_for_block(&block.header); let mut evm = self.evm_config.evm_with_env(&mut self.state, env); let is_regolith = @@ -260,11 +255,10 @@ where fn apply_post_execution_changes( &mut self, block: &BlockWithSenders, - total_difficulty: U256, _receipts: &[Receipt], ) -> Result { let balance_increments = - post_block_balance_increments(&self.chain_spec.clone(), &block.block, total_difficulty); + post_block_balance_increments(&self.chain_spec.clone(), &block.block); // increment balances self.state .increment_balances(balance_increments.clone()) @@ -317,7 +311,7 @@ mod tests { use crate::OpChainSpec; use alloy_consensus::TxEip1559; use alloy_primitives::{ - b256, Address, PrimitiveSignature as Signature, StorageKey, StorageValue, + b256, Address, PrimitiveSignature as Signature, StorageKey, StorageValue, U256, }; use op_alloy_consensus::TxDeposit; use reth_chainspec::MIN_TRANSACTION_GAS; @@ -417,22 +411,13 @@ mod tests { // Attempt to execute a block with one deposit and one non-deposit transaction executor - .execute_and_verify_one( - ( - &BlockWithSenders { - block: Block { - header, - body: BlockBody { - transactions: vec![tx, tx_deposit], - ..Default::default() - }, - }, - senders: vec![addr, addr], - }, - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders { + block: Block { + header, + body: BlockBody { transactions: vec![tx, tx_deposit], ..Default::default() }, + }, + senders: vec![addr, addr], + }) .unwrap(); let receipts = executor.receipts(); @@ -501,22 +486,13 @@ mod tests { // attempt to execute an empty block with parent beacon block root, this should not fail executor - .execute_and_verify_one( - ( - &BlockWithSenders { - block: Block { - header, - body: BlockBody { - transactions: vec![tx, tx_deposit], - ..Default::default() - }, - }, - senders: vec![addr, addr], - }, - U256::ZERO, - ) - .into(), - ) + .execute_and_verify_one(&BlockWithSenders { + block: Block { + header, + body: BlockBody { transactions: vec![tx, tx_deposit], ..Default::default() }, + }, + senders: vec![addr, addr], + }) .expect("Executing a block while canyon is active should not fail"); let receipts = executor.receipts(); diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index ec5d2ce00560..9bfa5fd8634f 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -110,19 +110,16 @@ impl ConfigureEvmEnv for OpEvmConfig { env.block.basefee = U256::ZERO; } - fn fill_cfg_env( - &self, - cfg_env: &mut CfgEnvWithHandlerCfg, - header: &Self::Header, - total_difficulty: U256, - ) { + fn fill_cfg_env(&self, cfg_env: &mut CfgEnvWithHandlerCfg, header: &Self::Header) { let spec_id = revm_spec( self.chain_spec(), &Head { number: header.number, timestamp: header.timestamp, difficulty: header.difficulty, - total_difficulty, + // NOTE: this does not matter within revm_spec as it uses paris hardfork block + // activation + total_difficulty: U256::MIN, hash: Default::default(), }, ); @@ -246,14 +243,11 @@ mod tests { .shanghai_activated() .build(); - // Define the total difficulty as zero (default) - let total_difficulty = U256::ZERO; - // Use the `OpEvmConfig` to create the `cfg_env` and `block_env` based on the ChainSpec, // Header, and total difficulty let EvmEnv { cfg_env_with_handler_cfg, .. } = OpEvmConfig::new(Arc::new(OpChainSpec { inner: chain_spec.clone() })) - .cfg_and_block_env(&header, total_difficulty); + .cfg_and_block_env(&header); // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the // ChainSpec diff --git a/crates/optimism/hardforks/src/dev.rs b/crates/optimism/hardforks/src/dev.rs index 6dcd28c46c9e..33877301c7d4 100644 --- a/crates/optimism/hardforks/src/dev.rs +++ b/crates/optimism/hardforks/src/dev.rs @@ -23,7 +23,11 @@ pub static DEV_HARDFORKS: LazyLock = LazyLock::new(|| { (EthereumHardfork::London.boxed(), ForkCondition::Block(0)), ( EthereumHardfork::Paris.boxed(), - ForkCondition::TTD { fork_block: None, total_difficulty: U256::ZERO }, + ForkCondition::TTD { + activation_block_number: 0, + fork_block: None, + total_difficulty: U256::ZERO, + }, ), (crate::OpHardfork::Bedrock.boxed(), ForkCondition::Block(0)), (crate::OpHardfork::Regolith.boxed(), ForkCondition::Timestamp(0)), diff --git a/crates/optimism/hardforks/src/hardfork.rs b/crates/optimism/hardforks/src/hardfork.rs index db886415beb4..75d294c9b3e5 100644 --- a/crates/optimism/hardforks/src/hardfork.rs +++ b/crates/optimism/hardforks/src/hardfork.rs @@ -220,7 +220,11 @@ impl OpHardfork { (EthereumHardfork::GrayGlacier.boxed(), ForkCondition::Block(105235063)), ( EthereumHardfork::Paris.boxed(), - ForkCondition::TTD { fork_block: Some(105235063), total_difficulty: U256::ZERO }, + ForkCondition::TTD { + activation_block_number: 105235063, + fork_block: Some(105235063), + total_difficulty: U256::ZERO, + }, ), (Self::Bedrock.boxed(), ForkCondition::Block(105235063)), (Self::Regolith.boxed(), ForkCondition::Timestamp(0)), @@ -252,7 +256,11 @@ impl OpHardfork { (EthereumHardfork::GrayGlacier.boxed(), ForkCondition::Block(0)), ( EthereumHardfork::Paris.boxed(), - ForkCondition::TTD { fork_block: Some(0), total_difficulty: U256::ZERO }, + ForkCondition::TTD { + activation_block_number: 0, + fork_block: Some(0), + total_difficulty: U256::ZERO, + }, ), (Self::Bedrock.boxed(), ForkCondition::Block(0)), (Self::Regolith.boxed(), ForkCondition::Timestamp(0)), @@ -284,7 +292,11 @@ impl OpHardfork { (EthereumHardfork::GrayGlacier.boxed(), ForkCondition::Block(0)), ( EthereumHardfork::Paris.boxed(), - ForkCondition::TTD { fork_block: Some(0), total_difficulty: U256::ZERO }, + ForkCondition::TTD { + activation_block_number: 0, + fork_block: Some(0), + total_difficulty: U256::ZERO, + }, ), (Self::Bedrock.boxed(), ForkCondition::Block(0)), (Self::Regolith.boxed(), ForkCondition::Timestamp(0)), @@ -316,7 +328,11 @@ impl OpHardfork { (EthereumHardfork::GrayGlacier.boxed(), ForkCondition::Block(0)), ( EthereumHardfork::Paris.boxed(), - ForkCondition::TTD { fork_block: Some(0), total_difficulty: U256::ZERO }, + ForkCondition::TTD { + activation_block_number: 0, + fork_block: Some(0), + total_difficulty: U256::ZERO, + }, ), (Self::Bedrock.boxed(), ForkCondition::Block(0)), (Self::Regolith.boxed(), ForkCondition::Timestamp(0)), diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 5a431699b33a..eab9afb4327b 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -641,12 +641,9 @@ where let mut witness_record = ExecutionWitnessRecord::default(); let _ = block_executor - .execute_with_state_closure( - (&(*block).clone().unseal(), block.difficulty()).into(), - |statedb: &State<_>| { - witness_record.record_executed_state(statedb); - }, - ) + .execute_with_state_closure(&(*block).clone().unseal(), |statedb: &State<_>| { + witness_record.record_executed_state(statedb); + }) .map_err(|err| EthApiError::Internal(err.into()))?; let ExecutionWitnessRecord { hashed_state, codes, keys } = witness_record; diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 834bfe245297..b98cfce62382 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -14,13 +14,11 @@ use alloy_rpc_types_trace::{ }; use async_trait::async_trait; use jsonrpsee::core::RpcResult; -use reth_chainspec::EthereumHardforks; -use reth_consensus_common::calc::{ - base_block_reward, base_block_reward_pre_merge, block_reward, ommer_reward, -}; +use reth_chainspec::{EthChainSpec, EthereumHardfork, MAINNET, SEPOLIA}; +use reth_consensus_common::calc::{base_block_reward_pre_merge, block_reward, ommer_reward}; use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_primitives_traits::{BlockBody, BlockHeader}; -use reth_provider::{BlockNumReader, BlockReader, ChainSpecProvider, HeaderProvider}; +use reth_provider::{BlockNumReader, BlockReader, ChainSpecProvider}; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::TraceApiServer; use reth_rpc_eth_api::{helpers::TraceExt, FromEthApiError, RpcNodeCore}; @@ -313,9 +311,7 @@ where // add reward traces for all blocks for block in &blocks { - if let Some(base_block_reward) = - self.calculate_base_block_reward(block.header.header())? - { + if let Some(base_block_reward) = self.calculate_base_block_reward(block.header())? { all_traces.extend( self.extract_reward_traces( block.header.header(), @@ -509,30 +505,19 @@ where header: &H, ) -> Result, Eth::Error> { let chain_spec = self.provider().chain_spec(); - let is_paris_activated = chain_spec.is_paris_active_at_block(header.number()); - - Ok(match is_paris_activated { - Some(true) => None, - Some(false) => Some(base_block_reward_pre_merge(&chain_spec, header.number())), - None => { - // if Paris hardfork is unknown, we need to fetch the total difficulty at the - // block's height and check if it is pre-merge to calculate the base block reward - if let Some(header_td) = self - .provider() - .header_td_by_number(header.number()) - .map_err(Eth::Error::from_eth_err)? - { - base_block_reward( - chain_spec.as_ref(), - header.number(), - header.difficulty(), - header_td, - ) - } else { - None - } - } - }) + let is_paris_activated = if chain_spec.chain() == MAINNET.chain() { + Some(header.number()) >= EthereumHardfork::Paris.mainnet_activation_block() + } else if chain_spec.chain() == SEPOLIA.chain() { + Some(header.number()) >= EthereumHardfork::Paris.sepolia_activation_block() + } else { + true + }; + + if is_paris_activated { + return Ok(None) + } + + Ok(Some(base_block_reward_pre_merge(&chain_spec, header.number()))) } /// Extracts the reward traces for the given block: diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index 04f12570aeff..0d2c09927c20 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -19,9 +19,7 @@ use reth_errors::{BlockExecutionError, ConsensusError, ProviderError}; use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_primitives::{GotExpected, NodePrimitives, SealedBlockWithSenders, SealedHeader}; use reth_primitives_traits::{constants::GAS_LIMIT_BOUND_DIVISOR, Block as _, BlockBody}; -use reth_provider::{ - BlockExecutionInput, BlockExecutionOutput, BlockReaderIdExt, StateProviderFactory, -}; +use reth_provider::{BlockExecutionOutput, BlockReaderIdExt, StateProviderFactory}; use reth_revm::{cached::CachedReads, database::StateProviderDatabase}; use reth_rpc_api::BlockSubmissionValidationApiServer; use reth_rpc_server_types::result::internal_rpc_err; @@ -152,18 +150,15 @@ where let block = block.unseal(); let mut accessed_blacklisted = None; - let output = executor.execute_with_state_closure( - BlockExecutionInput::new(&block, U256::MAX), - |state| { - if !self.disallow.is_empty() { - for account in state.cache.accounts.keys() { - if self.disallow.contains(account) { - accessed_blacklisted = Some(*account); - } + let output = executor.execute_with_state_closure(&block, |state| { + if !self.disallow.is_empty() { + for account in state.cache.accounts.keys() { + if self.disallow.contains(account) { + accessed_blacklisted = Some(*account); } } - }, - )?; + } + })?; // update the cached reads self.update_cached_reads(latest_header_hash, request_cache).await; diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index 444874e8e4a2..e2d2addf7d74 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -337,10 +337,6 @@ where // Fetch the block let fetch_block_start = Instant::now(); - let td = provider - .header_td_by_number(block_number)? - .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))?; - // we need the block's transactions but we don't need the transaction hashes let block = provider .block_with_senders(block_number.into(), TransactionVariant::NoHash)? @@ -356,7 +352,7 @@ where // Execute the block let execute_start = Instant::now(); - self.metrics.metered_one((&block, td).into(), |input| { + self.metrics.metered_one(&block, |input| { executor.execute_and_verify_one(input).map_err(|error| { let header = block.header(); StageError::Block { diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index 8d26ff0a9015..03e9ce0da01d 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -1241,10 +1241,7 @@ impl EvmEnvProvider> for ConsistentProvider where EvmConfig: ConfigureEvmEnv
>, { - let total_difficulty = self - .header_td_by_number(header.number())? - .ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?; - Ok(evm_config.cfg_and_block_env(header, total_difficulty)) + Ok(evm_config.cfg_and_block_env(header)) } } diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 05dbe2832ea9..4b5cccfc9f92 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -1651,10 +1651,7 @@ impl EvmEnvProvider> where EvmConfig: ConfigureEvmEnv
>, { - let total_difficulty = self - .header_td_by_number(header.number())? - .ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?; - Ok(evm_config.cfg_and_block_env(header, total_difficulty)) + Ok(evm_config.cfg_and_block_env(header)) } } diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 6ee83b9c7ee2..99cc6fa29c77 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -716,7 +716,7 @@ impl EvmEnvProvider for MockEthProvider { where EvmConfig: ConfigureEvmEnv
, { - Ok(evm_config.cfg_and_block_env(header, U256::MAX)) + Ok(evm_config.cfg_and_block_env(header)) } } diff --git a/examples/custom-beacon-withdrawals/src/main.rs b/examples/custom-beacon-withdrawals/src/main.rs index c4b8676bd0c3..f484b082be7a 100644 --- a/examples/custom-beacon-withdrawals/src/main.rs +++ b/examples/custom-beacon-withdrawals/src/main.rs @@ -129,12 +129,8 @@ where /// # Caution /// /// This does not initialize the tx environment. - fn evm_env_for_block( - &self, - header: &alloy_consensus::Header, - total_difficulty: U256, - ) -> EnvWithHandlerCfg { - let evm_env = self.evm_config.cfg_and_block_env(header, total_difficulty); + fn evm_env_for_block(&self, header: &alloy_consensus::Header) -> EnvWithHandlerCfg { + let evm_env = self.evm_config.cfg_and_block_env(header); let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; EnvWithHandlerCfg::new_with_cfg_env(cfg_env_with_handler_cfg, block_env, Default::default()) } @@ -148,11 +144,7 @@ where type Primitives = EthPrimitives; type Error = BlockExecutionError; - fn apply_pre_execution_changes( - &mut self, - block: &BlockWithSenders, - _total_difficulty: U256, - ) -> Result<(), Self::Error> { + fn apply_pre_execution_changes(&mut self, block: &BlockWithSenders) -> Result<(), Self::Error> { // Set state clear flag if the block is after the Spurious Dragon hardfork. let state_clear_flag = (*self.chain_spec).is_spurious_dragon_active_at_block(block.header.number); @@ -164,7 +156,6 @@ where fn execute_transactions( &mut self, _block: &BlockWithSenders, - _total_difficulty: U256, ) -> Result, Self::Error> { Ok(ExecuteOutput { receipts: vec![], gas_used: 0 }) } @@ -172,10 +163,9 @@ where fn apply_post_execution_changes( &mut self, block: &BlockWithSenders, - total_difficulty: U256, _receipts: &[Receipt], ) -> Result { - let env = self.evm_env_for_block(&block.header, total_difficulty); + let env = self.evm_env_for_block(&block.header); let mut evm = self.evm_config.evm_with_env(&mut self.state, env); if let Some(withdrawals) = block.body.withdrawals.as_ref() { diff --git a/examples/custom-evm/src/main.rs b/examples/custom-evm/src/main.rs index d45b6f1ba0a3..4d2fea296e62 100644 --- a/examples/custom-evm/src/main.rs +++ b/examples/custom-evm/src/main.rs @@ -4,7 +4,7 @@ use alloy_consensus::Header; use alloy_genesis::Genesis; -use alloy_primitives::{address, Address, Bytes, U256}; +use alloy_primitives::{address, Address, Bytes}; use reth::{ builder::{ components::{ExecutorBuilder, PayloadServiceBuilder}, @@ -103,13 +103,8 @@ impl ConfigureEvmEnv for MyEvmConfig { self.inner.fill_tx_env_system_contract_call(env, caller, contract, data); } - fn fill_cfg_env( - &self, - cfg_env: &mut CfgEnvWithHandlerCfg, - header: &Self::Header, - total_difficulty: U256, - ) { - self.inner.fill_cfg_env(cfg_env, header, total_difficulty); + fn fill_cfg_env(&self, cfg_env: &mut CfgEnvWithHandlerCfg, header: &Self::Header) { + self.inner.fill_cfg_env(cfg_env, header); } fn next_cfg_and_block_env( diff --git a/examples/stateful-precompile/src/main.rs b/examples/stateful-precompile/src/main.rs index 4b463f6ad317..e02a28a4a319 100644 --- a/examples/stateful-precompile/src/main.rs +++ b/examples/stateful-precompile/src/main.rs @@ -4,7 +4,7 @@ use alloy_consensus::Header; use alloy_genesis::Genesis; -use alloy_primitives::{Address, Bytes, U256}; +use alloy_primitives::{Address, Bytes}; use parking_lot::RwLock; use reth::{ api::NextBlockEnvAttributes, @@ -165,13 +165,8 @@ impl ConfigureEvmEnv for MyEvmConfig { self.inner.fill_tx_env_system_contract_call(env, caller, contract, data) } - fn fill_cfg_env( - &self, - cfg_env: &mut CfgEnvWithHandlerCfg, - header: &Self::Header, - total_difficulty: U256, - ) { - self.inner.fill_cfg_env(cfg_env, header, total_difficulty) + fn fill_cfg_env(&self, cfg_env: &mut CfgEnvWithHandlerCfg, header: &Self::Header) { + self.inner.fill_cfg_env(cfg_env, header) } fn next_cfg_and_block_env(