1717package core
1818
1919import (
20+ "fmt"
21+
22+ "github.com/ava-labs/libevm/core/vm"
2023 "github.com/ava-labs/libevm/log"
2124 "github.com/ava-labs/libevm/params"
2225)
@@ -27,6 +30,50 @@ func (st *StateTransition) rulesHooks() params.RulesHooks {
2730 return rules .Hooks ()
2831}
2932
33+ // NOTE: other than the final paragraph, the comment on
34+ // [StateTransition.TransitionDb] is copied, verbatim, from the upstream
35+ // version, which has been changed to [StateTransition.transitionDb] to allow
36+ // its behaviour to be augmented.
37+
38+ // Keeps the vm package imported by this specific file so VS Code can support
39+ // comments like [vm.EVM].
40+ var _ = (* vm .EVM )(nil )
41+
42+ // TransitionDb will transition the state by applying the current message and
43+ // returning the evm execution result with following fields.
44+ //
45+ // - used gas: total gas used (including gas being refunded)
46+ // - returndata: the returned data from evm
47+ // - concrete execution error: various EVM errors which abort the execution, e.g.
48+ // ErrOutOfGas, ErrExecutionReverted
49+ //
50+ // However if any consensus issue encountered, return the error directly with
51+ // nil evm execution result.
52+ //
53+ // libevm-specific behaviour: if, during execution, [vm.EVM.InvalidateExecution]
54+ // is called with a non-nil error then said error will be returned, wrapped. All
55+ // state transitions (e.g. nonce incrementing) will be reverted to a snapshot
56+ // taken before execution.
57+ func (st * StateTransition ) TransitionDb () (* ExecutionResult , error ) {
58+ if err := st .canExecuteTransaction (); err != nil {
59+ return nil , err
60+ }
61+
62+ snap := st .state .Snapshot () // computationally cheap operation
63+ res , err := st .transitionDb () // original geth implementation
64+
65+ // [NOTE]: At the time of implementation of this libevm override, non-nil
66+ // values of `err` and `invalid` (below) are mutually exclusive. However, as
67+ // a defensive measure, we don't return early on non-nil `err` in case an
68+ // upstream update breaks this invariant.
69+
70+ if invalid := st .evm .ExecutionInvalidated (); invalid != nil {
71+ st .state .RevertToSnapshot (snap )
72+ err = fmt .Errorf ("execution invalidated: %w" , invalid )
73+ }
74+ return res , err
75+ }
76+
3077// canExecuteTransaction is a convenience wrapper for calling the
3178// [params.RulesHooks.CanExecuteTransaction] hook.
3279func (st * StateTransition ) canExecuteTransaction () error {
0 commit comments