diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 8aec2758f8b..b19cb29f915 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -326,7 +326,8 @@ public: } double getVerificationProgress() override { - return chainman().GuessVerificationProgress(WITH_LOCK(chainman().GetMutex(), return chainman().ActiveChain().Tip())); + LOCK(chainman().GetMutex()); + return chainman().GuessVerificationProgress(chainman().ActiveChain().Tip()); } bool isInitialBlockDownload() override { @@ -410,7 +411,7 @@ public: { return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn, this](SynchronizationState sync_state, const CBlockIndex* block) { fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()}, - chainman().GuessVerificationProgress(block)); + WITH_LOCK(chainman().GetMutex(), return chainman().GuessVerificationProgress(block))); })); } std::unique_ptr handleNotifyHeaderTip(NotifyHeaderTipFn fn) override diff --git a/src/validation.cpp b/src/validation.cpp index 1213d8be9f9..b75387602bd 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4727,7 +4727,6 @@ bool Chainstate::LoadChainTip() // Ignoring return value for now. (void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(/*init=*/true, m_chainman.m_blockman.m_blockfiles_indexed), *pindex); } - return true; } @@ -5608,11 +5607,8 @@ bool Chainstate::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size) return ret; } -//! Guess how far we are in the verification process at the given block index -//! require cs_main if pindex has not been validated yet (because m_chain_tx_count might be unset) double ChainstateManager::GuessVerificationProgress(const CBlockIndex* pindex) const { - const ChainTxData& data{GetParams().TxData()}; if (pindex == nullptr) { return 0.0; } @@ -5622,16 +5618,21 @@ double ChainstateManager::GuessVerificationProgress(const CBlockIndex* pindex) c return 0.0; } - int64_t nNow = time(nullptr); - - double fTxTotal; - - if (pindex->m_chain_tx_count <= data.tx_count) { - fTxTotal = data.tx_count + (nNow - data.nTime) * data.dTxRate; - } else { - fTxTotal = pindex->m_chain_tx_count + (nNow - pindex->GetBlockTime()) * data.dTxRate; + int64_t end_of_chain_timestamp = TicksSinceEpoch(NodeClock::time_point{std::chrono::seconds{pindex->GetBlockTime()}}); + if (m_best_header && m_best_header->nChainWork > pindex->nChainWork) { + int64_t header_age = TicksSinceEpoch(Now()) - m_best_header->GetBlockTime(); + if (header_age < 24 * 60 * 60) { + end_of_chain_timestamp = std::max(end_of_chain_timestamp, m_best_header->GetBlockTime()); + } } + double fTxTotal; + const ChainTxData& data{GetParams().TxData()}; + if (pindex->m_chain_tx_count <= data.tx_count) { + fTxTotal = data.tx_count + (end_of_chain_timestamp - data.nTime) * data.dTxRate; + } else { + fTxTotal = pindex->m_chain_tx_count + (end_of_chain_timestamp - pindex->GetBlockTime()) * data.dTxRate; + } return std::min(pindex->m_chain_tx_count / fTxTotal, 1.0); } diff --git a/src/validation.h b/src/validation.h index e361c7af101..9c2bd9936be 100644 --- a/src/validation.h +++ b/src/validation.h @@ -1149,7 +1149,7 @@ public: bool IsInitialBlockDownload() const; /** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */ - double GuessVerificationProgress(const CBlockIndex* pindex) const; + double GuessVerificationProgress(const CBlockIndex* pindex) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main); /** * Import blocks from an external file