mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: deduplicate fork timestamp configuration in ChainSpec (#8038)
This commit is contained in:
@ -479,8 +479,8 @@ mod tests {
|
||||
DatabaseEnv,
|
||||
};
|
||||
use reth_primitives::{
|
||||
Chain, ForkTimestamps, Genesis, IntegerList, GOERLI, GOERLI_GENESIS_HASH, MAINNET,
|
||||
MAINNET_GENESIS_HASH, SEPOLIA, SEPOLIA_GENESIS_HASH,
|
||||
Chain, Genesis, IntegerList, GOERLI, GOERLI_GENESIS_HASH, MAINNET, MAINNET_GENESIS_HASH,
|
||||
SEPOLIA, SEPOLIA_GENESIS_HASH,
|
||||
};
|
||||
use reth_provider::test_utils::create_test_provider_factory_with_chain_spec;
|
||||
|
||||
@ -570,7 +570,6 @@ mod tests {
|
||||
..Default::default()
|
||||
},
|
||||
hardforks: BTreeMap::default(),
|
||||
fork_timestamps: ForkTimestamps::default(),
|
||||
genesis_hash: None,
|
||||
paris_block_and_final_difficulty: None,
|
||||
deposit_contract: None,
|
||||
|
||||
@ -2,8 +2,7 @@ pub use alloy_chains::{Chain, ChainKind, NamedChain};
|
||||
pub use info::ChainInfo;
|
||||
pub use spec::{
|
||||
AllGenesisFormats, BaseFeeParams, BaseFeeParamsKind, ChainSpec, ChainSpecBuilder,
|
||||
DisplayHardforks, ForkBaseFeeParams, ForkCondition, ForkTimestamps, DEV, GOERLI, HOLESKY,
|
||||
MAINNET, SEPOLIA,
|
||||
DisplayHardforks, ForkBaseFeeParams, ForkCondition, DEV, GOERLI, HOLESKY, MAINNET, SEPOLIA,
|
||||
};
|
||||
#[cfg(feature = "optimism")]
|
||||
pub use spec::{BASE_MAINNET, BASE_SEPOLIA, OP_MAINNET, OP_SEPOLIA};
|
||||
|
||||
@ -41,7 +41,6 @@ pub static MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
15537394,
|
||||
U256::from(58_750_003_716_598_352_816_469u128),
|
||||
)),
|
||||
fork_timestamps: ForkTimestamps::default().shanghai(1681338455).cancun(1710338135),
|
||||
hardforks: BTreeMap::from([
|
||||
(Hardfork::Frontier, ForkCondition::Block(0)),
|
||||
(Hardfork::Homestead, ForkCondition::Block(1150000)),
|
||||
@ -90,7 +89,6 @@ pub static GOERLI: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
)),
|
||||
// <https://goerli.etherscan.io/block/7382818>
|
||||
paris_block_and_final_difficulty: Some((7382818, U256::from(10_790_000))),
|
||||
fork_timestamps: ForkTimestamps::default().shanghai(1678832736).cancun(1705473120),
|
||||
hardforks: BTreeMap::from([
|
||||
(Hardfork::Frontier, ForkCondition::Block(0)),
|
||||
(Hardfork::Homestead, ForkCondition::Block(0)),
|
||||
@ -133,7 +131,6 @@ pub static SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
)),
|
||||
// <https://sepolia.etherscan.io/block/1450409>
|
||||
paris_block_and_final_difficulty: Some((1450409, U256::from(17_000_018_015_853_232u128))),
|
||||
fork_timestamps: ForkTimestamps::default().shanghai(1677557088).cancun(1706655072),
|
||||
hardforks: BTreeMap::from([
|
||||
(Hardfork::Frontier, ForkCondition::Block(0)),
|
||||
(Hardfork::Homestead, ForkCondition::Block(0)),
|
||||
@ -179,7 +176,6 @@ pub static HOLESKY: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
"b5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4"
|
||||
)),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(1))),
|
||||
fork_timestamps: ForkTimestamps::default().shanghai(1696000704).cancun(1707305664),
|
||||
hardforks: BTreeMap::from([
|
||||
(Hardfork::Frontier, ForkCondition::Block(0)),
|
||||
(Hardfork::Homestead, ForkCondition::Block(0)),
|
||||
@ -224,7 +220,6 @@ pub static DEV: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
"2f980576711e3617a5e4d83dd539548ec0f7792007d505a3d2e9674833af2d7c"
|
||||
)),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
fork_timestamps: ForkTimestamps::default().shanghai(0).cancun(0),
|
||||
hardforks: BTreeMap::from([
|
||||
(Hardfork::Frontier, ForkCondition::Block(0)),
|
||||
(Hardfork::Homestead, ForkCondition::Block(0)),
|
||||
@ -270,11 +265,6 @@ pub static OP_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
genesis_hash: Some(b256!(
|
||||
"7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b"
|
||||
)),
|
||||
fork_timestamps: ForkTimestamps::default()
|
||||
.shanghai(1704992401)
|
||||
.canyon(1704992401)
|
||||
.cancun(1710374401)
|
||||
.ecotone(1710374401),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
hardforks: BTreeMap::from([
|
||||
(Hardfork::Frontier, ForkCondition::Block(0)),
|
||||
@ -322,11 +312,6 @@ pub static OP_SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
genesis_hash: Some(b256!(
|
||||
"102de6ffb001480cc9b8b548fd05c34cd4f46ae4aa91759393db90ea0409887d"
|
||||
)),
|
||||
fork_timestamps: ForkTimestamps::default()
|
||||
.shanghai(1699981200)
|
||||
.canyon(1699981200)
|
||||
.cancun(1708534800)
|
||||
.ecotone(1708534800),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
hardforks: BTreeMap::from([
|
||||
(Hardfork::Frontier, ForkCondition::Block(0)),
|
||||
@ -376,11 +361,6 @@ pub static BASE_SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
genesis_hash: Some(b256!(
|
||||
"0dcc9e089e30b90ddfc55be9a37dd15bc551aeee999d2e2b51414c54eaf934e4"
|
||||
)),
|
||||
fork_timestamps: ForkTimestamps::default()
|
||||
.shanghai(1699981200)
|
||||
.canyon(1699981200)
|
||||
.cancun(1708534800)
|
||||
.ecotone(1708534800),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
hardforks: BTreeMap::from([
|
||||
(Hardfork::Frontier, ForkCondition::Block(0)),
|
||||
@ -430,11 +410,6 @@ pub static BASE_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
genesis_hash: Some(b256!(
|
||||
"f712aa9241cc24369b143cf6dce85f0902a9731e70d66818a3a5845b296c73dd"
|
||||
)),
|
||||
fork_timestamps: ForkTimestamps::default()
|
||||
.shanghai(1704992401)
|
||||
.canyon(1704992401)
|
||||
.cancun(1710374401)
|
||||
.ecotone(1710374401),
|
||||
paris_block_and_final_difficulty: Some((0, U256::from(0))),
|
||||
hardforks: BTreeMap::from([
|
||||
(Hardfork::Frontier, ForkCondition::Block(0)),
|
||||
@ -535,12 +510,6 @@ pub struct ChainSpec {
|
||||
#[serde(skip, default)]
|
||||
pub paris_block_and_final_difficulty: Option<(u64, U256)>,
|
||||
|
||||
/// Timestamps of various hardforks
|
||||
///
|
||||
/// This caches entries in `hardforks` map
|
||||
#[serde(skip, default)]
|
||||
pub fork_timestamps: ForkTimestamps,
|
||||
|
||||
/// The active hard forks and their activation conditions
|
||||
pub hardforks: BTreeMap<Hardfork, ForkCondition>,
|
||||
|
||||
@ -565,7 +534,6 @@ impl Default for ChainSpec {
|
||||
genesis_hash: Default::default(),
|
||||
genesis: Default::default(),
|
||||
paris_block_and_final_difficulty: Default::default(),
|
||||
fork_timestamps: Default::default(),
|
||||
hardforks: Default::default(),
|
||||
deposit_contract: Default::default(),
|
||||
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
|
||||
@ -819,28 +787,19 @@ impl ChainSpec {
|
||||
/// Convenience method to check if [Hardfork::Shanghai] is active at a given timestamp.
|
||||
#[inline]
|
||||
pub fn is_shanghai_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||
self.fork_timestamps
|
||||
.shanghai
|
||||
.map(|shanghai| timestamp >= shanghai)
|
||||
.unwrap_or_else(|| self.is_fork_active_at_timestamp(Hardfork::Shanghai, timestamp))
|
||||
self.is_fork_active_at_timestamp(Hardfork::Shanghai, timestamp)
|
||||
}
|
||||
|
||||
/// Convenience method to check if [Hardfork::Cancun] is active at a given timestamp.
|
||||
#[inline]
|
||||
pub fn is_cancun_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||
self.fork_timestamps
|
||||
.cancun
|
||||
.map(|cancun| timestamp >= cancun)
|
||||
.unwrap_or_else(|| self.is_fork_active_at_timestamp(Hardfork::Cancun, timestamp))
|
||||
self.is_fork_active_at_timestamp(Hardfork::Cancun, timestamp)
|
||||
}
|
||||
|
||||
/// Convenience method to check if [Hardfork::Prague] is active at a given timestamp.
|
||||
#[inline]
|
||||
pub fn is_prague_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||
self.fork_timestamps
|
||||
.prague
|
||||
.map(|prague| timestamp >= prague)
|
||||
.unwrap_or_else(|| self.is_fork_active_at_timestamp(Hardfork::Prague, timestamp))
|
||||
self.is_fork_active_at_timestamp(Hardfork::Prague, timestamp)
|
||||
}
|
||||
|
||||
/// Convenience method to check if [Hardfork::Byzantium] is active at a given block number.
|
||||
@ -1084,7 +1043,6 @@ impl From<Genesis> for ChainSpec {
|
||||
chain: genesis.config.chain_id.into(),
|
||||
genesis,
|
||||
genesis_hash: None,
|
||||
fork_timestamps: ForkTimestamps::from_hardforks(&hardforks),
|
||||
hardforks,
|
||||
paris_block_and_final_difficulty,
|
||||
deposit_contract: None,
|
||||
@ -1093,94 +1051,6 @@ impl From<Genesis> for ChainSpec {
|
||||
}
|
||||
}
|
||||
|
||||
/// Various timestamps of forks
|
||||
#[derive(Debug, Clone, Default, Eq, PartialEq)]
|
||||
pub struct ForkTimestamps {
|
||||
/// The timestamp of the Shanghai fork
|
||||
pub shanghai: Option<u64>,
|
||||
/// The timestamp of the Cancun fork
|
||||
pub cancun: Option<u64>,
|
||||
/// The timestamp of the Prague fork
|
||||
pub prague: Option<u64>,
|
||||
/// The timestamp of the Regolith fork
|
||||
#[cfg(feature = "optimism")]
|
||||
pub regolith: Option<u64>,
|
||||
/// The timestamp of the Canyon fork
|
||||
#[cfg(feature = "optimism")]
|
||||
pub canyon: Option<u64>,
|
||||
/// The timestamp of the Ecotone fork
|
||||
#[cfg(feature = "optimism")]
|
||||
pub ecotone: Option<u64>,
|
||||
}
|
||||
|
||||
impl ForkTimestamps {
|
||||
/// Creates a new [`ForkTimestamps`] from the given hardforks by extracting the timestamps
|
||||
fn from_hardforks(forks: &BTreeMap<Hardfork, ForkCondition>) -> Self {
|
||||
let mut timestamps = ForkTimestamps::default();
|
||||
if let Some(shanghai) = forks.get(&Hardfork::Shanghai).and_then(|f| f.as_timestamp()) {
|
||||
timestamps = timestamps.shanghai(shanghai);
|
||||
}
|
||||
if let Some(cancun) = forks.get(&Hardfork::Cancun).and_then(|f| f.as_timestamp()) {
|
||||
timestamps = timestamps.cancun(cancun);
|
||||
}
|
||||
if let Some(prague) = forks.get(&Hardfork::Prague).and_then(|f| f.as_timestamp()) {
|
||||
timestamps = timestamps.prague(prague);
|
||||
}
|
||||
#[cfg(feature = "optimism")]
|
||||
{
|
||||
if let Some(regolith) = forks.get(&Hardfork::Regolith).and_then(|f| f.as_timestamp()) {
|
||||
timestamps = timestamps.regolith(regolith);
|
||||
}
|
||||
if let Some(canyon) = forks.get(&Hardfork::Canyon).and_then(|f| f.as_timestamp()) {
|
||||
timestamps = timestamps.canyon(canyon);
|
||||
}
|
||||
if let Some(ecotone) = forks.get(&Hardfork::Ecotone).and_then(|f| f.as_timestamp()) {
|
||||
timestamps = timestamps.ecotone(ecotone);
|
||||
}
|
||||
}
|
||||
timestamps
|
||||
}
|
||||
|
||||
/// Sets the given Shanghai timestamp
|
||||
pub fn shanghai(mut self, shanghai: u64) -> Self {
|
||||
self.shanghai = Some(shanghai);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the given Cancun timestamp
|
||||
pub fn cancun(mut self, cancun: u64) -> Self {
|
||||
self.cancun = Some(cancun);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the given Prague timestamp
|
||||
pub fn prague(mut self, prague: u64) -> Self {
|
||||
self.prague = Some(prague);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the given regolith timestamp
|
||||
#[cfg(feature = "optimism")]
|
||||
pub fn regolith(mut self, regolith: u64) -> Self {
|
||||
self.regolith = Some(regolith);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the given canyon timestamp
|
||||
#[cfg(feature = "optimism")]
|
||||
pub fn canyon(mut self, canyon: u64) -> Self {
|
||||
self.canyon = Some(canyon);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the given ecotone timestamp
|
||||
#[cfg(feature = "optimism")]
|
||||
pub fn ecotone(mut self, ecotone: u64) -> Self {
|
||||
self.ecotone = Some(ecotone);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper type for compatibility with geth's config
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
@ -1418,7 +1288,6 @@ impl ChainSpecBuilder {
|
||||
chain: self.chain.expect("The chain is required"),
|
||||
genesis: self.genesis.expect("The genesis is required"),
|
||||
genesis_hash: None,
|
||||
fork_timestamps: ForkTimestamps::from_hardforks(&self.hardforks),
|
||||
hardforks: self.hardforks,
|
||||
paris_block_and_final_difficulty,
|
||||
deposit_contract: None,
|
||||
@ -1839,36 +1708,6 @@ Post-merge hard forks (timestamp based):
|
||||
);
|
||||
}
|
||||
|
||||
// Tests that the ForkTimestamps are correctly set up.
|
||||
#[test]
|
||||
fn test_fork_timestamps() {
|
||||
let spec = ChainSpec::builder().chain(Chain::mainnet()).genesis(Genesis::default()).build();
|
||||
assert!(spec.fork_timestamps.shanghai.is_none());
|
||||
|
||||
let spec = ChainSpec::builder()
|
||||
.chain(Chain::mainnet())
|
||||
.genesis(Genesis::default())
|
||||
.with_fork(Hardfork::Shanghai, ForkCondition::Timestamp(1337))
|
||||
.build();
|
||||
assert_eq!(spec.fork_timestamps.shanghai, Some(1337));
|
||||
assert!(spec.is_shanghai_active_at_timestamp(1337));
|
||||
assert!(!spec.is_shanghai_active_at_timestamp(1336));
|
||||
}
|
||||
|
||||
// Tests that all predefined timestamps are correctly set up in the chainspecs
|
||||
#[test]
|
||||
fn test_predefined_chain_spec_fork_timestamps() {
|
||||
let predefined = [&MAINNET, &SEPOLIA, &HOLESKY, &GOERLI];
|
||||
|
||||
for spec in predefined.iter() {
|
||||
let expected_timestamp_forks = &spec.fork_timestamps;
|
||||
let got_timestamp_forks = ForkTimestamps::from_hardforks(&spec.hardforks);
|
||||
|
||||
// make sure they're the same
|
||||
assert_eq!(expected_timestamp_forks, &got_timestamp_forks);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that we skip any fork blocks in block #0 (the genesis ruleset)
|
||||
#[test]
|
||||
fn ignores_genesis_fork_blocks() {
|
||||
|
||||
@ -56,8 +56,8 @@ pub use block::{
|
||||
};
|
||||
pub use chain::{
|
||||
AllGenesisFormats, BaseFeeParams, BaseFeeParamsKind, Chain, ChainInfo, ChainKind, ChainSpec,
|
||||
ChainSpecBuilder, DisplayHardforks, ForkBaseFeeParams, ForkCondition, ForkTimestamps,
|
||||
NamedChain, DEV, GOERLI, HOLESKY, MAINNET, SEPOLIA,
|
||||
ChainSpecBuilder, DisplayHardforks, ForkBaseFeeParams, ForkCondition, NamedChain, DEV, GOERLI,
|
||||
HOLESKY, MAINNET, SEPOLIA,
|
||||
};
|
||||
#[cfg(feature = "zstd-codec")]
|
||||
pub use compression::*;
|
||||
|
||||
Reference in New Issue
Block a user