1use core::fmt::Debug;
4
5use alloy_primitives::U256;
6use revm::{
7 context::{BlockEnv, CfgEnv},
8 primitives::hardfork::SpecId,
9};
10
11#[derive(Debug, Clone, Default, PartialEq, Eq)]
13pub struct EvmEnv<Spec = SpecId, BlockEnv = revm::context::BlockEnv> {
14 pub cfg_env: CfgEnv<Spec>,
16 pub block_env: BlockEnv,
18}
19
20impl<Spec, BlockEnv> EvmEnv<Spec, BlockEnv> {
21 pub const fn new(cfg_env: CfgEnv<Spec>, block_env: BlockEnv) -> Self {
28 Self { cfg_env, block_env }
29 }
30}
31
32impl<Spec, BlockEnv: BlockEnvironment> EvmEnv<Spec, BlockEnv> {
33 pub fn map_block_env<NewBlockEnv>(
35 self,
36 f: impl FnOnce(BlockEnv) -> NewBlockEnv,
37 ) -> EvmEnv<Spec, NewBlockEnv> {
38 let Self { cfg_env, block_env } = self;
39 EvmEnv { cfg_env, block_env: f(block_env) }
40 }
41
42 pub const fn block_env(&self) -> &BlockEnv {
44 &self.block_env
45 }
46
47 pub const fn cfg_env(&self) -> &CfgEnv<Spec> {
49 &self.cfg_env
50 }
51
52 pub const fn chainid(&self) -> u64 {
54 self.cfg_env.chain_id
55 }
56
57 pub const fn spec_id(&self) -> &Spec {
59 &self.cfg_env.spec
60 }
61
62 pub fn with_block_number(mut self, number: U256) -> Self {
64 self.block_env.inner_mut().number = number;
65 self
66 }
67
68 pub fn with_block_number_opt(mut self, number: Option<U256>) -> Self {
73 if let Some(number) = number {
74 self.block_env.inner_mut().number = number;
75 }
76 self
77 }
78
79 pub fn set_block_number_opt(&mut self, number: Option<U256>) -> &mut Self {
81 if let Some(number) = number {
82 self.block_env.inner_mut().number = number;
83 }
84 self
85 }
86
87 pub fn with_timestamp(mut self, timestamp: U256) -> Self {
89 self.block_env.inner_mut().timestamp = timestamp;
90 self
91 }
92
93 pub fn with_timestamp_opt(mut self, timestamp: Option<U256>) -> Self {
98 if let Some(timestamp) = timestamp {
99 self.block_env.inner_mut().timestamp = timestamp;
100 }
101 self
102 }
103
104 pub fn set_timestamp_opt(&mut self, timestamp: Option<U256>) -> &mut Self {
106 if let Some(timestamp) = timestamp {
107 self.block_env.inner_mut().timestamp = timestamp;
108 }
109 self
110 }
111
112 pub fn with_base_fee(mut self, base_fee: u64) -> Self {
114 self.block_env.inner_mut().basefee = base_fee;
115 self
116 }
117
118 pub fn with_base_fee_opt(mut self, base_fee: Option<u64>) -> Self {
123 if let Some(base_fee) = base_fee {
124 self.block_env.inner_mut().basefee = base_fee;
125 }
126 self
127 }
128
129 pub fn set_base_fee_opt(&mut self, base_fee: Option<u64>) -> &mut Self {
131 if let Some(base_fee) = base_fee {
132 self.block_env.inner_mut().basefee = base_fee;
133 }
134 self
135 }
136}
137
138impl<Spec, BlockEnv> From<(CfgEnv<Spec>, BlockEnv)> for EvmEnv<Spec, BlockEnv> {
139 fn from((cfg_env, block_env): (CfgEnv<Spec>, BlockEnv)) -> Self {
140 Self { cfg_env, block_env }
141 }
142}
143
144pub trait BlockEnvironment: revm::context::Block + Clone + Debug + Send + Sync + 'static {
148 fn inner_mut(&mut self) -> &mut revm::context::BlockEnv;
150}
151
152impl BlockEnvironment for BlockEnv {
153 fn inner_mut(&mut self) -> &mut revm::context::BlockEnv {
154 self
155 }
156}