1use crate::{
2 frame::EthFrame, instructions::InstructionProvider, Handler, MainnetHandler, PrecompileProvider,
3};
4use context::{
5 result::{
6 EVMError, ExecResultAndState, ExecutionResult, HaltReason, InvalidTransaction,
7 ResultAndState, ResultVecAndState, TransactionIndexedError,
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
16type TransactManyFinalizeResult<ExecutionResult, State, Error> =
18 Result<ResultVecAndState<ExecutionResult, State>, TransactionIndexedError<Error>>;
19
20pub trait ExecuteEvm {
22 type ExecutionResult;
24 type State;
26 type Error;
28 type Tx: Transaction;
30 type Block: Block;
32
33 fn set_block(&mut self, block: Self::Block);
35
36 fn transact_one(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error>;
53
54 fn finalize(&mut self) -> Self::State;
59
60 #[inline]
68 fn transact(
69 &mut self,
70 tx: Self::Tx,
71 ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
72 let output_or_error = self.transact_one(tx);
73 let state = self.finalize();
75 let output = output_or_error?;
76 Ok(ExecResultAndState::new(output, state))
77 }
78
79 #[inline]
89 fn transact_many(
90 &mut self,
91 txs: impl Iterator<Item = Self::Tx>,
92 ) -> Result<Vec<Self::ExecutionResult>, TransactionIndexedError<Self::Error>> {
93 let mut outputs = Vec::new();
94 for (index, tx) in txs.enumerate() {
95 outputs.push(
96 self.transact_one(tx)
97 .inspect_err(|_| {
98 let _ = self.finalize();
99 })
100 .map_err(|error| TransactionIndexedError::new(error, index))?,
101 );
102 }
103 Ok(outputs)
104 }
105
106 #[inline]
110 fn transact_many_finalize(
111 &mut self,
112 txs: impl Iterator<Item = Self::Tx>,
113 ) -> TransactManyFinalizeResult<Self::ExecutionResult, Self::State, Self::Error> {
114 let result = self.transact_many(txs)?;
116 let state = self.finalize();
117 Ok(ExecResultAndState::new(result, state))
118 }
119
120 fn replay(
122 &mut self,
123 ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error>;
124}
125
126pub trait ExecuteCommitEvm: ExecuteEvm {
128 fn commit(&mut self, state: Self::State);
130
131 #[inline]
135 fn commit_inner(&mut self) {
136 let state = self.finalize();
137 self.commit(state);
138 }
139
140 #[inline]
142 fn transact_commit(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
143 let output = self.transact_one(tx)?;
144 self.commit_inner();
145 Ok(output)
146 }
147
148 #[inline]
152 fn transact_many_commit(
153 &mut self,
154 txs: impl Iterator<Item = Self::Tx>,
155 ) -> Result<Vec<Self::ExecutionResult>, TransactionIndexedError<Self::Error>> {
156 let outputs = self.transact_many(txs)?;
157 self.commit_inner();
158 Ok(outputs)
159 }
160
161 #[inline]
165 fn replay_commit(&mut self) -> Result<Self::ExecutionResult, Self::Error> {
166 let result = self.replay()?;
167 self.commit(result.state);
168 Ok(result.result)
169 }
170}
171
172impl<CTX, INSP, INST, PRECOMPILES> ExecuteEvm
173 for Evm<CTX, INSP, INST, PRECOMPILES, EthFrame<EthInterpreter>>
174where
175 CTX: ContextTr<Journal: JournalTr<State = EvmState>> + ContextSetters,
176 INST: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
177 PRECOMPILES: PrecompileProvider<CTX, Output = InterpreterResult>,
178{
179 type ExecutionResult = ExecutionResult<HaltReason>;
180 type State = EvmState;
181 type Error = EVMError<<CTX::Db as Database>::Error, InvalidTransaction>;
182 type Tx = <CTX as ContextTr>::Tx;
183 type Block = <CTX as ContextTr>::Block;
184
185 #[inline]
186 fn transact_one(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
187 self.ctx.set_tx(tx);
188 MainnetHandler::default().run(self)
189 }
190
191 #[inline]
192 fn finalize(&mut self) -> Self::State {
193 self.journal_mut().finalize()
194 }
195
196 #[inline]
197 fn set_block(&mut self, block: Self::Block) {
198 self.ctx.set_block(block);
199 }
200
201 #[inline]
202 fn replay(&mut self) -> Result<ResultAndState<HaltReason>, Self::Error> {
203 MainnetHandler::default().run(self).map(|result| {
204 let state = self.finalize();
205 ResultAndState::new(result, state)
206 })
207 }
208}
209
210impl<CTX, INSP, INST, PRECOMPILES> ExecuteCommitEvm
211 for Evm<CTX, INSP, INST, PRECOMPILES, EthFrame<EthInterpreter>>
212where
213 CTX: ContextTr<Journal: JournalTr<State = EvmState>, Db: DatabaseCommit> + ContextSetters,
214 INST: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
215 PRECOMPILES: PrecompileProvider<CTX, Output = InterpreterResult>,
216{
217 #[inline]
218 fn commit(&mut self, state: Self::State) {
219 self.db_mut().commit(state);
220 }
221}