mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore(chainspec): move op stack chain specs to reth-optimism-chainspec (#10485)
This commit is contained in:
@ -27,7 +27,6 @@ alloy-trie.workspace = true
|
||||
# op
|
||||
op-alloy-rpc-types = { workspace = true, optional = true }
|
||||
|
||||
|
||||
# misc
|
||||
auto_impl.workspace = true
|
||||
once_cell.workspace = true
|
||||
@ -56,5 +55,6 @@ std = []
|
||||
arbitrary = [
|
||||
"alloy-chains/arbitrary"
|
||||
]
|
||||
test-utils = []
|
||||
|
||||
|
||||
|
||||
@ -7,11 +7,3 @@ pub(crate) const MAINNET_DEPOSIT_CONTRACT: DepositContract = DepositContract::ne
|
||||
11052984,
|
||||
b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"),
|
||||
);
|
||||
|
||||
/// Max gas limit on Base Sepolia: <https://sepolia.basescan.org/block/12506483>
|
||||
#[cfg(feature = "optimism")]
|
||||
pub(crate) const BASE_SEPOLIA_MAX_GAS_LIMIT: u64 = 45_000_000;
|
||||
|
||||
/// Max gas limit on Base: <https://basescan.org/block/17208876>
|
||||
#[cfg(feature = "optimism")]
|
||||
pub(crate) const BASE_MAINNET_MAX_GAS_LIMIT: u64 = 105_000_000;
|
||||
|
||||
@ -9,35 +9,31 @@
|
||||
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
pub use alloy_chains::{Chain, ChainKind, NamedChain};
|
||||
pub use info::ChainInfo;
|
||||
pub use spec::{
|
||||
BaseFeeParams, BaseFeeParamsKind, ChainSpec, ChainSpecBuilder, ChainSpecProvider,
|
||||
DepositContract, ForkBaseFeeParams, DEV, HOLESKY, MAINNET, SEPOLIA,
|
||||
};
|
||||
#[cfg(feature = "optimism")]
|
||||
pub use spec::{BASE_MAINNET, BASE_SEPOLIA, OP_MAINNET, OP_SEPOLIA};
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate alloc;
|
||||
|
||||
// /// The config info module namely spec id.
|
||||
// pub mod config;
|
||||
/// The chain info module.
|
||||
mod info;
|
||||
|
||||
/// The chain spec module.
|
||||
mod spec;
|
||||
|
||||
mod api;
|
||||
pub use api::EthChainSpec;
|
||||
|
||||
/// Chain specific constants
|
||||
pub(crate) mod constants;
|
||||
|
||||
mod api;
|
||||
/// The chain info module.
|
||||
mod info;
|
||||
/// The chain spec module.
|
||||
mod spec;
|
||||
|
||||
pub use alloy_chains::{Chain, ChainKind, NamedChain};
|
||||
/// Re-export for convenience
|
||||
pub use reth_ethereum_forks::*;
|
||||
|
||||
pub use api::EthChainSpec;
|
||||
pub use info::ChainInfo;
|
||||
#[cfg(feature = "test-utils")]
|
||||
pub use spec::test_fork_ids;
|
||||
pub use spec::{
|
||||
BaseFeeParams, BaseFeeParamsKind, ChainSpec, ChainSpecBuilder, ChainSpecProvider,
|
||||
DepositContract, ForkBaseFeeParams, DEV, HOLESKY, MAINNET, SEPOLIA,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@ -1,17 +1,26 @@
|
||||
use crate::{constants::MAINNET_DEPOSIT_CONTRACT, EthChainSpec};
|
||||
pub use alloy_eips::eip1559::BaseFeeParams;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||
#[cfg(feature = "std")]
|
||||
use std::sync::Arc;
|
||||
|
||||
use alloy_chains::{Chain, ChainKind, NamedChain};
|
||||
use alloy_genesis::Genesis;
|
||||
use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256};
|
||||
use alloy_trie::EMPTY_ROOT_HASH;
|
||||
use derive_more::From;
|
||||
use once_cell::sync::Lazy;
|
||||
#[cfg(feature = "optimism")]
|
||||
use reth_ethereum_forks::OptimismHardfork;
|
||||
use reth_ethereum_forks::{
|
||||
ChainHardforks, DisplayHardforks, EthereumHardfork, EthereumHardforks, ForkCondition,
|
||||
ForkFilter, ForkFilterKey, ForkHash, ForkId, Hardfork, Head, DEV_HARDFORKS,
|
||||
};
|
||||
use reth_network_peers::NodeRecord;
|
||||
use reth_network_peers::{
|
||||
base_nodes, base_testnet_nodes, holesky_nodes, mainnet_nodes, op_nodes, op_testnet_nodes,
|
||||
sepolia_nodes, NodeRecord,
|
||||
};
|
||||
use reth_primitives_traits::{
|
||||
constants::{
|
||||
DEV_GENESIS_HASH, EIP1559_INITIAL_BASE_FEE, EMPTY_WITHDRAWALS, ETHEREUM_BLOCK_GAS_LIMIT,
|
||||
@ -20,16 +29,8 @@ use reth_primitives_traits::{
|
||||
Header, SealedHeader,
|
||||
};
|
||||
use reth_trie_common::root::state_root_ref_unhashed;
|
||||
#[cfg(feature = "std")]
|
||||
use std::sync::Arc;
|
||||
|
||||
pub use alloy_eips::eip1559::BaseFeeParams;
|
||||
#[cfg(feature = "optimism")]
|
||||
use reth_ethereum_forks::OptimismHardfork;
|
||||
use reth_network_peers::{
|
||||
base_nodes, base_testnet_nodes, holesky_nodes, mainnet_nodes, op_nodes, op_testnet_nodes,
|
||||
sepolia_nodes,
|
||||
};
|
||||
use crate::{constants::MAINNET_DEPOSIT_CONTRACT, EthChainSpec};
|
||||
|
||||
/// The Ethereum mainnet spec
|
||||
pub static MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
@ -123,112 +124,6 @@ pub static DEV: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
.into()
|
||||
});
|
||||
|
||||
/// The Optimism Mainnet spec
|
||||
#[cfg(feature = "optimism")]
|
||||
pub static OP_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
ChainSpec {
|
||||
chain: Chain::optimism_mainnet(),
|
||||
// genesis contains empty alloc field because state at first bedrock block is imported
|
||||
// manually from trusted source
|
||||
genesis: serde_json::from_str(include_str!("../res/genesis/optimism.json"))
|
||||
.expect("Can't deserialize Optimism Mainnet genesis json"),
|
||||
genesis_hash: Some(b256!(
|
||||
"7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b"
|
||||
)),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
hardforks: OptimismHardfork::op_mainnet(),
|
||||
base_fee_params: BaseFeeParamsKind::Variable(
|
||||
vec![
|
||||
(EthereumHardfork::London.boxed(), BaseFeeParams::optimism()),
|
||||
(OptimismHardfork::Canyon.boxed(), BaseFeeParams::optimism_canyon()),
|
||||
]
|
||||
.into(),
|
||||
),
|
||||
max_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT,
|
||||
prune_delete_limit: 10000,
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
});
|
||||
|
||||
/// The OP Sepolia spec
|
||||
#[cfg(feature = "optimism")]
|
||||
pub static OP_SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
ChainSpec {
|
||||
chain: Chain::from_named(NamedChain::OptimismSepolia),
|
||||
genesis: serde_json::from_str(include_str!("../res/genesis/sepolia_op.json"))
|
||||
.expect("Can't deserialize OP Sepolia genesis json"),
|
||||
genesis_hash: Some(b256!(
|
||||
"102de6ffb001480cc9b8b548fd05c34cd4f46ae4aa91759393db90ea0409887d"
|
||||
)),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
hardforks: OptimismHardfork::op_sepolia(),
|
||||
base_fee_params: BaseFeeParamsKind::Variable(
|
||||
vec![
|
||||
(EthereumHardfork::London.boxed(), BaseFeeParams::optimism_sepolia()),
|
||||
(OptimismHardfork::Canyon.boxed(), BaseFeeParams::optimism_sepolia_canyon()),
|
||||
]
|
||||
.into(),
|
||||
),
|
||||
max_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT,
|
||||
prune_delete_limit: 10000,
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
});
|
||||
|
||||
/// The Base Sepolia spec
|
||||
#[cfg(feature = "optimism")]
|
||||
pub static BASE_SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
ChainSpec {
|
||||
chain: Chain::base_sepolia(),
|
||||
genesis: serde_json::from_str(include_str!("../res/genesis/sepolia_base.json"))
|
||||
.expect("Can't deserialize Base Sepolia genesis json"),
|
||||
genesis_hash: Some(b256!(
|
||||
"0dcc9e089e30b90ddfc55be9a37dd15bc551aeee999d2e2b51414c54eaf934e4"
|
||||
)),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
hardforks: OptimismHardfork::base_sepolia(),
|
||||
base_fee_params: BaseFeeParamsKind::Variable(
|
||||
vec![
|
||||
(EthereumHardfork::London.boxed(), BaseFeeParams::base_sepolia()),
|
||||
(OptimismHardfork::Canyon.boxed(), BaseFeeParams::base_sepolia_canyon()),
|
||||
]
|
||||
.into(),
|
||||
),
|
||||
max_gas_limit: crate::constants::BASE_SEPOLIA_MAX_GAS_LIMIT,
|
||||
prune_delete_limit: 10000,
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
});
|
||||
|
||||
/// The Base mainnet spec
|
||||
#[cfg(feature = "optimism")]
|
||||
pub static BASE_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
ChainSpec {
|
||||
chain: Chain::base_mainnet(),
|
||||
genesis: serde_json::from_str(include_str!("../res/genesis/base.json"))
|
||||
.expect("Can't deserialize Base genesis json"),
|
||||
genesis_hash: Some(b256!(
|
||||
"f712aa9241cc24369b143cf6dce85f0902a9731e70d66818a3a5845b296c73dd"
|
||||
)),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
hardforks: OptimismHardfork::base_mainnet(),
|
||||
base_fee_params: BaseFeeParamsKind::Variable(
|
||||
vec![
|
||||
(EthereumHardfork::London.boxed(), BaseFeeParams::optimism()),
|
||||
(OptimismHardfork::Canyon.boxed(), BaseFeeParams::optimism_canyon()),
|
||||
]
|
||||
.into(),
|
||||
),
|
||||
max_gas_limit: crate::constants::BASE_MAINNET_MAX_GAS_LIMIT,
|
||||
prune_delete_limit: 10000,
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
});
|
||||
|
||||
/// A wrapper around [`BaseFeeParams`] that allows for specifying constant or dynamic EIP-1559
|
||||
/// parameters based on the active [Hardfork].
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@ -1134,30 +1029,31 @@ impl OptimismGenesisInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/// Verifies [`ChainSpec`] configuration against expected data in given cases.
|
||||
#[cfg(any(test, feature = "test-utils"))]
|
||||
pub fn test_fork_ids(spec: &ChainSpec, cases: &[(Head, ForkId)]) {
|
||||
for (block, expected_id) in cases {
|
||||
let computed_id = spec.fork_id(block);
|
||||
assert_eq!(
|
||||
expected_id, &computed_id,
|
||||
"Expected fork ID {:?}, computed fork ID {:?} at block {}",
|
||||
expected_id, computed_id, block.number
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use core::ops::Deref;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use alloy_chains::Chain;
|
||||
use alloy_genesis::{ChainConfig, GenesisAccount};
|
||||
use alloy_primitives::{b256, hex};
|
||||
use core::ops::Deref;
|
||||
use reth_ethereum_forks::{ForkCondition, ForkHash, ForkId, Head};
|
||||
use reth_trie_common::TrieAccount;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
use reth_ethereum_forks::OptimismHardforks;
|
||||
|
||||
fn test_fork_ids(spec: &ChainSpec, cases: &[(Head, ForkId)]) {
|
||||
for (block, expected_id) in cases {
|
||||
let computed_id = spec.fork_id(block);
|
||||
assert_eq!(
|
||||
expected_id, &computed_id,
|
||||
"Expected fork ID {:?}, computed fork ID {:?} at block {}",
|
||||
expected_id, computed_id, block.number
|
||||
);
|
||||
}
|
||||
}
|
||||
use super::*;
|
||||
|
||||
fn test_hardfork_fork_ids(spec: &ChainSpec, cases: &[(EthereumHardfork, ForkId)]) {
|
||||
for (hardfork, expected_id) in cases {
|
||||
@ -1662,159 +1558,6 @@ Post-merge hard forks (timestamp based):
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn base_mainnet_forkids() {
|
||||
test_fork_ids(
|
||||
&BASE_MAINNET,
|
||||
&[
|
||||
(
|
||||
Head { number: 0, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x67, 0xda, 0x02, 0x60]), next: 1704992401 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1704992400, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x67, 0xda, 0x02, 0x60]), next: 1704992401 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1704992401, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x3c, 0x28, 0x3c, 0xb3]), next: 1710374401 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1710374400, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x3c, 0x28, 0x3c, 0xb3]), next: 1710374401 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1710374401, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x51, 0xcc, 0x98, 0xb3]), next: 1720627201 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1720627200, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x51, 0xcc, 0x98, 0xb3]), next: 1720627201 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1720627201, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xe4, 0x01, 0x0e, 0xb9]), next: 1726070401 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1726070401, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xbc, 0x38, 0xf9, 0xca]), next: 0 },
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn op_sepolia_forkids() {
|
||||
test_fork_ids(
|
||||
&OP_SEPOLIA,
|
||||
&[
|
||||
(
|
||||
Head { number: 0, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x67, 0xa4, 0x03, 0x28]), next: 1699981200 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1699981199, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x67, 0xa4, 0x03, 0x28]), next: 1699981200 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1699981200, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xa4, 0x8d, 0x6a, 0x00]), next: 1708534800 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1708534799, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xa4, 0x8d, 0x6a, 0x00]), next: 1708534800 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1708534800, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xcc, 0x17, 0xc7, 0xeb]), next: 1716998400 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1716998399, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xcc, 0x17, 0xc7, 0xeb]), next: 1716998400 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1716998400, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x54, 0x0a, 0x8c, 0x5d]), next: 1723478400 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1723478399, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x54, 0x0a, 0x8c, 0x5d]), next: 1723478400 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1723478400, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x75, 0xde, 0xa4, 0x1e]), next: 0 },
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn op_mainnet_forkids() {
|
||||
test_fork_ids(
|
||||
&OP_MAINNET,
|
||||
&[
|
||||
(
|
||||
Head { number: 0, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xca, 0xf5, 0x17, 0xed]), next: 3950000 },
|
||||
),
|
||||
// TODO: complete these, see https://github.com/paradigmxyz/reth/issues/8012
|
||||
(
|
||||
Head { number: 105235063, timestamp: 1710374401, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x19, 0xda, 0x4c, 0x52]), next: 1720627201 },
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn base_sepolia_forkids() {
|
||||
test_fork_ids(
|
||||
&BASE_SEPOLIA,
|
||||
&[
|
||||
(
|
||||
Head { number: 0, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xb9, 0x59, 0xb9, 0xf7]), next: 1699981200 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1699981199, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xb9, 0x59, 0xb9, 0xf7]), next: 1699981200 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1699981200, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x60, 0x7c, 0xd5, 0xa1]), next: 1708534800 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1708534799, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x60, 0x7c, 0xd5, 0xa1]), next: 1708534800 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1708534800, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xbe, 0x96, 0x9b, 0x17]), next: 1716998400 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1716998399, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0xbe, 0x96, 0x9b, 0x17]), next: 1716998400 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1716998400, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x4e, 0x45, 0x7a, 0x49]), next: 1723478400 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1723478399, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x4e, 0x45, 0x7a, 0x49]), next: 1723478400 },
|
||||
),
|
||||
(
|
||||
Head { number: 0, timestamp: 1723478400, ..Default::default() },
|
||||
ForkId { hash: ForkHash([0x5e, 0xdf, 0xa3, 0xb6]), next: 0 },
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dev_forkids() {
|
||||
test_fork_ids(
|
||||
@ -2599,51 +2342,6 @@ Post-merge hard forks (timestamp based):
|
||||
assert_eq!(spec.hardfork_fork_filter(EthereumHardfork::Shanghai), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "optimism")]
|
||||
fn base_mainnet_genesis() {
|
||||
let genesis = BASE_MAINNET.genesis_header();
|
||||
assert_eq!(
|
||||
genesis.hash_slow(),
|
||||
b256!("f712aa9241cc24369b143cf6dce85f0902a9731e70d66818a3a5845b296c73dd")
|
||||
);
|
||||
let base_fee = genesis
|
||||
.next_block_base_fee(BASE_MAINNET.base_fee_params_at_timestamp(genesis.timestamp))
|
||||
.unwrap();
|
||||
// <https://base.blockscout.com/block/1>
|
||||
assert_eq!(base_fee, 980000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "optimism")]
|
||||
fn base_sepolia_genesis() {
|
||||
let genesis = BASE_SEPOLIA.genesis_header();
|
||||
assert_eq!(
|
||||
genesis.hash_slow(),
|
||||
b256!("0dcc9e089e30b90ddfc55be9a37dd15bc551aeee999d2e2b51414c54eaf934e4")
|
||||
);
|
||||
let base_fee = genesis
|
||||
.next_block_base_fee(BASE_SEPOLIA.base_fee_params_at_timestamp(genesis.timestamp))
|
||||
.unwrap();
|
||||
// <https://base-sepolia.blockscout.com/block/1>
|
||||
assert_eq!(base_fee, 980000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "optimism")]
|
||||
fn op_sepolia_genesis() {
|
||||
let genesis = OP_SEPOLIA.genesis_header();
|
||||
assert_eq!(
|
||||
genesis.hash_slow(),
|
||||
b256!("102de6ffb001480cc9b8b548fd05c34cd4f46ae4aa91759393db90ea0409887d")
|
||||
);
|
||||
let base_fee = genesis
|
||||
.next_block_base_fee(OP_SEPOLIA.base_fee_params_at_timestamp(genesis.timestamp))
|
||||
.unwrap();
|
||||
// <https://optimism-sepolia.blockscout.com/block/1>
|
||||
assert_eq!(base_fee, 980000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn latest_eth_mainnet_fork_id() {
|
||||
assert_eq!(
|
||||
@ -2651,234 +2349,4 @@ Post-merge hard forks (timestamp based):
|
||||
MAINNET.latest_fork_id()
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn latest_base_mainnet_fork_id() {
|
||||
assert_eq!(
|
||||
ForkId { hash: ForkHash([0xbc, 0x38, 0xf9, 0xca]), next: 0 },
|
||||
BASE_MAINNET.latest_fork_id()
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn is_bedrock_active() {
|
||||
assert!(!OP_MAINNET.is_bedrock_active_at_block(1))
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn parse_optimism_hardforks() {
|
||||
let geth_genesis = r#"
|
||||
{
|
||||
"config": {
|
||||
"bedrockBlock": 10,
|
||||
"regolithTime": 20,
|
||||
"canyonTime": 30,
|
||||
"ecotoneTime": 40,
|
||||
"fjordTime": 50,
|
||||
"graniteTime": 51,
|
||||
"optimism": {
|
||||
"eip1559Elasticity": 60,
|
||||
"eip1559Denominator": 70
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
let genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
|
||||
|
||||
let actual_bedrock_block = genesis.config.extra_fields.get("bedrockBlock");
|
||||
assert_eq!(actual_bedrock_block, Some(serde_json::Value::from(10)).as_ref());
|
||||
let actual_regolith_timestamp = genesis.config.extra_fields.get("regolithTime");
|
||||
assert_eq!(actual_regolith_timestamp, Some(serde_json::Value::from(20)).as_ref());
|
||||
let actual_canyon_timestamp = genesis.config.extra_fields.get("canyonTime");
|
||||
assert_eq!(actual_canyon_timestamp, Some(serde_json::Value::from(30)).as_ref());
|
||||
let actual_ecotone_timestamp = genesis.config.extra_fields.get("ecotoneTime");
|
||||
assert_eq!(actual_ecotone_timestamp, Some(serde_json::Value::from(40)).as_ref());
|
||||
let actual_fjord_timestamp = genesis.config.extra_fields.get("fjordTime");
|
||||
assert_eq!(actual_fjord_timestamp, Some(serde_json::Value::from(50)).as_ref());
|
||||
let actual_granite_timestamp = genesis.config.extra_fields.get("graniteTime");
|
||||
assert_eq!(actual_granite_timestamp, Some(serde_json::Value::from(51)).as_ref());
|
||||
|
||||
let optimism_object = genesis.config.extra_fields.get("optimism").unwrap();
|
||||
assert_eq!(
|
||||
optimism_object,
|
||||
&serde_json::json!({
|
||||
"eip1559Elasticity": 60,
|
||||
"eip1559Denominator": 70,
|
||||
})
|
||||
);
|
||||
|
||||
let chain_spec: ChainSpec = genesis.into();
|
||||
|
||||
assert_eq!(
|
||||
chain_spec.base_fee_params,
|
||||
BaseFeeParamsKind::Constant(BaseFeeParams::new(70, 60))
|
||||
);
|
||||
|
||||
assert!(!chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 0));
|
||||
|
||||
assert!(chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 10));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 20));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 30));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 40));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 50));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 51));
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn parse_optimism_hardforks_variable_base_fee_params() {
|
||||
let geth_genesis = r#"
|
||||
{
|
||||
"config": {
|
||||
"bedrockBlock": 10,
|
||||
"regolithTime": 20,
|
||||
"canyonTime": 30,
|
||||
"ecotoneTime": 40,
|
||||
"fjordTime": 50,
|
||||
"graniteTime": 51,
|
||||
"optimism": {
|
||||
"eip1559Elasticity": 60,
|
||||
"eip1559Denominator": 70,
|
||||
"eip1559DenominatorCanyon": 80
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
let genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
|
||||
|
||||
let actual_bedrock_block = genesis.config.extra_fields.get("bedrockBlock");
|
||||
assert_eq!(actual_bedrock_block, Some(serde_json::Value::from(10)).as_ref());
|
||||
let actual_regolith_timestamp = genesis.config.extra_fields.get("regolithTime");
|
||||
assert_eq!(actual_regolith_timestamp, Some(serde_json::Value::from(20)).as_ref());
|
||||
let actual_canyon_timestamp = genesis.config.extra_fields.get("canyonTime");
|
||||
assert_eq!(actual_canyon_timestamp, Some(serde_json::Value::from(30)).as_ref());
|
||||
let actual_ecotone_timestamp = genesis.config.extra_fields.get("ecotoneTime");
|
||||
assert_eq!(actual_ecotone_timestamp, Some(serde_json::Value::from(40)).as_ref());
|
||||
let actual_fjord_timestamp = genesis.config.extra_fields.get("fjordTime");
|
||||
assert_eq!(actual_fjord_timestamp, Some(serde_json::Value::from(50)).as_ref());
|
||||
let actual_granite_timestamp = genesis.config.extra_fields.get("graniteTime");
|
||||
assert_eq!(actual_granite_timestamp, Some(serde_json::Value::from(51)).as_ref());
|
||||
|
||||
let optimism_object = genesis.config.extra_fields.get("optimism").unwrap();
|
||||
assert_eq!(
|
||||
optimism_object,
|
||||
&serde_json::json!({
|
||||
"eip1559Elasticity": 60,
|
||||
"eip1559Denominator": 70,
|
||||
"eip1559DenominatorCanyon": 80
|
||||
})
|
||||
);
|
||||
|
||||
let chain_spec: ChainSpec = genesis.into();
|
||||
|
||||
assert_eq!(
|
||||
chain_spec.base_fee_params,
|
||||
BaseFeeParamsKind::Variable(
|
||||
vec![
|
||||
(EthereumHardfork::London.boxed(), BaseFeeParams::new(70, 60)),
|
||||
(OptimismHardfork::Canyon.boxed(), BaseFeeParams::new(80, 60)),
|
||||
]
|
||||
.into()
|
||||
)
|
||||
);
|
||||
|
||||
assert!(!chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 0));
|
||||
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 0));
|
||||
|
||||
assert!(chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 10));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 20));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 30));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 40));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 50));
|
||||
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 51));
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn parse_genesis_optimism_with_variable_base_fee_params() {
|
||||
use op_alloy_rpc_types::genesis::OptimismBaseFeeInfo;
|
||||
|
||||
let geth_genesis = r#"
|
||||
{
|
||||
"config": {
|
||||
"chainId": 8453,
|
||||
"homesteadBlock": 0,
|
||||
"eip150Block": 0,
|
||||
"eip155Block": 0,
|
||||
"eip158Block": 0,
|
||||
"byzantiumBlock": 0,
|
||||
"constantinopleBlock": 0,
|
||||
"petersburgBlock": 0,
|
||||
"istanbulBlock": 0,
|
||||
"muirGlacierBlock": 0,
|
||||
"berlinBlock": 0,
|
||||
"londonBlock": 0,
|
||||
"arrowGlacierBlock": 0,
|
||||
"grayGlacierBlock": 0,
|
||||
"mergeNetsplitBlock": 0,
|
||||
"bedrockBlock": 0,
|
||||
"regolithTime": 15,
|
||||
"terminalTotalDifficulty": 0,
|
||||
"terminalTotalDifficultyPassed": true,
|
||||
"optimism": {
|
||||
"eip1559Elasticity": 6,
|
||||
"eip1559Denominator": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
let genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
|
||||
let chainspec = ChainSpec::from(genesis.clone());
|
||||
|
||||
let actual_chain_id = genesis.config.chain_id;
|
||||
assert_eq!(actual_chain_id, 8453);
|
||||
|
||||
assert_eq!(
|
||||
chainspec.hardforks.get(EthereumHardfork::Istanbul),
|
||||
Some(ForkCondition::Block(0))
|
||||
);
|
||||
|
||||
let actual_bedrock_block = genesis.config.extra_fields.get("bedrockBlock");
|
||||
assert_eq!(actual_bedrock_block, Some(serde_json::Value::from(0)).as_ref());
|
||||
let actual_canyon_timestamp = genesis.config.extra_fields.get("canyonTime");
|
||||
assert_eq!(actual_canyon_timestamp, None);
|
||||
|
||||
assert!(genesis.config.terminal_total_difficulty_passed);
|
||||
|
||||
let optimism_object = genesis.config.extra_fields.get("optimism").unwrap();
|
||||
let optimism_base_fee_info =
|
||||
serde_json::from_value::<OptimismBaseFeeInfo>(optimism_object.clone()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
optimism_base_fee_info,
|
||||
OptimismBaseFeeInfo {
|
||||
eip1559_elasticity: Some(6),
|
||||
eip1559_denominator: Some(50),
|
||||
eip1559_denominator_canyon: None,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
chainspec.base_fee_params,
|
||||
BaseFeeParamsKind::Constant(BaseFeeParams {
|
||||
max_change_denominator: 50,
|
||||
elasticity_multiplier: 6,
|
||||
})
|
||||
);
|
||||
|
||||
assert!(chainspec.is_fork_active_at_block(OptimismHardfork::Bedrock, 0));
|
||||
|
||||
assert!(chainspec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 20));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user