diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 51dcadad6f88..5c58efced2cd 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1967,7 +1967,7 @@ void PeerManagerImpl::BlockConnected( // The following task can be skipped since we don't maintain a mempool for // the historical chainstate. - if (role.historical) { + if (role.historical || m_chainman.IsInitialBlockDownload()) { return; } LOCK(m_tx_download_mutex); diff --git a/src/test/util/validation.cpp b/src/test/util/validation.cpp index c199d912a386..79c571614aa3 100644 --- a/src/test/util/validation.cpp +++ b/src/test/util/validation.cpp @@ -25,6 +25,7 @@ void TestChainstateManager::DisableNextWrite() void TestChainstateManager::ResetIbd() { m_cached_finished_ibd = false; + m_cached_chaintip_recent = false; assert(IsInitialBlockDownload()); } diff --git a/src/validation.cpp b/src/validation.cpp index 2052748343a2..a3dcf1d15195 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1958,31 +1958,29 @@ void Chainstate::InitCoinsCache(size_t cache_size_bytes) // bool ChainstateManager::IsInitialBlockDownload() const { - // Optimization: pre-test latch before taking the lock. - if (m_cached_finished_ibd.load(std::memory_order_relaxed)) - return false; - - LOCK(cs_main); if (m_cached_finished_ibd.load(std::memory_order_relaxed)) return false; if (m_blockman.LoadingBlocks()) { return true; } - CChain& chain{ActiveChain()}; - if (chain.Tip() == nullptr) { - return true; - } - if (chain.Tip()->nChainWork < MinimumChainWork()) { - return true; - } - if (chain.Tip()->Time() < Now() - m_options.max_tip_age) { + if (!m_cached_chaintip_recent) return true; - } LogInfo("Leaving InitialBlockDownload (latching to false)"); m_cached_finished_ibd.store(true, std::memory_order_relaxed); return false; } +void ChainstateManager::UpdateCachedChaintipRecent() +{ + AssertLockHeld(cs_main); + CChain& chain{ActiveChain()}; + if (chain.Tip() == nullptr) return; + if (chain.Tip()->nChainWork < MinimumChainWork()) return; + if (chain.Tip()->Time() < Now() - m_options.max_tip_age) return; + + m_cached_chaintip_recent = true; +} + void Chainstate::CheckForkWarningConditions() { AssertLockHeld(cs_main); @@ -3027,6 +3025,7 @@ bool Chainstate::DisconnectTip(BlockValidationState& state, DisconnectedBlockTra } m_chain.SetTip(*pindexDelete->pprev); + m_chainman.UpdateCachedChaintipRecent(); UpdateTip(pindexDelete->pprev); // Let wallets know transactions went from 1-confirmed to @@ -3157,6 +3156,7 @@ bool Chainstate::ConnectTip( } // Update m_chain & related variables. m_chain.SetTip(*pindexNew); + m_chainman.UpdateCachedChaintipRecent(); UpdateTip(pindexNew); const auto time_6{SteadyClock::now()}; @@ -4643,6 +4643,7 @@ bool Chainstate::LoadChainTip() return false; } m_chain.SetTip(*pindex); + m_chainman.UpdateCachedChaintipRecent(); tip = m_chain.Tip(); // Make sure our chain tip before shutting down scores better than any other candidate diff --git a/src/validation.h b/src/validation.h index 77958b53dd11..5688cd7ced35 100644 --- a/src/validation.h +++ b/src/validation.h @@ -1035,6 +1035,7 @@ class ChainstateManager * const, which latches this for caching purposes. */ mutable std::atomic m_cached_finished_ibd{false}; + mutable std::atomic m_cached_chaintip_recent{false}; /** * Every received block is assigned a unique and increasing identifier, so we @@ -1168,6 +1169,7 @@ class ChainstateManager /** Check whether we are doing an initial block download (synchronizing from disk or network) */ bool IsInitialBlockDownload() const; + void UpdateCachedChaintipRecent() EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */ double GuessVerificationProgress(const CBlockIndex* pindex) const EXCLUSIVE_LOCKS_REQUIRED(GetMutex());