revm_handler/
evm.rs

1use crate::{instructions::EthInstructions, EthFrame, Handler, MainnetHandler, PrecompileProvider};
2use context::{
3    result::{EVMError, ExecutionResult, HaltReason, InvalidTransaction, ResultAndState},
4    setters::ContextSetters,
5    ContextTr, Database, Evm, Journal,
6};
7use database_interface::DatabaseCommit;
8use interpreter::{interpreter::EthInterpreter, InterpreterResult};
9use primitives::Log;
10use state::EvmState;
11use std::vec::Vec;
12
13/// Execute EVM transactions.
14pub trait ExecuteEvm: ContextSetters {
15    type Output;
16
17    fn transact_previous(&mut self) -> Self::Output;
18
19    fn transact(&mut self, tx: Self::Tx) -> Self::Output {
20        self.set_tx(tx);
21        self.transact_previous()
22    }
23}
24
25/// Execute EVM transactions and commit to the state.
26/// TODO this trait can be implemented for all ExecuteEvm for specific Output/CommitOutput
27pub trait ExecuteCommitEvm: ExecuteEvm {
28    type CommitOutput;
29
30    fn transact_commit_previous(&mut self) -> Self::CommitOutput;
31
32    fn transact_commit(&mut self, tx: Self::Tx) -> Self::CommitOutput {
33        self.set_tx(tx);
34        self.transact_commit_previous()
35    }
36}
37
38impl<CTX, INSP, PRECOMPILES> ExecuteEvm
39    for Evm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILES>
40where
41    CTX: ContextSetters + ContextTr<Journal: Journal<FinalOutput = (EvmState, Vec<Log>)>>,
42    PRECOMPILES: PrecompileProvider<Context = CTX, Output = InterpreterResult>,
43{
44    type Output = Result<
45        ResultAndState<HaltReason>,
46        EVMError<<CTX::Db as Database>::Error, InvalidTransaction>,
47    >;
48
49    fn transact_previous(&mut self) -> Self::Output {
50        let mut t = MainnetHandler::<_, _, EthFrame<_, _, _>>::default();
51        t.run(self)
52    }
53}
54
55impl<CTX, INSP, PRECOMPILES> ExecuteCommitEvm
56    for Evm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILES>
57where
58    CTX: ContextSetters
59        + ContextTr<Journal: Journal<FinalOutput = (EvmState, Vec<Log>)>, Db: DatabaseCommit>,
60    PRECOMPILES: PrecompileProvider<Context = CTX, Output = InterpreterResult>,
61{
62    type CommitOutput = Result<
63        ExecutionResult<HaltReason>,
64        EVMError<<CTX::Db as Database>::Error, InvalidTransaction>,
65    >;
66
67    fn transact_commit_previous(&mut self) -> Self::CommitOutput {
68        self.transact_previous().map(|r| {
69            self.db().commit(r.state);
70            r.result
71        })
72    }
73}