chore: simplify revm specId mapping (#13553)

This commit is contained in:
Matthias Seitz
2024-12-27 12:14:10 +01:00
committed by GitHub
parent 6049b6eb0a
commit d644900a80
6 changed files with 148 additions and 162 deletions

View File

@ -1,56 +1,86 @@
use alloy_consensus::Header;
use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_ethereum_forks::{EthereumHardfork, Head};
use reth_ethereum_forks::EthereumHardfork;
/// Returns the revm [`SpecId`](revm_primitives::SpecId) 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_merge(
chain_spec: &ChainSpec,
timestamp: u64,
) -> revm_primitives::SpecId {
if chain_spec.is_osaka_active_at_timestamp(timestamp) {
revm_primitives::OSAKA
} else if chain_spec.is_prague_active_at_timestamp(timestamp) {
revm_primitives::PRAGUE
} else if chain_spec.is_cancun_active_at_timestamp(timestamp) {
revm_primitives::CANCUN
} else if chain_spec.is_shanghai_active_at_timestamp(timestamp) {
revm_primitives::SHANGHAI
} else {
revm_primitives::MERGE
}
/// Map the latest active hardfork at the given header to a revm
/// [`SpecId`](revm_primitives::SpecId).
pub fn revm_spec(chain_spec: &ChainSpec, header: &Header) -> revm_primitives::SpecId {
revm_spec_by_timestamp_and_block_number(chain_spec, header.timestamp, header.number)
}
/// Map the latest active hardfork at the given block to a revm [`SpecId`](revm_primitives::SpecId).
pub fn revm_spec(chain_spec: &ChainSpec, block: &Head) -> revm_primitives::SpecId {
if chain_spec.fork(EthereumHardfork::Prague).active_at_head(block) {
/// Map the latest active hardfork at the given timestamp or block number to a revm
/// [`SpecId`](revm_primitives::SpecId).
pub fn revm_spec_by_timestamp_and_block_number(
chain_spec: &ChainSpec,
timestamp: u64,
block_number: u64,
) -> revm_primitives::SpecId {
if chain_spec
.fork(EthereumHardfork::Osaka)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::OSAKA
} else if chain_spec
.fork(EthereumHardfork::Prague)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::PRAGUE
} else if chain_spec.fork(EthereumHardfork::Cancun).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::Cancun)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::CANCUN
} else if chain_spec.fork(EthereumHardfork::Shanghai).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::Shanghai)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::SHANGHAI
} else if chain_spec.is_paris_active_at_block(block.number).is_some_and(|active| active) {
} 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) {
} else if chain_spec
.fork(EthereumHardfork::London)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::LONDON
} else if chain_spec.fork(EthereumHardfork::Berlin).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::Berlin)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::BERLIN
} else if chain_spec.fork(EthereumHardfork::Istanbul).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::Istanbul)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::ISTANBUL
} else if chain_spec.fork(EthereumHardfork::Petersburg).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::Petersburg)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::PETERSBURG
} else if chain_spec.fork(EthereumHardfork::Byzantium).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::Byzantium)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::BYZANTIUM
} else if chain_spec.fork(EthereumHardfork::SpuriousDragon).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::SpuriousDragon)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::SPURIOUS_DRAGON
} else if chain_spec.fork(EthereumHardfork::Tangerine).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::Tangerine)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::TANGERINE
} else if chain_spec.fork(EthereumHardfork::Homestead).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::Homestead)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::HOMESTEAD
} else if chain_spec.fork(EthereumHardfork::Frontier).active_at_head(block) {
} else if chain_spec
.fork(EthereumHardfork::Frontier)
.active_at_timestamp_or_number(timestamp, block_number)
{
revm_primitives::FRONTIER
} else {
panic!(
@ -67,23 +97,26 @@ mod tests {
use reth_chainspec::{ChainSpecBuilder, MAINNET};
#[test]
fn test_revm_spec_by_timestamp_after_merge() {
fn test_revm_spec_by_timestamp() {
assert_eq!(
revm_spec_by_timestamp_after_merge(
revm_spec_by_timestamp_and_block_number(
&ChainSpecBuilder::mainnet().cancun_activated().build(),
0,
0
),
revm_primitives::CANCUN
);
assert_eq!(
revm_spec_by_timestamp_after_merge(
revm_spec_by_timestamp_and_block_number(
&ChainSpecBuilder::mainnet().shanghai_activated().build(),
0,
0
),
revm_primitives::SHANGHAI
);
let mainnet = ChainSpecBuilder::mainnet().build();
assert_eq!(
revm_spec_by_timestamp_after_merge(&ChainSpecBuilder::mainnet().build(), 0),
revm_spec_by_timestamp_and_block_number(&mainnet, 0, mainnet.paris_block().unwrap()),
revm_primitives::MERGE
);
}
@ -91,60 +124,75 @@ mod tests {
#[test]
fn test_to_revm_spec() {
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().cancun_activated().build(), &Head::default()),
revm_spec(&ChainSpecBuilder::mainnet().cancun_activated().build(), &Default::default()),
revm_primitives::CANCUN
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().shanghai_activated().build(), &Head::default()),
revm_spec(
&ChainSpecBuilder::mainnet().shanghai_activated().build(),
&Default::default()
),
revm_primitives::SHANGHAI
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), &Head::default()),
revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), &Default::default()),
revm_primitives::MERGE
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), &Head::default()),
revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), &Default::default()),
revm_primitives::LONDON
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), &Head::default()),
revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), &Default::default()),
revm_primitives::BERLIN
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().istanbul_activated().build(), &Head::default()),
revm_spec(
&ChainSpecBuilder::mainnet().istanbul_activated().build(),
&Default::default()
),
revm_primitives::ISTANBUL
);
assert_eq!(
revm_spec(
&ChainSpecBuilder::mainnet().petersburg_activated().build(),
&Head::default()
&Default::default()
),
revm_primitives::PETERSBURG
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().byzantium_activated().build(), &Head::default()),
revm_spec(
&ChainSpecBuilder::mainnet().byzantium_activated().build(),
&Default::default()
),
revm_primitives::BYZANTIUM
);
assert_eq!(
revm_spec(
&ChainSpecBuilder::mainnet().spurious_dragon_activated().build(),
&Head::default()
&Default::default()
),
revm_primitives::SPURIOUS_DRAGON
);
assert_eq!(
revm_spec(
&ChainSpecBuilder::mainnet().tangerine_whistle_activated().build(),
&Head::default()
&Default::default()
),
revm_primitives::TANGERINE
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().homestead_activated().build(), &Head::default()),
revm_spec(
&ChainSpecBuilder::mainnet().homestead_activated().build(),
&Default::default()
),
revm_primitives::HOMESTEAD
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), &Head::default()),
revm_spec(
&ChainSpecBuilder::mainnet().frontier_activated().build(),
&Default::default()
),
revm_primitives::FRONTIER
);
}
@ -152,60 +200,55 @@ mod tests {
#[test]
fn test_eth_spec() {
assert_eq!(
revm_spec(&MAINNET, &Head { timestamp: 1710338135, ..Default::default() }),
revm_spec(&MAINNET, &Header { timestamp: 1710338135, ..Default::default() }),
revm_primitives::CANCUN
);
assert_eq!(
revm_spec(&MAINNET, &Head { timestamp: 1681338455, ..Default::default() }),
revm_spec(&MAINNET, &Header { timestamp: 1681338455, ..Default::default() }),
revm_primitives::SHANGHAI
);
assert_eq!(
revm_spec(
&MAINNET,
&Head {
total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128),
difficulty: U256::from(10_u128),
number: 15537394,
..Default::default()
}
&Header { difficulty: U256::from(10_u128), number: 15537394, ..Default::default() }
),
revm_primitives::MERGE
);
assert_eq!(
revm_spec(&MAINNET, &Head { number: 15537394 - 10, ..Default::default() }),
revm_spec(&MAINNET, &Header { number: 15537394 - 10, ..Default::default() }),
revm_primitives::LONDON
);
assert_eq!(
revm_spec(&MAINNET, &Head { number: 12244000 + 10, ..Default::default() }),
revm_spec(&MAINNET, &Header { number: 12244000 + 10, ..Default::default() }),
revm_primitives::BERLIN
);
assert_eq!(
revm_spec(&MAINNET, &Head { number: 12244000 - 10, ..Default::default() }),
revm_spec(&MAINNET, &Header { number: 12244000 - 10, ..Default::default() }),
revm_primitives::ISTANBUL
);
assert_eq!(
revm_spec(&MAINNET, &Head { number: 7280000 + 10, ..Default::default() }),
revm_spec(&MAINNET, &Header { number: 7280000 + 10, ..Default::default() }),
revm_primitives::PETERSBURG
);
assert_eq!(
revm_spec(&MAINNET, &Head { number: 7280000 - 10, ..Default::default() }),
revm_spec(&MAINNET, &Header { number: 7280000 - 10, ..Default::default() }),
revm_primitives::BYZANTIUM
);
assert_eq!(
revm_spec(&MAINNET, &Head { number: 2675000 + 10, ..Default::default() }),
revm_spec(&MAINNET, &Header { number: 2675000 + 10, ..Default::default() }),
revm_primitives::SPURIOUS_DRAGON
);
assert_eq!(
revm_spec(&MAINNET, &Head { number: 2675000 - 10, ..Default::default() }),
revm_spec(&MAINNET, &Header { number: 2675000 - 10, ..Default::default() }),
revm_primitives::TANGERINE
);
assert_eq!(
revm_spec(&MAINNET, &Head { number: 1150000 + 10, ..Default::default() }),
revm_spec(&MAINNET, &Header { number: 1150000 + 10, ..Default::default() }),
revm_primitives::HOMESTEAD
);
assert_eq!(
revm_spec(&MAINNET, &Head { number: 1150000 - 10, ..Default::default() }),
revm_spec(&MAINNET, &Header { number: 1150000 - 10, ..Default::default() }),
revm_primitives::FRONTIER
);
}

View File

@ -20,9 +20,9 @@ extern crate alloc;
use core::convert::Infallible;
use alloc::{sync::Arc, vec::Vec};
use alloy_consensus::Header;
use alloy_consensus::{BlockHeader, Header};
use alloy_primitives::{Address, Bytes, TxKind, U256};
use reth_chainspec::{ChainSpec, Head};
use reth_chainspec::ChainSpec;
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes};
use reth_primitives::{transaction::FillTxEnv, TransactionSigned};
use revm_primitives::{
@ -31,7 +31,7 @@ use revm_primitives::{
mod config;
use alloy_eips::eip1559::INITIAL_BASE_FEE;
pub use config::{revm_spec, revm_spec_by_timestamp_after_merge};
pub use config::{revm_spec, revm_spec_by_timestamp_and_block_number};
use reth_ethereum_forks::EthereumHardfork;
pub mod execute;
@ -110,17 +110,7 @@ impl ConfigureEvmEnv for EthEvmConfig {
}
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,
// NOTE: this does nothing within revm_spec
total_difficulty: U256::MIN,
hash: Default::default(),
},
);
let spec_id = config::revm_spec(self.chain_spec(), header);
cfg_env.chain_id = self.chain_spec.chain().id();
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;
@ -137,7 +127,11 @@ impl ConfigureEvmEnv for EthEvmConfig {
let cfg = CfgEnv::default().with_chain_id(self.chain_spec.chain().id());
// ensure we're not missing any timestamp based hardforks
let spec_id = revm_spec_by_timestamp_after_merge(&self.chain_spec, attributes.timestamp);
let spec_id = revm_spec_by_timestamp_and_block_number(
&self.chain_spec,
attributes.timestamp,
parent.number() + 1,
);
// 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(0)