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#[derive(Debug)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct CallFrame {
14 pub return_memory_range: Range<usize>,
16 pub frame_data: FrameData,
18}
19
20#[derive(Debug)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22pub struct CreateFrame {
23 pub created_address: Address,
25 pub frame_data: FrameData,
27}
28
29#[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 pub checkpoint: JournalCheckpoint,
42 pub interpreter: Interpreter,
44}
45
46#[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
130 pub fn instruction_result(&self) -> InstructionResult {
131 self.interpreter_result().result
132 }
133}
134
135#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
137#[derive(Debug)]
138pub enum FrameOrResult {
139 Frame(Frame),
141 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 pub fn is_call(&self) -> bool {
176 matches!(self, Frame::Call { .. })
177 }
178
179 pub fn is_create(&self) -> bool {
181 matches!(self, Frame::Create { .. })
182 }
183
184 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 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 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 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 pub fn interpreter(&self) -> &Interpreter {
221 &self.frame_data().interpreter
222 }
223
224 pub fn interpreter_mut(&mut self) -> &mut Interpreter {
226 &mut self.frame_data_mut().interpreter
227 }
228}
229
230impl FrameOrResult {
231 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 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 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}