revm_primitives/
hardfork.rs

1#![allow(non_camel_case_types)]
2// enumn has missing docs. Should be replaced in the future https://github.com/bluealloy/revm/issues/2402
3#![allow(missing_docs)]
4
5use core::str::FromStr;
6pub use num_enum::TryFromPrimitive;
7pub use std::string::{String, ToString};
8pub use SpecId::*;
9
10/// Specification IDs and their activation block
11///
12/// Information was obtained from the [Ethereum Execution Specifications](https://github.com/ethereum/execution-specs).
13#[repr(u8)]
14#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, TryFromPrimitive)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub enum SpecId {
17    /// Frontier hard fork
18    /// Activated at block 0
19    FRONTIER = 0,
20    /// Frontier Thawing hard fork
21    /// Activated at block 200000
22    FRONTIER_THAWING,
23    /// Homestead hard fork
24    /// Activated at block 1150000
25    HOMESTEAD,
26    /// DAO Fork hard fork
27    /// Activated at block 1920000
28    DAO_FORK,
29    /// Tangerine Whistle hard fork
30    /// Activated at block 2463000
31    TANGERINE,
32    /// Spurious Dragon hard fork
33    /// Activated at block 2675000
34    SPURIOUS_DRAGON,
35    /// Byzantium hard fork
36    /// Activated at block 4370000
37    BYZANTIUM,
38    /// Constantinople hard fork
39    /// Activated at block 7280000 is overwritten with PETERSBURG
40    CONSTANTINOPLE,
41    /// Petersburg hard fork
42    /// Activated at block 7280000
43    PETERSBURG,
44    /// Istanbul hard fork
45    /// Activated at block 9069000
46    ISTANBUL,
47    /// Muir Glacier hard fork
48    /// Activated at block 9200000
49    MUIR_GLACIER,
50    /// Berlin hard fork
51    /// Activated at block 12244000
52    BERLIN,
53    /// London hard fork
54    /// Activated at block 12965000
55    LONDON,
56    /// Arrow Glacier hard fork
57    /// Activated at block 13773000
58    ARROW_GLACIER,
59    /// Gray Glacier hard fork
60    /// Activated at block 15050000
61    GRAY_GLACIER,
62    /// Paris/Merge hard fork
63    /// Activated at block 15537394 (TTD: 58750000000000000000000)
64    MERGE,
65    /// Shanghai hard fork
66    /// Activated at block 17034870 (Timestamp: 1681338455)
67    SHANGHAI,
68    /// Cancun hard fork
69    /// Activated at block 19426587 (Timestamp: 1710338135)
70    CANCUN,
71    /// Prague hard fork
72    /// Activated at block 22431084 (Timestamp: 1746612311)
73    #[default]
74    PRAGUE,
75    /// Osaka hard fork
76    /// Activated at block TBD
77    OSAKA,
78    /// Amsterdam hard fork
79    /// Activated at block TBD
80    AMSTERDAM,
81}
82
83impl SpecId {
84    /// Returns the [`SpecId`] for the given [`u8`].
85    #[inline]
86    pub fn try_from_u8(spec_id: u8) -> Option<Self> {
87        Self::try_from(spec_id).ok()
88    }
89
90    /// Returns `true` if the given specification ID is enabled in this spec.
91    #[inline]
92    pub const fn is_enabled_in(self, other: Self) -> bool {
93        self as u8 >= other as u8
94    }
95}
96
97/// String identifiers for hardforks.
98pub mod name {
99    /// String identifier for the Frontier hardfork
100    pub const FRONTIER: &str = "Frontier";
101    /// String identifier for the Frontier Thawing hardfork
102    pub const FRONTIER_THAWING: &str = "Frontier Thawing";
103    /// String identifier for the Homestead hardfork
104    pub const HOMESTEAD: &str = "Homestead";
105    /// String identifier for the DAO Fork hardfork
106    pub const DAO_FORK: &str = "DAO Fork";
107    /// String identifier for the Tangerine Whistle hardfork
108    pub const TANGERINE: &str = "Tangerine";
109    /// String identifier for the Spurious Dragon hardfork
110    pub const SPURIOUS_DRAGON: &str = "Spurious";
111    /// String identifier for the Byzantium hardfork
112    pub const BYZANTIUM: &str = "Byzantium";
113    /// String identifier for the Constantinople hardfork
114    pub const CONSTANTINOPLE: &str = "Constantinople";
115    /// String identifier for the Petersburg hardfork
116    pub const PETERSBURG: &str = "Petersburg";
117    /// String identifier for the Istanbul hardfork
118    pub const ISTANBUL: &str = "Istanbul";
119    /// String identifier for the Muir Glacier hardfork
120    pub const MUIR_GLACIER: &str = "MuirGlacier";
121    /// String identifier for the Berlin hardfork
122    pub const BERLIN: &str = "Berlin";
123    /// String identifier for the London hardfork
124    pub const LONDON: &str = "London";
125    /// String identifier for the Arrow Glacier hardfork
126    pub const ARROW_GLACIER: &str = "Arrow Glacier";
127    /// String identifier for the Gray Glacier hardfork
128    pub const GRAY_GLACIER: &str = "Gray Glacier";
129    /// String identifier for the Paris/Merge hardfork
130    pub const MERGE: &str = "Merge";
131    /// String identifier for the Shanghai hardfork
132    pub const SHANGHAI: &str = "Shanghai";
133    /// String identifier for the Cancun hardfork
134    pub const CANCUN: &str = "Cancun";
135    /// String identifier for the Prague hardfork
136    pub const PRAGUE: &str = "Prague";
137    /// String identifier for the Osaka hardfork
138    pub const OSAKA: &str = "Osaka";
139    /// String identifier for the Amsterdam hardfork
140    pub const AMSTERDAM: &str = "Amsterdam";
141    /// String identifier for the latest hardfork
142    pub const LATEST: &str = "Latest";
143}
144
145/// Error type for unknown hardfork names. Returned by [`SpecId::from_str`].
146#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
147pub struct UnknownHardfork;
148
149impl FromStr for SpecId {
150    type Err = UnknownHardfork;
151
152    fn from_str(s: &str) -> Result<Self, Self::Err> {
153        match s {
154            name::FRONTIER => Ok(Self::FRONTIER),
155            name::FRONTIER_THAWING => Ok(Self::FRONTIER_THAWING),
156            name::HOMESTEAD => Ok(Self::HOMESTEAD),
157            name::DAO_FORK => Ok(Self::DAO_FORK),
158            name::TANGERINE => Ok(Self::TANGERINE),
159            name::SPURIOUS_DRAGON => Ok(Self::SPURIOUS_DRAGON),
160            name::BYZANTIUM => Ok(Self::BYZANTIUM),
161            name::CONSTANTINOPLE => Ok(Self::CONSTANTINOPLE),
162            name::PETERSBURG => Ok(Self::PETERSBURG),
163            name::ISTANBUL => Ok(Self::ISTANBUL),
164            name::MUIR_GLACIER => Ok(Self::MUIR_GLACIER),
165            name::BERLIN => Ok(Self::BERLIN),
166            name::LONDON => Ok(Self::LONDON),
167            name::ARROW_GLACIER => Ok(Self::ARROW_GLACIER),
168            name::GRAY_GLACIER => Ok(Self::GRAY_GLACIER),
169            name::MERGE => Ok(Self::MERGE),
170            name::SHANGHAI => Ok(Self::SHANGHAI),
171            name::CANCUN => Ok(Self::CANCUN),
172            name::PRAGUE => Ok(Self::PRAGUE),
173            name::OSAKA => Ok(Self::OSAKA),
174            name::AMSTERDAM => Ok(Self::AMSTERDAM),
175            _ => Err(UnknownHardfork),
176        }
177    }
178}
179
180impl From<SpecId> for &'static str {
181    fn from(spec_id: SpecId) -> Self {
182        match spec_id {
183            SpecId::FRONTIER => name::FRONTIER,
184            SpecId::FRONTIER_THAWING => name::FRONTIER_THAWING,
185            SpecId::HOMESTEAD => name::HOMESTEAD,
186            SpecId::DAO_FORK => name::DAO_FORK,
187            SpecId::TANGERINE => name::TANGERINE,
188            SpecId::SPURIOUS_DRAGON => name::SPURIOUS_DRAGON,
189            SpecId::BYZANTIUM => name::BYZANTIUM,
190            SpecId::CONSTANTINOPLE => name::CONSTANTINOPLE,
191            SpecId::PETERSBURG => name::PETERSBURG,
192            SpecId::ISTANBUL => name::ISTANBUL,
193            SpecId::MUIR_GLACIER => name::MUIR_GLACIER,
194            SpecId::BERLIN => name::BERLIN,
195            SpecId::LONDON => name::LONDON,
196            SpecId::ARROW_GLACIER => name::ARROW_GLACIER,
197            SpecId::GRAY_GLACIER => name::GRAY_GLACIER,
198            SpecId::MERGE => name::MERGE,
199            SpecId::SHANGHAI => name::SHANGHAI,
200            SpecId::CANCUN => name::CANCUN,
201            SpecId::PRAGUE => name::PRAGUE,
202            SpecId::OSAKA => name::OSAKA,
203            SpecId::AMSTERDAM => name::AMSTERDAM,
204        }
205    }
206}
207
208impl core::fmt::Display for SpecId {
209    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
210        write!(f, "{}", <&'static str>::from(*self))
211    }
212}