mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-19 23:03:45 +01:00
Merge bitcoin/bitcoin#32528: rpc: Round verificationprogress to 1 for a recent tip
fab1e02086refactor: Pass verification_progress into block tip notifications (MarcoFalke)fa76b378e4rpc: Round verificationprogress to exactly 1 for a recent tip (MarcoFalke)faf6304bdftest: Use mockable time in GuessVerificationProgress (MarcoFalke) Pull request description: Some users really seem to care about this. While it shouldn't matter much, the diff is so trivial that it is probably worth doing. Fixes #31127 One could also consider to split the field into two dedicated ones (https://github.com/bitcoin/bitcoin/issues/28847#issuecomment-1807115357), but this is left for a more involved follow-up and may also be controversial. ACKs for top commit: achow101: ACKfab1e02086pinheadmz: ACKfab1e02086sipa: utACKfab1e02086Tree-SHA512: a3c24e3c446d38fbad9399c1e7f1ffa7904490a3a7d12623b44e583b435cc8b5f1ba83b84d29c7ffaf22028bc909c7cec07202b825480449c6419d2a190938f5
This commit is contained in:
@@ -3557,7 +3557,11 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
|
||||
m_chainman.m_options.signals->UpdatedBlockTip(pindexNewTip, pindexFork, still_in_ibd);
|
||||
}
|
||||
|
||||
if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(GetSynchronizationState(still_in_ibd, m_chainman.m_blockman.m_blockfiles_indexed), *pindexNewTip))) {
|
||||
if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(
|
||||
/*state=*/GetSynchronizationState(still_in_ibd, m_chainman.m_blockman.m_blockfiles_indexed),
|
||||
/*index=*/*pindexNewTip,
|
||||
/*verification_progress=*/m_chainman.GuessVerificationProgress(pindexNewTip))))
|
||||
{
|
||||
// Just breaking and returning success for now. This could
|
||||
// be changed to bubble up the kernel::Interrupted value to
|
||||
// the caller so the caller could distinguish between
|
||||
@@ -3790,7 +3794,10 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
||||
// parameter indicating the source of the tip change so hooks can
|
||||
// distinguish user-initiated invalidateblock changes from other
|
||||
// changes.
|
||||
(void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_blockfiles_indexed), *to_mark_failed->pprev);
|
||||
(void)m_chainman.GetNotifications().blockTip(
|
||||
/*state=*/GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_blockfiles_indexed),
|
||||
/*index=*/*to_mark_failed->pprev,
|
||||
/*verification_progress=*/WITH_LOCK(m_chainman.GetMutex(), return m_chainman.GuessVerificationProgress(to_mark_failed->pprev)));
|
||||
|
||||
// Fire ActiveTipChange now for the current chain tip to make sure clients are notified.
|
||||
// ActivateBestChain may call this as well, but not necessarily.
|
||||
@@ -4688,7 +4695,10 @@ bool Chainstate::LoadChainTip()
|
||||
// Ensure KernelNotifications m_tip_block is set even if no new block arrives.
|
||||
if (this->GetRole() != ChainstateRole::BACKGROUND) {
|
||||
// Ignoring return value for now.
|
||||
(void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(/*init=*/true, m_chainman.m_blockman.m_blockfiles_indexed), *pindex);
|
||||
(void)m_chainman.GetNotifications().blockTip(
|
||||
/*state=*/GetSynchronizationState(/*init=*/true, m_chainman.m_blockman.m_blockfiles_indexed),
|
||||
/*index=*/*pindex,
|
||||
/*verification_progress=*/m_chainman.GuessVerificationProgress(tip));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -5572,10 +5582,9 @@ 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
|
||||
{
|
||||
AssertLockHeld(GetMutex());
|
||||
const ChainTxData& data{GetParams().TxData()};
|
||||
if (pindex == nullptr) {
|
||||
return 0.0;
|
||||
@@ -5586,14 +5595,25 @@ double ChainstateManager::GuessVerificationProgress(const CBlockIndex* pindex) c
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int64_t nNow = time(nullptr);
|
||||
const int64_t nNow{TicksSinceEpoch<std::chrono::seconds>(NodeClock::now())};
|
||||
const auto block_time{
|
||||
(Assume(m_best_header) && std::abs(nNow - pindex->GetBlockTime()) <= Ticks<std::chrono::seconds>(2h) &&
|
||||
Assume(m_best_header->nHeight >= pindex->nHeight)) ?
|
||||
// When the header is known to be recent, switch to a height-based
|
||||
// approach. This ensures the returned value is quantized when
|
||||
// close to "1.0", because some users expect it to be. This also
|
||||
// avoids relying too much on the exact miner-set timestamp, which
|
||||
// may be off.
|
||||
nNow - (m_best_header->nHeight - pindex->nHeight) * GetConsensus().nPowTargetSpacing :
|
||||
pindex->GetBlockTime(),
|
||||
};
|
||||
|
||||
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;
|
||||
fTxTotal = pindex->m_chain_tx_count + (nNow - block_time) * data.dTxRate;
|
||||
}
|
||||
|
||||
return std::min<double>(pindex->m_chain_tx_count / fTxTotal, 1.0);
|
||||
|
||||
Reference in New Issue
Block a user