revm/
frame.rs

1use crate::{
2    interpreter::Interpreter,
3    primitives::{Address, Output},
4    JournalCheckpoint,
5};
6use core::ops::Range;
7use revm_interpreter::{CallOutcome, CreateOutcome, Gas, InstructionResult, InterpreterResult};
8use std::boxed::Box;
9
10/// Call CallStackFrame.
11#[derive(Debug)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct CallFrame {
14    /// Call frame has return memory range where output will be stored.
15    pub return_memory_range: Range<usize>,
16    /// Frame data.
17    pub frame_data: FrameData,
18}
19
20#[derive(Debug)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22pub struct CreateFrame {
23    /// Create frame has a created address.
24    pub created_address: Address,
25    /// Frame data.
26    pub frame_data: FrameData,
27}
28
29/// Eof Create Frame.
30#[derive(Debug)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub struct EOFCreateFrame {
33    pub created_address: Address,
34    pub frame_data: FrameData,
35}
36
37#[derive(Debug)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39pub struct FrameData {
40    /// Journal checkpoint.
41    pub checkpoint: JournalCheckpoint,
42    /// Interpreter.
43    pub interpreter: Interpreter,
44}
45
46/// Call stack frame.
47#[derive(Debug)]
48#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
49pub enum Frame {
50    Call(Box<CallFrame>),
51    Create(Box<CreateFrame>),
52    EOFCreate(Box<EOFCreateFrame>),
53}
54
55#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
56#[derive(Debug)]
57pub enum FrameResult {
58    Call(CallOutcome),
59    Create(CreateOutcome),
60    EOFCreate(CreateOutcome),
61}
62
63impl FrameResult {
64    /// Casts frame result to interpreter result.
65    #[inline]
66    pub fn into_interpreter_result(self) -> InterpreterResult {
67        match self {
68            FrameResult::Call(outcome) => outcome.result,
69            FrameResult::Create(outcome) => outcome.result,
70            FrameResult::EOFCreate(outcome) => outcome.result,
71        }
72    }
73
74    /// Returns execution output.
75    #[inline]
76    pub fn output(&self) -> Output {
77        match self {
78            FrameResult::Call(outcome) => Output::Call(outcome.result.output.clone()),
79            FrameResult::Create(outcome) => {
80                Output::Create(outcome.result.output.clone(), outcome.address)
81            }
82            FrameResult::EOFCreate(outcome) => {
83                Output::Create(outcome.result.output.clone(), outcome.address)
84            }
85        }
86    }
87
88    /// Returns reference to gas.
89    #[inline]
90    pub fn gas(&self) -> &Gas {
91        match self {
92            FrameResult::Call(outcome) => &outcome.result.gas,
93            FrameResult::Create(outcome) => &outcome.result.gas,
94            FrameResult::EOFCreate(outcome) => &outcome.result.gas,
95        }
96    }
97
98    /// Returns mutable reference to interpreter result.
99    #[inline]
100    pub fn gas_mut(&mut self) -> &mut Gas {
101        match self {
102            FrameResult::Call(outcome) => &mut outcome.result.gas,
103            FrameResult::Create(outcome) => &mut outcome.result.gas,
104            FrameResult::EOFCreate(outcome) => &mut outcome.result.gas,
105        }
106    }
107
108    /// Returns reference to interpreter result.
109    #[inline]
110    pub fn interpreter_result(&self) -> &InterpreterResult {
111        match self {
112            FrameResult::Call(outcome) => &outcome.result,
113            FrameResult::Create(outcome) => &outcome.result,
114            FrameResult::EOFCreate(outcome) => &outcome.result,
115        }
116    }
117
118    /// Returns mutable reference to interpreter result.
119    #[inline]
120    pub fn interpreter_result_mut(&mut self) -> &InterpreterResult {
121        match self {
122            FrameResult::Call(outcome) => &mut outcome.result,
123            FrameResult::Create(outcome) => &mut outcome.result,
124            FrameResult::EOFCreate(outcome) => &mut outcome.result,
125        }
126    }
127
128    /// Return Instruction result.
129    #[inline]
130    pub fn instruction_result(&self) -> InstructionResult {
131        self.interpreter_result().result
132    }
133}
134
135/// Contains either a frame or a result.
136#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
137#[derive(Debug)]
138pub enum FrameOrResult {
139    /// Boxed call or create frame.
140    Frame(Frame),
141    /// Call or create result.
142    Result(FrameResult),
143}
144
145impl Frame {
146    pub fn new_create(
147        created_address: Address,
148        checkpoint: JournalCheckpoint,
149        interpreter: Interpreter,
150    ) -> Self {
151        Frame::Create(Box::new(CreateFrame {
152            created_address,
153            frame_data: FrameData {
154                checkpoint,
155                interpreter,
156            },
157        }))
158    }
159
160    pub fn new_call(
161        return_memory_range: Range<usize>,
162        checkpoint: JournalCheckpoint,
163        interpreter: Interpreter,
164    ) -> Self {
165        Frame::Call(Box::new(CallFrame {
166            return_memory_range,
167            frame_data: FrameData {
168                checkpoint,
169                interpreter,
170            },
171        }))
172    }
173
174    /// Returns true if frame is call frame.
175    pub fn is_call(&self) -> bool {
176        matches!(self, Frame::Call { .. })
177    }
178
179    /// Returns true if frame is create frame.
180    pub fn is_create(&self) -> bool {
181        matches!(self, Frame::Create { .. })
182    }
183
184    /// Returns created address if frame is create otherwise returns None.
185    pub fn created_address(&self) -> Option<Address> {
186        match self {
187            Frame::Create(create_frame) => Some(create_frame.created_address),
188            _ => None,
189        }
190    }
191
192    /// Takes frame and returns frame data.
193    pub fn into_frame_data(self) -> FrameData {
194        match self {
195            Frame::Call(call_frame) => call_frame.frame_data,
196            Frame::Create(create_frame) => create_frame.frame_data,
197            Frame::EOFCreate(eof_create_frame) => eof_create_frame.frame_data,
198        }
199    }
200
201    /// Returns reference to frame data.
202    pub fn frame_data(&self) -> &FrameData {
203        match self {
204            Self::Call(call_frame) => &call_frame.frame_data,
205            Self::Create(create_frame) => &create_frame.frame_data,
206            Self::EOFCreate(eof_create_frame) => &eof_create_frame.frame_data,
207        }
208    }
209
210    /// Returns mutable reference to frame data.
211    pub fn frame_data_mut(&mut self) -> &mut FrameData {
212        match self {
213            Self::Call(call_frame) => &mut call_frame.frame_data,
214            Self::Create(create_frame) => &mut create_frame.frame_data,
215            Self::EOFCreate(eof_create_frame) => &mut eof_create_frame.frame_data,
216        }
217    }
218
219    /// Returns a reference to the interpreter.
220    pub fn interpreter(&self) -> &Interpreter {
221        &self.frame_data().interpreter
222    }
223
224    /// Returns a mutable reference to the interpreter.
225    pub fn interpreter_mut(&mut self) -> &mut Interpreter {
226        &mut self.frame_data_mut().interpreter
227    }
228}
229
230impl FrameOrResult {
231    /// Creates new create frame.
232    pub fn new_create_frame(
233        created_address: Address,
234        checkpoint: JournalCheckpoint,
235        interpreter: Interpreter,
236    ) -> Self {
237        Self::Frame(Frame::new_create(created_address, checkpoint, interpreter))
238    }
239
240    pub fn new_eofcreate_frame(
241        created_address: Address,
242        checkpoint: JournalCheckpoint,
243        interpreter: Interpreter,
244    ) -> Self {
245        Self::Frame(Frame::EOFCreate(Box::new(EOFCreateFrame {
246            created_address,
247            frame_data: FrameData {
248                checkpoint,
249                interpreter,
250            },
251        })))
252    }
253
254    /// Creates new call frame.
255    pub fn new_call_frame(
256        return_memory_range: Range<usize>,
257        checkpoint: JournalCheckpoint,
258        interpreter: Interpreter,
259    ) -> Self {
260        Self::Frame(Frame::new_call(
261            return_memory_range,
262            checkpoint,
263            interpreter,
264        ))
265    }
266
267    /// Creates new create result.
268    pub fn new_create_result(
269        interpreter_result: InterpreterResult,
270        address: Option<Address>,
271    ) -> Self {
272        FrameOrResult::Result(FrameResult::Create(CreateOutcome {
273            result: interpreter_result,
274            address,
275        }))
276    }
277
278    pub fn new_eofcreate_result(
279        interpreter_result: InterpreterResult,
280        address: Option<Address>,
281    ) -> Self {
282        FrameOrResult::Result(FrameResult::EOFCreate(CreateOutcome {
283            result: interpreter_result,
284            address,
285        }))
286    }
287
288    pub fn new_call_result(
289        interpreter_result: InterpreterResult,
290        memory_offset: Range<usize>,
291    ) -> Self {
292        FrameOrResult::Result(FrameResult::Call(CallOutcome {
293            result: interpreter_result,
294            memory_offset,
295        }))
296    }
297}