mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-27 07:14:48 +00:00
Do not unlock cs_main in ABC unless we've actually made progress.
Technically, some internal datastructures may be in an inconsistent state if we do this, though there are no known bugs there. Still, for future safety, its much better to only unlock cs_main if we've made progress (not just tried a reorg which may make progress). Github-Pull: #13023 Rebased-From: ecc3c4a019e6db30e208b8554b1a3658dcb9a80a
This commit is contained in:
parent
c71e535aec
commit
0948153ea6
@ -2575,45 +2575,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
|
||||
|
||||
CBlockIndex *pindexOldTip = chainActive.Tip();
|
||||
if (pindexMostWork == nullptr) {
|
||||
pindexMostWork = FindMostWorkChain();
|
||||
}
|
||||
if (pindexMostWork == nullptr) {
|
||||
pindexMostWork = FindMostWorkChain();
|
||||
}
|
||||
|
||||
// Whether we have anything to do at all.
|
||||
if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip())
|
||||
return true;
|
||||
// Whether we have anything to do at all.
|
||||
if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip()) {
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
if (fInvalidFound) {
|
||||
// Wipe cache, we may need another branch now.
|
||||
pindexMostWork = nullptr;
|
||||
}
|
||||
pindexNewTip = chainActive.Tip();
|
||||
pindexFork = chainActive.FindFork(pindexOldTip);
|
||||
fInitialDownload = IsInitialBlockDownload();
|
||||
if (fInvalidFound) {
|
||||
// Wipe cache, we may need another branch now.
|
||||
pindexMostWork = nullptr;
|
||||
}
|
||||
pindexNewTip = chainActive.Tip();
|
||||
|
||||
for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
|
||||
assert(trace.pblock && trace.pindex);
|
||||
GetMainSignals().BlockConnected(trace.pblock, trace.pindex, trace.conflictedTxs);
|
||||
}
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -2637,6 +2645,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));
|
||||
}
|
||||
|
@ -56,7 +56,11 @@ void SyncWithValidationInterfaceQueue();
|
||||
class CValidationInterface {
|
||||
protected:
|
||||
/**
|
||||
* Notifies listeners of updated block chain tip
|
||||
* Notifies listeners when the block chain tip advances.
|
||||
*
|
||||
* When multiple blocks are connected at once, UpdatedBlockTip will be called on the final tip
|
||||
* but may not be called on every intermediate tip. If the latter behavior is desired,
|
||||
* subscribe to BlockConnected() instead.
|
||||
*
|
||||
* Called on a background thread.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user