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    #[inline]
58    pub fn is_call(&self) -> bool {
59        matches!(self, InterpreterAction::NewFrame(FrameInput::Call(..)))
60    }
61
62    /// Returns `true` if action is create.
63    #[inline]
64    pub fn is_create(&self) -> bool {
65        matches!(self, InterpreterAction::NewFrame(FrameInput::Create(..)))
66    }
67
68    /// Returns `true` if action is return.
69    #[inline]
70    pub fn is_return(&self) -> bool {
71        matches!(self, InterpreterAction::Return { .. })
72    }
73
74    /// Returns [`Gas`] if action is return.
75    #[inline]
76    pub fn gas_mut(&mut self) -> Option<&mut Gas> {
77        match self {
78            InterpreterAction::Return(result) => Some(&mut result.gas),
79            _ => None,
80        }
81    }
82
83    /// Returns [`InterpreterResult`] if action is return.
84    ///
85    /// Else it returns [None].
86    #[inline]
87    pub fn into_result_return(self) -> Option<InterpreterResult> {
88        match self {
89            InterpreterAction::Return(result) => Some(result),
90            _ => None,
91        }
92    }
93
94    /// Returns [`InstructionResult`] if action is return.
95    ///
96    /// Else it returns [None].
97    #[inline]
98    pub fn instruction_result(&self) -> Option<InstructionResult> {
99        match self {
100            InterpreterAction::Return(result) => Some(result.result),
101            _ => None,
102        }
103    }
104
105    /// Create new frame action with the given frame input.
106    #[inline]
107    pub fn new_frame(frame_input: FrameInput) -> Self {
108        Self::NewFrame(frame_input)
109    }
110
111    /// Create new halt action with the given result and gas.
112    #[inline]
113    pub fn new_halt(result: InstructionResult, gas: Gas) -> Self {
114        Self::Return(InterpreterResult::new(result, Bytes::new(), gas))
115    }
116
117    /// Create new return action with the given result, output and gas.
118    #[inline]
119    pub fn new_return(result: InstructionResult, output: Bytes, gas: Gas) -> Self {
120        Self::Return(InterpreterResult::new(result, output, gas))
121    }
122
123    /// Create new stop action.
124    #[inline]
125    pub fn new_stop() -> Self {
126        Self::Return(InterpreterResult::new(
127            InstructionResult::Stop,
128            Bytes::new(),
129            Gas::new(0),
130        ))
131    }
132}