diff --git a/Cargo.lock b/Cargo.lock index 2cdaedf5659a..062c7b4bd9b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8456,6 +8456,7 @@ dependencies = [ "reth-ethereum-forks", "reth-network-peers", "reth-optimism-forks", + "reth-optimism-primitives", "reth-primitives-traits", "serde_json", "thiserror 2.0.11", diff --git a/crates/optimism/chainspec/Cargo.toml b/crates/optimism/chainspec/Cargo.toml index 404402a6cb9b..b2c48bf36f3d 100644 --- a/crates/optimism/chainspec/Cargo.toml +++ b/crates/optimism/chainspec/Cargo.toml @@ -20,6 +20,7 @@ reth-network-peers.workspace = true # op-reth reth-optimism-forks.workspace = true +reth-optimism-primitives.workspace = true # ethereum alloy-chains.workspace = true @@ -57,6 +58,7 @@ std = [ "reth-ethereum-forks/std", "reth-primitives-traits/std", "reth-optimism-forks/std", + "reth-optimism-primitives/std", "alloy-consensus/std", "once_cell/std", "derive_more/std", diff --git a/crates/optimism/chainspec/src/base.rs b/crates/optimism/chainspec/src/base.rs index a6d302b507f5..4965e499f5e9 100644 --- a/crates/optimism/chainspec/src/base.rs +++ b/crates/optimism/chainspec/src/base.rs @@ -4,12 +4,12 @@ use alloc::{sync::Arc, vec}; use alloy_chains::Chain; use alloy_primitives::{b256, U256}; -use reth_chainspec::{make_genesis_header, BaseFeeParams, BaseFeeParamsKind, ChainSpec}; +use reth_chainspec::{BaseFeeParams, BaseFeeParamsKind, ChainSpec}; use reth_ethereum_forks::{EthereumHardfork, Hardfork}; use reth_optimism_forks::OpHardfork; use reth_primitives_traits::SealedHeader; -use crate::{LazyLock, OpChainSpec}; +use crate::{make_op_genesis_header, LazyLock, OpChainSpec}; /// The Base mainnet spec pub static BASE_MAINNET: LazyLock> = LazyLock::new(|| { @@ -20,7 +20,7 @@ pub static BASE_MAINNET: LazyLock> = LazyLock::new(|| { inner: ChainSpec { chain: Chain::base_mainnet(), genesis_header: SealedHeader::new( - make_genesis_header(&genesis, &hardforks), + make_op_genesis_header(&genesis, &hardforks), b256!("f712aa9241cc24369b143cf6dce85f0902a9731e70d66818a3a5845b296c73dd"), ), genesis, diff --git a/crates/optimism/chainspec/src/base_sepolia.rs b/crates/optimism/chainspec/src/base_sepolia.rs index ef412f10946f..bfec355a63d7 100644 --- a/crates/optimism/chainspec/src/base_sepolia.rs +++ b/crates/optimism/chainspec/src/base_sepolia.rs @@ -4,12 +4,12 @@ use alloc::{sync::Arc, vec}; use alloy_chains::Chain; use alloy_primitives::{b256, U256}; -use reth_chainspec::{make_genesis_header, BaseFeeParams, BaseFeeParamsKind, ChainSpec, Hardfork}; +use reth_chainspec::{BaseFeeParams, BaseFeeParamsKind, ChainSpec, Hardfork}; use reth_ethereum_forks::EthereumHardfork; use reth_optimism_forks::OpHardfork; use reth_primitives_traits::SealedHeader; -use crate::{LazyLock, OpChainSpec}; +use crate::{make_op_genesis_header, LazyLock, OpChainSpec}; /// The Base Sepolia spec pub static BASE_SEPOLIA: LazyLock> = LazyLock::new(|| { @@ -20,7 +20,7 @@ pub static BASE_SEPOLIA: LazyLock> = LazyLock::new(|| { inner: ChainSpec { chain: Chain::base_sepolia(), genesis_header: SealedHeader::new( - make_genesis_header(&genesis, &hardforks), + make_op_genesis_header(&genesis, &hardforks), b256!("0dcc9e089e30b90ddfc55be9a37dd15bc551aeee999d2e2b51414c54eaf934e4"), ), genesis, diff --git a/crates/optimism/chainspec/src/dev.rs b/crates/optimism/chainspec/src/dev.rs index f7614a8bc06c..57d84ce0b0b0 100644 --- a/crates/optimism/chainspec/src/dev.rs +++ b/crates/optimism/chainspec/src/dev.rs @@ -5,11 +5,11 @@ use alloc::sync::Arc; use alloy_chains::Chain; use alloy_consensus::constants::DEV_GENESIS_HASH; use alloy_primitives::U256; -use reth_chainspec::{make_genesis_header, BaseFeeParams, BaseFeeParamsKind, ChainSpec}; +use reth_chainspec::{BaseFeeParams, BaseFeeParamsKind, ChainSpec}; use reth_optimism_forks::DEV_HARDFORKS; use reth_primitives_traits::SealedHeader; -use crate::{LazyLock, OpChainSpec}; +use crate::{make_op_genesis_header, LazyLock, OpChainSpec}; /// OP dev testnet specification /// @@ -23,7 +23,7 @@ pub static OP_DEV: LazyLock> = LazyLock::new(|| { inner: ChainSpec { chain: Chain::dev(), genesis_header: SealedHeader::new( - make_genesis_header(&genesis, &hardforks), + make_op_genesis_header(&genesis, &hardforks), DEV_GENESIS_HASH, ), genesis, diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index 8f54193a2e64..e90d621d8afd 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -19,7 +19,7 @@ mod op_sepolia; use alloc::{boxed::Box, vec, vec::Vec}; use alloy_chains::Chain; -use alloy_consensus::Header; +use alloy_consensus::{proofs::storage_root_unhashed, Header}; use alloy_eips::eip7840::BlobParams; use alloy_genesis::Genesis; use alloy_primitives::{B256, U256}; @@ -36,6 +36,7 @@ use reth_chainspec::{ use reth_ethereum_forks::{ChainHardforks, EthereumHardfork, ForkCondition, Hardfork}; use reth_network_peers::NodeRecord; use reth_optimism_forks::{OpHardfork, OpHardforks}; +use reth_optimism_primitives::ADDRESS_L2_TO_L1_MESSAGE_PASSER; use reth_primitives_traits::{sync::LazyLock, SealedHeader}; /// Chain spec builder for a OP stack chain. @@ -421,6 +422,32 @@ impl OpGenesisInfo { } } +/// Helper method building a [`Header`] given [`Genesis`] and [`ChainHardforks`]. +pub fn make_op_genesis_header(genesis: &Genesis, hardforks: &ChainHardforks) -> Header { + let mut header = reth_chainspec::make_genesis_header(genesis, hardforks); + + // If Isthmus is active, overwrite the withdrawals root with the storage root of predeploy + // `L2ToL1MessagePasser.sol` + if hardforks.fork(OpHardfork::Isthmus).active_at_timestamp(header.timestamp) { + match genesis.alloc.get(&ADDRESS_L2_TO_L1_MESSAGE_PASSER) { + Some(predeploy) => { + if let Some(ref storage) = predeploy.storage { + header.withdrawals_root = + Some(storage_root_unhashed(storage.iter().map(|(k, v)| (*k, (*v).into())))) + } + } + None => + // todo: log this when no_std tracing available + /*debug!(target: "reth::cli", + "Isthmus active but predeploy L2ToL1MessagePasser.sol not found in genesis alloc" + ),*/ + {} + } + } + + header +} + #[cfg(test)] mod tests { use alloy_genesis::{ChainConfig, Genesis}; diff --git a/crates/optimism/chainspec/src/op.rs b/crates/optimism/chainspec/src/op.rs index 2d6777d277f0..dddd26dfb29d 100644 --- a/crates/optimism/chainspec/src/op.rs +++ b/crates/optimism/chainspec/src/op.rs @@ -1,10 +1,10 @@ //! Chain specification for the Optimism Mainnet network. -use crate::{LazyLock, OpChainSpec}; +use crate::{make_op_genesis_header, LazyLock, OpChainSpec}; use alloc::{sync::Arc, vec}; use alloy_chains::Chain; use alloy_primitives::{b256, U256}; -use reth_chainspec::{make_genesis_header, BaseFeeParams, BaseFeeParamsKind, ChainSpec, Hardfork}; +use reth_chainspec::{BaseFeeParams, BaseFeeParamsKind, ChainSpec, Hardfork}; use reth_ethereum_forks::EthereumHardfork; use reth_optimism_forks::OpHardfork; use reth_primitives_traits::SealedHeader; @@ -20,7 +20,7 @@ pub static OP_MAINNET: LazyLock> = LazyLock::new(|| { inner: ChainSpec { chain: Chain::optimism_mainnet(), genesis_header: SealedHeader::new( - make_genesis_header(&genesis, &hardforks), + make_op_genesis_header(&genesis, &hardforks), b256!("7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b"), ), genesis, diff --git a/crates/optimism/chainspec/src/op_sepolia.rs b/crates/optimism/chainspec/src/op_sepolia.rs index 2c963d360e66..3ed22db6457f 100644 --- a/crates/optimism/chainspec/src/op_sepolia.rs +++ b/crates/optimism/chainspec/src/op_sepolia.rs @@ -1,10 +1,10 @@ //! Chain specification for the Optimism Sepolia testnet network. -use crate::{LazyLock, OpChainSpec}; +use crate::{make_op_genesis_header, LazyLock, OpChainSpec}; use alloc::{sync::Arc, vec}; use alloy_chains::{Chain, NamedChain}; use alloy_primitives::{b256, U256}; -use reth_chainspec::{make_genesis_header, BaseFeeParams, BaseFeeParamsKind, ChainSpec, Hardfork}; +use reth_chainspec::{BaseFeeParams, BaseFeeParamsKind, ChainSpec, Hardfork}; use reth_ethereum_forks::EthereumHardfork; use reth_optimism_forks::OpHardfork; use reth_primitives_traits::SealedHeader; @@ -18,7 +18,7 @@ pub static OP_SEPOLIA: LazyLock> = LazyLock::new(|| { inner: ChainSpec { chain: Chain::from_named(NamedChain::OptimismSepolia), genesis_header: SealedHeader::new( - make_genesis_header(&genesis, &hardforks), + make_op_genesis_header(&genesis, &hardforks), b256!("102de6ffb001480cc9b8b548fd05c34cd4f46ae4aa91759393db90ea0409887d"), ), genesis,