@@ -79,7 +79,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
7979 return nil , nil , 0 , fmt .Errorf ("could not apply tx %d [%v]: %w" , i , tx .Hash ().Hex (), err )
8080 }
8181 statedb .Prepare (tx .Hash (), i )
82- receipt , err := applyTransaction (msg , p .config , nil , gp , statedb , blockNumber , blockHash , tx , usedGas , vmenv )
82+ receipt , err := applyTransaction (msg , p .config , nil , gp , statedb , blockNumber , blockHash , tx , usedGas , vmenv , nil )
8383 if err != nil {
8484 return nil , nil , 0 , fmt .Errorf ("could not apply tx %d [%v]: %w" , i , tx .Hash ().Hex (), err )
8585 }
@@ -92,16 +92,24 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
9292 return receipts , allLogs , * usedGas , nil
9393}
9494
95- func applyTransaction (msg types.Message , config * params.ChainConfig , author * common.Address , gp * GasPool , statedb * state.StateDB , blockNumber * big.Int , blockHash common.Hash , tx * types.Transaction , usedGas * uint64 , evm * vm.EVM ) (* types.Receipt , error ) {
95+ func applyTransaction (msg types.Message , config * params.ChainConfig , author * common.Address , gp * GasPool , statedb * state.StateDB , blockNumber * big.Int , blockHash common.Hash , tx * types.Transaction , usedGas * uint64 , evm * vm.EVM , preFinalizeHook func () error ) (* types.Receipt , error ) {
9696 // Create a new context to be used in the EVM environment.
9797 txContext := NewEVMTxContext (msg )
9898 evm .Reset (txContext , statedb )
9999
100+ snapshot := statedb .Snapshot ()
100101 // Apply the transaction to the current state (included in the env).
101102 result , err := ApplyMessage (evm , msg , gp )
102103 if err != nil {
103104 return nil , err
104105 }
106+ if preFinalizeHook != nil {
107+ err = preFinalizeHook ()
108+ if err != nil {
109+ statedb .RevertToSnapshot (snapshot )
110+ return nil , err
111+ }
112+ }
105113
106114 // Update the state with pending changes.
107115 var root []byte
@@ -186,15 +194,15 @@ func applyTransactionWithResult(msg types.Message, config *params.ChainConfig, b
186194// and uses the input parameters for its environment. It returns the receipt
187195// for the transaction, gas used and an error if the transaction failed,
188196// indicating the block was invalid.
189- func ApplyTransaction (config * params.ChainConfig , bc ChainContext , author * common.Address , gp * GasPool , statedb * state.StateDB , header * types.Header , tx * types.Transaction , usedGas * uint64 , cfg vm.Config ) (* types.Receipt , error ) {
197+ func ApplyTransaction (config * params.ChainConfig , bc ChainContext , author * common.Address , gp * GasPool , statedb * state.StateDB , header * types.Header , tx * types.Transaction , usedGas * uint64 , cfg vm.Config , preFinalizeHook func () error ) (* types.Receipt , error ) {
190198 msg , err := tx .AsMessage (types .MakeSigner (config , header .Number ), header .BaseFee )
191199 if err != nil {
192200 return nil , err
193201 }
194202 // Create a new context to be used in the EVM environment
195203 blockContext := NewEVMBlockContext (header , bc , author )
196204 vmenv := vm .NewEVM (blockContext , vm.TxContext {}, statedb , config , cfg )
197- return applyTransaction (msg , config , author , gp , statedb , header .Number , header .Hash (), tx , usedGas , vmenv )
205+ return applyTransaction (msg , config , author , gp , statedb , header .Number , header .Hash (), tx , usedGas , vmenv , preFinalizeHook )
198206}
199207
200208func ApplyTransactionWithResult (config * params.ChainConfig , bc ChainContext , author * common.Address , gp * GasPool , statedb * state.StateDB , header * types.Header , tx * types.Transaction , usedGas * uint64 , cfg vm.Config ) (* types.Receipt , * ExecutionResult , error ) {
0 commit comments