anvil/
hardfork.rs
1use alloy_hardforks::EthereumHardfork;
2use alloy_op_hardforks::OpHardfork::{self};
3use alloy_rpc_types::BlockNumberOrTag;
4
5use op_revm::OpSpecId;
6use revm::primitives::hardfork::SpecId;
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub enum ChainHardfork {
10 Ethereum(EthereumHardfork),
11 Optimism(OpHardfork),
12}
13
14impl From<EthereumHardfork> for ChainHardfork {
15 fn from(value: EthereumHardfork) -> Self {
16 Self::Ethereum(value)
17 }
18}
19
20impl From<OpHardfork> for ChainHardfork {
21 fn from(value: OpHardfork) -> Self {
22 Self::Optimism(value)
23 }
24}
25
26impl From<ChainHardfork> for SpecId {
27 fn from(fork: ChainHardfork) -> Self {
28 match fork {
29 ChainHardfork::Ethereum(hardfork) => spec_id_from_ethereum_hardfork(hardfork),
30 ChainHardfork::Optimism(hardfork) => spec_id_from_optimism_hardfork(hardfork).into(),
31 }
32 }
33}
34
35pub fn spec_id_from_ethereum_hardfork(hardfork: EthereumHardfork) -> SpecId {
37 match hardfork {
38 EthereumHardfork::Frontier => SpecId::FRONTIER,
39 EthereumHardfork::Homestead => SpecId::HOMESTEAD,
40 EthereumHardfork::Dao => SpecId::DAO_FORK,
41 EthereumHardfork::Tangerine => SpecId::TANGERINE,
42 EthereumHardfork::SpuriousDragon => SpecId::SPURIOUS_DRAGON,
43 EthereumHardfork::Byzantium => SpecId::BYZANTIUM,
44 EthereumHardfork::Constantinople => SpecId::CONSTANTINOPLE,
45 EthereumHardfork::Petersburg => SpecId::PETERSBURG,
46 EthereumHardfork::Istanbul => SpecId::ISTANBUL,
47 EthereumHardfork::MuirGlacier => SpecId::MUIR_GLACIER,
48 EthereumHardfork::Berlin => SpecId::BERLIN,
49 EthereumHardfork::London => SpecId::LONDON,
50 EthereumHardfork::ArrowGlacier => SpecId::ARROW_GLACIER,
51 EthereumHardfork::GrayGlacier => SpecId::GRAY_GLACIER,
52 EthereumHardfork::Paris => SpecId::MERGE,
53 EthereumHardfork::Shanghai => SpecId::SHANGHAI,
54 EthereumHardfork::Cancun => SpecId::CANCUN,
55 EthereumHardfork::Prague => SpecId::PRAGUE,
56 EthereumHardfork::Osaka => SpecId::OSAKA,
57 }
58}
59
60pub fn spec_id_from_optimism_hardfork(hardfork: OpHardfork) -> OpSpecId {
62 match hardfork {
63 OpHardfork::Bedrock => OpSpecId::BEDROCK,
64 OpHardfork::Regolith => OpSpecId::REGOLITH,
65 OpHardfork::Canyon => OpSpecId::CANYON,
66 OpHardfork::Ecotone => OpSpecId::ECOTONE,
67 OpHardfork::Fjord => OpSpecId::FJORD,
68 OpHardfork::Granite => OpSpecId::GRANITE,
69 OpHardfork::Holocene => OpSpecId::HOLOCENE,
70 OpHardfork::Isthmus => OpSpecId::ISTHMUS,
71 OpHardfork::Interop => OpSpecId::INTEROP,
72 }
73}
74
75pub fn ethereum_hardfork_from_block_tag(block: impl Into<BlockNumberOrTag>) -> EthereumHardfork {
77 let num = match block.into() {
78 BlockNumberOrTag::Earliest => 0,
79 BlockNumberOrTag::Number(num) => num,
80 _ => u64::MAX,
81 };
82
83 EthereumHardfork::from_mainnet_block_number(num)
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use alloy_hardforks::ethereum::mainnet::*;
90 #[allow(unused_imports)]
91 use alloy_rpc_types::BlockNumberOrTag;
92
93 #[test]
94 fn test_ethereum_spec_id_mapping() {
95 assert_eq!(spec_id_from_ethereum_hardfork(EthereumHardfork::Frontier), SpecId::FRONTIER);
96 assert_eq!(spec_id_from_ethereum_hardfork(EthereumHardfork::Homestead), SpecId::HOMESTEAD);
97
98 assert_eq!(spec_id_from_ethereum_hardfork(EthereumHardfork::Cancun), SpecId::CANCUN);
100 assert_eq!(spec_id_from_ethereum_hardfork(EthereumHardfork::Prague), SpecId::PRAGUE);
101 }
102
103 #[test]
104 fn test_optimism_spec_id_mapping() {
105 assert_eq!(spec_id_from_optimism_hardfork(OpHardfork::Bedrock), OpSpecId::BEDROCK);
106 assert_eq!(spec_id_from_optimism_hardfork(OpHardfork::Regolith), OpSpecId::REGOLITH);
107
108 assert_eq!(spec_id_from_optimism_hardfork(OpHardfork::Holocene), OpSpecId::HOLOCENE);
110 assert_eq!(spec_id_from_optimism_hardfork(OpHardfork::Interop), OpSpecId::INTEROP);
111 }
112
113 #[test]
114 fn test_hardfork_from_block_tag_numbers() {
115 assert_eq!(
116 ethereum_hardfork_from_block_tag(MAINNET_HOMESTEAD_BLOCK - 1),
117 EthereumHardfork::Frontier
118 );
119 assert_eq!(
120 ethereum_hardfork_from_block_tag(MAINNET_LONDON_BLOCK + 1),
121 EthereumHardfork::London
122 );
123 }
124}