Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Refactor fork handling and optimize revm_spec function #30

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/node/src/chainspec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub static ODYSSEY_MAINNET: Lazy<Arc<OpChainSpec>> = Lazy::new(|| {
genesis_hash: once_cell_set(b256!(
"2f980576711e3617a5e4d83dd539548ec0f7792007d505a3d2e9674833af2d7c"
)),
paris_block_and_final_difficulty: Some((0, U256::from(0))),
paris_block_and_final_difficulty: Some((0, U256::ZERO)),
hardforks: ODYSSEY_FORKS.clone(),
base_fee_params: BaseFeeParamsKind::Variable(
vec![
Expand Down
70 changes: 21 additions & 49 deletions crates/node/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@

use alloy_primitives::{Address, Bytes, TxKind, U256};
use odyssey_precompile::secp256r1;
use reth_chainspec::{ChainSpec, EthereumHardfork, Head};
use reth_chainspec::{ChainSpec, Head};
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes};
use reth_optimism_chainspec::OpChainSpec;
use reth_optimism_forks::OptimismHardfork;
use reth_primitives::{
revm_primitives::{CfgEnvWithHandlerCfg, TxEnv},
transaction::FillTxEnv,
Expand All @@ -31,8 +30,12 @@ use reth_revm::{
},
ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector,
};
use crate::fork::{Fork, FORKS, FORK_SPEC_MAP};

use std::sync::Arc;



/// Custom EVM configuration
#[derive(Debug, Clone)]
pub struct OdysseyEvmConfig {
Expand Down Expand Up @@ -260,53 +263,18 @@ impl ConfigureEvm for OdysseyEvmConfig {
}

/// Determine the revm spec ID from the current block and reth chainspec.
fn revm_spec(chain_spec: &ChainSpec, block: &Head) -> reth_revm::primitives::SpecId {
if chain_spec.fork(EthereumHardfork::Prague).active_at_head(block) {
reth_revm::primitives::PRAGUE_EOF
} else if chain_spec.fork(OptimismHardfork::Granite).active_at_head(block) {
reth_revm::primitives::GRANITE
} else if chain_spec.fork(OptimismHardfork::Fjord).active_at_head(block) {
reth_revm::primitives::FJORD
} else if chain_spec.fork(OptimismHardfork::Ecotone).active_at_head(block) {
reth_revm::primitives::ECOTONE
} else if chain_spec.fork(OptimismHardfork::Canyon).active_at_head(block) {
reth_revm::primitives::CANYON
} else if chain_spec.fork(OptimismHardfork::Regolith).active_at_head(block) {
reth_revm::primitives::REGOLITH
} else if chain_spec.fork(OptimismHardfork::Bedrock).active_at_head(block) {
reth_revm::primitives::BEDROCK
} else if chain_spec.fork(EthereumHardfork::Prague).active_at_head(block) {
reth_revm::primitives::PRAGUE
} else if chain_spec.fork(EthereumHardfork::Cancun).active_at_head(block) {
reth_revm::primitives::CANCUN
} else if chain_spec.fork(EthereumHardfork::Shanghai).active_at_head(block) {
reth_revm::primitives::SHANGHAI
} else if chain_spec.fork(EthereumHardfork::Paris).active_at_head(block) {
reth_revm::primitives::MERGE
} else if chain_spec.fork(EthereumHardfork::London).active_at_head(block) {
reth_revm::primitives::LONDON
} else if chain_spec.fork(EthereumHardfork::Berlin).active_at_head(block) {
reth_revm::primitives::BERLIN
} else if chain_spec.fork(EthereumHardfork::Istanbul).active_at_head(block) {
reth_revm::primitives::ISTANBUL
} else if chain_spec.fork(EthereumHardfork::Petersburg).active_at_head(block) {
reth_revm::primitives::PETERSBURG
} else if chain_spec.fork(EthereumHardfork::Byzantium).active_at_head(block) {
reth_revm::primitives::BYZANTIUM
} else if chain_spec.fork(EthereumHardfork::SpuriousDragon).active_at_head(block) {
reth_revm::primitives::SPURIOUS_DRAGON
} else if chain_spec.fork(EthereumHardfork::Tangerine).active_at_head(block) {
reth_revm::primitives::TANGERINE
} else if chain_spec.fork(EthereumHardfork::Homestead).active_at_head(block) {
reth_revm::primitives::HOMESTEAD
} else if chain_spec.fork(EthereumHardfork::Frontier).active_at_head(block) {
reth_revm::primitives::FRONTIER
} else {
panic!(
"invalid hardfork chainspec: expected at least one hardfork, got {:?}",
chain_spec.hardforks
)
}
fn revm_spec(chain_spec: &ChainSpec, block: &Head) -> SpecId {
FORKS
.iter()
.find_map(|&fork| {
let is_active = match fork {
Fork::Ethereum(f) => chain_spec.fork(f).active_at_head(block),
Fork::Optimism(f) => chain_spec.fork(f).active_at_head(block),
};
is_active.then(|| FORK_SPEC_MAP.get(&fork)).flatten()
})
.copied()
.unwrap_or_else(|| panic!("No valid hardfork found in chain spec"))
}

#[cfg(test)]
Expand All @@ -317,9 +285,11 @@ mod tests {
revm_primitives::{BlockEnv, CfgEnv, SpecId},
ForkCondition,
};
use std::time::Instant;

#[test]
fn test_fill_cfg_and_block_env() {
let start = Instant::now();
let mut cfg_env = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST);
let mut block_env = BlockEnv::default();
let header = Header::default();
Expand All @@ -340,5 +310,7 @@ mod tests {
);

assert_eq!(cfg_env.chain_id, chain_spec.chain().id());
let stop = start.elapsed();
println!("{:?}", stop);
}
}
73 changes: 73 additions & 0 deletions crates/node/src/fork.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use std::collections::BTreeMap;

use once_cell::sync::Lazy;
use reth_chainspec::EthereumHardfork;
use reth_optimism_forks::OptimismHardfork;
use reth_revm::primitives::SpecId;

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]


/// Represents a fork in either the Ethereum or Optimism network.
pub enum Fork {
/// An Ethereum network fork.
Ethereum(EthereumHardfork),
/// An Optimism network fork.
Optimism(OptimismHardfork),
}


/// A list of all forks in reverse chronological order (newest first).
pub static FORKS: Lazy<Vec<Fork>> = Lazy::new(|| {
vec![
// Optimism forks (from newest to old for efficient lookup)
Fork::Optimism(OptimismHardfork::Granite),
Fork::Optimism(OptimismHardfork::Fjord),
Fork::Optimism(OptimismHardfork::Ecotone),
Fork::Optimism(OptimismHardfork::Canyon),
Fork::Optimism(OptimismHardfork::Regolith),
Fork::Optimism(OptimismHardfork::Bedrock),

// Ethereum forks (from newest to old for efficient lookup)
Fork::Ethereum(EthereumHardfork::Prague),
Fork::Ethereum(EthereumHardfork::Cancun),
Fork::Ethereum(EthereumHardfork::Shanghai),
Fork::Ethereum(EthereumHardfork::Paris),
Fork::Ethereum(EthereumHardfork::London),
Fork::Ethereum(EthereumHardfork::Berlin),
Fork::Ethereum(EthereumHardfork::Istanbul),
Fork::Ethereum(EthereumHardfork::Petersburg),
Fork::Ethereum(EthereumHardfork::Byzantium),
Fork::Ethereum(EthereumHardfork::SpuriousDragon),
Fork::Ethereum(EthereumHardfork::Tangerine),
Fork::Ethereum(EthereumHardfork::Homestead),
Fork::Ethereum(EthereumHardfork::Frontier),
]
});


/// Maps each fork to its corresponding EVM specification ID.
pub static FORK_SPEC_MAP: Lazy<BTreeMap<Fork, SpecId>> = Lazy::new(|| {
let mut map = BTreeMap::new();
map.insert(Fork::Optimism(OptimismHardfork::Granite), SpecId::GRANITE);
map.insert(Fork::Optimism(OptimismHardfork::Fjord), SpecId::FJORD);
map.insert(Fork::Optimism(OptimismHardfork::Ecotone), SpecId::ECOTONE);
map.insert(Fork::Optimism(OptimismHardfork::Canyon), SpecId::CANYON);
map.insert(Fork::Optimism(OptimismHardfork::Regolith), SpecId::REGOLITH);
map.insert(Fork::Optimism(OptimismHardfork::Bedrock), SpecId::BEDROCK);
map.insert(Fork::Ethereum(EthereumHardfork::Prague), SpecId::PRAGUE_EOF);
map.insert(Fork::Ethereum(EthereumHardfork::Cancun), SpecId::CANCUN);
map.insert(Fork::Ethereum(EthereumHardfork::Shanghai), SpecId::SHANGHAI);
map.insert(Fork::Ethereum(EthereumHardfork::Paris), SpecId::MERGE);
map.insert(Fork::Ethereum(EthereumHardfork::London), SpecId::LONDON);
map.insert(Fork::Ethereum(EthereumHardfork::Berlin), SpecId::BERLIN);
map.insert(Fork::Ethereum(EthereumHardfork::Istanbul), SpecId::ISTANBUL);
map.insert(Fork::Ethereum(EthereumHardfork::Petersburg), SpecId::PETERSBURG);
map.insert(Fork::Ethereum(EthereumHardfork::Byzantium), SpecId::BYZANTIUM);
map.insert(Fork::Ethereum(EthereumHardfork::SpuriousDragon), SpecId::SPURIOUS_DRAGON);
map.insert(Fork::Ethereum(EthereumHardfork::Tangerine), SpecId::TANGERINE);
map.insert(Fork::Ethereum(EthereumHardfork::Homestead), SpecId::HOMESTEAD);
map.insert(Fork::Ethereum(EthereumHardfork::Frontier), SpecId::FRONTIER);
map
});

1 change: 1 addition & 0 deletions crates/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
pub mod chainspec;
pub mod evm;
pub mod node;
pub mod fork;
Loading