From fd79bb753080ca98b368a9c0437c477b1f7477b3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 1 Apr 2021 17:46:22 -0300 Subject: [PATCH] Optimize ActivateBestChain for long chains Github-Pull: #2290 Rebased-From: 8d15cf58ca0fd3f97fd6bcaf671b2b7e9f62caa9 --- src/validation.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index ef9a3e728d69c..3ec2b5773ccc2 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2138,12 +2138,11 @@ static void PruneBlockIndexCandidates() * Try to make some progress towards making pindexMostWork the active block. * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. */ -static bool ActivateBestChainStep(CValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr& pblock, bool fAlreadyChecked, ConnectTrace& connectTrace) +static bool ActivateBestChainStep(CValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr& pblock, bool fAlreadyChecked, bool& fInvalidFound, ConnectTrace& connectTrace) { AssertLockHeld(cs_main); if (pblock == NULL) fAlreadyChecked = false; - bool fInvalidFound = false; const CBlockIndex* pindexOldTip = chainActive.Tip(); const CBlockIndex* pindexFork = chainActive.FindFork(pindexMostWork); @@ -2246,16 +2245,23 @@ bool ActivateBestChain(CValidationState& state, std::shared_ptr pb ConnectTrace connectTrace(mempool); // Destructed before cs_main is unlocked CBlockIndex *pindexOldTip = chainActive.Tip(); - pindexMostWork = FindMostWorkChain(); + if (pindexMostWork == nullptr) { + pindexMostWork = FindMostWorkChain(); + } // Whether we have anything to do at all. - if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip()) + if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip()) return true; + bool fInvalidFound = false; std::shared_ptr nullBlockPtr; - if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fAlreadyChecked, connectTrace)) + if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fAlreadyChecked, fInvalidFound, connectTrace)) return false; + if (fInvalidFound) { + // Wipe cache, we may need another branch now. + pindexMostWork = nullptr; + } pindexNewTip = chainActive.Tip(); pindexFork = chainActive.FindFork(pindexOldTip); fInitialDownload = IsInitialBlockDownload();