1use context::{ContextTr, FrameStack, JournalTr};
2use handler::{
3 evm::{ContextDbError, FrameInitResult, FrameTr},
4 instructions::InstructionProvider,
5 EthFrame, EvmTr, FrameInitOrResult, FrameResult, ItemOrResult,
6};
7use interpreter::{
8 interpreter::EthInterpreter, interpreter_action::FrameInit, CallOutcome, InterpreterTypes,
9};
10
11use crate::{
12 handler::{frame_end, frame_start},
13 inspect_instructions, Inspector, JournalExt,
14};
15
16pub trait InspectorEvmTr:
22 EvmTr<
23 Frame: InspectorFrame<IT = EthInterpreter>,
24 Instructions: InstructionProvider<InterpreterTypes = EthInterpreter, Context = Self::Context>,
25 Context: ContextTr<Journal: JournalExt>,
26>
27{
28 type Inspector: Inspector<Self::Context, EthInterpreter>;
30
31 #[allow(clippy::type_complexity)]
35 fn all_inspector(
36 &self,
37 ) -> (
38 &Self::Context,
39 &Self::Instructions,
40 &Self::Precompiles,
41 &FrameStack<Self::Frame>,
42 &Self::Inspector,
43 );
44
45 #[allow(clippy::type_complexity)]
49 fn all_mut_inspector(
50 &mut self,
51 ) -> (
52 &mut Self::Context,
53 &mut Self::Instructions,
54 &mut Self::Precompiles,
55 &mut FrameStack<Self::Frame>,
56 &mut Self::Inspector,
57 );
58
59 fn inspector(&mut self) -> &mut Self::Inspector {
61 let (_, _, _, _, inspector) = self.all_mut_inspector();
62 inspector
63 }
64
65 fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector) {
69 let (ctx, _, _, _, inspector) = self.all_mut_inspector();
70 (ctx, inspector)
71 }
72
73 fn ctx_inspector_frame(
77 &mut self,
78 ) -> (&mut Self::Context, &mut Self::Inspector, &mut Self::Frame) {
79 let (ctx, _, _, frame, inspector) = self.all_mut_inspector();
80 (ctx, inspector, frame.get())
81 }
82
83 fn ctx_inspector_frame_instructions(
85 &mut self,
86 ) -> (
87 &mut Self::Context,
88 &mut Self::Inspector,
89 &mut Self::Frame,
90 &mut Self::Instructions,
91 ) {
92 let (ctx, instructions, _, frame, inspector) = self.all_mut_inspector();
93 (ctx, inspector, frame.get(), instructions)
94 }
95
96 #[inline]
98 fn inspect_frame_init(
99 &mut self,
100 mut frame_init: <Self::Frame as FrameTr>::FrameInit,
101 ) -> Result<FrameInitResult<'_, Self::Frame>, ContextDbError<Self::Context>> {
102 let (ctx, inspector) = self.ctx_inspector();
103 if let Some(mut output) = frame_start(ctx, inspector, &mut frame_init.frame_input) {
104 frame_end(ctx, inspector, &frame_init.frame_input, &mut output);
105 return Ok(ItemOrResult::Result(output));
106 }
107
108 let frame_input = frame_init.frame_input.clone();
109 let logs_i = ctx.journal().logs().len();
110 if let ItemOrResult::Result(mut output) = self.frame_init(frame_init)? {
111 let (ctx, inspector) = self.ctx_inspector();
112 if let FrameResult::Call(CallOutcome {
114 was_precompile_called,
115 precompile_call_logs,
116 ..
117 }) = &mut output
118 {
119 if *was_precompile_called {
120 let logs = ctx.journal_mut().logs()[logs_i..].to_vec();
121 for log in logs.iter().chain(precompile_call_logs.iter()).cloned() {
122 inspector.log(ctx, log);
123 }
124 }
125 }
126 frame_end(ctx, inspector, &frame_input, &mut output);
127 return Ok(ItemOrResult::Result(output));
128 }
129
130 let (ctx, inspector, frame) = self.ctx_inspector_frame();
132 if let Some(frame) = frame.eth_frame() {
133 let interp = &mut frame.interpreter;
134 inspector.initialize_interp(interp, ctx);
135 };
136 Ok(ItemOrResult::Item(frame))
137 }
138
139 #[inline]
143 fn inspect_frame_run(
144 &mut self,
145 ) -> Result<FrameInitOrResult<Self::Frame>, ContextDbError<Self::Context>> {
146 let (ctx, inspector, frame, instructions) = self.ctx_inspector_frame_instructions();
147
148 let Some(frame) = frame.eth_frame() else {
149 return self.frame_run();
150 };
151
152 let next_action = inspect_instructions(
153 ctx,
154 &mut frame.interpreter,
155 inspector,
156 instructions.instruction_table(),
157 );
158 let mut result = frame.process_next_action(ctx, next_action);
159
160 if let Ok(ItemOrResult::Result(frame_result)) = &mut result {
161 let (ctx, inspector, frame) = self.ctx_inspector_frame();
162 if let Some(frame) = frame.eth_frame() {
164 frame_end(ctx, inspector, &frame.input, frame_result);
165 frame.set_finished(true);
166 }
167 };
168 result
169 }
170}
171
172pub trait InspectorFrame: FrameTr<FrameResult = FrameResult, FrameInit = FrameInit> {
174 type IT: InterpreterTypes;
176
177 fn eth_frame(&mut self) -> Option<&mut EthFrame<EthInterpreter>>;
182}
183
184impl InspectorFrame for EthFrame<EthInterpreter> {
186 type IT = EthInterpreter;
187
188 fn eth_frame(&mut self) -> Option<&mut EthFrame<EthInterpreter>> {
189 Some(self)
190 }
191}