Skip to main content

ethrex_vm/
execution_result.rs

1use bytes::Bytes;
2use ethrex_common::types::Log;
3use ethrex_levm::errors::{ExecutionReport as LevmExecutionReport, TxResult};
4
5#[derive(Debug)]
6pub enum ExecutionResult {
7    Success {
8        gas_used: u64,
9        gas_refunded: u64,
10        logs: Vec<Log>,
11        output: Bytes,
12    },
13    /// Reverted by `REVERT` opcode
14    Revert { gas_used: u64, output: Bytes },
15    /// Reverted for other reasons, spends all gas.
16    Halt {
17        reason: String,
18        /// Halting will spend all the gas, which will be equal to gas_limit.
19        gas_used: u64,
20    },
21}
22
23impl ExecutionResult {
24    pub fn is_success(&self) -> bool {
25        matches!(self, ExecutionResult::Success { .. })
26    }
27    pub fn gas_used(&self) -> u64 {
28        match self {
29            ExecutionResult::Success { gas_used, .. } => *gas_used,
30            ExecutionResult::Revert { gas_used, .. } => *gas_used,
31            ExecutionResult::Halt { gas_used, .. } => *gas_used,
32        }
33    }
34    pub fn logs(&self) -> Vec<Log> {
35        match self {
36            ExecutionResult::Success { logs, .. } => logs.clone(),
37            _ => vec![],
38        }
39    }
40    pub fn gas_refunded(&self) -> u64 {
41        match self {
42            ExecutionResult::Success { gas_refunded, .. } => *gas_refunded,
43            _ => 0,
44        }
45    }
46
47    pub fn output(&self) -> Bytes {
48        match self {
49            ExecutionResult::Success { output, .. } => output.clone(),
50            ExecutionResult::Revert { output, .. } => output.clone(),
51            ExecutionResult::Halt { .. } => Bytes::new(),
52        }
53    }
54}
55
56impl From<LevmExecutionReport> for ExecutionResult {
57    fn from(val: LevmExecutionReport) -> Self {
58        match val.result {
59            TxResult::Success => ExecutionResult::Success {
60                gas_used: val.gas_used,
61                gas_refunded: val.gas_refunded,
62                logs: val.logs,
63                output: val.output,
64            },
65            TxResult::Revert(error) => {
66                if error.is_revert_opcode() {
67                    ExecutionResult::Revert {
68                        gas_used: val.gas_used,
69                        output: val.output,
70                    }
71                } else {
72                    ExecutionResult::Halt {
73                        reason: error.to_string(),
74                        gas_used: val.gas_used,
75                    }
76                }
77            }
78        }
79    }
80}