diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 7e24842225..c1a271898d 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -20,6 +20,7 @@ import ( "bufio" "errors" "fmt" + "github.com/ethereum/go-ethereum/core/types/bal" "os" "reflect" "runtime" @@ -243,12 +244,12 @@ func makeFullNode(ctx *cli.Context) *node.Node { if ctx.IsSet(utils.BlockAccessListExecutionModeFlag.Name) { val := ctx.String(utils.BlockAccessListExecutionModeFlag.Name) switch val { - case utils.BalExecutionModeFull: - cfg.Eth.BALExecutionMode = 0 + case utils.BalExecutionModeOptimized: + cfg.Eth.BALExecutionMode = bal.BALExecutionOptimized case utils.BalExecutionModeNoBatchIO: - cfg.Eth.BALExecutionMode = 1 + cfg.Eth.BALExecutionMode = bal.BALExecutionNoBatchIO case utils.BalExecutionModeSequential: - cfg.Eth.BALExecutionMode = 2 + cfg.Eth.BALExecutionMode = bal.BALExecutionSequential default: utils.Fatalf("invalid option for --bal.executionmode: %s. acceptable values are full|nobatchio|sequential", val) } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 25a7df5a09..ee4376f20d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1124,13 +1124,13 @@ block access list execution type. possible inputs are: - sequential: no performance acceleration - full: parallel transaction execution, state root calculation, async warming of access list reads - nobatchio: same as 'full', but without async warming of access list reads`, - Value: BalExecutionModeFull, + Value: BalExecutionModeOptimized, Category: flags.MiscCategory, } ) const ( - BalExecutionModeFull = "full" + BalExecutionModeOptimized = "full" BalExecutionModeNoBatchIO = "nobatchio" BalExecutionModeSequential = "sequential" ) diff --git a/core/blockchain.go b/core/blockchain.go index 6345e05609..b99cc587c4 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -179,12 +179,6 @@ const ( BlockChainVersion uint64 = 9 ) -const ( - BALExecutionModeFull = 0 - BALExecutionModeNoBatchIO = iota - BALExecutionModeSequential = iota -) - // BlockChainConfig contains the configuration of the BlockChain object. type BlockChainConfig struct { // Trie database related options @@ -246,8 +240,7 @@ type BlockChainConfig struct { StatelessSelfValidation bool // Generate execution witnesses and self-check against them (testing purpose) EnableWitnessStats bool // Whether trie access statistics collection is enabled - // TODO clean this config up to use defined constants... - BALExecutionMode int + BALExecutionMode bal.BALExecutionMode } // DefaultConfig returns the default config. @@ -609,7 +602,7 @@ func (bc *BlockChain) processBlockWithAccessList(parentRoot common.Hash, block * statedb *state.StateDB ) - useAsyncReads := bc.cfg.BALExecutionMode != BALExecutionModeNoBatchIO + useAsyncReads := bc.cfg.BALExecutionMode != bal.BALExecutionNoBatchIO al := block.AccessList() // TODO: make the return of this method not be a pointer accessListReader := bal.NewAccessListReader(*al) prefetchReader, err := bc.statedb.ReaderEIP7928(parentRoot, accessListReader.StorageKeys(useAsyncReads), runtime.NumCPU()) @@ -2146,7 +2139,7 @@ func (bc *BlockChain) insertChain(ctx context.Context, chain types.Blocks, setHe return nil, it.index, err } blockHasAccessList := block.AccessList() != nil - if blockHasAccessList && bc.cfg.BALExecutionMode != BALExecutionModeSequential { + if blockHasAccessList && bc.cfg.BALExecutionMode != bal.BALExecutionSequential { res.stats.reportBALMetrics() } else { res.stats.reportMetrics() @@ -2265,7 +2258,7 @@ func (bc *BlockChain) ProcessBlock(ctx context.Context, parentRoot common.Hash, blockHasAccessList := block.AccessList() != nil // optimized execution path for blocks which contain BALs - if blockHasAccessList && bc.cfg.BALExecutionMode != BALExecutionModeSequential { + if blockHasAccessList && bc.cfg.BALExecutionMode != bal.BALExecutionSequential { return bc.processBlockWithAccessList(parentRoot, block, config.WriteHead) } diff --git a/core/state/reader_eip_7928.go b/core/state/reader_eip_7928.go index fb5ba1e64b..0b3eb67ffb 100644 --- a/core/state/reader_eip_7928.go +++ b/core/state/reader_eip_7928.go @@ -290,6 +290,7 @@ func (r *ReaderWithBlockLevelAccessList) CodeSize(addr common.Address, codeHash // recorded during state reading operations. type StateReaderTracker interface { GetStateAccessList() bal.StateAccesses + Clear() } func NewReaderWithTracker(r Reader) Reader { @@ -333,3 +334,7 @@ func (r *readerTracker) Storage(addr common.Address, slot common.Hash) (common.H func (r *readerTracker) GetStateAccessList() bal.StateAccesses { return r.access } + +func (r *readerTracker) Clear() { + r.access = make(bal.StateAccesses) +} diff --git a/core/types/bal/bal.go b/core/types/bal/bal.go index b18c728fc3..47efc797a3 100644 --- a/core/types/bal/bal.go +++ b/core/types/bal/bal.go @@ -531,3 +531,11 @@ func (a *AccountMutations) Eq(other *AccountMutations) bool { } return true } + +type BALExecutionMode int + +const ( + BALExecutionOptimized BALExecutionMode = iota + BALExecutionNoBatchIO + BALExecutionSequential +) diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 5f144243f4..d40a3c4aea 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -19,6 +19,7 @@ package ethconfig import ( "errors" + "github.com/ethereum/go-ethereum/core/types/bal" "time" "github.com/ethereum/go-ethereum/common" @@ -210,7 +211,7 @@ type Config struct { // RangeLimit restricts the maximum range (end - start) for range queries. RangeLimit uint64 `toml:",omitempty"` - BALExecutionMode int + BALExecutionMode bal.BALExecutionMode } // CreateConsensusEngine creates a consensus engine for the given chain config. diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 68f9b7dc6a..0775fd828a 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -3,6 +3,7 @@ package ethconfig import ( + "github.com/ethereum/go-ethereum/core/types/bal" "time" "github.com/ethereum/go-ethereum/common" @@ -68,7 +69,7 @@ func (c Config) MarshalTOML() (interface{}, error) { TxSyncDefaultTimeout time.Duration `toml:",omitempty"` TxSyncMaxTimeout time.Duration `toml:",omitempty"` RangeLimit uint64 `toml:",omitempty"` - BALExecutionMode int + BALExecutionMode bal.BALExecutionMode } var enc Config enc.Genesis = c.Genesis @@ -340,7 +341,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { c.RangeLimit = *dec.RangeLimit } if dec.BALExecutionMode != nil { - c.BALExecutionMode = *dec.BALExecutionMode + c.BALExecutionMode = bal.BALExecutionMode(*dec.BALExecutionMode) } return nil } diff --git a/miner/worker.go b/miner/worker.go index 6e5c92dddb..6817c1af92 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -377,10 +377,6 @@ func (miner *Miner) makeEnv(parent *types.Header, header *types.Header, coinbase }, nil } -var ( - errAccessListOversized = errors.New("access list oversized") -) - func (miner *Miner) commitTransaction(env *environment, tx *types.Transaction) (err error) { if tx.Type() == types.BlobTxType { return miner.commitBlobTransaction(env, tx) @@ -432,43 +428,19 @@ func (miner *Miner) applyTransaction(env *environment, tx *types.Transaction) (* snap = env.state.Snapshot() gp = env.gasPool.Snapshot() ) - var stateCopy *state.StateDB - var prevReader state.Reader - if env.accessList != nil { - prevReader = env.state.Reader() - stateCopy = env.state.WithReader(state.NewReaderWithTracker(env.state.Reader())) - env.evm.StateDB = stateCopy - } else { - stateCopy = env.state - } - mutations, receipt, err := core.ApplyTransaction(env.evm, env.gasPool, stateCopy, env.header, tx) + mutations, receipt, err := core.ApplyTransaction(env.evm, env.gasPool, env.state, env.header, tx) if err != nil { if env.accessList != nil { - // transaction couldn't be applied. reset env state to what it was before - env.state = env.state.WithReader(prevReader) - env.evm.StateDB = env.state - } else { - env.state.RevertToSnapshot(snap) + env.state.Reader().(state.StateReaderTracker).Clear() } + env.state.RevertToSnapshot(snap) env.gasPool.Set(gp) + return nil, err } if env.accessList != nil { - al := env.accessList.Copy() - al.AccumulateMutations(mutations, uint16(env.tcount)+1) - al.AccumulateReads(stateCopy.Reader().(state.StateReaderTracker).GetStateAccessList()) - if env.size+tx.Size()+uint64(al.ToEncodingObj().EncodedSize()) >= params.MaxBlockSize-maxBlockSizeBufferZone { - env.gasPool.Set(gp) - - // transaction couldn't be applied. reset env state to what it was before - env.state = env.state.WithReader(prevReader) - env.evm.StateDB = env.state - return nil, errAccessListOversized - } - - env.state = stateCopy.WithReader(prevReader) - env.evm.StateDB = env.state - env.accessList = al + env.accessList.AccumulateMutations(mutations, uint16(env.tcount)+1) + env.accessList.AccumulateReads(env.state.Reader().(state.StateReaderTracker).GetStateAccessList()) } return receipt, err } @@ -481,7 +453,6 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran if env.gasPool == nil { env.gasPool = core.NewGasPool(gasLimit) } -loop: for { // Check interruption signal and abort building if it's fired. if interrupt != nil { @@ -580,12 +551,6 @@ loop: case errors.Is(err, nil): // Everything ok, collect the logs and shift in the next transaction from the same account txs.Shift() - case errors.Is(err, errAccessListOversized): - // Transaction can't be applied because it would cause the block to be oversized due to the - // contribution of the state accesses/modifications it makes. - // terminate the payload construction as it's not guaranteed we will be able to find a transaction - // that can fit in a short amount of time. - break loop default: // Transaction is regarded as invalid, drop all consecutive transactions from // the same sender because of `nonce-too-high` clause.