revm_optimism/
spec.rs

1use revm::specification::hardfork::SpecId;
2
3#[repr(u8)]
4#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Default)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6#[allow(non_camel_case_types)]
7pub enum OpSpecId {
8    BEDROCK = 100,
9    REGOLITH,
10    CANYON,
11    ECOTONE,
12    FJORD,
13    GRANITE,
14    HOLOCENE,
15    #[default]
16    ISTHMUS,
17    INTEROP,
18}
19
20impl OpSpecId {
21    /// Converts the [`OpSpecId`] into a [`SpecId`].
22    pub const fn into_eth_spec(self) -> SpecId {
23        match self {
24            Self::BEDROCK | Self::REGOLITH => SpecId::MERGE,
25            Self::CANYON => SpecId::SHANGHAI,
26            Self::ECOTONE | Self::FJORD | Self::GRANITE | Self::HOLOCENE => SpecId::CANCUN,
27            Self::ISTHMUS | Self::INTEROP => SpecId::PRAGUE,
28        }
29    }
30
31    pub const fn is_enabled_in(self, other: OpSpecId) -> bool {
32        other as u8 <= self as u8
33    }
34}
35
36impl From<OpSpecId> for SpecId {
37    fn from(spec: OpSpecId) -> Self {
38        spec.into_eth_spec()
39    }
40}
41
42impl TryFrom<&str> for OpSpecId {
43    type Error = ();
44
45    fn try_from(name: &str) -> Result<Self, Self::Error> {
46        match name {
47            name::BEDROCK => Ok(OpSpecId::BEDROCK),
48            name::REGOLITH => Ok(OpSpecId::REGOLITH),
49            name::CANYON => Ok(OpSpecId::CANYON),
50            name::ECOTONE => Ok(OpSpecId::ECOTONE),
51            name::FJORD => Ok(OpSpecId::FJORD),
52            name::GRANITE => Ok(OpSpecId::GRANITE),
53            _ => Err(()),
54        }
55    }
56}
57
58impl From<OpSpecId> for &'static str {
59    fn from(spec_id: OpSpecId) -> Self {
60        match spec_id {
61            OpSpecId::BEDROCK => name::BEDROCK,
62            OpSpecId::REGOLITH => name::REGOLITH,
63            OpSpecId::CANYON => name::CANYON,
64            OpSpecId::ECOTONE => name::ECOTONE,
65            OpSpecId::FJORD => name::FJORD,
66            OpSpecId::GRANITE => name::GRANITE,
67            OpSpecId::HOLOCENE => name::HOLOCENE,
68            OpSpecId::ISTHMUS => name::ISTHMUS,
69            OpSpecId::INTEROP => name::INTEROP,
70        }
71    }
72}
73
74/// String identifiers for Optimism hardforks
75pub mod name {
76    pub const BEDROCK: &str = "Bedrock";
77    pub const REGOLITH: &str = "Regolith";
78    pub const CANYON: &str = "Canyon";
79    pub const ECOTONE: &str = "Ecotone";
80    pub const FJORD: &str = "Fjord";
81    pub const GRANITE: &str = "Granite";
82    pub const HOLOCENE: &str = "Holocene";
83    pub const ISTHMUS: &str = "Isthmus";
84    pub const INTEROP: &str = "Interop";
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90
91    #[test]
92    fn test_bedrock_post_merge_hardforks() {
93        assert!(OpSpecId::BEDROCK
94            .into_eth_spec()
95            .is_enabled_in(SpecId::MERGE));
96        assert!(!OpSpecId::BEDROCK
97            .into_eth_spec()
98            .is_enabled_in(SpecId::SHANGHAI));
99        assert!(!OpSpecId::BEDROCK
100            .into_eth_spec()
101            .is_enabled_in(SpecId::CANCUN));
102        assert!(!OpSpecId::BEDROCK
103            .into_eth_spec()
104            .is_enabled_in(SpecId::LATEST));
105        assert!(OpSpecId::BEDROCK.is_enabled_in(OpSpecId::BEDROCK));
106        assert!(!OpSpecId::BEDROCK.is_enabled_in(OpSpecId::REGOLITH));
107    }
108
109    #[test]
110    fn test_regolith_post_merge_hardforks() {
111        assert!(OpSpecId::REGOLITH
112            .into_eth_spec()
113            .is_enabled_in(SpecId::MERGE));
114        assert!(!OpSpecId::REGOLITH
115            .into_eth_spec()
116            .is_enabled_in(SpecId::SHANGHAI));
117        assert!(!OpSpecId::REGOLITH
118            .into_eth_spec()
119            .is_enabled_in(SpecId::CANCUN));
120        assert!(!OpSpecId::REGOLITH
121            .into_eth_spec()
122            .is_enabled_in(SpecId::LATEST));
123        assert!(OpSpecId::REGOLITH.is_enabled_in(OpSpecId::BEDROCK));
124        assert!(OpSpecId::REGOLITH.is_enabled_in(OpSpecId::REGOLITH));
125    }
126
127    #[test]
128    fn test_canyon_post_merge_hardforks() {
129        assert!(OpSpecId::CANYON
130            .into_eth_spec()
131            .is_enabled_in(SpecId::MERGE));
132        assert!(OpSpecId::CANYON
133            .into_eth_spec()
134            .is_enabled_in(SpecId::SHANGHAI));
135        assert!(!OpSpecId::CANYON
136            .into_eth_spec()
137            .is_enabled_in(SpecId::CANCUN));
138        assert!(!OpSpecId::CANYON
139            .into_eth_spec()
140            .is_enabled_in(SpecId::LATEST));
141        assert!(OpSpecId::CANYON.is_enabled_in(OpSpecId::BEDROCK));
142        assert!(OpSpecId::CANYON.is_enabled_in(OpSpecId::REGOLITH));
143        assert!(OpSpecId::CANYON.is_enabled_in(OpSpecId::CANYON));
144    }
145
146    #[test]
147    fn test_ecotone_post_merge_hardforks() {
148        assert!(OpSpecId::ECOTONE
149            .into_eth_spec()
150            .is_enabled_in(SpecId::MERGE));
151        assert!(OpSpecId::ECOTONE
152            .into_eth_spec()
153            .is_enabled_in(SpecId::SHANGHAI));
154        assert!(OpSpecId::ECOTONE
155            .into_eth_spec()
156            .is_enabled_in(SpecId::CANCUN));
157        assert!(!OpSpecId::ECOTONE
158            .into_eth_spec()
159            .is_enabled_in(SpecId::LATEST));
160        assert!(OpSpecId::ECOTONE.is_enabled_in(OpSpecId::BEDROCK));
161        assert!(OpSpecId::ECOTONE.is_enabled_in(OpSpecId::REGOLITH));
162        assert!(OpSpecId::ECOTONE.is_enabled_in(OpSpecId::CANYON));
163        assert!(OpSpecId::ECOTONE.is_enabled_in(OpSpecId::ECOTONE));
164    }
165
166    #[test]
167    fn test_fjord_post_merge_hardforks() {
168        assert!(OpSpecId::FJORD.into_eth_spec().is_enabled_in(SpecId::MERGE));
169        assert!(OpSpecId::FJORD
170            .into_eth_spec()
171            .is_enabled_in(SpecId::SHANGHAI));
172        assert!(OpSpecId::FJORD
173            .into_eth_spec()
174            .is_enabled_in(SpecId::CANCUN));
175        assert!(!OpSpecId::FJORD
176            .into_eth_spec()
177            .is_enabled_in(SpecId::LATEST));
178        assert!(OpSpecId::FJORD.is_enabled_in(OpSpecId::BEDROCK));
179        assert!(OpSpecId::FJORD.is_enabled_in(OpSpecId::REGOLITH));
180        assert!(OpSpecId::FJORD.is_enabled_in(OpSpecId::CANYON));
181        assert!(OpSpecId::FJORD.is_enabled_in(OpSpecId::ECOTONE));
182        assert!(OpSpecId::FJORD.is_enabled_in(OpSpecId::FJORD));
183    }
184}