diff options
author | Jesse Cohen <jc@jc.lol> | 2018-04-15 11:22:28 -0400 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2018-05-18 14:10:39 +0800 |
commit | acdf4338221e35d5ec7b299bb18ccd953e28c985 (patch) | |
tree | e873d3583a965dd667ca49a553e5ad61d996c5a7 /src | |
parent | 5ff571e90c9fa71e189863e9cb21d15d5991f7da (diff) |
Hold cs_main while calling UpdatedBlockTip() and ui.NotifyBlockTip
Ensures that callbacks are invoked in the order in which the chain is updated
Resolves #12978
GitHub-Pull: #12988
Rebased-From: d86edd3
Diffstat (limited to 'src')
-rw-r--r-- | src/validation.cpp | 19 | ||||
-rw-r--r-- | src/validationinterface.cpp | 4 |
2 files changed, 13 insertions, 10 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index 1f0ceba70c..f981d2659a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -351,7 +351,7 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool CBlockIndex* tip = chainActive.Tip(); assert(tip != nullptr); - + CBlockIndex index; index.pprev = tip; // CheckSequenceLocks() uses chainActive.Height()+1 to evaluate @@ -2607,18 +2607,17 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams& assert(trace.pblock && trace.pindex); GetMainSignals().BlockConnected(trace.pblock, trace.pindex, trace.conflictedTxs); } - } - // When we reach this point, we switched to a new tip (stored in pindexNewTip). - // Notifications/callbacks that can run without cs_main + // 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); - // Notify external listeners about the new tip. - GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload); - - // Always notify the UI if a new block tip was connected - if (pindexFork != pindexNewTip) { - uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip); + // Always notify the UI if a new block tip was connected + if (pindexFork != pindexNewTip) { + uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip); + } } + // When we reach this point, we switched to a new tip (stored in pindexNewTip). if (nStopAtHeight && pindexNewTip && pindexNewTip->nHeight >= nStopAtHeight) StartShutdown(); diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 928df4fa65..746263f113 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -139,6 +139,10 @@ void CMainSignals::MempoolEntryRemoved(CTransactionRef ptx, MemPoolRemovalReason } void CMainSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) { + // Dependencies exist that require UpdatedBlockTip events to be delivered in the order in which + // the chain actually updates. One way to ensure this is for the caller to invoke this signal + // in the same critical section where the chain is updated + m_internals->m_schedulerClient.AddToProcessQueue([pindexNew, pindexFork, fInitialDownload, this] { m_internals->UpdatedBlockTip(pindexNew, pindexFork, fInitialDownload); }); |