reth_ethereum_forks/hardfork/
mod.rs

1mod macros;
2
3mod ethereum;
4pub use ethereum::EthereumHardfork;
5
6mod dev;
7pub use dev::DEV_HARDFORKS;
8
9use core::{
10    any::Any,
11    hash::{Hash, Hasher},
12};
13use dyn_clone::DynClone;
14
15/// Generic hardfork trait.
16#[auto_impl::auto_impl(&, Box)]
17pub trait Hardfork: Any + DynClone + Send + Sync + 'static {
18    /// Fork name.
19    fn name(&self) -> &'static str;
20}
21
22dyn_clone::clone_trait_object!(Hardfork);
23
24impl core::fmt::Debug for dyn Hardfork + 'static {
25    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26        f.debug_struct(self.name()).finish()
27    }
28}
29
30impl PartialEq for dyn Hardfork + 'static {
31    fn eq(&self, other: &Self) -> bool {
32        self.name() == other.name()
33    }
34}
35
36impl Eq for dyn Hardfork + 'static {}
37
38impl Hash for dyn Hardfork + 'static {
39    fn hash<H: Hasher>(&self, state: &mut H) {
40        self.name().hash(state)
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    use std::str::FromStr;
48
49    #[test]
50    fn check_hardfork_from_str() {
51        let hardfork_str = [
52            "frOntier",
53            "homEstead",
54            "dao",
55            "tAngerIne",
56            "spurIousdrAgon",
57            "byzAntium",
58            "constantinople",
59            "petersburg",
60            "istanbul",
61            "muirglacier",
62            "bErlin",
63            "lonDon",
64            "arrowglacier",
65            "grayglacier",
66            "PARIS",
67            "ShAnGhAI",
68            "CaNcUn",
69            "PrAguE",
70        ];
71        let expected_hardforks = [
72            EthereumHardfork::Frontier,
73            EthereumHardfork::Homestead,
74            EthereumHardfork::Dao,
75            EthereumHardfork::Tangerine,
76            EthereumHardfork::SpuriousDragon,
77            EthereumHardfork::Byzantium,
78            EthereumHardfork::Constantinople,
79            EthereumHardfork::Petersburg,
80            EthereumHardfork::Istanbul,
81            EthereumHardfork::MuirGlacier,
82            EthereumHardfork::Berlin,
83            EthereumHardfork::London,
84            EthereumHardfork::ArrowGlacier,
85            EthereumHardfork::GrayGlacier,
86            EthereumHardfork::Paris,
87            EthereumHardfork::Shanghai,
88            EthereumHardfork::Cancun,
89            EthereumHardfork::Prague,
90        ];
91
92        let hardforks: Vec<EthereumHardfork> =
93            hardfork_str.iter().map(|h| EthereumHardfork::from_str(h).unwrap()).collect();
94
95        assert_eq!(hardforks, expected_hardforks);
96    }
97
98    #[test]
99    fn check_nonexistent_hardfork_from_str() {
100        assert!(EthereumHardfork::from_str("not a hardfork").is_err());
101    }
102}