diff --git a/core/blockchain.go b/core/blockchain.go index b98c2d43aa..2cc3fcc3d5 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -231,14 +231,15 @@ type BlockChain struct { statedb *state.CachingDB // State database to reuse between imports (contains state cache) txIndexer *txIndexer // Transaction indexer, might be nil if not enabled - hc *HeaderChain - rmLogsFeed event.Feed - chainFeed event.Feed - chainHeadFeed event.Feed - logsFeed event.Feed - blockProcFeed event.Feed - scope event.SubscriptionScope - genesisBlock *types.Block + hc *HeaderChain + rmLogsFeed event.Feed + chainFeed event.Feed + chainHeadFeed event.Feed + logsFeed event.Feed + blockProcFeed event.Feed + blockProcCounter int32 + scope event.SubscriptionScope + genesisBlock *types.Block // This mutex synchronizes chain write operations. // Readers don't need to take it, they can just read the database. @@ -1570,8 +1571,6 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { if len(chain) == 0 { return 0, nil } - bc.blockProcFeed.Send(true) - defer bc.blockProcFeed.Send(false) // Do a sanity check that the provided chain is actually ordered and linked. for i := 1; i < len(chain); i++ { @@ -1611,6 +1610,16 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness if bc.insertStopped() { return nil, 0, nil } + + if atomic.AddInt32(&bc.blockProcCounter, 1) == 1 { + bc.blockProcFeed.Send(true) + } + defer func() { + if atomic.AddInt32(&bc.blockProcCounter, -1) == 0 { + bc.blockProcFeed.Send(false) + } + }() + // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) SenderCacher().RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain)