revm_primitives/
hardfork.rs1#![expect(non_camel_case_types)]
4
5use core::str::FromStr;
6pub use std::string::{String, ToString};
7pub use SpecId::*;
8
9#[repr(u8)]
13#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub enum SpecId {
16 FRONTIER = 0,
20 HOMESTEAD,
24 TANGERINE,
28 SPURIOUS_DRAGON,
32 BYZANTIUM,
36 PETERSBURG,
40 ISTANBUL,
44 BERLIN,
48 LONDON,
52 MERGE,
56 SHANGHAI,
60 CANCUN,
64 PRAGUE,
68 #[default]
72 OSAKA,
73 AMSTERDAM,
77}
78
79impl SpecId {
80 #[doc(alias = "MAX")]
86 pub const NEXT: Self = Self::AMSTERDAM;
87
88 #[inline]
90 pub const fn try_from_u8(spec_id: u8) -> Option<Self> {
91 if spec_id <= Self::NEXT as u8 {
92 Some(unsafe { core::mem::transmute::<u8, Self>(spec_id) })
94 } else {
95 None
96 }
97 }
98
99 #[inline]
101 pub const fn is_enabled_in(self, other: Self) -> bool {
102 self as u8 >= other as u8
103 }
104}
105
106impl From<SpecId> for u8 {
107 #[inline]
108 fn from(spec_id: SpecId) -> Self {
109 spec_id as u8
110 }
111}
112
113impl TryFrom<u8> for SpecId {
114 type Error = u8;
115
116 #[inline]
117 fn try_from(value: u8) -> Result<Self, Self::Error> {
118 Self::try_from_u8(value).ok_or(value)
119 }
120}
121
122pub mod name {
124 pub const FRONTIER: &str = "Frontier";
126 pub const HOMESTEAD: &str = "Homestead";
128 pub const TANGERINE: &str = "Tangerine";
130 pub const SPURIOUS_DRAGON: &str = "Spurious";
132 pub const BYZANTIUM: &str = "Byzantium";
134 pub const PETERSBURG: &str = "Petersburg";
136 pub const ISTANBUL: &str = "Istanbul";
138 pub const BERLIN: &str = "Berlin";
140 pub const LONDON: &str = "London";
142 pub const MERGE: &str = "Merge";
144 pub const SHANGHAI: &str = "Shanghai";
146 pub const CANCUN: &str = "Cancun";
148 pub const PRAGUE: &str = "Prague";
150 pub const OSAKA: &str = "Osaka";
152 pub const AMSTERDAM: &str = "Amsterdam";
154 pub const LATEST: &str = "Latest";
156}
157
158#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
160pub struct UnknownHardfork;
161
162impl FromStr for SpecId {
163 type Err = UnknownHardfork;
164
165 fn from_str(s: &str) -> Result<Self, Self::Err> {
166 match s {
167 name::FRONTIER => Ok(Self::FRONTIER),
168 name::HOMESTEAD => Ok(Self::HOMESTEAD),
169 name::TANGERINE => Ok(Self::TANGERINE),
170 name::SPURIOUS_DRAGON => Ok(Self::SPURIOUS_DRAGON),
171 name::BYZANTIUM => Ok(Self::BYZANTIUM),
172 name::PETERSBURG => Ok(Self::PETERSBURG),
173 name::ISTANBUL => Ok(Self::ISTANBUL),
174 name::BERLIN => Ok(Self::BERLIN),
175 name::LONDON => Ok(Self::LONDON),
176 name::MERGE => Ok(Self::MERGE),
177 name::SHANGHAI => Ok(Self::SHANGHAI),
178 name::CANCUN => Ok(Self::CANCUN),
179 name::PRAGUE => Ok(Self::PRAGUE),
180 name::OSAKA => Ok(Self::OSAKA),
181 name::AMSTERDAM => Ok(Self::AMSTERDAM),
182 _ => Err(UnknownHardfork),
183 }
184 }
185}
186
187impl From<SpecId> for &'static str {
188 fn from(spec_id: SpecId) -> Self {
189 match spec_id {
190 SpecId::FRONTIER => name::FRONTIER,
191 SpecId::HOMESTEAD => name::HOMESTEAD,
192 SpecId::TANGERINE => name::TANGERINE,
193 SpecId::SPURIOUS_DRAGON => name::SPURIOUS_DRAGON,
194 SpecId::BYZANTIUM => name::BYZANTIUM,
195 SpecId::PETERSBURG => name::PETERSBURG,
196 SpecId::ISTANBUL => name::ISTANBUL,
197 SpecId::BERLIN => name::BERLIN,
198 SpecId::LONDON => name::LONDON,
199 SpecId::MERGE => name::MERGE,
200 SpecId::SHANGHAI => name::SHANGHAI,
201 SpecId::CANCUN => name::CANCUN,
202 SpecId::PRAGUE => name::PRAGUE,
203 SpecId::OSAKA => name::OSAKA,
204 SpecId::AMSTERDAM => name::AMSTERDAM,
205 }
206 }
207}
208
209impl core::fmt::Display for SpecId {
210 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
211 write!(f, "{}", <&'static str>::from(*self))
212 }
213}