Skip to main content

ethrex_vm/
tracing.rs

1use crate::backends::levm::LEVM;
2use ethrex_common::tracing::{CallTrace, OpcodeTraceResult, PrestateResult};
3use ethrex_common::types::Block;
4pub use ethrex_levm::tracing::OpcodeTracerConfig;
5
6use crate::{Evm, EvmError};
7
8impl Evm {
9    /// Runs a single tx with the call tracer and outputs its trace.
10    /// Assumes that the received state already contains changes from previous blocks and other
11    /// transactions within its block.
12    /// Wraps LEVM::trace_tx_calls depending on the feature.
13    pub fn trace_tx_calls(
14        &mut self,
15        block: &Block,
16        tx_index: usize,
17        only_top_call: bool,
18        with_log: bool,
19    ) -> Result<CallTrace, EvmError> {
20        let tx = block
21            .body
22            .transactions
23            .get(tx_index)
24            .ok_or(EvmError::Custom(
25                "Missing Transaction for Trace".to_string(),
26            ))?;
27
28        LEVM::trace_tx_calls(
29            &mut self.db,
30            &block.header,
31            tx,
32            only_top_call,
33            with_log,
34            self.vm_type,
35            self.crypto.as_ref(),
36        )
37    }
38
39    /// Executes a single tx and captures the pre/post account state (prestateTracer).
40    /// Assumes that the received state already contains changes from previous transactions.
41    pub fn trace_tx_prestate(
42        &mut self,
43        block: &Block,
44        tx_index: usize,
45        diff_mode: bool,
46        include_empty: bool,
47    ) -> Result<PrestateResult, EvmError> {
48        let tx = block
49            .body
50            .transactions
51            .get(tx_index)
52            .ok_or(EvmError::Custom(
53                "Missing Transaction for Trace".to_string(),
54            ))?;
55
56        LEVM::trace_tx_prestate(
57            &mut self.db,
58            &block.header,
59            tx,
60            diff_mode,
61            include_empty,
62            self.vm_type,
63            self.crypto.as_ref(),
64        )
65    }
66
67    /// Executes a single tx and captures the per-opcode (EIP-3155) trace.
68    /// Assumes that the received state already contains changes from previous transactions.
69    pub fn trace_tx_opcodes(
70        &mut self,
71        block: &Block,
72        tx_index: usize,
73        cfg: OpcodeTracerConfig,
74    ) -> Result<OpcodeTraceResult, EvmError> {
75        let tx = block
76            .body
77            .transactions
78            .get(tx_index)
79            .ok_or(EvmError::Custom(
80                "Missing Transaction for Trace".to_string(),
81            ))?;
82
83        LEVM::trace_tx_opcodes(
84            &mut self.db,
85            &block.header,
86            tx,
87            cfg,
88            self.vm_type,
89            self.crypto.as_ref(),
90        )
91    }
92
93    /// Reruns the given block, saving the changes on the state, doesn't output any results or receipts.
94    /// If the optional argument `stop_index` is set, the run will stop just before executing the transaction at that index
95    /// and won't process the withdrawals afterwards.
96    /// WrapsLEVM::rerun_block depending on the feature.
97    pub fn rerun_block(
98        &mut self,
99        block: &Block,
100        stop_index: Option<usize>,
101    ) -> Result<(), EvmError> {
102        LEVM::rerun_block(
103            &mut self.db,
104            block,
105            stop_index,
106            self.vm_type,
107            self.crypto.as_ref(),
108        )
109    }
110}