foundry_evm_core/evm/
eth.rs1use super::*;
2
3type EthEvmHandler<'db, I> =
4 MainnetHandler<EthRevmEvm<'db, I>, EVMError<DatabaseError>, EthFrame<EthInterpreter>>;
5
6pub type EthRevmEvm<'db, I> = RevmEvm<
7 EthEvmContext<&'db mut dyn DatabaseExt<EthEvmFactory>>,
8 I,
9 EthInstructions<EthInterpreter, EthEvmContext<&'db mut dyn DatabaseExt<EthEvmFactory>>>,
10 PrecompilesMap,
11 EthFrame<EthInterpreter>,
12>;
13
14pub struct EthFoundryEvm<
15 'db,
16 I: FoundryInspectorExt<EthEvmContext<&'db mut dyn DatabaseExt<EthEvmFactory>>>,
17> {
18 pub inner: EthRevmEvm<'db, I>,
19}
20
21impl<'db, I: FoundryInspectorExt<EthEvmContext<&'db mut dyn DatabaseExt<EthEvmFactory>>>> Evm
22 for EthFoundryEvm<'db, I>
23{
24 type Precompiles = PrecompilesMap;
25 type Inspector = I;
26 type DB = &'db mut dyn DatabaseExt<EthEvmFactory>;
27 type Error = EVMError<DatabaseError>;
28 type HaltReason = HaltReason;
29 type Spec = SpecId;
30 type Tx = TxEnv;
31 type BlockEnv = BlockEnv;
32
33 fn block(&self) -> &BlockEnv {
34 &self.inner.block
35 }
36
37 fn chain_id(&self) -> u64 {
38 self.inner.ctx.cfg.chain_id
39 }
40
41 fn components(&self) -> (&Self::DB, &Self::Inspector, &Self::Precompiles) {
42 (&self.inner.ctx.journaled_state.database, &self.inner.inspector, &self.inner.precompiles)
43 }
44
45 fn components_mut(&mut self) -> (&mut Self::DB, &mut Self::Inspector, &mut Self::Precompiles) {
46 (
47 &mut self.inner.ctx.journaled_state.database,
48 &mut self.inner.inspector,
49 &mut self.inner.precompiles,
50 )
51 }
52
53 fn set_inspector_enabled(&mut self, _enabled: bool) {
54 unimplemented!("FoundryEvm is always inspecting")
55 }
56
57 fn transact_raw(
58 &mut self,
59 tx: Self::Tx,
60 ) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
61 self.inner.set_tx(tx);
62
63 let result = EthEvmHandler::<I>::default().inspect_run(&mut self.inner)?;
64
65 Ok(ResultAndState::new(result, self.inner.ctx.journaled_state.inner.state.clone()))
66 }
67
68 fn transact_system_call(
69 &mut self,
70 _caller: Address,
71 _contract: Address,
72 _data: Bytes,
73 ) -> Result<ExecResultAndState<ExecutionResult>, Self::Error> {
74 unimplemented!()
75 }
76
77 fn finish(self) -> (Self::DB, EvmEnv<Self::Spec>)
78 where
79 Self: Sized,
80 {
81 let Context { block: block_env, cfg: cfg_env, journaled_state, .. } = self.inner.ctx;
82
83 (journaled_state.database, EvmEnv { block_env, cfg_env })
84 }
85}
86
87impl<'db, I: FoundryInspectorExt<EthEvmContext<&'db mut dyn DatabaseExt<EthEvmFactory>>>> Deref
88 for EthFoundryEvm<'db, I>
89{
90 type Target = EthEvmContext<&'db mut dyn DatabaseExt<EthEvmFactory>>;
91
92 fn deref(&self) -> &Self::Target {
93 &self.inner.ctx
94 }
95}
96
97impl<'db, I: FoundryInspectorExt<EthEvmContext<&'db mut dyn DatabaseExt<EthEvmFactory>>>> DerefMut
98 for EthFoundryEvm<'db, I>
99{
100 fn deref_mut(&mut self) -> &mut Self::Target {
101 &mut self.inner.ctx
102 }
103}
104
105impl FoundryEvmFactory for EthEvmFactory {
106 type FoundryContext<'db> = EthEvmContext<&'db mut dyn DatabaseExt<Self>>;
107
108 type FoundryEvm<'db, I: FoundryInspectorExt<Self::FoundryContext<'db>>> = EthFoundryEvm<'db, I>;
109
110 fn create_foundry_evm_with_inspector<'db, I: FoundryInspectorExt<Self::FoundryContext<'db>>>(
111 &self,
112 db: &'db mut dyn DatabaseExt<Self>,
113 evm_env: EvmEnv,
114 inspector: I,
115 ) -> Self::FoundryEvm<'db, I> {
116 let eth_evm = Self::default().create_evm_with_inspector(db, evm_env, inspector);
117 let mut inner = eth_evm.into_inner();
118 inner.ctx.cfg.tx_chain_id_check = true;
119
120 let mut evm = EthFoundryEvm { inner };
121 evm.inspector().get_networks().inject_precompiles(evm.precompiles_mut());
122 evm
123 }
124
125 fn create_foundry_nested_evm<'db>(
126 &self,
127 db: &'db mut dyn DatabaseExt<Self>,
128 evm_env: EvmEnv,
129 inspector: &'db mut dyn FoundryInspectorExt<Self::FoundryContext<'db>>,
130 ) -> Box<dyn NestedEvm<Spec = SpecId, Block = BlockEnv, Tx = TxEnv> + 'db> {
131 Box::new(self.create_foundry_evm_with_inspector(db, evm_env, inspector).inner)
132 }
133}
134
135impl<'db, I: FoundryInspectorExt<EthEvmContext<&'db mut dyn DatabaseExt<EthEvmFactory>>>> NestedEvm
136 for EthRevmEvm<'db, I>
137{
138 type Spec = SpecId;
139 type Block = BlockEnv;
140 type Tx = TxEnv;
141
142 fn journal_inner_mut(&mut self) -> &mut JournaledState {
143 &mut self.ctx_mut().journaled_state.inner
144 }
145
146 fn run_execution(&mut self, frame: FrameInput) -> Result<FrameResult, EVMError<DatabaseError>> {
147 let mut handler = EthEvmHandler::<I>::default();
148
149 let memory =
151 SharedMemory::new_with_buffer(self.ctx().local().shared_memory_buffer().clone());
152 let first_frame_input = FrameInit { depth: 0, memory, frame_input: frame };
153
154 let mut frame_result = handler.inspect_run_exec_loop(self, first_frame_input)?;
156
157 handler.last_frame_result(self, &mut frame_result)?;
159
160 Ok(frame_result)
161 }
162
163 fn transact_raw(
164 &mut self,
165 tx: Self::Tx,
166 ) -> Result<ResultAndState<HaltReason>, EVMError<DatabaseError>> {
167 self.set_tx(tx);
168
169 let result = EthEvmHandler::<I>::default().inspect_run(self)?;
170
171 Ok(ResultAndState::new(result, self.ctx.journaled_state.inner.state.clone()))
172 }
173
174 fn to_evm_env(&self) -> EvmEnv<Self::Spec, Self::Block> {
175 self.ctx_ref().evm_clone()
176 }
177}