diff --git a/cmd/geth/main.go b/cmd/geth/main.go index ad8ab1fc1e..56ec5b1541 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -160,6 +160,7 @@ var ( utils.BeaconCheckpointFileFlag, utils.LogSlowBlockFlag, utils.PrefetchWorkersFlag, + utils.BlockingPrefetch, }, utils.NetworkFlags, utils.DatabaseFlags) rpcFlags = []cli.Flag{ diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 27e840ee64..a1f15d52db 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -721,6 +721,12 @@ var ( Category: flags.MiscCategory, } + BlockingPrefetch = &cli.BoolFlag{ + Name: "bal.blockingprefetch", + Usage: "only relevant when executing in parallel with a BAL: if true, the prefetcher will block tx/state-root calculation until all scheduled fetching tasks have completed.", + Category: flags.MiscCategory, + } + // RPC settings IPCDisabledFlag = &cli.BoolFlag{ Name: "ipcdisable", @@ -2467,7 +2473,8 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh TrienodeHistory: ctx.Int64(TrienodeHistoryFlag.Name), NodeFullValueCheckpoint: uint32(ctx.Uint(TrienodeHistoryFullValueCheckpointFlag.Name)), - PrefetchWorkers: int(ctx.Uint(PrefetchWorkersFlag.Name)), + PrefetchWorkers: int(ctx.Uint(PrefetchWorkersFlag.Name)), + BlockingPrefetch: ctx.Bool(BlockingPrefetch.Name), // Disable transaction indexing/unindexing. TxLookupLimit: -1, diff --git a/core/blockchain.go b/core/blockchain.go index 33172aff91..d55f1baecb 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -211,7 +211,9 @@ type BlockChainConfig struct { Overrides *ChainOverrides // Optional chain config overrides VmConfig vm.Config // Config options for the EVM Interpreter - PrefetchWorkers int // number of concurrent go-routines for BAL state prefetching + // BAL-related + PrefetchWorkers int // number of concurrent go-routines for BAL state prefetching + BlockingPrefetch bool // whether the prefetch should block further execution until it finishes // TxLookupLimit specifies the maximum number of blocks from head for which // transaction hashes will be indexed. @@ -599,7 +601,7 @@ func (bc *BlockChain) processBlockWithAccessList(parentRoot common.Hash, block * 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 := sdb.ReaderEIP7928(parentRoot, accessListReader.StorageKeys(useAsyncReads), bc.cfg.PrefetchWorkers) + prefetchReader, err := sdb.ReaderEIP7928(parentRoot, accessListReader.StorageKeys(useAsyncReads), bc.cfg.PrefetchWorkers, bc.cfg.BlockingPrefetch) if err != nil { return nil, err } diff --git a/core/state/database.go b/core/state/database.go index 5628fb211c..c7b91c90c5 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -240,7 +240,7 @@ func (db *CachingDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reade } // ReaderEIP7928 creates a state reader with the manner of Block-level accessList. -func (db *CachingDB) ReaderEIP7928(stateRoot common.Hash, accessList map[common.Address][]common.Hash, threads int) (Reader, error) { +func (db *CachingDB) ReaderEIP7928(stateRoot common.Hash, accessList map[common.Address][]common.Hash, threads int, block bool) (Reader, error) { base, err := db.StateReader(stateRoot) if err != nil { return nil, err @@ -250,6 +250,11 @@ func (db *CachingDB) ReaderEIP7928(stateRoot common.Hash, accessList map[common. // Construct the state reader with background prefetching pr := newPrefetchStateReader(r, accessList, threads) + if block { + if err := pr.Wait(); err != nil { + panic("wat do") + } + } return newReaderWithPrefetch(db.codedb.Reader(), pr, pr), nil } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index ab3a0e3b75..4f8b5f18ed 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -162,6 +162,7 @@ func (t *BlockTest) createTestBlockChain(config *params.ChainConfig, snapshotter }, StatelessSelfValidation: witness, NoPrefetch: true, + BlockingPrefetch: true, PrefetchWorkers: 100, // note: this is totally unrelated to NoPrefetch, just for BAL execution } if snapshotter {