reth_seismic_forks/
lib.rs

1//! Seismic-Reth hard forks.
2extern crate alloc;
3
4use alloc::vec;
5use alloy_primitives::uint;
6use once_cell::sync::Lazy as LazyLock;
7use reth_ethereum_forks::{ChainHardforks, EthereumHardfork, ForkCondition, Hardfork};
8
9/// Seismic hardfork enum
10#[derive(Clone, Debug)]
11#[allow(missing_docs)]
12pub enum SeismicHardfork {
13    Mercury,
14}
15
16impl Hardfork for SeismicHardfork {
17    fn name(&self) -> &'static str {
18        match self {
19            Self::Mercury => "Mercury",
20        }
21    }
22}
23
24/// Mainnet hardforks
25/// Based off EthereumHardfork::mainnet(),
26/// with existing eth hardforks activated at block 0
27pub static SEISMIC_MAINNET_HARDFORKS: LazyLock<ChainHardforks> = LazyLock::new(|| {
28    ChainHardforks::new(vec![
29        (EthereumHardfork::Frontier.boxed(), ForkCondition::Block(0)),
30        (EthereumHardfork::Homestead.boxed(), ForkCondition::Block(0)),
31        (EthereumHardfork::Dao.boxed(), ForkCondition::Block(0)),
32        (EthereumHardfork::Tangerine.boxed(), ForkCondition::Block(0)),
33        (EthereumHardfork::SpuriousDragon.boxed(), ForkCondition::Block(0)),
34        (EthereumHardfork::Byzantium.boxed(), ForkCondition::Block(0)),
35        (EthereumHardfork::Constantinople.boxed(), ForkCondition::Block(0)),
36        (EthereumHardfork::Petersburg.boxed(), ForkCondition::Block(0)),
37        (EthereumHardfork::Istanbul.boxed(), ForkCondition::Block(0)),
38        (EthereumHardfork::MuirGlacier.boxed(), ForkCondition::Block(0)),
39        (EthereumHardfork::Berlin.boxed(), ForkCondition::Block(0)),
40        (EthereumHardfork::London.boxed(), ForkCondition::Block(0)),
41        (EthereumHardfork::ArrowGlacier.boxed(), ForkCondition::Block(0)),
42        (EthereumHardfork::GrayGlacier.boxed(), ForkCondition::Block(0)),
43        (
44            EthereumHardfork::Paris.boxed(),
45            ForkCondition::TTD {
46                activation_block_number: 0,
47                fork_block: None,
48                total_difficulty: uint!(58_750_000_000_000_000_000_000_U256),
49            },
50        ),
51        (EthereumHardfork::Shanghai.boxed(), ForkCondition::Timestamp(0)),
52        (EthereumHardfork::Cancun.boxed(), ForkCondition::Timestamp(0)),
53        (EthereumHardfork::Prague.boxed(), ForkCondition::Timestamp(0)),
54        (SeismicHardfork::Mercury.boxed(), ForkCondition::Timestamp(0)),
55    ])
56});
57
58/// Dev hardforks
59pub static SEISMIC_DEV_HARDFORKS: LazyLock<ChainHardforks> = LazyLock::new(|| {
60    ChainHardforks::new(vec![
61        (EthereumHardfork::Frontier.boxed(), ForkCondition::Block(0)),
62        (EthereumHardfork::Homestead.boxed(), ForkCondition::Block(0)),
63        (EthereumHardfork::Dao.boxed(), ForkCondition::Block(0)),
64        (EthereumHardfork::Tangerine.boxed(), ForkCondition::Block(0)),
65        (EthereumHardfork::SpuriousDragon.boxed(), ForkCondition::Block(0)),
66        (EthereumHardfork::Byzantium.boxed(), ForkCondition::Block(0)),
67        (EthereumHardfork::Constantinople.boxed(), ForkCondition::Block(0)),
68        (EthereumHardfork::Petersburg.boxed(), ForkCondition::Block(0)),
69        (EthereumHardfork::Istanbul.boxed(), ForkCondition::Block(0)),
70        (EthereumHardfork::MuirGlacier.boxed(), ForkCondition::Block(0)),
71        (EthereumHardfork::Berlin.boxed(), ForkCondition::Block(0)),
72        (EthereumHardfork::London.boxed(), ForkCondition::Block(0)),
73        (EthereumHardfork::ArrowGlacier.boxed(), ForkCondition::Block(0)),
74        (EthereumHardfork::GrayGlacier.boxed(), ForkCondition::Block(0)),
75        (
76            EthereumHardfork::Paris.boxed(),
77            ForkCondition::TTD {
78                activation_block_number: 0,
79                fork_block: None,
80                total_difficulty: uint!(58_750_000_000_000_000_000_000_U256),
81            },
82        ),
83        (EthereumHardfork::Shanghai.boxed(), ForkCondition::Timestamp(0)),
84        (EthereumHardfork::Cancun.boxed(), ForkCondition::Timestamp(0)),
85        (EthereumHardfork::Prague.boxed(), ForkCondition::Timestamp(0)),
86        (SeismicHardfork::Mercury.boxed(), ForkCondition::Timestamp(0)),
87    ])
88});
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93    use core::panic;
94
95    #[test]
96    fn check_ethereum_hardforks_at_zero() {
97        let eth_mainnet_forks = EthereumHardfork::mainnet();
98        let seismic_hardforks = SEISMIC_MAINNET_HARDFORKS.clone();
99        for eth_hf in eth_mainnet_forks {
100            let (fork, _) = eth_hf;
101            let lookup = seismic_hardforks.get(fork);
102            match lookup {
103                Some(condition) => {
104                    if fork <= EthereumHardfork::Prague {
105                        assert!(
106                            condition.active_at_timestamp(0) || condition.active_at_block(0),
107                            "Hardfork {} not active at timestamp 1",
108                            fork
109                        );
110                    }
111                }
112                None => {
113                    panic!("Hardfork {} not found in hardforks", fork);
114                }
115            }
116        }
117    }
118
119    #[test]
120    fn check_seismic_hardforks_at_zero() {
121        let seismic_hardforks = SEISMIC_MAINNET_HARDFORKS.clone();
122        assert!(
123            seismic_hardforks.get(SeismicHardfork::Mercury).is_some(),
124            "Missing hardfork mercury"
125        );
126    }
127}