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 TBD
73    #[default]
74    PRAGUE,
75    /// Osaka hard fork
76    /// Activated at block TBD
77    OSAKA,
78}
79
80impl SpecId {
81    /// Returns the [`SpecId`] for the given [`u8`].
82    #[inline]
83    pub fn try_from_u8(spec_id: u8) -> Option<Self> {
84        Self::try_from(spec_id).ok()
85    }
86
87    /// Returns `true` if the given specification ID is enabled in this spec.
88    #[inline]
89    pub const fn is_enabled_in(self, other: Self) -> bool {
90        self as u8 >= other as u8
91    }
92}
93
94/// String identifiers for hardforks.
95pub mod name {
96    /// String identifier for the Frontier hardfork
97    pub const FRONTIER: &str = "Frontier";
98    /// String identifier for the Frontier Thawing hardfork
99    pub const FRONTIER_THAWING: &str = "Frontier Thawing";
100    /// String identifier for the Homestead hardfork
101    pub const HOMESTEAD: &str = "Homestead";
102    /// String identifier for the DAO Fork hardfork
103    pub const DAO_FORK: &str = "DAO Fork";
104    /// String identifier for the Tangerine Whistle hardfork
105    pub const TANGERINE: &str = "Tangerine";
106    /// String identifier for the Spurious Dragon hardfork
107    pub const SPURIOUS_DRAGON: &str = "Spurious";
108    /// String identifier for the Byzantium hardfork
109    pub const BYZANTIUM: &str = "Byzantium";
110    /// String identifier for the Constantinople hardfork
111    pub const CONSTANTINOPLE: &str = "Constantinople";
112    /// String identifier for the Petersburg hardfork
113    pub const PETERSBURG: &str = "Petersburg";
114    /// String identifier for the Istanbul hardfork
115    pub const ISTANBUL: &str = "Istanbul";
116    /// String identifier for the Muir Glacier hardfork
117    pub const MUIR_GLACIER: &str = "MuirGlacier";
118    /// String identifier for the Berlin hardfork
119    pub const BERLIN: &str = "Berlin";
120    /// String identifier for the London hardfork
121    pub const LONDON: &str = "London";
122    /// String identifier for the Arrow Glacier hardfork
123    pub const ARROW_GLACIER: &str = "Arrow Glacier";
124    /// String identifier for the Gray Glacier hardfork
125    pub const GRAY_GLACIER: &str = "Gray Glacier";
126    /// String identifier for the Paris/Merge hardfork
127    pub const MERGE: &str = "Merge";
128    /// String identifier for the Shanghai hardfork
129    pub const SHANGHAI: &str = "Shanghai";
130    /// String identifier for the Cancun hardfork
131    pub const CANCUN: &str = "Cancun";
132    /// String identifier for the Prague hardfork
133    pub const PRAGUE: &str = "Prague";
134    /// String identifier for the Osaka hardfork (Prague with EOF)
135    pub const OSAKA: &str = "PragueEOF";
136    /// String identifier for the latest hardfork
137    pub const LATEST: &str = "Latest";
138}
139
140/// Error type for unknown hardfork names. Returned by [`SpecId::from_str`].
141#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
142pub struct UnknownHardfork;
143
144impl FromStr for SpecId {
145    type Err = UnknownHardfork;
146
147    fn from_str(s: &str) -> Result<Self, Self::Err> {
148        match s {
149            name::FRONTIER => Ok(Self::FRONTIER),
150            name::FRONTIER_THAWING => Ok(Self::FRONTIER_THAWING),
151            name::HOMESTEAD => Ok(Self::HOMESTEAD),
152            name::DAO_FORK => Ok(Self::DAO_FORK),
153            name::TANGERINE => Ok(Self::TANGERINE),
154            name::SPURIOUS_DRAGON => Ok(Self::SPURIOUS_DRAGON),
155            name::BYZANTIUM => Ok(Self::BYZANTIUM),
156            name::CONSTANTINOPLE => Ok(Self::CONSTANTINOPLE),
157            name::PETERSBURG => Ok(Self::PETERSBURG),
158            name::ISTANBUL => Ok(Self::ISTANBUL),
159            name::MUIR_GLACIER => Ok(Self::MUIR_GLACIER),
160            name::BERLIN => Ok(Self::BERLIN),
161            name::LONDON => Ok(Self::LONDON),
162            name::ARROW_GLACIER => Ok(Self::ARROW_GLACIER),
163            name::GRAY_GLACIER => Ok(Self::GRAY_GLACIER),
164            name::MERGE => Ok(Self::MERGE),
165            name::SHANGHAI => Ok(Self::SHANGHAI),
166            name::CANCUN => Ok(Self::CANCUN),
167            name::PRAGUE => Ok(Self::PRAGUE),
168            name::OSAKA => Ok(Self::OSAKA),
169            _ => Err(UnknownHardfork),
170        }
171    }
172}
173
174impl From<SpecId> for &'static str {
175    fn from(spec_id: SpecId) -> Self {
176        match spec_id {
177            SpecId::FRONTIER => name::FRONTIER,
178            SpecId::FRONTIER_THAWING => name::FRONTIER_THAWING,
179            SpecId::HOMESTEAD => name::HOMESTEAD,
180            SpecId::DAO_FORK => name::DAO_FORK,
181            SpecId::TANGERINE => name::TANGERINE,
182            SpecId::SPURIOUS_DRAGON => name::SPURIOUS_DRAGON,
183            SpecId::BYZANTIUM => name::BYZANTIUM,
184            SpecId::CONSTANTINOPLE => name::CONSTANTINOPLE,
185            SpecId::PETERSBURG => name::PETERSBURG,
186            SpecId::ISTANBUL => name::ISTANBUL,
187            SpecId::MUIR_GLACIER => name::MUIR_GLACIER,
188            SpecId::BERLIN => name::BERLIN,
189            SpecId::LONDON => name::LONDON,
190            SpecId::ARROW_GLACIER => name::ARROW_GLACIER,
191            SpecId::GRAY_GLACIER => name::GRAY_GLACIER,
192            SpecId::MERGE => name::MERGE,
193            SpecId::SHANGHAI => name::SHANGHAI,
194            SpecId::CANCUN => name::CANCUN,
195            SpecId::PRAGUE => name::PRAGUE,
196            SpecId::OSAKA => name::OSAKA,
197        }
198    }
199}
200
201impl core::fmt::Display for SpecId {
202    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
203        write!(f, "{}", <&'static str>::from(*self))
204    }
205}