ethrex_vm/
execution_result.rs1use 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 Revert { gas_used: u64, output: Bytes },
15 Halt {
17 reason: String,
18 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}