reth_optimism_evm/
config.rs
1use alloy_consensus::BlockHeader;
2use op_revm::OpSpecId;
3use reth_optimism_forks::OpHardforks;
4use revm::primitives::{Address, Bytes, B256};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct OpNextBlockEnvAttributes {
9 pub timestamp: u64,
11 pub suggested_fee_recipient: Address,
13 pub prev_randao: B256,
15 pub gas_limit: u64,
17 pub parent_beacon_block_root: Option<B256>,
19 pub extra_data: Bytes,
21}
22
23pub fn revm_spec(chain_spec: impl OpHardforks, header: impl BlockHeader) -> OpSpecId {
25 revm_spec_by_timestamp_after_bedrock(chain_spec, header.timestamp())
26}
27
28pub fn revm_spec_by_timestamp_after_bedrock(
35 chain_spec: impl OpHardforks,
36 timestamp: u64,
37) -> OpSpecId {
38 if chain_spec.is_interop_active_at_timestamp(timestamp) {
39 OpSpecId::INTEROP
40 } else if chain_spec.is_isthmus_active_at_timestamp(timestamp) {
41 OpSpecId::ISTHMUS
42 } else if chain_spec.is_holocene_active_at_timestamp(timestamp) {
43 OpSpecId::HOLOCENE
44 } else if chain_spec.is_granite_active_at_timestamp(timestamp) {
45 OpSpecId::GRANITE
46 } else if chain_spec.is_fjord_active_at_timestamp(timestamp) {
47 OpSpecId::FJORD
48 } else if chain_spec.is_ecotone_active_at_timestamp(timestamp) {
49 OpSpecId::ECOTONE
50 } else if chain_spec.is_canyon_active_at_timestamp(timestamp) {
51 OpSpecId::CANYON
52 } else if chain_spec.is_regolith_active_at_timestamp(timestamp) {
53 OpSpecId::REGOLITH
54 } else {
55 OpSpecId::BEDROCK
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use alloy_consensus::Header;
63 use reth_chainspec::ChainSpecBuilder;
64 use reth_optimism_chainspec::{OpChainSpec, OpChainSpecBuilder};
65
66 #[test]
67 fn test_revm_spec_by_timestamp_after_merge() {
68 #[inline(always)]
69 fn op_cs(f: impl FnOnce(OpChainSpecBuilder) -> OpChainSpecBuilder) -> OpChainSpec {
70 let cs = ChainSpecBuilder::mainnet().chain(reth_chainspec::Chain::from_id(10)).into();
71 f(cs).build()
72 }
73 assert_eq!(
74 revm_spec_by_timestamp_after_bedrock(op_cs(|cs| cs.interop_activated()), 0),
75 OpSpecId::INTEROP
76 );
77 assert_eq!(
78 revm_spec_by_timestamp_after_bedrock(op_cs(|cs| cs.isthmus_activated()), 0),
79 OpSpecId::ISTHMUS
80 );
81 assert_eq!(
82 revm_spec_by_timestamp_after_bedrock(op_cs(|cs| cs.holocene_activated()), 0),
83 OpSpecId::HOLOCENE
84 );
85 assert_eq!(
86 revm_spec_by_timestamp_after_bedrock(op_cs(|cs| cs.granite_activated()), 0),
87 OpSpecId::GRANITE
88 );
89 assert_eq!(
90 revm_spec_by_timestamp_after_bedrock(op_cs(|cs| cs.fjord_activated()), 0),
91 OpSpecId::FJORD
92 );
93 assert_eq!(
94 revm_spec_by_timestamp_after_bedrock(op_cs(|cs| cs.ecotone_activated()), 0),
95 OpSpecId::ECOTONE
96 );
97 assert_eq!(
98 revm_spec_by_timestamp_after_bedrock(op_cs(|cs| cs.canyon_activated()), 0),
99 OpSpecId::CANYON
100 );
101 assert_eq!(
102 revm_spec_by_timestamp_after_bedrock(op_cs(|cs| cs.bedrock_activated()), 0),
103 OpSpecId::BEDROCK
104 );
105 assert_eq!(
106 revm_spec_by_timestamp_after_bedrock(op_cs(|cs| cs.regolith_activated()), 0),
107 OpSpecId::REGOLITH
108 );
109 }
110
111 #[test]
112 fn test_to_revm_spec() {
113 #[inline(always)]
114 fn op_cs(f: impl FnOnce(OpChainSpecBuilder) -> OpChainSpecBuilder) -> OpChainSpec {
115 let cs = ChainSpecBuilder::mainnet().chain(reth_chainspec::Chain::from_id(10)).into();
116 f(cs).build()
117 }
118 assert_eq!(
119 revm_spec(op_cs(|cs| cs.isthmus_activated()), Header::default()),
120 OpSpecId::ISTHMUS
121 );
122 assert_eq!(
123 revm_spec(op_cs(|cs| cs.holocene_activated()), Header::default()),
124 OpSpecId::HOLOCENE
125 );
126 assert_eq!(
127 revm_spec(op_cs(|cs| cs.granite_activated()), Header::default()),
128 OpSpecId::GRANITE
129 );
130 assert_eq!(revm_spec(op_cs(|cs| cs.fjord_activated()), Header::default()), OpSpecId::FJORD);
131 assert_eq!(
132 revm_spec(op_cs(|cs| cs.ecotone_activated()), Header::default()),
133 OpSpecId::ECOTONE
134 );
135 assert_eq!(
136 revm_spec(op_cs(|cs| cs.canyon_activated()), Header::default()),
137 OpSpecId::CANYON
138 );
139 assert_eq!(
140 revm_spec(op_cs(|cs| cs.bedrock_activated()), Header::default()),
141 OpSpecId::BEDROCK
142 );
143 assert_eq!(
144 revm_spec(op_cs(|cs| cs.regolith_activated()), Header::default()),
145 OpSpecId::REGOLITH
146 );
147 }
148}