@@ -2666,45 +2666,53 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
26662666 SyncWithValidationInterfaceQueue ();
26672667 }
26682668
2669- const CBlockIndex *pindexFork;
2670- bool fInitialDownload ;
26712669 {
26722670 LOCK (cs_main);
2673- ConnectTrace connectTrace (mempool); // Destructed before cs_main is unlocked
2671+ CBlockIndex* starting_tip = chainActive.Tip ();
2672+ bool blocks_connected = false ;
2673+ do {
2674+ // We absolutely may not unlock cs_main until we've made forward progress
2675+ // (with the exception of shutdown due to hardware issues, low disk space, etc).
2676+ ConnectTrace connectTrace (mempool); // Destructed before cs_main is unlocked
2677+
2678+ if (pindexMostWork == nullptr ) {
2679+ pindexMostWork = FindMostWorkChain ();
2680+ }
26742681
2675- CBlockIndex *pindexOldTip = chainActive. Tip ();
2676- if (pindexMostWork == nullptr ) {
2677- pindexMostWork = FindMostWorkChain () ;
2678- }
2682+ // Whether we have anything to do at all.
2683+ if (pindexMostWork == nullptr || pindexMostWork == chainActive. Tip () ) {
2684+ break ;
2685+ }
26792686
2680- // Whether we have anything to do at all.
2681- if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip ())
2682- return true ;
2687+ bool fInvalidFound = false ;
2688+ std::shared_ptr<const CBlock> nullBlockPtr;
2689+ if (!ActivateBestChainStep (state, chainparams, pindexMostWork, pblock && pblock->GetHash () == pindexMostWork->GetBlockHash () ? pblock : nullBlockPtr, fInvalidFound , connectTrace))
2690+ return false ;
2691+ blocks_connected = true ;
26832692
2684- bool fInvalidFound = false ;
2685- std::shared_ptr<const CBlock> nullBlockPtr;
2686- if (!ActivateBestChainStep (state, chainparams, pindexMostWork, pblock && pblock->GetHash () == pindexMostWork->GetBlockHash () ? pblock : nullBlockPtr, fInvalidFound , connectTrace))
2687- return false ;
2693+ if (fInvalidFound ) {
2694+ // Wipe cache, we may need another branch now.
2695+ pindexMostWork = nullptr ;
2696+ }
2697+ pindexNewTip = chainActive.Tip ();
26882698
2689- if (fInvalidFound ) {
2690- // Wipe cache, we may need another branch now.
2691- pindexMostWork = nullptr ;
2692- }
2693- pindexNewTip = chainActive.Tip ();
2694- pindexFork = chainActive.FindFork (pindexOldTip);
2695- fInitialDownload = IsInitialBlockDownload ();
2699+ for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected ()) {
2700+ assert (trace.pblock && trace.pindex );
2701+ GetMainSignals ().BlockConnected (trace.pblock , trace.pindex , trace.conflictedTxs );
2702+ }
2703+ } while (!chainActive.Tip () || (starting_tip && CBlockIndexWorkComparator ()(chainActive.Tip (), starting_tip)));
2704+ if (!blocks_connected) return true ;
26962705
2697- for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected ()) {
2698- assert (trace.pblock && trace.pindex );
2699- GetMainSignals ().BlockConnected (trace.pblock , trace.pindex , trace.conflictedTxs );
2700- }
2706+ const CBlockIndex* pindexFork = chainActive.FindFork (starting_tip);
2707+ bool fInitialDownload = IsInitialBlockDownload ();
27012708
27022709 // Notify external listeners about the new tip.
27032710 // Enqueue while holding cs_main to ensure that UpdatedBlockTip is called in the order in which blocks are connected
2704- GetMainSignals ().UpdatedBlockTip (pindexNewTip, pindexFork, fInitialDownload );
2705-
2706- // Always notify the UI if a new block tip was connected
27072711 if (pindexFork != pindexNewTip) {
2712+ // Notify ValidationInterface subscribers
2713+ GetMainSignals ().UpdatedBlockTip (pindexNewTip, pindexFork, fInitialDownload );
2714+
2715+ // Always notify the UI if a new block tip was connected
27082716 uiInterface.NotifyBlockTip (fInitialDownload , pindexNewTip);
27092717 }
27102718 }
@@ -2728,6 +2736,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
27282736
27292737 return true ;
27302738}
2739+
27312740bool ActivateBestChain (CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) {
27322741 return g_chainstate.ActivateBestChain (state, chainparams, std::move (pblock));
27332742}
0 commit comments