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)]
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)]
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/// Eof Create Frame
23#[derive(Debug)]
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
25pub struct EOFCreateFrame {
26    pub created_address: Address,
27}
28
29/// Frame Data
30///
31/// [`FrameData`] bundles different types of frames.
32#[derive(Debug)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34pub enum FrameData {
35    Call(CallFrame),
36    Create(CreateFrame),
37    EOFCreate(EOFCreateFrame),
38}
39
40/// Frame Result
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42#[derive(Debug)]
43pub enum FrameResult {
44    Call(CallOutcome),
45    Create(CreateOutcome),
46    EOFCreate(CreateOutcome),
47}
48
49impl FrameResult {
50    /// Casts frame result to interpreter result.
51    #[inline]
52    pub fn into_interpreter_result(self) -> InterpreterResult {
53        match self {
54            FrameResult::Call(outcome) => outcome.result,
55            FrameResult::Create(outcome) => outcome.result,
56            FrameResult::EOFCreate(outcome) => outcome.result,
57        }
58    }
59
60    /// Returns execution output.
61    #[inline]
62    pub fn output(&self) -> Output {
63        match self {
64            FrameResult::Call(outcome) => Output::Call(outcome.result.output.clone()),
65            FrameResult::Create(outcome) => {
66                Output::Create(outcome.result.output.clone(), outcome.address)
67            }
68            FrameResult::EOFCreate(outcome) => {
69                Output::Create(outcome.result.output.clone(), outcome.address)
70            }
71        }
72    }
73
74    /// Returns reference to gas.
75    #[inline]
76    pub fn gas(&self) -> &Gas {
77        match self {
78            FrameResult::Call(outcome) => &outcome.result.gas,
79            FrameResult::Create(outcome) => &outcome.result.gas,
80            FrameResult::EOFCreate(outcome) => &outcome.result.gas,
81        }
82    }
83
84    /// Returns mutable reference to interpreter result.
85    #[inline]
86    pub fn gas_mut(&mut self) -> &mut Gas {
87        match self {
88            FrameResult::Call(outcome) => &mut outcome.result.gas,
89            FrameResult::Create(outcome) => &mut outcome.result.gas,
90            FrameResult::EOFCreate(outcome) => &mut outcome.result.gas,
91        }
92    }
93
94    /// Returns reference to interpreter result.
95    #[inline]
96    pub fn interpreter_result(&self) -> &InterpreterResult {
97        match self {
98            FrameResult::Call(outcome) => &outcome.result,
99            FrameResult::Create(outcome) => &outcome.result,
100            FrameResult::EOFCreate(outcome) => &outcome.result,
101        }
102    }
103
104    /// Returns mutable reference to interpreter result.
105    #[inline]
106    pub fn interpreter_result_mut(&mut self) -> &InterpreterResult {
107        match self {
108            FrameResult::Call(outcome) => &mut outcome.result,
109            FrameResult::Create(outcome) => &mut outcome.result,
110            FrameResult::EOFCreate(outcome) => &mut outcome.result,
111        }
112    }
113
114    /// Return Instruction result.
115    #[inline]
116    pub fn instruction_result(&self) -> InstructionResult {
117        self.interpreter_result().result
118    }
119}
120
121impl FrameData {
122    pub fn new_create(created_address: Address) -> Self {
123        Self::Create(CreateFrame { created_address })
124    }
125
126    pub fn new_call(return_memory_range: Range<usize>) -> Self {
127        Self::Call(CallFrame {
128            return_memory_range,
129        })
130    }
131
132    /// Returns true if frame is call frame.
133    pub fn is_call(&self) -> bool {
134        matches!(self, Self::Call { .. })
135    }
136
137    /// Returns true if frame is create frame.
138    pub fn is_create(&self) -> bool {
139        matches!(self, Self::Create { .. })
140    }
141
142    /// Returns created address if frame is create otherwise returns None.
143    pub fn created_address(&self) -> Option<Address> {
144        match self {
145            Self::Create(create_frame) => Some(create_frame.created_address),
146            _ => None,
147        }
148    }
149}