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, FrameInput,
9 InterpreterTypes,
10};
11
12use crate::{
13 handler::{frame_end, frame_start, inspect_logs},
14 inspect_instructions, Inspector, JournalExt,
15};
16
17pub trait InspectorEvmTr:
23 EvmTr<
24 Frame: InspectorFrame<IT = EthInterpreter>,
25 Instructions: InstructionProvider<InterpreterTypes = EthInterpreter, Context = Self::Context>,
26 Context: ContextTr<Journal: JournalExt>,
27>
28{
29 type Inspector: Inspector<Self::Context, EthInterpreter, FrameInput, FrameResult>;
31
32 #[expect(clippy::type_complexity)]
36 fn all_inspector(
37 &self,
38 ) -> (
39 &Self::Context,
40 &Self::Instructions,
41 &Self::Precompiles,
42 &FrameStack<Self::Frame>,
43 &Self::Inspector,
44 );
45
46 #[expect(clippy::type_complexity)]
50 fn all_mut_inspector(
51 &mut self,
52 ) -> (
53 &mut Self::Context,
54 &mut Self::Instructions,
55 &mut Self::Precompiles,
56 &mut FrameStack<Self::Frame>,
57 &mut Self::Inspector,
58 );
59
60 fn inspector(&mut self) -> &mut Self::Inspector {
62 let (_, _, _, _, inspector) = self.all_mut_inspector();
63 inspector
64 }
65
66 fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector) {
70 let (ctx, _, _, _, inspector) = self.all_mut_inspector();
71 (ctx, inspector)
72 }
73
74 fn ctx_inspector_frame(
78 &mut self,
79 ) -> (&mut Self::Context, &mut Self::Inspector, &mut Self::Frame) {
80 let (ctx, _, _, frame, inspector) = self.all_mut_inspector();
81 (ctx, inspector, frame.get())
82 }
83
84 fn ctx_inspector_frame_instructions(
86 &mut self,
87 ) -> (
88 &mut Self::Context,
89 &mut Self::Inspector,
90 &mut Self::Frame,
91 &mut Self::Instructions,
92 ) {
93 let (ctx, instructions, _, frame, inspector) = self.all_mut_inspector();
94 (ctx, inspector, frame.get(), instructions)
95 }
96
97 #[inline]
99 fn inspect_frame_init(
100 &mut self,
101 mut frame_init: <Self::Frame as FrameTr>::FrameInit,
102 ) -> Result<FrameInitResult<'_, Self::Frame>, ContextDbError<Self::Context>> {
103 let (ctx, inspector) = self.ctx_inspector();
104 if let Some(mut output) = frame_start(ctx, inspector, &mut frame_init.frame_input) {
105 frame_end(ctx, inspector, &frame_init.frame_input, &mut output);
106 return Ok(ItemOrResult::Result(output));
107 }
108
109 let frame_input = frame_init.frame_input.clone();
110 let logs_i = ctx.journal().logs().len();
111 if let ItemOrResult::Result(mut output) = self.frame_init(frame_init)? {
112 let (ctx, inspector) = self.ctx_inspector();
113 if ctx.journal().logs().len() != logs_i {
116 inspect_logs(None, ctx, inspector, logs_i);
117 }
118 if let FrameResult::Call(CallOutcome {
120 was_precompile_called: true,
121 precompile_call_logs,
122 ..
123 }) = &output
124 {
125 for log in precompile_call_logs.clone() {
126 inspector.log(ctx, log);
127 }
128 }
129 frame_end(ctx, inspector, &frame_input, &mut output);
130 return Ok(ItemOrResult::Result(output));
131 }
132
133 let (ctx, inspector, frame) = self.ctx_inspector_frame();
135 if ctx.journal().logs().len() != logs_i {
136 inspect_logs(None, ctx, inspector, logs_i);
137 }
138 if let Some(frame) = frame.eth_frame() {
139 let interp = &mut frame.interpreter;
140 inspector.initialize_interp(interp, ctx);
141 };
142 Ok(ItemOrResult::Item(frame))
143 }
144
145 #[inline]
149 fn inspect_frame_run(
150 &mut self,
151 ) -> Result<FrameInitOrResult<Self::Frame>, ContextDbError<Self::Context>> {
152 let (ctx, inspector, frame, instructions) = self.ctx_inspector_frame_instructions();
153
154 let Some(frame) = frame.eth_frame() else {
155 return self.frame_run();
156 };
157
158 let next_action = inspect_instructions(
159 ctx,
160 &mut frame.interpreter,
161 inspector,
162 instructions.instruction_table(),
163 instructions.gas_table(),
164 );
165 let mut result = frame.process_next_action(ctx, next_action);
166
167 if let Ok(ItemOrResult::Result(frame_result)) = &mut result {
168 let (ctx, inspector, frame) = self.ctx_inspector_frame();
169 if let Some(frame) = frame.eth_frame() {
171 frame_end(ctx, inspector, &frame.input, frame_result);
172 frame.set_finished(true);
173 }
174 };
175 result
176 }
177}
178
179pub trait InspectorFrame: FrameTr<FrameResult = FrameResult, FrameInit = FrameInit> {
181 type IT: InterpreterTypes;
183
184 fn eth_frame(&mut self) -> Option<&mut EthFrame<EthInterpreter>>;
189}
190
191impl InspectorFrame for EthFrame<EthInterpreter> {
193 type IT = EthInterpreter;
194
195 fn eth_frame(&mut self) -> Option<&mut EthFrame<EthInterpreter>> {
196 Some(self)
197 }
198}