1use crate::{
2 instructions::InstructionProvider, EthFrame, Handler, MainnetHandler, PrecompileProvider,
3};
4use context::{
5 result::{EVMError, ExecutionResult, HaltReason, InvalidTransaction, ResultAndState},
6 Block, ContextSetters, ContextTr, Database, Evm, JournalOutput, JournalTr, Transaction,
7};
8use database_interface::DatabaseCommit;
9use interpreter::{interpreter::EthInterpreter, InterpreterResult};
10
11pub trait ExecuteEvm {
13 type Output;
15 type Tx: Transaction;
17 type Block: Block;
19
20 fn set_tx(&mut self, tx: Self::Tx);
22
23 fn set_block(&mut self, block: Self::Block);
25
26 fn replay(&mut self) -> Self::Output;
28
29 fn transact(&mut self, tx: Self::Tx) -> Self::Output {
33 self.set_tx(tx);
34 self.replay()
35 }
36}
37
38pub trait ExecuteCommitEvm: ExecuteEvm {
40 type CommitOutput;
42
43 fn replay_commit(&mut self) -> Self::CommitOutput;
45
46 fn transact_commit(&mut self, tx: Self::Tx) -> Self::CommitOutput {
48 self.set_tx(tx);
49 self.replay_commit()
50 }
51}
52
53impl<CTX, INSP, INST, PRECOMPILES> ExecuteEvm for Evm<CTX, INSP, INST, PRECOMPILES>
54where
55 CTX: ContextTr<Journal: JournalTr<FinalOutput = JournalOutput>> + ContextSetters,
56 INST: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
57 PRECOMPILES: PrecompileProvider<CTX, Output = InterpreterResult>,
58{
59 type Output = Result<
60 ResultAndState<HaltReason>,
61 EVMError<<CTX::Db as Database>::Error, InvalidTransaction>,
62 >;
63
64 type Tx = <CTX as ContextTr>::Tx;
65
66 type Block = <CTX as ContextTr>::Block;
67
68 fn replay(&mut self) -> Self::Output {
69 let mut t = MainnetHandler::<_, _, EthFrame<_, _, _>>::default();
70 t.run(self)
71 }
72
73 fn set_tx(&mut self, tx: Self::Tx) {
74 self.data.ctx.set_tx(tx);
75 }
76
77 fn set_block(&mut self, block: Self::Block) {
78 self.data.ctx.set_block(block);
79 }
80}
81
82impl<CTX, INSP, INST, PRECOMPILES> ExecuteCommitEvm for Evm<CTX, INSP, INST, PRECOMPILES>
83where
84 CTX: ContextTr<Journal: JournalTr<FinalOutput = JournalOutput>, Db: DatabaseCommit>
85 + ContextSetters,
86 INST: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
87 PRECOMPILES: PrecompileProvider<CTX, Output = InterpreterResult>,
88{
89 type CommitOutput = Result<
90 ExecutionResult<HaltReason>,
91 EVMError<<CTX::Db as Database>::Error, InvalidTransaction>,
92 >;
93
94 fn replay_commit(&mut self) -> Self::CommitOutput {
95 self.replay().map(|r| {
96 self.db().commit(r.state);
97 r.result
98 })
99 }
100}