revm_inspector/
traits.rs

1use context::ContextTr;
2use handler::{
3    evm::{ContextDbError, FrameInitResult, FrameTr},
4    instructions::InstructionProvider,
5    EthFrame, EvmTr, FrameInitOrResult, ItemOrResult,
6};
7use interpreter::{interpreter::EthInterpreter, FrameInput, Interpreter, InterpreterTypes};
8
9use crate::{
10    handler::{frame_end, frame_start},
11    inspect_instructions, Inspector, JournalExt,
12};
13
14/// Inspector EVM trait. Extends the [`EvmTr`] trait with inspector related methods.
15///
16/// It contains execution of interpreter with [`crate::Inspector`] calls [`crate::Inspector::step`] and [`crate::Inspector::step_end`] calls.
17///
18/// It is used inside [`crate::InspectorHandler`] to extend evm with support for inspection.
19pub trait InspectorEvmTr:
20    EvmTr<
21    Frame = EthFrame<EthInterpreter>,
22    Instructions: InstructionProvider<InterpreterTypes = EthInterpreter, Context = Self::Context>,
23    Context: ContextTr<Journal: JournalExt>,
24>
25{
26    /// The inspector type used for EVM execution inspection.
27    type Inspector: Inspector<Self::Context, EthInterpreter>;
28
29    /// Returns a mutable reference to the inspector.
30    fn inspector(&mut self) -> &mut Self::Inspector;
31
32    /// Returns a tuple of mutable references to the context and the inspector.
33    ///
34    /// Useful when you want to allow inspector to modify the context.
35    fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector);
36
37    /// Returns a tuple of mutable references to the context, the inspector and the frame.
38    ///
39    /// Useful when you want to allow inspector to modify the context and the frame.
40    fn ctx_inspector_frame(
41        &mut self,
42    ) -> (&mut Self::Context, &mut Self::Inspector, &mut Self::Frame);
43
44    /// Returns a tuple of mutable references to the context, the inspector, the frame and the instructions.
45    fn ctx_inspector_frame_instructions(
46        &mut self,
47    ) -> (
48        &mut Self::Context,
49        &mut Self::Inspector,
50        &mut Self::Frame,
51        &mut Self::Instructions,
52    );
53
54    /// Initializes the frame for the given frame input. Frame is pushed to the frame stack.
55    #[inline]
56    fn inspect_frame_init(
57        &mut self,
58        mut frame_init: <Self::Frame as FrameTr>::FrameInit,
59    ) -> Result<FrameInitResult<'_, Self::Frame>, ContextDbError<Self::Context>> {
60        let (ctx, inspector) = self.ctx_inspector();
61        if let Some(mut output) = frame_start(ctx, inspector, &mut frame_init.frame_input) {
62            frame_end(ctx, inspector, &frame_init.frame_input, &mut output);
63            return Ok(ItemOrResult::Result(output));
64        }
65        if let ItemOrResult::Result(frame) = self.frame_init(frame_init)? {
66            return Ok(ItemOrResult::Result(frame));
67        }
68
69        // if it is new frame, initialize the interpreter.
70        let (ctx, inspector, frame) = self.ctx_inspector_frame();
71        let interp = frame.interpreter();
72        inspector.initialize_interp(interp, ctx);
73        Ok(ItemOrResult::Item(frame))
74    }
75
76    /// Run the frame from the top of the stack. Returns the frame init or result.
77    ///
78    /// If frame has returned result it would mark it as finished.
79    #[inline]
80    fn inspect_frame_run(
81        &mut self,
82    ) -> Result<FrameInitOrResult<Self::Frame>, ContextDbError<Self::Context>> {
83        let (ctx, inspector, frame, instructions) = self.ctx_inspector_frame_instructions();
84
85        let next_action = inspect_instructions(
86            ctx,
87            frame.interpreter(),
88            inspector,
89            instructions.instruction_table(),
90        );
91        let mut result = frame.process_next_action(ctx, next_action);
92
93        if let Ok(ItemOrResult::Result(frame_result)) = &mut result {
94            let (ctx, inspector, frame) = self.ctx_inspector_frame();
95            frame_end(ctx, inspector, frame.frame_input(), frame_result);
96            frame.set_finished(true);
97        };
98        result
99    }
100}
101
102/// Trait that extends the [`FrameTr`] trait with additional functionality that is needed for inspection.
103pub trait InspectorFrame: FrameTr {
104    /// The interpreter types used by this frame.
105    type IT: InterpreterTypes;
106
107    /// Returns a mutable reference to the interpreter.
108    fn interpreter(&mut self) -> &mut Interpreter<Self::IT>;
109
110    /// Returns a reference to the frame input. Frame input is needed for call/create/eofcreate [`crate::Inspector`] methods
111    fn frame_input(&self) -> &FrameInput;
112}
113
114/// Impl InspectorFrame for EthFrame.
115impl InspectorFrame for EthFrame<EthInterpreter> {
116    type IT = EthInterpreter;
117
118    fn interpreter(&mut self) -> &mut Interpreter<Self::IT> {
119        &mut self.interpreter
120    }
121
122    fn frame_input(&self) -> &FrameInput {
123        &self.input
124    }
125}