revm_handler/
frame_data.rs1use context_interface::{cfg::GasParams, result::Output};
2use core::ops::Range;
3use interpreter::{CallOutcome, CreateOutcome, Gas, InstructionResult, InterpreterResult};
4use primitives::Address;
5
6#[derive(Debug, Clone)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct CallFrame {
10 pub return_memory_range: Range<usize>,
12}
13
14#[derive(Debug, Clone)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct CreateFrame {
18 pub created_address: Address,
20}
21
22#[derive(Debug, Clone)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27pub enum FrameData {
28 Call(CallFrame),
30 Create(CreateFrame),
32}
33
34#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36#[derive(Debug, Clone)]
37pub enum FrameResult {
38 Call(CallOutcome),
40 Create(CreateOutcome),
42}
43
44impl FrameResult {
45 #[inline]
47 pub fn new_call_oog(
48 gas_limit: u64,
49 memory_offset: core::ops::Range<usize>,
50 reservoir: u64,
51 ) -> Self {
52 Self::Call(CallOutcome::new_oog(gas_limit, memory_offset, reservoir))
53 }
54
55 #[inline]
57 pub fn new_create_oog(gas_limit: u64, reservoir: u64) -> Self {
58 Self::Create(CreateOutcome::new_oog(gas_limit, reservoir))
59 }
60
61 #[inline]
63 pub fn into_interpreter_result(self) -> InterpreterResult {
64 match self {
65 FrameResult::Call(outcome) => outcome.result,
66 FrameResult::Create(outcome) => outcome.result,
67 }
68 }
69
70 #[inline]
72 pub fn output(&self) -> Output {
73 match self {
74 FrameResult::Call(outcome) => Output::Call(outcome.result.output.clone()),
75 FrameResult::Create(outcome) => {
76 Output::Create(outcome.result.output.clone(), outcome.address)
77 }
78 }
79 }
80
81 #[inline]
83 pub const fn gas(&self) -> &Gas {
84 match self {
85 FrameResult::Call(outcome) => &outcome.result.gas,
86 FrameResult::Create(outcome) => &outcome.result.gas,
87 }
88 }
89
90 #[inline]
92 pub const fn gas_mut(&mut self) -> &mut Gas {
93 match self {
94 FrameResult::Call(outcome) => &mut outcome.result.gas,
95 FrameResult::Create(outcome) => &mut outcome.result.gas,
96 }
97 }
98
99 #[inline]
101 pub const fn interpreter_result(&self) -> &InterpreterResult {
102 match self {
103 FrameResult::Call(outcome) => &outcome.result,
104 FrameResult::Create(outcome) => &outcome.result,
105 }
106 }
107
108 #[inline]
110 pub const fn interpreter_result_mut(&mut self) -> &mut InterpreterResult {
111 match self {
112 FrameResult::Call(outcome) => &mut outcome.result,
113 FrameResult::Create(outcome) => &mut outcome.result,
114 }
115 }
116
117 #[inline]
119 pub const fn instruction_result(&self) -> InstructionResult {
120 self.interpreter_result().result
121 }
122
123 #[inline]
136 pub fn refundable_state_gas(&self, gas_params: &GasParams) -> Option<u64> {
137 match self {
138 FrameResult::Call(outcome) => (!outcome.instruction_result().is_ok()
139 && outcome.charged_new_account_state_gas)
140 .then(|| gas_params.new_account_state_gas()),
141 FrameResult::Create(outcome) => ((outcome.address.is_none()
142 || !outcome.instruction_result().is_ok())
143 && outcome.charged_create_state_gas)
144 .then(|| gas_params.create_state_gas()),
145 }
146 }
147}
148
149impl FrameData {
150 pub const fn new_create(created_address: Address) -> Self {
152 Self::Create(CreateFrame { created_address })
153 }
154
155 pub const fn new_call(return_memory_range: Range<usize>) -> Self {
157 Self::Call(CallFrame {
158 return_memory_range,
159 })
160 }
161
162 pub const fn is_call(&self) -> bool {
164 matches!(self, Self::Call { .. })
165 }
166
167 pub const fn is_create(&self) -> bool {
169 matches!(self, Self::Create { .. })
170 }
171
172 pub const fn created_address(&self) -> Option<Address> {
174 match self {
175 Self::Create(create_frame) => Some(create_frame.created_address),
176 _ => None,
177 }
178 }
179}