1use crate::{
2 instructions::InstructionProvider, EthFrame, Handler, MainnetHandler, PrecompileProvider,
3};
4use context::{
5 result::{
6 EVMError, ExecutionResult, HaltReason, InvalidTransaction, ResultAndState,
7 ResultVecAndState,
8 },
9 Block, ContextSetters, ContextTr, Database, Evm, JournalTr, Transaction,
10};
11use database_interface::DatabaseCommit;
12use interpreter::{interpreter::EthInterpreter, InterpreterResult};
13use state::EvmState;
14use std::vec::Vec;
15
16pub trait ExecuteEvm {
18 type ExecutionResult;
20 type State;
22 type Error;
24 type Tx: Transaction;
26 type Block: Block;
28
29 fn set_block(&mut self, block: Self::Block);
31
32 fn transact(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error>;
49
50 fn finalize(&mut self) -> Self::State;
55
56 fn transact_finalize(
64 &mut self,
65 tx: Self::Tx,
66 ) -> Result<ResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
67 let output_or_error = self.transact(tx);
68 let state = self.finalize();
70 let output = output_or_error?;
71 Ok(ResultAndState::new(output, state))
72 }
73
74 fn transact_multi(
85 &mut self,
86 txs: impl Iterator<Item = Self::Tx>,
87 ) -> Result<Vec<Self::ExecutionResult>, Self::Error> {
88 let mut outputs = Vec::new();
89 for tx in txs {
90 outputs.push(self.transact(tx).inspect_err(|_| {
91 let _ = self.finalize();
92 })?);
93 }
94 Ok(outputs)
95 }
96
97 fn transact_multi_finalize(
102 &mut self,
103 txs: impl Iterator<Item = Self::Tx>,
104 ) -> Result<ResultVecAndState<Self::ExecutionResult, Self::State>, Self::Error> {
105 let result = self.transact_multi(txs)?;
107 let state = self.finalize();
108 Ok(ResultAndState::new(result, state))
109 }
110
111 fn replay(&mut self)
115 -> Result<ResultAndState<Self::ExecutionResult, Self::State>, Self::Error>;
116}
117
118pub trait ExecuteCommitEvm: ExecuteEvm {
120 fn commit(&mut self, state: Self::State);
122
123 fn commit_inner(&mut self) {
127 let state = self.finalize();
128 self.commit(state);
129 }
130
131 fn transact_commit(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
133 let output = self.transact(tx)?;
134 self.commit_inner();
135 Ok(output)
136 }
137
138 fn transact_multi_commit(
142 &mut self,
143 txs: impl Iterator<Item = Self::Tx>,
144 ) -> Result<Vec<Self::ExecutionResult>, Self::Error> {
145 let outputs = self.transact_multi(txs)?;
146 self.commit_inner();
147 Ok(outputs)
148 }
149
150 fn replay_commit(&mut self) -> Result<Self::ExecutionResult, Self::Error> {
154 let result = self.replay()?;
155 self.commit(result.state);
156 Ok(result.result)
157 }
158}
159
160impl<CTX, INSP, INST, PRECOMPILES> ExecuteEvm for Evm<CTX, INSP, INST, PRECOMPILES>
161where
162 CTX: ContextTr<Journal: JournalTr<State = EvmState>> + ContextSetters,
163 INST: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
164 PRECOMPILES: PrecompileProvider<CTX, Output = InterpreterResult>,
165{
166 type ExecutionResult = ExecutionResult<HaltReason>;
167 type State = EvmState;
168 type Error = EVMError<<CTX::Db as Database>::Error, InvalidTransaction>;
169 type Tx = <CTX as ContextTr>::Tx;
170 type Block = <CTX as ContextTr>::Block;
171
172 fn transact(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
173 self.ctx.set_tx(tx);
174 let mut t = MainnetHandler::<_, _, EthFrame<_, _, _>>::default();
175 t.run(self)
176 }
177
178 fn finalize(&mut self) -> Self::State {
179 self.journal_mut().finalize()
180 }
181
182 fn set_block(&mut self, block: Self::Block) {
183 self.ctx.set_block(block);
184 }
185
186 fn replay(
187 &mut self,
188 ) -> Result<ResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
189 let mut t = MainnetHandler::<_, _, EthFrame<_, _, _>>::default();
190 t.run(self).map(|result| {
191 let state = self.finalize();
192 ResultAndState::new(result, state)
193 })
194 }
195}
196
197impl<CTX, INSP, INST, PRECOMPILES> ExecuteCommitEvm for Evm<CTX, INSP, INST, PRECOMPILES>
198where
199 CTX: ContextTr<Journal: JournalTr<State = EvmState>, Db: DatabaseCommit> + ContextSetters,
200 INST: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
201 PRECOMPILES: PrecompileProvider<CTX, Output = InterpreterResult>,
202{
203 fn commit(&mut self, state: Self::State) {
204 self.db_mut().commit(state);
205 }
206}