revm_interpreter/
interpreter_action.rs

1mod call_inputs;
2mod call_outcome;
3mod create_inputs;
4mod create_outcome;
5
6pub use call_inputs::{CallInput, CallInputs, CallScheme, CallValue};
7pub use call_outcome::CallOutcome;
8pub use create_inputs::CreateInputs;
9pub use create_outcome::CreateOutcome;
10use primitives::Bytes;
11
12use crate::{Gas, InstructionResult, InterpreterResult, SharedMemory};
13use std::boxed::Box;
14
15/// Input data for creating a new execution frame.
16#[derive(Clone, Debug, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub enum FrameInput {
19    /// No input data (empty frame)
20    Empty,
21    /// `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL` instruction called.
22    Call(Box<CallInputs>),
23    /// `CREATE` or `CREATE2` instruction called.
24    Create(Box<CreateInputs>),
25}
26
27/// Initialization data for creating a new execution frame.
28#[derive(Clone, Debug, PartialEq, Eq)]
29#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
30pub struct FrameInit {
31    /// depth of the next frame
32    pub depth: usize,
33    /// shared memory set to this shared context
34    pub memory: SharedMemory,
35    /// Data needed as input for Interpreter.
36    pub frame_input: FrameInput,
37}
38
39impl AsMut<Self> for FrameInput {
40    fn as_mut(&mut self) -> &mut Self {
41        self
42    }
43}
44
45/// Actions that the interpreter can request from the host environment.
46#[derive(Clone, Debug, PartialEq, Eq)]
47#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
48pub enum InterpreterAction {
49    /// New frame
50    NewFrame(FrameInput),
51    /// Interpreter finished execution.
52    Return(InterpreterResult),
53}
54
55impl InterpreterAction {
56    /// Returns `true` if action is call.
57    pub fn is_call(&self) -> bool {
58        matches!(self, InterpreterAction::NewFrame(FrameInput::Call(..)))
59    }
60
61    /// Returns `true` if action is create.
62    pub fn is_create(&self) -> bool {
63        matches!(self, InterpreterAction::NewFrame(FrameInput::Create(..)))
64    }
65
66    /// Returns `true` if action is return.
67    pub fn is_return(&self) -> bool {
68        matches!(self, InterpreterAction::Return { .. })
69    }
70
71    /// Returns [`InterpreterResult`] if action is return.
72    ///
73    /// Else it returns [None].
74    pub fn into_result_return(self) -> Option<InterpreterResult> {
75        match self {
76            InterpreterAction::Return(result) => Some(result),
77            _ => None,
78        }
79    }
80
81    /// Returns [`InstructionResult`] if action is return.
82    ///
83    /// Else it returns [None].
84    pub fn instruction_result(&self) -> Option<InstructionResult> {
85        match self {
86            InterpreterAction::Return(result) => Some(result.result),
87            _ => None,
88        }
89    }
90
91    /// Create new frame action with the given frame input.
92    pub fn new_frame(frame_input: FrameInput) -> Self {
93        Self::NewFrame(frame_input)
94    }
95
96    /// Create new halt action with the given result and gas.
97    pub fn new_halt(result: InstructionResult, gas: Gas) -> Self {
98        Self::Return(InterpreterResult::new(result, Bytes::new(), gas))
99    }
100
101    /// Create new return action with the given result, output and gas.
102    pub fn new_return(result: InstructionResult, output: Bytes, gas: Gas) -> Self {
103        Self::Return(InterpreterResult::new(result, output, gas))
104    }
105
106    /// Create new stop action.
107    pub fn new_stop() -> Self {
108        Self::Return(InterpreterResult::new(
109            InstructionResult::Stop,
110            Bytes::new(),
111            Gas::new(0),
112        ))
113    }
114}