core: avoid starting prefetcher before process block to avoid duplication

We moved the starting of prefetcher to process block function as we need
to copy the state for block-stm (and hence we need separate prefetchers
for both). The witness generation code from upstream starts the prefetcher
early as the witness object is constructed. This lead to OOM issues as
we would be starting duplicate prefetchers per block leading to increase
in go routines with time (eventually OOM). This commit skips starting the
prefetcher earlier and instead pass the witness to process block to start
it later.
This commit is contained in:
Manav Darji 2025-04-30 14:51:46 -04:00
parent 2e71e50b6b
commit 8ea52f5036
No known key found for this signature in database
GPG key ID: A426F0124435F36E
2 changed files with 9 additions and 6 deletions

View file

@ -577,7 +577,7 @@ func NewParallelBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis
return bc, nil return bc, nil
} }
func (bc *BlockChain) ProcessBlock(block *types.Block, parent *types.Header) (_ types.Receipts, _ []*types.Log, _ uint64, _ *state.StateDB, vtime time.Duration, blockEndErr error) { func (bc *BlockChain) ProcessBlock(block *types.Block, parent *types.Header, witness *stateless.Witness) (_ types.Receipts, _ []*types.Log, _ uint64, _ *state.StateDB, vtime time.Duration, blockEndErr error) {
// Process the block using processor and parallelProcessor at the same time, take the one which finishes first, cancel the other, and return the result // Process the block using processor and parallelProcessor at the same time, take the one which finishes first, cancel the other, and return the result
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
@ -629,7 +629,7 @@ func (bc *BlockChain) ProcessBlock(block *types.Block, parent *types.Header) (_
processorCount++ processorCount++
go func() { go func() {
parallelStatedb.StartPrefetcher("chain", nil) parallelStatedb.StartPrefetcher("chain", witness)
pstart := time.Now() pstart := time.Now()
res, err := bc.parallelProcessor.Process(block, parallelStatedb, bc.vmConfig, ctx) res, err := bc.parallelProcessor.Process(block, parallelStatedb, bc.vmConfig, ctx)
blockExecutionParallelTimer.UpdateSince(pstart) blockExecutionParallelTimer.UpdateSince(pstart)
@ -654,7 +654,7 @@ func (bc *BlockChain) ProcessBlock(block *types.Block, parent *types.Header) (_
processorCount++ processorCount++
go func() { go func() {
statedb.StartPrefetcher("chain", nil) statedb.StartPrefetcher("chain", witness)
pstart := time.Now() pstart := time.Now()
res, err := bc.processor.Process(block, statedb, bc.vmConfig, ctx) res, err := bc.processor.Process(block, statedb, bc.vmConfig, ctx)
blockExecutionSerialTimer.UpdateSince(pstart) blockExecutionSerialTimer.UpdateSince(pstart)
@ -2344,7 +2344,10 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
return nil, it.index, err return nil, it.index, err
} }
} }
statedb.StartPrefetcher("chain", witness) // Bor: We start the prefetcher in process block function called below
// and not here as we copy state for block-stm in that function. Also,
// we don't want to start duplicate prefetchers per block.
// statedb.StartPrefetcher("chain", witness)
} }
activeState = statedb activeState = statedb
@ -2373,7 +2376,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
// Process block using the parent state as reference point // Process block using the parent state as reference point
pstart := time.Now() pstart := time.Now()
receipts, logs, usedGas, statedb, vtime, err := bc.ProcessBlock(block, parent) receipts, logs, usedGas, statedb, vtime, err := bc.ProcessBlock(block, parent, witness)
activeState = statedb activeState = statedb
if err != nil { if err != nil {

View file

@ -176,7 +176,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
if err != nil { if err != nil {
return err return err
} }
receipts, logs, usedGas, statedb, _, err := blockchain.ProcessBlock(block, blockchain.GetBlockByHash(block.ParentHash()).Header()) receipts, logs, usedGas, statedb, _, err := blockchain.ProcessBlock(block, blockchain.GetBlockByHash(block.ParentHash()).Header(), nil)
res := &ProcessResult{ res := &ProcessResult{
Receipts: receipts, Receipts: receipts,
Logs: logs, Logs: logs,