diff --git a/src/validation.cpp b/src/validation.cpp index 1efe109b6f6..59654c9d193 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2858,7 +2858,8 @@ static void UpdateTipLog( const CBlockIndex* tip, const std::string& func_name, const std::string& prefix, - const std::string& warning_messages) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) + const std::string& warning_messages, + const bool background_validation) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { AssertLockHeld(::cs_main); @@ -2869,7 +2870,7 @@ static void UpdateTipLog( tip->GetBlockHash().ToString(), tip->nHeight, tip->nVersion, log(tip->nChainWork.getdouble()) / log(2.0), tip->m_chain_tx_count, FormatISO8601DateTime(tip->GetBlockTime()), - chainman.GuessVerificationProgress(tip), + background_validation ? chainman.GetBackgroundVerificationProgress(*tip) : chainman.GuessVerificationProgress(tip), coins_tip.DynamicMemoryUsage() * (1.0 / (1 << 20)), coins_tip.GetCacheSize(), !warning_messages.empty() ? strprintf(" warning='%s'", warning_messages) : ""); @@ -2886,7 +2887,7 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) // Only log every so often so that we don't bury log messages at the tip. constexpr int BACKGROUND_LOG_INTERVAL = 2000; if (pindexNew->nHeight % BACKGROUND_LOG_INTERVAL == 0) { - UpdateTipLog(m_chainman, coins_tip, pindexNew, __func__, "[background validation] ", ""); + UpdateTipLog(m_chainman, coins_tip, pindexNew, __func__, "[background validation] ", "", /*background_validation=*/true); } return; } @@ -2909,7 +2910,7 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) } } UpdateTipLog(m_chainman, coins_tip, pindexNew, __func__, "", - util::Join(warning_messages, Untranslated(", ")).original); + util::Join(warning_messages, Untranslated(", ")).original, /*background_validation=*/false); } /** Disconnect m_chain's tip. @@ -5520,6 +5521,19 @@ double ChainstateManager::GuessVerificationProgress(const CBlockIndex* pindex) c return std::min(pindex->m_chain_tx_count / fTxTotal, 1.0); } +double ChainstateManager::GetBackgroundVerificationProgress(const CBlockIndex& pindex) const +{ + AssertLockHeld(GetMutex()); + Assert(HistoricalChainstate()); + auto target_block = HistoricalChainstate()->TargetBlock(); + + if (pindex.m_chain_tx_count == 0 || target_block->m_chain_tx_count == 0) { + LogDebug(BCLog::VALIDATION, "[background validation] Block %d has unset m_chain_tx_count. Unable to estimate verification progress.", pindex.nHeight); + return 0.0; + } + return static_cast(pindex.m_chain_tx_count) / static_cast(target_block->m_chain_tx_count); +} + Chainstate& ChainstateManager::InitializeChainstate(CTxMemPool* mempool) { AssertLockHeld(::cs_main); diff --git a/src/validation.h b/src/validation.h index 729cdbaa147..cee0dd728b3 100644 --- a/src/validation.h +++ b/src/validation.h @@ -1194,9 +1194,15 @@ public: /** Check whether we are doing an initial block download (synchronizing from disk or network) */ bool IsInitialBlockDownload() const noexcept; - /** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */ + /** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). + * This is also the case in the assumeutxo context, meaning that the progress reported for + * the snapshot chainstate may suggest that all historical blocks have already been verified + * even though that may not actually be the case. */ double GuessVerificationProgress(const CBlockIndex* pindex) const EXCLUSIVE_LOCKS_REQUIRED(GetMutex()); + /** Guess background verification progress in case assume-utxo was used (as a fraction between 0.0=genesis and 1.0=snapshot blocks). */ + double GetBackgroundVerificationProgress(const CBlockIndex& pindex) const EXCLUSIVE_LOCKS_REQUIRED(GetMutex()); + /** * Import blocks from an external file *