revm_interpreter/interpreter_action/call_outcome.rs
1use crate::{Gas, InstructionResult, InterpreterResult};
2use core::ops::Range;
3use primitives::{Bytes, Log};
4use std::vec::Vec;
5
6/// Represents the outcome of a call operation in a virtual machine.
7///
8/// This struct encapsulates the result of executing an instruction by an interpreter, including
9/// the result itself, gas usage information, and the memory offset where output data is stored.
10///
11/// # Fields
12///
13/// * `result` - The result of the interpreter's execution, including output data and gas usage.
14/// * `memory_offset` - The range in memory where the output data is located.
15#[derive(Clone, Debug, PartialEq, Eq)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct CallOutcome {
18 /// The result of the interpreter's execution, including output data and gas usage
19 pub result: InterpreterResult,
20 /// The range in memory where the output data is located
21 pub memory_offset: Range<usize>,
22 /// Flag to indicate if the call is precompile call.
23 /// Used by inspector so it can copy the logs for Inspector::logs call.
24 pub was_precompile_called: bool,
25 /// Precompile call logs. Needs as revert/halt would delete them from Journal.
26 /// So they can't be accessed by inspector.
27 pub precompile_call_logs: Vec<Log>,
28 /// EIP-8037: copied from `CallInputs::charged_new_account_state_gas`. Tells
29 /// the parent frame whether `new_account_state_gas` was upfront-charged on
30 /// the parent's tracker for this call, so the parent can refund it when
31 /// the call reverts/halts.
32 pub charged_new_account_state_gas: bool,
33}
34
35impl CallOutcome {
36 /// Constructs a new [`CallOutcome`].
37 ///
38 /// Creates an instance of [`CallOutcome`] with the given interpreter result and memory offset.
39 ///
40 /// # Arguments
41 ///
42 /// * `result` - The result of the interpreter's execution.
43 /// * `memory_offset` - The range in memory indicating where the output data is stored.
44 pub const fn new(result: InterpreterResult, memory_offset: Range<usize>) -> Self {
45 Self {
46 result,
47 memory_offset,
48 was_precompile_called: false,
49 precompile_call_logs: Vec::new(),
50 charged_new_account_state_gas: false,
51 }
52 }
53
54 /// Constructs a new [`CallOutcome`] for an out-of-gas error.
55 ///
56 /// # Arguments
57 ///
58 /// * `gas_limit` - The gas limit that was exceeded.
59 /// * `memory_offset` - The range in memory indicating where the output data is stored.
60 pub fn new_oog(gas_limit: u64, memory_offset: Range<usize>, reservoir: u64) -> Self {
61 Self::new(
62 InterpreterResult::new_oog(gas_limit, reservoir),
63 memory_offset,
64 )
65 }
66
67 /// Returns a reference to the instruction result.
68 ///
69 /// Provides access to the result of the executed instruction.
70 ///
71 /// # Returns
72 ///
73 /// A reference to the [`InstructionResult`].
74 pub const fn instruction_result(&self) -> &InstructionResult {
75 &self.result.result
76 }
77
78 /// Returns the gas usage information.
79 ///
80 /// Provides access to the gas usage details of the executed instruction.
81 ///
82 /// # Returns
83 ///
84 /// An instance of [`Gas`] representing the gas usage.
85 pub const fn gas(&self) -> Gas {
86 self.result.gas
87 }
88
89 /// Returns a reference to the output data.
90 ///
91 /// Provides access to the output data generated by the executed instruction.
92 ///
93 /// # Returns
94 ///
95 /// A reference to the output data as [`Bytes`].
96 pub const fn output(&self) -> &Bytes {
97 &self.result.output
98 }
99
100 /// Returns the start position of the memory offset.
101 ///
102 /// Provides the starting index of the memory range where the output data is stored.
103 ///
104 /// # Returns
105 ///
106 /// The starting index of the memory offset as [`usize`].
107 pub const fn memory_start(&self) -> usize {
108 self.memory_offset.start
109 }
110
111 /// Returns the length of the memory range.
112 ///
113 /// Provides the length of the memory range where the output data is stored.
114 ///
115 /// # Returns
116 ///
117 /// The length of the memory range as [`usize`].
118 pub fn memory_length(&self) -> usize {
119 self.memory_offset.len()
120 }
121}