@@ -2666,45 +2666,53 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
2666
2666
SyncWithValidationInterfaceQueue ();
2667
2667
}
2668
2668
2669
- const CBlockIndex *pindexFork;
2670
- bool fInitialDownload ;
2671
2669
{
2672
2670
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
+ }
2674
2681
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
+ }
2679
2686
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 ;
2683
2692
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 ();
2688
2698
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 ;
2696
2705
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 ();
2701
2708
2702
2709
// Notify external listeners about the new tip.
2703
2710
// 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
2707
2711
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
2708
2716
uiInterface.NotifyBlockTip (fInitialDownload , pindexNewTip);
2709
2717
}
2710
2718
}
@@ -2728,6 +2736,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
2728
2736
2729
2737
return true ;
2730
2738
}
2739
+
2731
2740
bool ActivateBestChain (CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) {
2732
2741
return g_chainstate.ActivateBestChain (state, chainparams, std::move (pblock));
2733
2742
}
0 commit comments