revm_specification/
hardfork.rs

1#![allow(non_camel_case_types)]
2
3pub use std::string::{String, ToString};
4pub use SpecId::*;
5
6/// Specification IDs and their activation block
7///
8/// Information was obtained from the [Ethereum Execution Specifications](https://github.com/ethereum/execution-specs).
9#[repr(u8)]
10#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, enumn::N)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub enum SpecId {
13    FRONTIER = 0,     // Frontier               0
14    FRONTIER_THAWING, // Frontier Thawing       200000
15    HOMESTEAD,        // Homestead              1150000
16    DAO_FORK,         // DAO Fork               1920000
17    TANGERINE,        // Tangerine Whistle      2463000
18    SPURIOUS_DRAGON,  // Spurious Dragon        2675000
19    BYZANTIUM,        // Byzantium              4370000
20    CONSTANTINOPLE,   // Constantinople         7280000 is overwritten with PETERSBURG
21    PETERSBURG,       // Petersburg             7280000
22    ISTANBUL,         // Istanbul	            9069000
23    MUIR_GLACIER,     // Muir Glacier           9200000
24    BERLIN,           // Berlin	                12244000
25    LONDON,           // London	                12965000
26    ARROW_GLACIER,    // Arrow Glacier          13773000
27    GRAY_GLACIER,     // Gray Glacier           15050000
28    MERGE,            // Paris/Merge            15537394 (TTD: 58750000000000000000000)
29    SHANGHAI,         // Shanghai               17034870 (Timestamp: 1681338455)
30    CANCUN,           // Cancun                 19426587 (Timestamp: 1710338135)
31    PRAGUE,           // Prague                 TBD
32    OSAKA,            // Osaka                  TBD
33    #[default]
34    LATEST = u8::MAX,
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
76impl From<&str> for SpecId {
77    fn from(name: &str) -> Self {
78        match name {
79            name::FRONTIER => Self::FRONTIER,
80            name::FRONTIER_THAWING => Self::FRONTIER_THAWING,
81            name::HOMESTEAD => Self::HOMESTEAD,
82            name::DAO_FORK => Self::DAO_FORK,
83            name::TANGERINE => Self::TANGERINE,
84            name::SPURIOUS_DRAGON => Self::SPURIOUS_DRAGON,
85            name::BYZANTIUM => Self::BYZANTIUM,
86            name::CONSTANTINOPLE => Self::CONSTANTINOPLE,
87            name::PETERSBURG => Self::PETERSBURG,
88            name::ISTANBUL => Self::ISTANBUL,
89            name::MUIR_GLACIER => Self::MUIR_GLACIER,
90            name::BERLIN => Self::BERLIN,
91            name::LONDON => Self::LONDON,
92            name::ARROW_GLACIER => Self::ARROW_GLACIER,
93            name::GRAY_GLACIER => Self::GRAY_GLACIER,
94            name::MERGE => Self::MERGE,
95            name::SHANGHAI => Self::SHANGHAI,
96            name::CANCUN => Self::CANCUN,
97            name::PRAGUE => Self::PRAGUE,
98            name::OSAKA => Self::OSAKA,
99            name::LATEST => Self::LATEST,
100            _ => Self::LATEST,
101        }
102    }
103}
104
105impl From<SpecId> for &'static str {
106    fn from(spec_id: SpecId) -> Self {
107        match spec_id {
108            SpecId::FRONTIER => name::FRONTIER,
109            SpecId::FRONTIER_THAWING => name::FRONTIER_THAWING,
110            SpecId::HOMESTEAD => name::HOMESTEAD,
111            SpecId::DAO_FORK => name::DAO_FORK,
112            SpecId::TANGERINE => name::TANGERINE,
113            SpecId::SPURIOUS_DRAGON => name::SPURIOUS_DRAGON,
114            SpecId::BYZANTIUM => name::BYZANTIUM,
115            SpecId::CONSTANTINOPLE => name::CONSTANTINOPLE,
116            SpecId::PETERSBURG => name::PETERSBURG,
117            SpecId::ISTANBUL => name::ISTANBUL,
118            SpecId::MUIR_GLACIER => name::MUIR_GLACIER,
119            SpecId::BERLIN => name::BERLIN,
120            SpecId::LONDON => name::LONDON,
121            SpecId::ARROW_GLACIER => name::ARROW_GLACIER,
122            SpecId::GRAY_GLACIER => name::GRAY_GLACIER,
123            SpecId::MERGE => name::MERGE,
124            SpecId::SHANGHAI => name::SHANGHAI,
125            SpecId::CANCUN => name::CANCUN,
126            SpecId::PRAGUE => name::PRAGUE,
127            SpecId::OSAKA => name::OSAKA,
128            SpecId::LATEST => name::LATEST,
129        }
130    }
131}
132
133impl core::fmt::Display for SpecId {
134    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
135        write!(f, "{}", <&'static str>::from(*self))
136    }
137}