revm_primitives/
hardfork.rs

1#![allow(non_camel_case_types)]
2
3use core::str::FromStr;
4pub use std::string::{String, ToString};
5pub use SpecId::*;
6
7/// Specification IDs and their activation block
8///
9/// Information was obtained from the [Ethereum Execution Specifications](https://github.com/ethereum/execution-specs).
10#[repr(u8)]
11#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, enumn::N)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub enum SpecId {
14    FRONTIER = 0,     // Frontier               0
15    FRONTIER_THAWING, // Frontier Thawing       200000
16    HOMESTEAD,        // Homestead              1150000
17    DAO_FORK,         // DAO Fork               1920000
18    TANGERINE,        // Tangerine Whistle      2463000
19    SPURIOUS_DRAGON,  // Spurious Dragon        2675000
20    BYZANTIUM,        // Byzantium              4370000
21    CONSTANTINOPLE,   // Constantinople         7280000 is overwritten with PETERSBURG
22    PETERSBURG,       // Petersburg             7280000
23    ISTANBUL,         // Istanbul	            9069000
24    MUIR_GLACIER,     // Muir Glacier           9200000
25    BERLIN,           // Berlin	                12244000
26    LONDON,           // London	                12965000
27    ARROW_GLACIER,    // Arrow Glacier          13773000
28    GRAY_GLACIER,     // Gray Glacier           15050000
29    MERGE,            // Paris/Merge            15537394 (TTD: 58750000000000000000000)
30    SHANGHAI,         // Shanghai               17034870 (Timestamp: 1681338455)
31    CANCUN,           // Cancun                 19426587 (Timestamp: 1710338135)
32    #[default]
33    PRAGUE, // PRAGUE                 TBD
34    OSAKA,            // Osaka                  TBD
35}
36
37impl SpecId {
38    /// Returns the [`SpecId`] for the given [`u8`].
39    #[inline]
40    pub fn try_from_u8(spec_id: u8) -> Option<Self> {
41        Self::n(spec_id)
42    }
43
44    /// Returns `true` if the given specification ID is enabled in this spec.
45    #[inline]
46    pub const fn is_enabled_in(self, other: Self) -> bool {
47        self as u8 >= other as u8
48    }
49}
50
51/// String identifiers for hardforks.
52pub mod name {
53    pub const FRONTIER: &str = "Frontier";
54    pub const FRONTIER_THAWING: &str = "Frontier Thawing";
55    pub const HOMESTEAD: &str = "Homestead";
56    pub const DAO_FORK: &str = "DAO Fork";
57    pub const TANGERINE: &str = "Tangerine";
58    pub const SPURIOUS_DRAGON: &str = "Spurious";
59    pub const BYZANTIUM: &str = "Byzantium";
60    pub const CONSTANTINOPLE: &str = "Constantinople";
61    pub const PETERSBURG: &str = "Petersburg";
62    pub const ISTANBUL: &str = "Istanbul";
63    pub const MUIR_GLACIER: &str = "MuirGlacier";
64    pub const BERLIN: &str = "Berlin";
65    pub const LONDON: &str = "London";
66    pub const ARROW_GLACIER: &str = "Arrow Glacier";
67    pub const GRAY_GLACIER: &str = "Gray Glacier";
68    pub const MERGE: &str = "Merge";
69    pub const SHANGHAI: &str = "Shanghai";
70    pub const CANCUN: &str = "Cancun";
71    pub const PRAGUE: &str = "Prague";
72    pub const OSAKA: &str = "PragueEOF";
73    pub const LATEST: &str = "Latest";
74}
75
76pub struct UnknownHardfork;
77
78impl FromStr for SpecId {
79    type Err = UnknownHardfork;
80
81    fn from_str(s: &str) -> Result<Self, Self::Err> {
82        match s {
83            name::FRONTIER => Ok(Self::FRONTIER),
84            name::FRONTIER_THAWING => Ok(Self::FRONTIER_THAWING),
85            name::HOMESTEAD => Ok(Self::HOMESTEAD),
86            name::DAO_FORK => Ok(Self::DAO_FORK),
87            name::TANGERINE => Ok(Self::TANGERINE),
88            name::SPURIOUS_DRAGON => Ok(Self::SPURIOUS_DRAGON),
89            name::BYZANTIUM => Ok(Self::BYZANTIUM),
90            name::CONSTANTINOPLE => Ok(Self::CONSTANTINOPLE),
91            name::PETERSBURG => Ok(Self::PETERSBURG),
92            name::ISTANBUL => Ok(Self::ISTANBUL),
93            name::MUIR_GLACIER => Ok(Self::MUIR_GLACIER),
94            name::BERLIN => Ok(Self::BERLIN),
95            name::LONDON => Ok(Self::LONDON),
96            name::ARROW_GLACIER => Ok(Self::ARROW_GLACIER),
97            name::GRAY_GLACIER => Ok(Self::GRAY_GLACIER),
98            name::MERGE => Ok(Self::MERGE),
99            name::SHANGHAI => Ok(Self::SHANGHAI),
100            name::CANCUN => Ok(Self::CANCUN),
101            name::PRAGUE => Ok(Self::PRAGUE),
102            name::OSAKA => Ok(Self::OSAKA),
103            _ => Err(UnknownHardfork),
104        }
105    }
106}
107
108impl From<SpecId> for &'static str {
109    fn from(spec_id: SpecId) -> Self {
110        match spec_id {
111            SpecId::FRONTIER => name::FRONTIER,
112            SpecId::FRONTIER_THAWING => name::FRONTIER_THAWING,
113            SpecId::HOMESTEAD => name::HOMESTEAD,
114            SpecId::DAO_FORK => name::DAO_FORK,
115            SpecId::TANGERINE => name::TANGERINE,
116            SpecId::SPURIOUS_DRAGON => name::SPURIOUS_DRAGON,
117            SpecId::BYZANTIUM => name::BYZANTIUM,
118            SpecId::CONSTANTINOPLE => name::CONSTANTINOPLE,
119            SpecId::PETERSBURG => name::PETERSBURG,
120            SpecId::ISTANBUL => name::ISTANBUL,
121            SpecId::MUIR_GLACIER => name::MUIR_GLACIER,
122            SpecId::BERLIN => name::BERLIN,
123            SpecId::LONDON => name::LONDON,
124            SpecId::ARROW_GLACIER => name::ARROW_GLACIER,
125            SpecId::GRAY_GLACIER => name::GRAY_GLACIER,
126            SpecId::MERGE => name::MERGE,
127            SpecId::SHANGHAI => name::SHANGHAI,
128            SpecId::CANCUN => name::CANCUN,
129            SpecId::PRAGUE => name::PRAGUE,
130            SpecId::OSAKA => name::OSAKA,
131        }
132    }
133}
134
135impl core::fmt::Display for SpecId {
136    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
137        write!(f, "{}", <&'static str>::from(*self))
138    }
139}