revm_handler/
frame_data.rs

1use context_interface::result::Output;
2use core::ops::Range;
3use interpreter::{CallOutcome, CreateOutcome, Gas, InstructionResult, InterpreterResult};
4use primitives::Address;
5
6/// Call Frame
7#[derive(Debug, Clone)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct CallFrame {
10    /// Call frame has return memory range where output will be stored.
11    pub return_memory_range: Range<usize>,
12}
13
14/// Create Frame
15#[derive(Debug, Clone)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct CreateFrame {
18    /// Create frame has a created address.
19    pub created_address: Address,
20}
21
22/// Frame Data
23///
24/// [`FrameData`] bundles different types of frames.
25#[derive(Debug, Clone)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27pub enum FrameData {
28    /// Call frame data.
29    Call(CallFrame),
30    /// Create frame data.
31    Create(CreateFrame),
32}
33
34/// Frame Result
35#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36#[derive(Debug, Clone)]
37pub enum FrameResult {
38    /// Call frame result.
39    Call(CallOutcome),
40    /// Create frame result.
41    Create(CreateOutcome),
42}
43
44impl FrameResult {
45    /// Creates a new call frame result for an out-of-gas error.
46    #[inline]
47    pub fn new_call_oog(gas_limit: u64, memory_offset: core::ops::Range<usize>) -> Self {
48        Self::Call(CallOutcome::new_oog(gas_limit, memory_offset))
49    }
50
51    /// Creates a new create frame result for an out-of-gas error.
52    #[inline]
53    pub fn new_create_oog(gas_limit: u64) -> Self {
54        Self::Create(CreateOutcome::new_oog(gas_limit))
55    }
56
57    /// Casts frame result to interpreter result.
58    #[inline]
59    pub fn into_interpreter_result(self) -> InterpreterResult {
60        match self {
61            FrameResult::Call(outcome) => outcome.result,
62            FrameResult::Create(outcome) => outcome.result,
63        }
64    }
65
66    /// Returns execution output.
67    #[inline]
68    pub fn output(&self) -> Output {
69        match self {
70            FrameResult::Call(outcome) => Output::Call(outcome.result.output.clone()),
71            FrameResult::Create(outcome) => {
72                Output::Create(outcome.result.output.clone(), outcome.address)
73            }
74        }
75    }
76
77    /// Returns reference to gas.
78    #[inline]
79    pub fn gas(&self) -> &Gas {
80        match self {
81            FrameResult::Call(outcome) => &outcome.result.gas,
82            FrameResult::Create(outcome) => &outcome.result.gas,
83        }
84    }
85
86    /// Returns mutable reference to interpreter result.
87    #[inline]
88    pub fn gas_mut(&mut self) -> &mut Gas {
89        match self {
90            FrameResult::Call(outcome) => &mut outcome.result.gas,
91            FrameResult::Create(outcome) => &mut outcome.result.gas,
92        }
93    }
94
95    /// Returns reference to interpreter result.
96    #[inline]
97    pub fn interpreter_result(&self) -> &InterpreterResult {
98        match self {
99            FrameResult::Call(outcome) => &outcome.result,
100            FrameResult::Create(outcome) => &outcome.result,
101        }
102    }
103
104    /// Returns mutable reference to interpreter result.
105    #[inline]
106    pub fn interpreter_result_mut(&mut self) -> &mut InterpreterResult {
107        match self {
108            FrameResult::Call(outcome) => &mut outcome.result,
109            FrameResult::Create(outcome) => &mut outcome.result,
110        }
111    }
112
113    /// Return Instruction result.
114    #[inline]
115    pub fn instruction_result(&self) -> InstructionResult {
116        self.interpreter_result().result
117    }
118}
119
120impl FrameData {
121    /// Creates a new create frame data.
122    pub fn new_create(created_address: Address) -> Self {
123        Self::Create(CreateFrame { created_address })
124    }
125
126    /// Creates a new call frame data.
127    pub fn new_call(return_memory_range: Range<usize>) -> Self {
128        Self::Call(CallFrame {
129            return_memory_range,
130        })
131    }
132
133    /// Returns true if frame is call frame.
134    pub fn is_call(&self) -> bool {
135        matches!(self, Self::Call { .. })
136    }
137
138    /// Returns true if frame is create frame.
139    pub fn is_create(&self) -> bool {
140        matches!(self, Self::Create { .. })
141    }
142
143    /// Returns created address if frame is create otherwise returns None.
144    pub fn created_address(&self) -> Option<Address> {
145        match self {
146            Self::Create(create_frame) => Some(create_frame.created_address),
147            _ => None,
148        }
149    }
150}