chore: move revm_spec methods from reth-primitives to chain specific crates (#9152)

This commit is contained in:
joshieDo
2024-06-27 21:11:29 +02:00
committed by GitHub
parent 9fd2cf027f
commit d8e6d01308
14 changed files with 256 additions and 165 deletions

4
Cargo.lock generated
View File

@ -2778,6 +2778,7 @@ dependencies = [
"eyre", "eyre",
"reth", "reth",
"reth-chainspec", "reth-chainspec",
"reth-evm-ethereum",
"reth-node-api", "reth-node-api",
"reth-node-core", "reth-node-core",
"reth-node-ethereum", "reth-node-ethereum",
@ -7065,6 +7066,7 @@ dependencies = [
"alloy-rlp", "alloy-rlp",
"reth-chainspec", "reth-chainspec",
"reth-engine-primitives", "reth-engine-primitives",
"reth-evm-ethereum",
"reth-payload-primitives", "reth-payload-primitives",
"reth-primitives", "reth-primitives",
"reth-rpc-types", "reth-rpc-types",
@ -7147,6 +7149,7 @@ dependencies = [
"alloy-sol-types", "alloy-sol-types",
"reth-chainspec", "reth-chainspec",
"reth-ethereum-consensus", "reth-ethereum-consensus",
"reth-ethereum-forks",
"reth-evm", "reth-evm",
"reth-execution-types", "reth-execution-types",
"reth-primitives", "reth-primitives",
@ -7164,6 +7167,7 @@ version = "1.0.0"
dependencies = [ dependencies = [
"reth-chainspec", "reth-chainspec",
"reth-consensus-common", "reth-consensus-common",
"reth-ethereum-forks",
"reth-evm", "reth-evm",
"reth-execution-errors", "reth-execution-errors",
"reth-execution-types", "reth-execution-types",

View File

@ -13,6 +13,7 @@ workspace = true
[dependencies] [dependencies]
# reth # reth
reth-chainspec.workspace = true reth-chainspec.workspace = true
reth-evm-ethereum.workspace = true
reth-primitives.workspace = true reth-primitives.workspace = true
reth-engine-primitives.workspace = true reth-engine-primitives.workspace = true
reth-payload-primitives.workspace = true reth-payload-primitives.workspace = true

View File

@ -2,10 +2,11 @@
use alloy_rlp::Encodable; use alloy_rlp::Encodable;
use reth_chainspec::ChainSpec; use reth_chainspec::ChainSpec;
use reth_evm_ethereum::revm_spec_by_timestamp_after_merge;
use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes};
use reth_primitives::{ use reth_primitives::{
constants::EIP1559_INITIAL_BASE_FEE, revm::config::revm_spec_by_timestamp_after_merge, Address, constants::EIP1559_INITIAL_BASE_FEE, Address, BlobTransactionSidecar, EthereumHardfork, Header,
BlobTransactionSidecar, EthereumHardfork, Header, SealedBlock, Withdrawals, B256, U256, SealedBlock, Withdrawals, B256, U256,
}; };
use reth_rpc_types::engine::{ use reth_rpc_types::engine::{
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadEnvelopeV4, ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadEnvelopeV4,

View File

@ -13,6 +13,7 @@ workspace = true
[dependencies] [dependencies]
# Reth # Reth
reth-chainspec.workspace = true reth-chainspec.workspace = true
reth-ethereum-forks.workspace = true
reth-evm.workspace = true reth-evm.workspace = true
reth-primitives.workspace = true reth-primitives.workspace = true
reth-revm.workspace = true reth-revm.workspace = true

View File

@ -1,5 +1,3 @@
#[cfg(feature = "optimism")]
use reth_chainspec::OptimismHardfork;
use reth_chainspec::{ChainSpec, EthereumHardforks}; use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_ethereum_forks::{EthereumHardfork, Head}; use reth_ethereum_forks::{EthereumHardfork, Head};
@ -11,21 +9,6 @@ pub fn revm_spec_by_timestamp_after_merge(
chain_spec: &ChainSpec, chain_spec: &ChainSpec,
timestamp: u64, timestamp: u64,
) -> revm_primitives::SpecId { ) -> 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) { if chain_spec.is_prague_active_at_timestamp(timestamp) {
revm_primitives::PRAGUE revm_primitives::PRAGUE
} else if chain_spec.is_cancun_active_at_timestamp(timestamp) { } 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. /// return `revm_spec` from spec configuration.
pub fn revm_spec(chain_spec: &ChainSpec, block: Head) -> revm_primitives::SpecId { pub fn revm_spec(chain_spec: &ChainSpec, block: &Head) -> revm_primitives::SpecId {
#[cfg(feature = "optimism")] if chain_spec.fork(EthereumHardfork::Prague).active_at_head(block) {
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) {
revm_primitives::PRAGUE 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 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 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 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 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 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 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 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 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 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 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 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 revm_primitives::FRONTIER
} else { } else {
panic!( panic!(
@ -114,137 +82,84 @@ mod tests {
revm_spec_by_timestamp_after_merge(&ChainSpecBuilder::mainnet().build(), 0), revm_spec_by_timestamp_after_merge(&ChainSpecBuilder::mainnet().build(), 0),
revm_primitives::MERGE 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] #[test]
fn test_to_revm_spec() { fn test_to_revm_spec() {
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().cancun_activated().build(), Head::default()), revm_spec(&ChainSpecBuilder::mainnet().cancun_activated().build(), &Head::default()),
revm_primitives::CANCUN revm_primitives::CANCUN
); );
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().shanghai_activated().build(), Head::default()), revm_spec(&ChainSpecBuilder::mainnet().shanghai_activated().build(), &Head::default()),
revm_primitives::SHANGHAI revm_primitives::SHANGHAI
); );
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), Head::default()), revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), &Head::default()),
revm_primitives::MERGE revm_primitives::MERGE
); );
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), Head::default()), revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), &Head::default()),
revm_primitives::LONDON revm_primitives::LONDON
); );
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), Head::default()), revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), &Head::default()),
revm_primitives::BERLIN revm_primitives::BERLIN
); );
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().istanbul_activated().build(), Head::default()), revm_spec(&ChainSpecBuilder::mainnet().istanbul_activated().build(), &Head::default()),
revm_primitives::ISTANBUL revm_primitives::ISTANBUL
); );
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().petersburg_activated().build(), Head::default()), revm_spec(
&ChainSpecBuilder::mainnet().petersburg_activated().build(),
&Head::default()
),
revm_primitives::PETERSBURG revm_primitives::PETERSBURG
); );
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().byzantium_activated().build(), Head::default()), revm_spec(&ChainSpecBuilder::mainnet().byzantium_activated().build(), &Head::default()),
revm_primitives::BYZANTIUM revm_primitives::BYZANTIUM
); );
assert_eq!( assert_eq!(
revm_spec( revm_spec(
&ChainSpecBuilder::mainnet().spurious_dragon_activated().build(), &ChainSpecBuilder::mainnet().spurious_dragon_activated().build(),
Head::default() &Head::default()
), ),
revm_primitives::SPURIOUS_DRAGON revm_primitives::SPURIOUS_DRAGON
); );
assert_eq!( assert_eq!(
revm_spec( revm_spec(
&ChainSpecBuilder::mainnet().tangerine_whistle_activated().build(), &ChainSpecBuilder::mainnet().tangerine_whistle_activated().build(),
Head::default() &Head::default()
), ),
revm_primitives::TANGERINE revm_primitives::TANGERINE
); );
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().homestead_activated().build(), Head::default()), revm_spec(&ChainSpecBuilder::mainnet().homestead_activated().build(), &Head::default()),
revm_primitives::HOMESTEAD revm_primitives::HOMESTEAD
); );
assert_eq!( assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), Head::default()), revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), &Head::default()),
revm_primitives::FRONTIER 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] #[test]
fn test_eth_spec() { fn test_eth_spec() {
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { timestamp: 1710338135, ..Default::default() }), revm_spec(&MAINNET, &Head { timestamp: 1710338135, ..Default::default() }),
revm_primitives::CANCUN revm_primitives::CANCUN
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { timestamp: 1681338455, ..Default::default() }), revm_spec(&MAINNET, &Head { timestamp: 1681338455, ..Default::default() }),
revm_primitives::SHANGHAI revm_primitives::SHANGHAI
); );
assert_eq!( assert_eq!(
revm_spec( revm_spec(
&MAINNET, &MAINNET,
Head { &Head {
total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128), total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128),
difficulty: U256::from(10_u128), difficulty: U256::from(10_u128),
..Default::default() ..Default::default()
@ -256,7 +171,7 @@ mod tests {
assert_eq!( assert_eq!(
revm_spec( revm_spec(
&MAINNET, &MAINNET,
Head { &Head {
number: 15537394 - 10, number: 15537394 - 10,
total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128), total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128),
difficulty: U256::from(10_u128), difficulty: U256::from(10_u128),
@ -266,39 +181,39 @@ mod tests {
revm_primitives::MERGE revm_primitives::MERGE
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { number: 15537394 - 10, ..Default::default() }), revm_spec(&MAINNET, &Head { number: 15537394 - 10, ..Default::default() }),
revm_primitives::LONDON revm_primitives::LONDON
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { number: 12244000 + 10, ..Default::default() }), revm_spec(&MAINNET, &Head { number: 12244000 + 10, ..Default::default() }),
revm_primitives::BERLIN revm_primitives::BERLIN
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { number: 12244000 - 10, ..Default::default() }), revm_spec(&MAINNET, &Head { number: 12244000 - 10, ..Default::default() }),
revm_primitives::ISTANBUL revm_primitives::ISTANBUL
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { number: 7280000 + 10, ..Default::default() }), revm_spec(&MAINNET, &Head { number: 7280000 + 10, ..Default::default() }),
revm_primitives::PETERSBURG revm_primitives::PETERSBURG
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { number: 7280000 - 10, ..Default::default() }), revm_spec(&MAINNET, &Head { number: 7280000 - 10, ..Default::default() }),
revm_primitives::BYZANTIUM revm_primitives::BYZANTIUM
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { number: 2675000 + 10, ..Default::default() }), revm_spec(&MAINNET, &Head { number: 2675000 + 10, ..Default::default() }),
revm_primitives::SPURIOUS_DRAGON revm_primitives::SPURIOUS_DRAGON
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { number: 2675000 - 10, ..Default::default() }), revm_spec(&MAINNET, &Head { number: 2675000 - 10, ..Default::default() }),
revm_primitives::TANGERINE revm_primitives::TANGERINE
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { number: 1150000 + 10, ..Default::default() }), revm_spec(&MAINNET, &Head { number: 1150000 + 10, ..Default::default() }),
revm_primitives::HOMESTEAD revm_primitives::HOMESTEAD
); );
assert_eq!( assert_eq!(
revm_spec(&MAINNET, Head { number: 1150000 - 10, ..Default::default() }), revm_spec(&MAINNET, &Head { number: 1150000 - 10, ..Default::default() }),
revm_primitives::FRONTIER revm_primitives::FRONTIER
); );
} }

View File

@ -12,8 +12,14 @@
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
extern crate alloc; extern crate alloc;
use reth_chainspec::{ChainSpec, Head};
use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv};
use reth_primitives::{Header, U256};
use reth_revm::{Database, EvmBuilder}; 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; pub mod execute;
@ -28,7 +34,30 @@ pub mod eip6110;
#[non_exhaustive] #[non_exhaustive]
pub struct EthEvmConfig; 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 { impl ConfigureEvm for EthEvmConfig {
type DefaultExternalContext<'a> = (); type DefaultExternalContext<'a> = ();

View File

@ -14,16 +14,11 @@ extern crate alloc;
use reth_chainspec::ChainSpec; use reth_chainspec::ChainSpec;
use reth_primitives::{ use reth_primitives::{
revm::{ revm::env::{fill_block_env, fill_tx_env},
config::revm_spec, Address, Header, TransactionSigned, U256,
env::{fill_block_env, fill_tx_env},
},
Address, Head, Header, TransactionSigned, U256,
}; };
use revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector}; use revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector};
use revm_primitives::{ use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, SpecId, TxEnv};
AnalysisKind, BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, SpecId, TxEnv,
};
pub mod either; pub mod either;
pub mod execute; pub mod execute;
@ -122,23 +117,7 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
chain_spec: &ChainSpec, chain_spec: &ChainSpec,
header: &Header, header: &Header,
total_difficulty: U256, 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 /// Convenience function to call both [`fill_cfg_env`](ConfigureEvmEnv::fill_cfg_env) and
/// [`fill_block_env`]. /// [`fill_block_env`].

View File

@ -13,6 +13,7 @@ workspace = true
[dependencies] [dependencies]
# Reth # Reth
reth-chainspec.workspace = true reth-chainspec.workspace = true
reth-ethereum-forks.workspace = true
reth-evm.workspace = true reth-evm.workspace = true
reth-primitives.workspace = true reth-primitives.workspace = true
reth-revm.workspace = true reth-revm.workspace = true

View File

@ -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
);
}
}

View File

@ -12,12 +12,14 @@
use reth_chainspec::ChainSpec; use reth_chainspec::ChainSpec;
use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv};
use reth_primitives::{ use reth_primitives::{
revm::{config::revm_spec, env::fill_op_tx_env}, revm::env::fill_op_tx_env,
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
Address, Head, Header, TransactionSigned, U256, Address, Head, Header, TransactionSigned, U256,
}; };
use reth_revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector}; 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; mod execute;
pub use execute::*; pub use execute::*;
pub mod l1; pub mod l1;
@ -46,7 +48,7 @@ impl ConfigureEvmEnv for OptimismEvmConfig {
) { ) {
let spec_id = revm_spec( let spec_id = revm_spec(
chain_spec, chain_spec,
Head { &Head {
number: header.number, number: header.number,
timestamp: header.timestamp, timestamp: header.timestamp,
difficulty: header.difficulty, difficulty: header.difficulty,

View File

@ -4,10 +4,10 @@
use alloy_rlp::Encodable; use alloy_rlp::Encodable;
use reth_chainspec::{ChainSpec, EthereumHardforks}; use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_evm_optimism::revm_spec_by_timestamp_after_bedrock;
use reth_payload_builder::EthPayloadBuilderAttributes; use reth_payload_builder::EthPayloadBuilderAttributes;
use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes};
use reth_primitives::{ use reth_primitives::{
revm::config::revm_spec_by_timestamp_after_merge,
revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}, revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId},
Address, BlobTransactionSidecar, Header, SealedBlock, TransactionSigned, Withdrawals, B256, Address, BlobTransactionSidecar, Header, SealedBlock, TransactionSigned, Withdrawals, B256,
U256, U256,
@ -113,7 +113,7 @@ impl PayloadBuilderAttributes for OptimismPayloadBuilderAttributes {
let cfg = CfgEnv::default().with_chain_id(chain_spec.chain().id()); let cfg = CfgEnv::default().with_chain_id(chain_spec.chain().id());
// ensure we're not missing any timestamp based hardforks // 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 // 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 // cancun now, we need to set the excess blob gas to the default value

View File

@ -1,8 +1,5 @@
//! Helpers for working with revm. //! 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. /// 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 /// It includes functions to fill transaction and block environments with relevant data, prepare

View File

@ -8,6 +8,7 @@ license.workspace = true
[dependencies] [dependencies]
reth.workspace = true reth.workspace = true
reth-chainspec.workspace = true reth-chainspec.workspace = true
reth-evm-ethereum.workspace = true
reth-node-api.workspace = true reth-node-api.workspace = true
reth-node-core.workspace = true reth-node-core.workspace = true
reth-primitives.workspace = true reth-primitives.workspace = true

View File

@ -2,6 +2,7 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
use alloy_genesis::Genesis;
use reth::{ use reth::{
builder::{components::ExecutorBuilder, BuilderContext, NodeBuilder}, builder::{components::ExecutorBuilder, BuilderContext, NodeBuilder},
primitives::{ primitives::{
@ -17,11 +18,14 @@ use reth::{
}, },
tasks::TaskManager, tasks::TaskManager,
}; };
use reth_chainspec::{Chain, ChainSpec}; use reth_chainspec::{Chain, ChainSpec, Head};
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes}; use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes};
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
use reth_node_ethereum::{EthExecutorProvider, EthereumNode}; 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 reth_tracing::{RethTracer, Tracer};
use std::sync::Arc; 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 { impl ConfigureEvm for MyEvmConfig {
type DefaultExternalContext<'a> = (); type DefaultExternalContext<'a> = ();