From d8e6d01308b6234fdbf3e4d447c9a10e6702df02 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Thu, 27 Jun 2024 21:11:29 +0200 Subject: [PATCH] chore: move `revm_spec` methods from `reth-primitives` to chain specific crates (#9152) --- Cargo.lock | 4 + crates/ethereum/engine-primitives/Cargo.toml | 1 + .../ethereum/engine-primitives/src/payload.rs | 5 +- crates/ethereum/evm/Cargo.toml | 1 + .../src/revm => ethereum/evm/src}/config.rs | 169 +++++------------- crates/ethereum/evm/src/lib.rs | 31 +++- crates/evm/src/lib.rs | 29 +-- crates/optimism/evm/Cargo.toml | 1 + crates/optimism/evm/src/config.rs | 133 ++++++++++++++ crates/optimism/evm/src/lib.rs | 6 +- crates/optimism/payload/src/payload.rs | 4 +- crates/primitives/src/revm/mod.rs | 3 - examples/custom-evm/Cargo.toml | 1 + examples/custom-evm/src/main.rs | 33 +++- 14 files changed, 256 insertions(+), 165 deletions(-) rename crates/{primitives/src/revm => ethereum/evm/src}/config.rs (54%) create mode 100644 crates/optimism/evm/src/config.rs diff --git a/Cargo.lock b/Cargo.lock index f4c97a3dad..063d3a26c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2778,6 +2778,7 @@ dependencies = [ "eyre", "reth", "reth-chainspec", + "reth-evm-ethereum", "reth-node-api", "reth-node-core", "reth-node-ethereum", @@ -7065,6 +7066,7 @@ dependencies = [ "alloy-rlp", "reth-chainspec", "reth-engine-primitives", + "reth-evm-ethereum", "reth-payload-primitives", "reth-primitives", "reth-rpc-types", @@ -7147,6 +7149,7 @@ dependencies = [ "alloy-sol-types", "reth-chainspec", "reth-ethereum-consensus", + "reth-ethereum-forks", "reth-evm", "reth-execution-types", "reth-primitives", @@ -7164,6 +7167,7 @@ version = "1.0.0" dependencies = [ "reth-chainspec", "reth-consensus-common", + "reth-ethereum-forks", "reth-evm", "reth-execution-errors", "reth-execution-types", diff --git a/crates/ethereum/engine-primitives/Cargo.toml b/crates/ethereum/engine-primitives/Cargo.toml index 231c7f640b..8a1f258089 100644 --- a/crates/ethereum/engine-primitives/Cargo.toml +++ b/crates/ethereum/engine-primitives/Cargo.toml @@ -13,6 +13,7 @@ workspace = true [dependencies] # reth reth-chainspec.workspace = true +reth-evm-ethereum.workspace = true reth-primitives.workspace = true reth-engine-primitives.workspace = true reth-payload-primitives.workspace = true diff --git a/crates/ethereum/engine-primitives/src/payload.rs b/crates/ethereum/engine-primitives/src/payload.rs index 7a4129963c..f9fde7028e 100644 --- a/crates/ethereum/engine-primitives/src/payload.rs +++ b/crates/ethereum/engine-primitives/src/payload.rs @@ -2,10 +2,11 @@ use alloy_rlp::Encodable; use reth_chainspec::ChainSpec; +use reth_evm_ethereum::revm_spec_by_timestamp_after_merge; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; use reth_primitives::{ - constants::EIP1559_INITIAL_BASE_FEE, revm::config::revm_spec_by_timestamp_after_merge, Address, - BlobTransactionSidecar, EthereumHardfork, Header, SealedBlock, Withdrawals, B256, U256, + constants::EIP1559_INITIAL_BASE_FEE, Address, BlobTransactionSidecar, EthereumHardfork, Header, + SealedBlock, Withdrawals, B256, U256, }; use reth_rpc_types::engine::{ ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadEnvelopeV4, diff --git a/crates/ethereum/evm/Cargo.toml b/crates/ethereum/evm/Cargo.toml index 1d996e5d39..7ea2e4b587 100644 --- a/crates/ethereum/evm/Cargo.toml +++ b/crates/ethereum/evm/Cargo.toml @@ -13,6 +13,7 @@ workspace = true [dependencies] # Reth reth-chainspec.workspace = true +reth-ethereum-forks.workspace = true reth-evm.workspace = true reth-primitives.workspace = true reth-revm.workspace = true diff --git a/crates/primitives/src/revm/config.rs b/crates/ethereum/evm/src/config.rs similarity index 54% rename from crates/primitives/src/revm/config.rs rename to crates/ethereum/evm/src/config.rs index 9ed2650926..77082b1f7d 100644 --- a/crates/primitives/src/revm/config.rs +++ b/crates/ethereum/evm/src/config.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "optimism")] -use reth_chainspec::OptimismHardfork; use reth_chainspec::{ChainSpec, EthereumHardforks}; use reth_ethereum_forks::{EthereumHardfork, Head}; @@ -11,21 +9,6 @@ pub fn revm_spec_by_timestamp_after_merge( chain_spec: &ChainSpec, timestamp: u64, ) -> revm_primitives::SpecId { - #[cfg(feature = "optimism")] - if chain_spec.is_optimism() { - return if chain_spec.fork(OptimismHardfork::Fjord).active_at_timestamp(timestamp) { - revm_primitives::FJORD - } else if chain_spec.fork(OptimismHardfork::Ecotone).active_at_timestamp(timestamp) { - revm_primitives::ECOTONE - } else if chain_spec.fork(OptimismHardfork::Canyon).active_at_timestamp(timestamp) { - revm_primitives::CANYON - } else if chain_spec.fork(OptimismHardfork::Regolith).active_at_timestamp(timestamp) { - revm_primitives::REGOLITH - } else { - revm_primitives::BEDROCK - } - } - if chain_spec.is_prague_active_at_timestamp(timestamp) { revm_primitives::PRAGUE } else if chain_spec.is_cancun_active_at_timestamp(timestamp) { @@ -38,47 +21,32 @@ pub fn revm_spec_by_timestamp_after_merge( } /// return `revm_spec` from spec configuration. -pub fn revm_spec(chain_spec: &ChainSpec, block: Head) -> revm_primitives::SpecId { - #[cfg(feature = "optimism")] - if chain_spec.is_optimism() { - if chain_spec.fork(OptimismHardfork::Fjord).active_at_head(&block) { - return revm_primitives::FJORD - } else if chain_spec.fork(OptimismHardfork::Ecotone).active_at_head(&block) { - return revm_primitives::ECOTONE - } else if chain_spec.fork(OptimismHardfork::Canyon).active_at_head(&block) { - return revm_primitives::CANYON - } else if chain_spec.fork(OptimismHardfork::Regolith).active_at_head(&block) { - return revm_primitives::REGOLITH - } else if chain_spec.fork(OptimismHardfork::Bedrock).active_at_head(&block) { - return revm_primitives::BEDROCK - } - } - - if chain_spec.fork(EthereumHardfork::Prague).active_at_head(&block) { +pub fn revm_spec(chain_spec: &ChainSpec, block: &Head) -> revm_primitives::SpecId { + if chain_spec.fork(EthereumHardfork::Prague).active_at_head(block) { revm_primitives::PRAGUE - } else if chain_spec.fork(EthereumHardfork::Cancun).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::Cancun).active_at_head(block) { revm_primitives::CANCUN - } else if chain_spec.fork(EthereumHardfork::Shanghai).active_at_head(&block) { + } 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.fork(EthereumHardfork::Paris).active_at_head(block) { revm_primitives::MERGE - } else if chain_spec.fork(EthereumHardfork::London).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::London).active_at_head(block) { revm_primitives::LONDON - } else if chain_spec.fork(EthereumHardfork::Berlin).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::Berlin).active_at_head(block) { revm_primitives::BERLIN - } else if chain_spec.fork(EthereumHardfork::Istanbul).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::Istanbul).active_at_head(block) { revm_primitives::ISTANBUL - } else if chain_spec.fork(EthereumHardfork::Petersburg).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::Petersburg).active_at_head(block) { revm_primitives::PETERSBURG - } else if chain_spec.fork(EthereumHardfork::Byzantium).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::Byzantium).active_at_head(block) { revm_primitives::BYZANTIUM - } else if chain_spec.fork(EthereumHardfork::SpuriousDragon).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::SpuriousDragon).active_at_head(block) { revm_primitives::SPURIOUS_DRAGON - } else if chain_spec.fork(EthereumHardfork::Tangerine).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::Tangerine).active_at_head(block) { revm_primitives::TANGERINE - } else if chain_spec.fork(EthereumHardfork::Homestead).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::Homestead).active_at_head(block) { revm_primitives::HOMESTEAD - } else if chain_spec.fork(EthereumHardfork::Frontier).active_at_head(&block) { + } else if chain_spec.fork(EthereumHardfork::Frontier).active_at_head(block) { revm_primitives::FRONTIER } else { panic!( @@ -114,137 +82,84 @@ mod tests { revm_spec_by_timestamp_after_merge(&ChainSpecBuilder::mainnet().build(), 0), revm_primitives::MERGE ); - #[cfg(feature = "optimism")] - { - #[inline(always)] - fn op_cs(f: impl FnOnce(ChainSpecBuilder) -> ChainSpecBuilder) -> ChainSpec { - let cs = ChainSpecBuilder::mainnet().chain(reth_chainspec::Chain::from_id(10)); - f(cs).build() - } - assert_eq!( - revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.fjord_activated()), 0), - revm_primitives::FJORD - ); - assert_eq!( - revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.ecotone_activated()), 0), - revm_primitives::ECOTONE - ); - assert_eq!( - revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.canyon_activated()), 0), - revm_primitives::CANYON - ); - assert_eq!( - revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.bedrock_activated()), 0), - revm_primitives::BEDROCK - ); - assert_eq!( - revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.regolith_activated()), 0), - revm_primitives::REGOLITH - ); - } } #[test] fn test_to_revm_spec() { assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().cancun_activated().build(), Head::default()), + revm_spec(&ChainSpecBuilder::mainnet().cancun_activated().build(), &Head::default()), revm_primitives::CANCUN ); assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().shanghai_activated().build(), Head::default()), + revm_spec(&ChainSpecBuilder::mainnet().shanghai_activated().build(), &Head::default()), revm_primitives::SHANGHAI ); assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), Head::default()), + revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), &Head::default()), revm_primitives::MERGE ); assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), Head::default()), + revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), &Head::default()), revm_primitives::LONDON ); assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), Head::default()), + revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), &Head::default()), revm_primitives::BERLIN ); assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().istanbul_activated().build(), Head::default()), + revm_spec(&ChainSpecBuilder::mainnet().istanbul_activated().build(), &Head::default()), revm_primitives::ISTANBUL ); assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().petersburg_activated().build(), Head::default()), + revm_spec( + &ChainSpecBuilder::mainnet().petersburg_activated().build(), + &Head::default() + ), revm_primitives::PETERSBURG ); assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().byzantium_activated().build(), Head::default()), + revm_spec(&ChainSpecBuilder::mainnet().byzantium_activated().build(), &Head::default()), revm_primitives::BYZANTIUM ); assert_eq!( revm_spec( &ChainSpecBuilder::mainnet().spurious_dragon_activated().build(), - Head::default() + &Head::default() ), revm_primitives::SPURIOUS_DRAGON ); assert_eq!( revm_spec( &ChainSpecBuilder::mainnet().tangerine_whistle_activated().build(), - Head::default() + &Head::default() ), revm_primitives::TANGERINE ); assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().homestead_activated().build(), Head::default()), + revm_spec(&ChainSpecBuilder::mainnet().homestead_activated().build(), &Head::default()), revm_primitives::HOMESTEAD ); assert_eq!( - revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), Head::default()), + revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), &Head::default()), revm_primitives::FRONTIER ); - #[cfg(feature = "optimism")] - { - #[inline(always)] - fn op_cs(f: impl FnOnce(ChainSpecBuilder) -> ChainSpecBuilder) -> ChainSpec { - let cs = ChainSpecBuilder::mainnet().chain(reth_chainspec::Chain::from_id(10)); - f(cs).build() - } - assert_eq!( - revm_spec(&op_cs(|cs| cs.fjord_activated()), Head::default()), - revm_primitives::FJORD - ); - assert_eq!( - revm_spec(&op_cs(|cs| cs.ecotone_activated()), Head::default()), - revm_primitives::ECOTONE - ); - assert_eq!( - revm_spec(&op_cs(|cs| cs.canyon_activated()), Head::default()), - revm_primitives::CANYON - ); - assert_eq!( - revm_spec(&op_cs(|cs| cs.bedrock_activated()), Head::default()), - revm_primitives::BEDROCK - ); - assert_eq!( - revm_spec(&op_cs(|cs| cs.regolith_activated()), Head::default()), - revm_primitives::REGOLITH - ); - } } #[test] fn test_eth_spec() { assert_eq!( - revm_spec(&MAINNET, Head { timestamp: 1710338135, ..Default::default() }), + revm_spec(&MAINNET, &Head { timestamp: 1710338135, ..Default::default() }), revm_primitives::CANCUN ); assert_eq!( - revm_spec(&MAINNET, Head { timestamp: 1681338455, ..Default::default() }), + revm_spec(&MAINNET, &Head { timestamp: 1681338455, ..Default::default() }), revm_primitives::SHANGHAI ); assert_eq!( revm_spec( &MAINNET, - Head { + &Head { total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128), difficulty: U256::from(10_u128), ..Default::default() @@ -256,7 +171,7 @@ mod tests { assert_eq!( revm_spec( &MAINNET, - Head { + &Head { number: 15537394 - 10, total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128), difficulty: U256::from(10_u128), @@ -266,39 +181,39 @@ mod tests { revm_primitives::MERGE ); assert_eq!( - revm_spec(&MAINNET, Head { number: 15537394 - 10, ..Default::default() }), + revm_spec(&MAINNET, &Head { number: 15537394 - 10, ..Default::default() }), revm_primitives::LONDON ); assert_eq!( - revm_spec(&MAINNET, Head { number: 12244000 + 10, ..Default::default() }), + revm_spec(&MAINNET, &Head { number: 12244000 + 10, ..Default::default() }), revm_primitives::BERLIN ); assert_eq!( - revm_spec(&MAINNET, Head { number: 12244000 - 10, ..Default::default() }), + revm_spec(&MAINNET, &Head { number: 12244000 - 10, ..Default::default() }), revm_primitives::ISTANBUL ); assert_eq!( - revm_spec(&MAINNET, Head { number: 7280000 + 10, ..Default::default() }), + revm_spec(&MAINNET, &Head { number: 7280000 + 10, ..Default::default() }), revm_primitives::PETERSBURG ); assert_eq!( - revm_spec(&MAINNET, Head { number: 7280000 - 10, ..Default::default() }), + revm_spec(&MAINNET, &Head { number: 7280000 - 10, ..Default::default() }), revm_primitives::BYZANTIUM ); assert_eq!( - revm_spec(&MAINNET, Head { number: 2675000 + 10, ..Default::default() }), + revm_spec(&MAINNET, &Head { number: 2675000 + 10, ..Default::default() }), revm_primitives::SPURIOUS_DRAGON ); assert_eq!( - revm_spec(&MAINNET, Head { number: 2675000 - 10, ..Default::default() }), + revm_spec(&MAINNET, &Head { number: 2675000 - 10, ..Default::default() }), revm_primitives::TANGERINE ); assert_eq!( - revm_spec(&MAINNET, Head { number: 1150000 + 10, ..Default::default() }), + revm_spec(&MAINNET, &Head { number: 1150000 + 10, ..Default::default() }), revm_primitives::HOMESTEAD ); assert_eq!( - revm_spec(&MAINNET, Head { number: 1150000 - 10, ..Default::default() }), + revm_spec(&MAINNET, &Head { number: 1150000 - 10, ..Default::default() }), revm_primitives::FRONTIER ); } diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index 73d8a8111b..17c0c7370b 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -12,8 +12,14 @@ #[cfg(not(feature = "std"))] extern crate alloc; +use reth_chainspec::{ChainSpec, Head}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; +use reth_primitives::{Header, U256}; use reth_revm::{Database, EvmBuilder}; +use revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg}; + +mod config; +pub use config::{revm_spec, revm_spec_by_timestamp_after_merge}; pub mod execute; @@ -28,7 +34,30 @@ pub mod eip6110; #[non_exhaustive] pub struct EthEvmConfig; -impl ConfigureEvmEnv for EthEvmConfig {} +impl ConfigureEvmEnv for EthEvmConfig { + fn fill_cfg_env( + cfg_env: &mut CfgEnvWithHandlerCfg, + chain_spec: &ChainSpec, + header: &Header, + total_difficulty: U256, + ) { + let spec_id = config::revm_spec( + chain_spec, + &Head { + number: header.number, + timestamp: header.timestamp, + difficulty: header.difficulty, + total_difficulty, + hash: Default::default(), + }, + ); + + cfg_env.chain_id = chain_spec.chain().id(); + cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse; + + cfg_env.handler_cfg.spec_id = spec_id; + } +} impl ConfigureEvm for EthEvmConfig { type DefaultExternalContext<'a> = (); diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index dd16aa0d04..f86219eec7 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -14,16 +14,11 @@ extern crate alloc; use reth_chainspec::ChainSpec; use reth_primitives::{ - revm::{ - config::revm_spec, - env::{fill_block_env, fill_tx_env}, - }, - Address, Head, Header, TransactionSigned, U256, + revm::env::{fill_block_env, fill_tx_env}, + Address, Header, TransactionSigned, U256, }; use revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector}; -use revm_primitives::{ - AnalysisKind, BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, SpecId, TxEnv, -}; +use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, SpecId, TxEnv}; pub mod either; pub mod execute; @@ -122,23 +117,7 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { chain_spec: &ChainSpec, header: &Header, total_difficulty: U256, - ) { - let spec_id = revm_spec( - chain_spec, - Head { - number: header.number, - timestamp: header.timestamp, - difficulty: header.difficulty, - total_difficulty, - hash: Default::default(), - }, - ); - - cfg_env.chain_id = chain_spec.chain().id(); - cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse; - - cfg_env.handler_cfg.spec_id = spec_id; - } + ); /// Convenience function to call both [`fill_cfg_env`](ConfigureEvmEnv::fill_cfg_env) and /// [`fill_block_env`]. diff --git a/crates/optimism/evm/Cargo.toml b/crates/optimism/evm/Cargo.toml index 47c8cedee2..f53293edee 100644 --- a/crates/optimism/evm/Cargo.toml +++ b/crates/optimism/evm/Cargo.toml @@ -13,6 +13,7 @@ workspace = true [dependencies] # Reth reth-chainspec.workspace = true +reth-ethereum-forks.workspace = true reth-evm.workspace = true reth-primitives.workspace = true reth-revm.workspace = true diff --git a/crates/optimism/evm/src/config.rs b/crates/optimism/evm/src/config.rs new file mode 100644 index 0000000000..1cdc917eac --- /dev/null +++ b/crates/optimism/evm/src/config.rs @@ -0,0 +1,133 @@ +use reth_chainspec::{ChainSpec, OptimismHardfork}; +use reth_ethereum_forks::{EthereumHardfork, Head}; + +/// Returns the spec id at the given timestamp. +/// +/// Note: This is only intended to be used after the merge, when hardforks are activated by +/// timestamp. +pub fn revm_spec_by_timestamp_after_bedrock( + chain_spec: &ChainSpec, + timestamp: u64, +) -> revm_primitives::SpecId { + if chain_spec.fork(OptimismHardfork::Fjord).active_at_timestamp(timestamp) { + revm_primitives::FJORD + } else if chain_spec.fork(OptimismHardfork::Ecotone).active_at_timestamp(timestamp) { + revm_primitives::ECOTONE + } else if chain_spec.fork(OptimismHardfork::Canyon).active_at_timestamp(timestamp) { + revm_primitives::CANYON + } else if chain_spec.fork(OptimismHardfork::Regolith).active_at_timestamp(timestamp) { + revm_primitives::REGOLITH + } else { + revm_primitives::BEDROCK + } +} + +/// return `revm_spec` from spec configuration. +pub fn revm_spec(chain_spec: &ChainSpec, block: &Head) -> revm_primitives::SpecId { + if chain_spec.fork(OptimismHardfork::Fjord).active_at_head(block) { + revm_primitives::FJORD + } else if chain_spec.fork(OptimismHardfork::Ecotone).active_at_head(block) { + revm_primitives::ECOTONE + } else if chain_spec.fork(OptimismHardfork::Canyon).active_at_head(block) { + revm_primitives::CANYON + } else if chain_spec.fork(OptimismHardfork::Regolith).active_at_head(block) { + revm_primitives::REGOLITH + } else if chain_spec.fork(OptimismHardfork::Bedrock).active_at_head(block) { + revm_primitives::BEDROCK + } else if chain_spec.fork(EthereumHardfork::Prague).active_at_head(block) { + revm_primitives::PRAGUE + } else if chain_spec.fork(EthereumHardfork::Cancun).active_at_head(block) { + 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) { + revm_primitives::MERGE + } else if chain_spec.fork(EthereumHardfork::London).active_at_head(block) { + revm_primitives::LONDON + } else if chain_spec.fork(EthereumHardfork::Berlin).active_at_head(block) { + revm_primitives::BERLIN + } else if chain_spec.fork(EthereumHardfork::Istanbul).active_at_head(block) { + revm_primitives::ISTANBUL + } else if chain_spec.fork(EthereumHardfork::Petersburg).active_at_head(block) { + revm_primitives::PETERSBURG + } else if chain_spec.fork(EthereumHardfork::Byzantium).active_at_head(block) { + revm_primitives::BYZANTIUM + } else if chain_spec.fork(EthereumHardfork::SpuriousDragon).active_at_head(block) { + revm_primitives::SPURIOUS_DRAGON + } else if chain_spec.fork(EthereumHardfork::Tangerine).active_at_head(block) { + revm_primitives::TANGERINE + } else if chain_spec.fork(EthereumHardfork::Homestead).active_at_head(block) { + revm_primitives::HOMESTEAD + } else if chain_spec.fork(EthereumHardfork::Frontier).active_at_head(block) { + revm_primitives::FRONTIER + } else { + panic!( + "invalid hardfork chainspec: expected at least one hardfork, got {:?}", + chain_spec.hardforks + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use reth_chainspec::ChainSpecBuilder; + + #[test] + fn test_revm_spec_by_timestamp_after_merge() { + #[inline(always)] + fn op_cs(f: impl FnOnce(ChainSpecBuilder) -> ChainSpecBuilder) -> ChainSpec { + let cs = ChainSpecBuilder::mainnet().chain(reth_chainspec::Chain::from_id(10)); + f(cs).build() + } + assert_eq!( + revm_spec_by_timestamp_after_bedrock(&op_cs(|cs| cs.fjord_activated()), 0), + revm_primitives::FJORD + ); + assert_eq!( + revm_spec_by_timestamp_after_bedrock(&op_cs(|cs| cs.ecotone_activated()), 0), + revm_primitives::ECOTONE + ); + assert_eq!( + revm_spec_by_timestamp_after_bedrock(&op_cs(|cs| cs.canyon_activated()), 0), + revm_primitives::CANYON + ); + assert_eq!( + revm_spec_by_timestamp_after_bedrock(&op_cs(|cs| cs.bedrock_activated()), 0), + revm_primitives::BEDROCK + ); + assert_eq!( + revm_spec_by_timestamp_after_bedrock(&op_cs(|cs| cs.regolith_activated()), 0), + revm_primitives::REGOLITH + ); + } + + #[test] + fn test_to_revm_spec() { + #[inline(always)] + fn op_cs(f: impl FnOnce(ChainSpecBuilder) -> ChainSpecBuilder) -> ChainSpec { + let cs = ChainSpecBuilder::mainnet().chain(reth_chainspec::Chain::from_id(10)); + f(cs).build() + } + assert_eq!( + revm_spec(&op_cs(|cs| cs.fjord_activated()), &Head::default()), + revm_primitives::FJORD + ); + assert_eq!( + revm_spec(&op_cs(|cs| cs.ecotone_activated()), &Head::default()), + revm_primitives::ECOTONE + ); + assert_eq!( + revm_spec(&op_cs(|cs| cs.canyon_activated()), &Head::default()), + revm_primitives::CANYON + ); + assert_eq!( + revm_spec(&op_cs(|cs| cs.bedrock_activated()), &Head::default()), + revm_primitives::BEDROCK + ); + assert_eq!( + revm_spec(&op_cs(|cs| cs.regolith_activated()), &Head::default()), + revm_primitives::REGOLITH + ); + } +} diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index 68aabf452c..5dff8d5de3 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -12,12 +12,14 @@ use reth_chainspec::ChainSpec; use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; use reth_primitives::{ - revm::{config::revm_spec, env::fill_op_tx_env}, + revm::env::fill_op_tx_env, revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, Address, Head, Header, TransactionSigned, U256, }; use reth_revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector}; +mod config; +pub use config::{revm_spec, revm_spec_by_timestamp_after_bedrock}; mod execute; pub use execute::*; pub mod l1; @@ -46,7 +48,7 @@ impl ConfigureEvmEnv for OptimismEvmConfig { ) { let spec_id = revm_spec( chain_spec, - Head { + &Head { number: header.number, timestamp: header.timestamp, difficulty: header.difficulty, diff --git a/crates/optimism/payload/src/payload.rs b/crates/optimism/payload/src/payload.rs index 1cdc1f6c4d..47db0d571e 100644 --- a/crates/optimism/payload/src/payload.rs +++ b/crates/optimism/payload/src/payload.rs @@ -4,10 +4,10 @@ use alloy_rlp::Encodable; use reth_chainspec::{ChainSpec, EthereumHardforks}; +use reth_evm_optimism::revm_spec_by_timestamp_after_bedrock; use reth_payload_builder::EthPayloadBuilderAttributes; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; use reth_primitives::{ - revm::config::revm_spec_by_timestamp_after_merge, revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}, Address, BlobTransactionSidecar, Header, SealedBlock, TransactionSigned, Withdrawals, B256, U256, @@ -113,7 +113,7 @@ impl PayloadBuilderAttributes for OptimismPayloadBuilderAttributes { let cfg = CfgEnv::default().with_chain_id(chain_spec.chain().id()); // ensure we're not missing any timestamp based hardforks - let spec_id = revm_spec_by_timestamp_after_merge(chain_spec, self.timestamp()); + let spec_id = revm_spec_by_timestamp_after_bedrock(chain_spec, self.timestamp()); // if the parent block did not have excess blob gas (i.e. it was pre-cancun), but it is // cancun now, we need to set the excess blob gas to the default value diff --git a/crates/primitives/src/revm/mod.rs b/crates/primitives/src/revm/mod.rs index 9937a209b9..40fc719c95 100644 --- a/crates/primitives/src/revm/mod.rs +++ b/crates/primitives/src/revm/mod.rs @@ -1,8 +1,5 @@ //! Helpers for working with revm. -/// Reth block execution/validation configuration and constants -pub mod config; - /// The `env` module provides utility methods for filling revm transaction and block environments. /// /// It includes functions to fill transaction and block environments with relevant data, prepare diff --git a/examples/custom-evm/Cargo.toml b/examples/custom-evm/Cargo.toml index 5822bcb227..a85b6ce8aa 100644 --- a/examples/custom-evm/Cargo.toml +++ b/examples/custom-evm/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true [dependencies] reth.workspace = true reth-chainspec.workspace = true +reth-evm-ethereum.workspace = true reth-node-api.workspace = true reth-node-core.workspace = true reth-primitives.workspace = true diff --git a/examples/custom-evm/src/main.rs b/examples/custom-evm/src/main.rs index 638a2dc172..968f0beff1 100644 --- a/examples/custom-evm/src/main.rs +++ b/examples/custom-evm/src/main.rs @@ -2,6 +2,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] +use alloy_genesis::Genesis; use reth::{ builder::{components::ExecutorBuilder, BuilderContext, NodeBuilder}, primitives::{ @@ -17,11 +18,14 @@ use reth::{ }, tasks::TaskManager, }; -use reth_chainspec::{Chain, ChainSpec}; +use reth_chainspec::{Chain, ChainSpec, Head}; use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes}; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_ethereum::{EthExecutorProvider, EthereumNode}; -use reth_primitives::Genesis; +use reth_primitives::{ + revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg}, + Header, U256, +}; use reth_tracing::{RethTracer, Tracer}; use std::sync::Arc; @@ -61,7 +65,30 @@ impl MyEvmConfig { } } -impl ConfigureEvmEnv for MyEvmConfig {} +impl ConfigureEvmEnv for MyEvmConfig { + fn fill_cfg_env( + cfg_env: &mut CfgEnvWithHandlerCfg, + chain_spec: &ChainSpec, + header: &Header, + total_difficulty: U256, + ) { + let spec_id = reth_evm_ethereum::revm_spec( + chain_spec, + &Head { + number: header.number, + timestamp: header.timestamp, + difficulty: header.difficulty, + total_difficulty, + hash: Default::default(), + }, + ); + + cfg_env.chain_id = chain_spec.chain().id(); + cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse; + + cfg_env.handler_cfg.spec_id = spec_id; + } +} impl ConfigureEvm for MyEvmConfig { type DefaultExternalContext<'a> = ();