From ef227c5f42a2e180b0e3b57d38ef5018fc8733d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 12 Feb 2021 12:45:34 +0200 Subject: [PATCH] core: fix temp memory blowup caused by defers holding on to state --- core/blockchain.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/core/blockchain.go b/core/blockchain.go index 7dd1097e9884..d65ce4f04849 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1805,6 +1805,17 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er return it.index, err } // No validation errors for the first block (or chain prefix skipped) + var activeState *state.StateDB + defer func() { + // The chain importer is starting and stopping trie prefetchers. If a bad + // block or other error is hit however, an early return may not properly + // terminate the background threads. This defer ensures that we clean up + // and dangling prefetcher, without defering each and holding on live refs. + if activeState != nil { + activeState.StopPrefetcher() + } + }() + for ; block != nil && err == nil || err == ErrKnownBlock; block, err = it.next() { // If the chain is terminating, stop processing blocks if bc.insertStopped() { @@ -1867,7 +1878,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er } // Enable prefetching to pull in trie node paths while processing transactions statedb.StartPrefetcher("chain") - defer statedb.StopPrefetcher() // stopped on write anyway, defer meant to catch early error returns + activeState = statedb // If we have a followup block, run that against the current state to pre-cache // transactions and probabilistically some of the account/storage trie nodes.