1use crate::helpers::Ctx;
2use revm::{
3 context::{BlockEnv, CfgEnv, Evm, TxEnv},
4 Database,
5};
6use std::sync::Arc;
7
8pub trait Tx: Send + Sync {
10 fn fill_tx_env(&self, tx_env: &mut TxEnv);
20
21 fn fill_tx<Db: Database, Insp, Inst, Prec, Frame>(
23 &self,
24 evm: &mut Evm<Ctx<Db>, Insp, Inst, Prec, Frame>,
25 ) where
26 Self: Sized,
27 {
28 evm.ctx.modify_tx(|tx_env| self.fill_tx_env(tx_env));
29 }
30}
31
32impl Tx for TxEnv {
33 fn fill_tx_env(&self, tx_env: &mut TxEnv) {
34 *tx_env = self.clone();
35 }
36}
37
38impl Tx for Arc<dyn Tx> {
39 fn fill_tx_env(&self, tx_env: &mut TxEnv) {
40 self.as_ref().fill_tx_env(tx_env);
41 }
42}
43
44impl Tx for Box<dyn Tx> {
45 fn fill_tx_env(&self, tx_env: &mut TxEnv) {
46 self.as_ref().fill_tx_env(tx_env);
47 }
48}
49
50impl<T> Tx for T
51where
52 T: Fn(&mut TxEnv) + Send + Sync,
53{
54 fn fill_tx_env(&self, tx_env: &mut TxEnv) {
55 self(tx_env);
56 }
57}
58
59pub trait Block: Send + Sync {
61 fn fill_block_env(&self, block_env: &mut BlockEnv);
70
71 fn fill_block<Db: Database, Insp, Inst, Prec, Frame>(
73 &self,
74 evm: &mut Evm<Ctx<Db>, Insp, Inst, Prec, Frame>,
75 ) where
76 Self: Sized,
77 {
78 evm.ctx.modify_block(|block_env| self.fill_block_env(block_env));
79 }
80
81 fn tx_count_hint(&self) -> Option<usize> {
84 None
85 }
86}
87
88impl<T> Block for T
89where
90 T: Fn(&mut BlockEnv) + Send + Sync,
91{
92 fn fill_block_env(&self, block_env: &mut BlockEnv) {
93 self(block_env);
94 }
95}
96
97impl Block for BlockEnv {
98 fn fill_block_env(&self, block_env: &mut BlockEnv) {
99 *block_env = self.clone();
100 }
101}
102
103impl Block for Arc<dyn Block> {
104 fn fill_block_env(&self, block_env: &mut BlockEnv) {
105 self.as_ref().fill_block_env(block_env);
106 }
107}
108
109impl Block for Box<dyn Block> {
110 fn fill_block_env(&self, block_env: &mut BlockEnv) {
111 self.as_ref().fill_block_env(block_env);
112 }
113}
114
115pub trait Cfg: Send + Sync {
133 fn fill_cfg_env(&self, cfg_env: &mut CfgEnv);
135
136 fn fill_cfg<Db: Database, Insp, Inst, Prec, Frame>(
138 &self,
139 evm: &mut Evm<Ctx<Db>, Insp, Inst, Prec, Frame>,
140 ) where
141 Self: Sized,
142 {
143 evm.ctx.modify_cfg(|cfg_env| self.fill_cfg_env(cfg_env));
144 }
145}
146
147impl Cfg for Arc<dyn Cfg> {
148 fn fill_cfg_env(&self, cfg_env: &mut CfgEnv) {
149 self.as_ref().fill_cfg_env(cfg_env);
150 }
151}
152
153impl Cfg for CfgEnv {
154 fn fill_cfg_env(&self, cfg_env: &mut CfgEnv) {
155 *cfg_env = self.clone();
156 }
157}
158
159impl Cfg for Box<dyn Cfg> {
160 fn fill_cfg_env(&self, cfg_env: &mut CfgEnv) {
161 self.as_ref().fill_cfg_env(cfg_env);
162 }
163}
164
165impl<T> Cfg for T
166where
167 T: Fn(&mut CfgEnv) + Send + Sync,
168{
169 fn fill_cfg_env(&self, cfg_env: &mut CfgEnv) {
170 self(cfg_env);
171 }
172}
173
174#[cfg(test)]
175mod test {
176 use alloy::{
177 consensus::constants::GWEI_TO_WEI,
178 primitives::{B256, U256},
179 };
180 use revm::{
181 context::{BlockEnv, CfgEnv},
182 context_interface::block::BlobExcessGasAndPrice,
183 };
184
185 use super::*;
186
187 #[allow(dead_code)]
188 fn object_safety(cfg: Box<dyn Cfg>, block: Box<dyn Block>, tx: Box<dyn Tx>) {
189 crate::test_utils::test_trevm().fill_cfg(&cfg).fill_block(&block).fill_tx(&tx);
190
191 unimplemented!("compilation check only")
192 }
193
194 impl Block for () {
195 fn fill_block_env(&self, block_env: &mut BlockEnv) {
196 let BlockEnv {
197 number,
198 beneficiary,
199 timestamp,
200 gas_limit,
201 basefee,
202 difficulty,
203 prevrandao,
204 blob_excess_gas_and_price,
205 } = block_env;
206 *number = U256::ONE;
207 *beneficiary = Default::default();
208 *timestamp = U256::from(1720450148u64); *gas_limit = 30_000_000;
210 *basefee = 5 * GWEI_TO_WEI;
211
212 let diff = B256::repeat_byte(0xab);
213 *prevrandao = Some(diff);
214 *difficulty = U256::from_be_bytes(diff.into());
215
216 *blob_excess_gas_and_price = Some(BlobExcessGasAndPrice::new(
217 1_000_000,
218 revm::primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE,
219 ));
220 }
221
222 fn tx_count_hint(&self) -> Option<usize> {
223 None
224 }
225 }
226
227 impl Cfg for () {
228 fn fill_cfg_env(&self, cfg_env: &mut CfgEnv) {
229 let CfgEnv { chain_id, .. } = cfg_env;
230 *chain_id = 1;
231 }
232 }
233}