aboutsummaryrefslogtreecommitdiff
path: root/src/validation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/validation.cpp')
-rw-r--r--src/validation.cpp65
1 files changed, 37 insertions, 28 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index daa33d3f5a..477b3e1550 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -2666,45 +2666,53 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
SyncWithValidationInterfaceQueue();
}
- const CBlockIndex *pindexFork;
- bool fInitialDownload;
{
LOCK(cs_main);
- ConnectTrace connectTrace(mempool); // Destructed before cs_main is unlocked
+ CBlockIndex* starting_tip = chainActive.Tip();
+ bool blocks_connected = false;
+ do {
+ // We absolutely may not unlock cs_main until we've made forward progress
+ // (with the exception of shutdown due to hardware issues, low disk space, etc).
+ ConnectTrace connectTrace(mempool); // Destructed before cs_main is unlocked
+
+ if (pindexMostWork == nullptr) {
+ pindexMostWork = FindMostWorkChain();
+ }
- CBlockIndex *pindexOldTip = chainActive.Tip();
- if (pindexMostWork == nullptr) {
- pindexMostWork = FindMostWorkChain();
- }
+ // Whether we have anything to do at all.
+ if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip()) {
+ break;
+ }
- // Whether we have anything to do at all.
- if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip())
- return true;
+ bool fInvalidFound = false;
+ std::shared_ptr<const CBlock> nullBlockPtr;
+ if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
+ return false;
+ blocks_connected = true;
- bool fInvalidFound = false;
- std::shared_ptr<const CBlock> nullBlockPtr;
- if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
- return false;
+ if (fInvalidFound) {
+ // Wipe cache, we may need another branch now.
+ pindexMostWork = nullptr;
+ }
+ pindexNewTip = chainActive.Tip();
- if (fInvalidFound) {
- // Wipe cache, we may need another branch now.
- pindexMostWork = nullptr;
- }
- pindexNewTip = chainActive.Tip();
- pindexFork = chainActive.FindFork(pindexOldTip);
- fInitialDownload = IsInitialBlockDownload();
+ for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
+ assert(trace.pblock && trace.pindex);
+ GetMainSignals().BlockConnected(trace.pblock, trace.pindex, trace.conflictedTxs);
+ }
+ } while (!chainActive.Tip() || (starting_tip && CBlockIndexWorkComparator()(chainActive.Tip(), starting_tip)));
+ if (!blocks_connected) return true;
- for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
- assert(trace.pblock && trace.pindex);
- GetMainSignals().BlockConnected(trace.pblock, trace.pindex, trace.conflictedTxs);
- }
+ const CBlockIndex* pindexFork = chainActive.FindFork(starting_tip);
+ bool fInitialDownload = IsInitialBlockDownload();
// Notify external listeners about the new tip.
// Enqueue while holding cs_main to ensure that UpdatedBlockTip is called in the order in which blocks are connected
- GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
-
- // Always notify the UI if a new block tip was connected
if (pindexFork != pindexNewTip) {
+ // Notify ValidationInterface subscribers
+ GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
+
+ // Always notify the UI if a new block tip was connected
uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip);
}
}
@@ -2728,6 +2736,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
return true;
}
+
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) {
return g_chainstate.ActivateBestChain(state, chainparams, std::move(pblock));
}