github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/evmcore/state_prefetcher.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package evmcore 18 19 import ( 20 "sync/atomic" 21 22 "github.com/unicornultrafoundation/go-u2u/core/state" 23 "github.com/unicornultrafoundation/go-u2u/core/types" 24 "github.com/unicornultrafoundation/go-u2u/core/vm" 25 "github.com/unicornultrafoundation/go-u2u/params" 26 27 "github.com/unicornultrafoundation/go-u2u/utils/signers/gsignercache" 28 ) 29 30 // statePrefetcher is a basic Prefetcher, which blindly executes a block on top 31 // of an arbitrary state with the goal of prefetching potentially useful state 32 // data from disk before the main block processor start executing. 33 type statePrefetcher struct { 34 config *params.ChainConfig // Chain configuration options 35 bc DummyChain // Canonical block chain 36 } 37 38 // newStatePrefetcher initialises a new statePrefetcher. 39 func newStatePrefetcher(config *params.ChainConfig, bc DummyChain) *statePrefetcher { 40 return &statePrefetcher{ 41 config: config, 42 bc: bc, 43 } 44 } 45 46 // Prefetch processes the state changes according to the Ethereum rules by running 47 // the transaction messages using the statedb, but any changes are discarded. The 48 // only goal is to pre-cache transaction signatures and state trie nodes. 49 func (p *statePrefetcher) Prefetch(block *EvmBlock, statedb *state.StateDB, cfg vm.Config, interrupt *uint32) { 50 var ( 51 header = block.Header() 52 gaspool = new(GasPool).AddGas(block.GasLimit) 53 blockContext = NewEVMBlockContext(header, p.bc, nil) 54 evm = vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) 55 signer = gsignercache.Wrap(types.MakeSigner(p.config, header.Number)) 56 ) 57 // Iterate over and process the individual transactions 58 byzantium := p.config.IsByzantium(block.Number) 59 for i, tx := range block.Transactions { 60 // If block precaching was interrupted, abort 61 if interrupt != nil && atomic.LoadUint32(interrupt) == 1 { 62 return 63 } 64 // Convert the transaction into an executable message and pre-cache its sender 65 msg, err := TxAsMessage(tx, signer, header.BaseFee) 66 if err != nil { 67 return // Also invalid block, bail out 68 } 69 statedb.Prepare(tx.Hash(), i) 70 if err := precacheTransaction(msg, p.config, gaspool, statedb, header, evm); err != nil { 71 return // Ugh, something went horribly wrong, bail out 72 } 73 // If we're pre-byzantium, pre-load trie nodes for the intermediate root 74 if !byzantium { 75 statedb.IntermediateRoot(true) 76 } 77 } 78 // If were post-byzantium, pre-load trie nodes for the final root hash 79 if byzantium { 80 statedb.IntermediateRoot(true) 81 } 82 } 83 84 // precacheTransaction attempts to apply a transaction to the given state database 85 // and uses the input parameters for its environment. The goal is not to execute 86 // the transaction successfully, rather to warm up touched data slots. 87 func precacheTransaction(msg types.Message, config *params.ChainConfig, gaspool *GasPool, statedb *state.StateDB, header *EvmHeader, evm *vm.EVM) error { 88 // Update the evm with the new transaction context. 89 evm.Reset(NewEVMTxContext(msg), statedb) 90 // Add addresses to access list if applicable 91 _, err := ApplyMessage(evm, msg, gaspool) 92 return err 93 }