1extern 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#[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
24pub 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
58pub 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}