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},
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 #[allow(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 #[allow(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 let FrameResult::Call(CallOutcome {
115 was_precompile_called,
116 precompile_call_logs,
117 ..
118 }) = &mut output
119 {
120 if *was_precompile_called {
121 let logs = ctx.journal_mut().logs()[logs_i..].to_vec();
122 for log in logs.into_iter().chain(precompile_call_logs.iter().cloned()) {
123 inspector.log(ctx, log);
124 }
125 }
126 }
127 frame_end(ctx, inspector, &frame_input, &mut output);
128 return Ok(ItemOrResult::Result(output));
129 }
130
131 let (ctx, inspector, frame) = self.ctx_inspector_frame();
133 if let Some(frame) = frame.eth_frame() {
134 let interp = &mut frame.interpreter;
135 inspector.initialize_interp(interp, ctx);
136 };
137 Ok(ItemOrResult::Item(frame))
138 }
139
140 #[inline]
144 fn inspect_frame_run(
145 &mut self,
146 ) -> Result<FrameInitOrResult<Self::Frame>, ContextDbError<Self::Context>> {
147 let (ctx, inspector, frame, instructions) = self.ctx_inspector_frame_instructions();
148
149 let Some(frame) = frame.eth_frame() else {
150 return self.frame_run();
151 };
152
153 let next_action = inspect_instructions(
154 ctx,
155 &mut frame.interpreter,
156 inspector,
157 instructions.instruction_table(),
158 );
159 let mut result = frame.process_next_action(ctx, next_action);
160
161 if let Ok(ItemOrResult::Result(frame_result)) = &mut result {
162 let (ctx, inspector, frame) = self.ctx_inspector_frame();
163 if let Some(frame) = frame.eth_frame() {
165 frame_end(ctx, inspector, &frame.input, frame_result);
166 frame.set_finished(true);
167 }
168 };
169 result
170 }
171}
172
173pub trait InspectorFrame: FrameTr<FrameResult = FrameResult, FrameInit = FrameInit> {
175 type IT: InterpreterTypes;
177
178 fn eth_frame(&mut self) -> Option<&mut EthFrame<EthInterpreter>>;
183}
184
185impl InspectorFrame for EthFrame<EthInterpreter> {
187 type IT = EthInterpreter;
188
189 fn eth_frame(&mut self) -> Option<&mut EthFrame<EthInterpreter>> {
190 Some(self)
191 }
192}