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
22const 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}