1use crate::frame::MyFrame;
2use revm::{
3 context::{ContextSetters, ContextTr, FrameStack, OutFrame},
4 handler::{
5 evm::{ContextDbError, FrameInitResult, FrameTr},
6 instructions::{EthInstructions, InstructionProvider},
7 EthFrame, EthPrecompiles, EvmTr, FrameInitOrResult,
8 },
9 inspector::{InspectorEvmTr, JournalExt},
10 interpreter::interpreter::EthInterpreter,
11 primitives::hardfork::SpecId,
12 Inspector,
13};
14
15#[derive(Debug)]
21pub struct MyEvm<CTX, INSP> {
22 pub ctx: CTX,
24 pub inspector: INSP,
27 pub instruction: EthInstructions<EthInterpreter, CTX>,
30 pub precompiles: EthPrecompiles,
33 pub frame_stack: FrameStack<MyFrame>,
35}
36
37impl<CTX: ContextTr, INSP> MyEvm<CTX, INSP> {
38 pub fn new(ctx: CTX, inspector: INSP) -> Self {
40 Self {
41 ctx,
42 inspector,
43 instruction: EthInstructions::new_mainnet_with_spec(SpecId::default()),
44 precompiles: EthPrecompiles::new(SpecId::default()),
45 frame_stack: FrameStack::new(),
46 }
47 }
48}
49
50impl<CTX: ContextTr, INSP> EvmTr for MyEvm<CTX, INSP> {
51 type Context = CTX;
52 type Instructions = EthInstructions<EthInterpreter, CTX>;
53 type Precompiles = EthPrecompiles;
54 type Frame = MyFrame;
55
56 #[inline]
57 fn all(
58 &self,
59 ) -> (
60 &Self::Context,
61 &Self::Instructions,
62 &Self::Precompiles,
63 &FrameStack<Self::Frame>,
64 ) {
65 (
66 &self.ctx,
67 &self.instruction,
68 &self.precompiles,
69 &self.frame_stack,
70 )
71 }
72
73 #[inline]
74 fn all_mut(
75 &mut self,
76 ) -> (
77 &mut Self::Context,
78 &mut Self::Instructions,
79 &mut Self::Precompiles,
80 &mut FrameStack<Self::Frame>,
81 ) {
82 (
83 &mut self.ctx,
84 &mut self.instruction,
85 &mut self.precompiles,
86 &mut self.frame_stack,
87 )
88 }
89
90 #[inline]
92 fn frame_init(
93 &mut self,
94 frame_input: <Self::Frame as FrameTr>::FrameInit,
95 ) -> Result<FrameInitResult<'_, Self::Frame>, ContextDbError<CTX>> {
96 let is_first_init = self.frame_stack.index().is_none();
97 let mut new_frame = if is_first_init {
98 self.frame_stack.start_init()
99 } else {
100 self.frame_stack.get_next()
101 };
102
103 let frame = new_frame.get(MyFrame::invalid);
106 let res = EthFrame::init_with_context(
107 OutFrame::new_init(&mut frame.eth_frame),
108 &mut self.ctx,
109 &mut self.precompiles,
110 frame_input,
111 )?;
112 let token = new_frame.consume();
113
114 Ok(res.map_item(|_inner_token| {
115 if is_first_init {
116 unsafe { self.frame_stack.end_init(token) };
117 } else {
118 unsafe { self.frame_stack.push(token) };
119 }
120 self.frame_stack.get()
121 }))
122 }
123
124 #[inline]
128 fn frame_run(&mut self) -> Result<FrameInitOrResult<Self::Frame>, ContextDbError<CTX>> {
129 let frame = self.frame_stack.get();
130 let context = &mut self.ctx;
131 let instructions = &mut self.instruction;
132
133 let action = frame.eth_frame.interpreter.run_plain(
134 instructions.instruction_table(),
135 instructions.gas_table(),
136 context,
137 );
138
139 frame
140 .eth_frame
141 .process_next_action(context, action)
142 .inspect(|i| {
143 if i.is_result() {
144 frame.eth_frame.set_finished(true);
145 }
146 })
147 }
148
149 #[inline]
152 fn frame_return_result(
153 &mut self,
154 result: <Self::Frame as FrameTr>::FrameResult,
155 ) -> Result<Option<<Self::Frame as FrameTr>::FrameResult>, ContextDbError<Self::Context>> {
156 if self.frame_stack.get().is_finished() {
157 self.frame_stack.pop();
158 }
159 if self.frame_stack.index().is_none() {
160 return Ok(Some(result));
161 }
162 self.frame_stack
163 .get()
164 .eth_frame
165 .return_result::<_, ContextDbError<Self::Context>>(&mut self.ctx, result)?;
166 Ok(None)
167 }
168}
169
170impl<CTX: ContextTr, INSP> InspectorEvmTr for MyEvm<CTX, INSP>
171where
172 CTX: ContextSetters<Journal: JournalExt>,
173 INSP: Inspector<CTX, EthInterpreter>,
174{
175 type Inspector = INSP;
176
177 fn all_inspector(
178 &self,
179 ) -> (
180 &Self::Context,
181 &Self::Instructions,
182 &Self::Precompiles,
183 &FrameStack<Self::Frame>,
184 &Self::Inspector,
185 ) {
186 (
187 &self.ctx,
188 &self.instruction,
189 &self.precompiles,
190 &self.frame_stack,
191 &self.inspector,
192 )
193 }
194
195 fn all_mut_inspector(
196 &mut self,
197 ) -> (
198 &mut Self::Context,
199 &mut Self::Instructions,
200 &mut Self::Precompiles,
201 &mut FrameStack<Self::Frame>,
202 &mut Self::Inspector,
203 ) {
204 (
205 &mut self.ctx,
206 &mut self.instruction,
207 &mut self.precompiles,
208 &mut self.frame_stack,
209 &mut self.inspector,
210 )
211 }
212}