tempo_revm/
exec.rs

1use crate::{
2    TempoBlockEnv, TempoInvalidTransaction, TempoTxEnv,
3    error::TempoHaltReason,
4    evm::{TempoContext, TempoEvm},
5    handler::TempoEvmHandler,
6};
7use alloy_evm::Database;
8use reth_evm::TransactionEnv;
9use revm::{
10    DatabaseCommit, ExecuteCommitEvm, ExecuteEvm,
11    context::{ContextSetters, TxEnv, result::ExecResultAndState},
12    context_interface::{
13        ContextTr, JournalTr,
14        result::{EVMError, ExecutionResult},
15    },
16    handler::{Handler, SystemCallTx, system_call::SystemCallEvm},
17    inspector::{InspectCommitEvm, InspectEvm, InspectSystemCallEvm, Inspector, InspectorHandler},
18    primitives::{Address, Bytes},
19    state::EvmState,
20};
21
22/// Total gas system transactions are allowed to use.
23const SYSTEM_CALL_GAS_LIMIT: u64 = 250_000_000;
24
25impl<DB, I> ExecuteEvm for TempoEvm<DB, I>
26where
27    DB: Database,
28{
29    type Tx = TempoTxEnv;
30    type Block = TempoBlockEnv;
31    type State = EvmState;
32    type Error = EVMError<DB::Error, TempoInvalidTransaction>;
33    type ExecutionResult = ExecutionResult<TempoHaltReason>;
34
35    fn set_block(&mut self, block: Self::Block) {
36        self.inner.ctx.set_block(block);
37    }
38
39    fn transact_one(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
40        self.inner.ctx.set_tx(tx);
41        let mut h = TempoEvmHandler::new();
42        h.run(self)
43    }
44
45    fn finalize(&mut self) -> Self::State {
46        self.inner.ctx.journal_mut().finalize()
47    }
48
49    fn replay(
50        &mut self,
51    ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
52        let mut h = TempoEvmHandler::new();
53        h.run(self).map(|result| {
54            let state = self.finalize();
55            ExecResultAndState::new(result, state)
56        })
57    }
58}
59
60impl<DB, I> ExecuteCommitEvm for TempoEvm<DB, I>
61where
62    DB: Database + DatabaseCommit,
63{
64    fn commit(&mut self, state: Self::State) {
65        self.inner.ctx.db_mut().commit(state);
66    }
67}
68
69impl<DB, I> InspectEvm for TempoEvm<DB, I>
70where
71    DB: Database,
72    I: Inspector<TempoContext<DB>>,
73{
74    type Inspector = I;
75
76    fn set_inspector(&mut self, inspector: Self::Inspector) {
77        self.inner.inspector = inspector;
78    }
79
80    fn inspect_one_tx(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
81        self.inner.ctx.set_tx(tx);
82        let mut h = TempoEvmHandler::new();
83        h.inspect_run(self)
84    }
85}
86
87impl<DB, I> InspectCommitEvm for TempoEvm<DB, I>
88where
89    DB: Database + DatabaseCommit,
90    I: Inspector<TempoContext<DB>>,
91{
92}
93
94impl<DB, I> SystemCallEvm for TempoEvm<DB, I>
95where
96    DB: Database,
97{
98    fn system_call_one_with_caller(
99        &mut self,
100        caller: Address,
101        system_contract_address: Address,
102        data: Bytes,
103    ) -> Result<Self::ExecutionResult, Self::Error> {
104        let mut tx = TxEnv::new_system_tx_with_caller(caller, system_contract_address, data);
105        tx.set_gas_limit(SYSTEM_CALL_GAS_LIMIT);
106        self.inner.ctx.set_tx(tx.into());
107        let mut h = TempoEvmHandler::new();
108        h.run_system_call(self)
109    }
110}
111
112impl<DB, I> InspectSystemCallEvm for TempoEvm<DB, I>
113where
114    DB: Database,
115    I: Inspector<TempoContext<DB>>,
116{
117    fn inspect_one_system_call_with_caller(
118        &mut self,
119        caller: Address,
120        system_contract_address: Address,
121        data: Bytes,
122    ) -> Result<Self::ExecutionResult, Self::Error> {
123        let mut tx = TxEnv::new_system_tx_with_caller(caller, system_contract_address, data);
124        tx.set_gas_limit(SYSTEM_CALL_GAS_LIMIT);
125        self.inner.ctx.set_tx(tx.into());
126        let mut h = TempoEvmHandler::new();
127        h.inspect_run_system_call(self)
128    }
129}