Skip to content

Commit 88b22ac

Browse files
committed
Merge bitcoin/bitcoin#32528: rpc: Round verificationprogress to 1 for a recent tip
fab1e02 refactor: Pass verification_progress into block tip notifications (MarcoFalke) fa76b37 rpc: Round verificationprogress to exactly 1 for a recent tip (MarcoFalke) faf6304 test: 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 (bitcoin/bitcoin#28847 (comment)), but this is left for a more involved follow-up and may also be controversial. ACKs for top commit: achow101: ACK fab1e02 pinheadmz: ACK fab1e02 sipa: utACK fab1e02 Tree-SHA512: a3c24e3c446d38fbad9399c1e7f1ffa7904490a3a7d12623b44e583b435cc8b5f1ba83b84d29c7ffaf22028bc909c7cec07202b825480449c6419d2a190938f5
2 parents aee7cec + fab1e02 commit 88b22ac

12 files changed

+60
-25
lines changed

src/bitcoin-chainstate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ int main(int argc, char* argv[])
7474
class KernelNotifications : public kernel::Notifications
7575
{
7676
public:
77-
kernel::InterruptResult blockTip(SynchronizationState, CBlockIndex&) override
77+
kernel::InterruptResult blockTip(SynchronizationState, CBlockIndex&, double) override
7878
{
7979
std::cout << "Block tip changed" << std::endl;
8080
return {};

src/init.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,10 +1787,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
17871787
#if HAVE_SYSTEM
17881788
const std::string block_notify = args.GetArg("-blocknotify", "");
17891789
if (!block_notify.empty()) {
1790-
uiInterface.NotifyBlockTip_connect([block_notify](SynchronizationState sync_state, const CBlockIndex* pBlockIndex) {
1791-
if (sync_state != SynchronizationState::POST_INIT || !pBlockIndex) return;
1790+
uiInterface.NotifyBlockTip_connect([block_notify](SynchronizationState sync_state, const CBlockIndex& block, double /* verification_progress */) {
1791+
if (sync_state != SynchronizationState::POST_INIT) return;
17921792
std::string command = block_notify;
1793-
ReplaceAll(command, "%s", pBlockIndex->GetBlockHash().GetHex());
1793+
ReplaceAll(command, "%s", block.GetBlockHash().GetHex());
17941794
std::thread t(runCommand, command);
17951795
t.detach(); // thread runs free
17961796
});

src/kernel/chainparams.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,9 @@ class CRegTestParams : public CChainParams
613613
};
614614

615615
chainTxData = ChainTxData{
616-
0,
617-
0,
618-
0
616+
.nTime = 0,
617+
.tx_count = 0,
618+
.dTxRate = 0.001, // Set a non-zero rate to make it testable
619619
};
620620

621621
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);

src/kernel/notifications_interface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class Notifications
3737
public:
3838
virtual ~Notifications() = default;
3939

40-
[[nodiscard]] virtual InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) { return {}; }
40+
[[nodiscard]] virtual InterruptResult blockTip(SynchronizationState state, CBlockIndex& index, double verification_progress) { return {}; }
4141
virtual void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {}
4242
virtual void progress(const bilingual_str& title, int progress_percent, bool resume_possible) {}
4343
virtual void warningSet(Warning id, const bilingual_str& message) {}

src/node/interface_ui.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { re
5555
void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); }
5656
void CClientUIInterface::NotifyAlertChanged() { return g_ui_signals.NotifyAlertChanged(); }
5757
void CClientUIInterface::ShowProgress(const std::string& title, int nProgress, bool resume_possible) { return g_ui_signals.ShowProgress(title, nProgress, resume_possible); }
58-
void CClientUIInterface::NotifyBlockTip(SynchronizationState s, const CBlockIndex* i) { return g_ui_signals.NotifyBlockTip(s, i); }
58+
void CClientUIInterface::NotifyBlockTip(SynchronizationState s, const CBlockIndex& block, double verification_progress) { return g_ui_signals.NotifyBlockTip(s, block, verification_progress); }
5959
void CClientUIInterface::NotifyHeaderTip(SynchronizationState s, int64_t height, int64_t timestamp, bool presync) { return g_ui_signals.NotifyHeaderTip(s, height, timestamp, presync); }
6060
void CClientUIInterface::BannedListChanged() { return g_ui_signals.BannedListChanged(); }
6161

src/node/interface_ui.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class CClientUIInterface
103103
ADD_SIGNALS_DECL_WRAPPER(ShowProgress, void, const std::string& title, int nProgress, bool resume_possible);
104104

105105
/** New block has been accepted */
106-
ADD_SIGNALS_DECL_WRAPPER(NotifyBlockTip, void, SynchronizationState, const CBlockIndex*);
106+
ADD_SIGNALS_DECL_WRAPPER(NotifyBlockTip, void, SynchronizationState, const CBlockIndex& block, double verification_progress);
107107

108108
/** Best header has changed */
109109
ADD_SIGNALS_DECL_WRAPPER(NotifyHeaderTip, void, SynchronizationState, int64_t height, int64_t timestamp, bool presync);

src/node/interfaces.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,8 @@ class NodeImpl : public Node
326326
}
327327
double getVerificationProgress() override
328328
{
329-
return chainman().GuessVerificationProgress(WITH_LOCK(chainman().GetMutex(), return chainman().ActiveChain().Tip()));
329+
LOCK(chainman().GetMutex());
330+
return chainman().GuessVerificationProgress(chainman().ActiveTip());
330331
}
331332
bool isInitialBlockDownload() override
332333
{
@@ -408,9 +409,8 @@ class NodeImpl : public Node
408409
}
409410
std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
410411
{
411-
return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn, this](SynchronizationState sync_state, const CBlockIndex* block) {
412-
fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
413-
chainman().GuessVerificationProgress(block));
412+
return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn](SynchronizationState sync_state, const CBlockIndex& block, double verification_progress) {
413+
fn(sync_state, BlockTip{block.nHeight, block.GetBlockTime(), block.GetBlockHash()}, verification_progress);
414414
}));
415415
}
416416
std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override

src/node/kernel_notifications.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static void AlertNotify(const std::string& strMessage)
4848

4949
namespace node {
5050

51-
kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state, CBlockIndex& index)
51+
kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state, CBlockIndex& index, double verification_progress)
5252
{
5353
{
5454
LOCK(m_tip_block_mutex);
@@ -57,7 +57,7 @@ kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state
5757
m_tip_block_cv.notify_all();
5858
}
5959

60-
uiInterface.NotifyBlockTip(state, &index);
60+
uiInterface.NotifyBlockTip(state, index, verification_progress);
6161
if (m_stop_at_height && index.nHeight >= m_stop_at_height) {
6262
if (!m_shutdown_request()) {
6363
LogError("Failed to send shutdown signal after reaching stop height\n");

src/node/kernel_notifications.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class KernelNotifications : public kernel::Notifications
3535
KernelNotifications(const std::function<bool()>& shutdown_request, std::atomic<int>& exit_status, node::Warnings& warnings)
3636
: m_shutdown_request(shutdown_request), m_exit_status{exit_status}, m_warnings{warnings} {}
3737

38-
[[nodiscard]] kernel::InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) override EXCLUSIVE_LOCKS_REQUIRED(!m_tip_block_mutex);
38+
[[nodiscard]] kernel::InterruptResult blockTip(SynchronizationState state, CBlockIndex& index, double verification_progress) override EXCLUSIVE_LOCKS_REQUIRED(!m_tip_block_mutex);
3939

4040
void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) override;
4141

src/validation.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3557,7 +3557,11 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
35573557
m_chainman.m_options.signals->UpdatedBlockTip(pindexNewTip, pindexFork, still_in_ibd);
35583558
}
35593559

3560-
if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(GetSynchronizationState(still_in_ibd, m_chainman.m_blockman.m_blockfiles_indexed), *pindexNewTip))) {
3560+
if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(
3561+
/*state=*/GetSynchronizationState(still_in_ibd, m_chainman.m_blockman.m_blockfiles_indexed),
3562+
/*index=*/*pindexNewTip,
3563+
/*verification_progress=*/m_chainman.GuessVerificationProgress(pindexNewTip))))
3564+
{
35613565
// Just breaking and returning success for now. This could
35623566
// be changed to bubble up the kernel::Interrupted value to
35633567
// the caller so the caller could distinguish between
@@ -3790,7 +3794,10 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
37903794
// parameter indicating the source of the tip change so hooks can
37913795
// distinguish user-initiated invalidateblock changes from other
37923796
// changes.
3793-
(void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_blockfiles_indexed), *to_mark_failed->pprev);
3797+
(void)m_chainman.GetNotifications().blockTip(
3798+
/*state=*/GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_blockfiles_indexed),
3799+
/*index=*/*to_mark_failed->pprev,
3800+
/*verification_progress=*/WITH_LOCK(m_chainman.GetMutex(), return m_chainman.GuessVerificationProgress(to_mark_failed->pprev)));
37943801

37953802
// Fire ActiveTipChange now for the current chain tip to make sure clients are notified.
37963803
// ActivateBestChain may call this as well, but not necessarily.
@@ -4688,7 +4695,10 @@ bool Chainstate::LoadChainTip()
46884695
// Ensure KernelNotifications m_tip_block is set even if no new block arrives.
46894696
if (this->GetRole() != ChainstateRole::BACKGROUND) {
46904697
// Ignoring return value for now.
4691-
(void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(/*init=*/true, m_chainman.m_blockman.m_blockfiles_indexed), *pindex);
4698+
(void)m_chainman.GetNotifications().blockTip(
4699+
/*state=*/GetSynchronizationState(/*init=*/true, m_chainman.m_blockman.m_blockfiles_indexed),
4700+
/*index=*/*pindex,
4701+
/*verification_progress=*/m_chainman.GuessVerificationProgress(tip));
46924702
}
46934703

46944704
return true;
@@ -5572,10 +5582,9 @@ bool Chainstate::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
55725582
return ret;
55735583
}
55745584

5575-
//! Guess how far we are in the verification process at the given block index
5576-
//! require cs_main if pindex has not been validated yet (because m_chain_tx_count might be unset)
55775585
double ChainstateManager::GuessVerificationProgress(const CBlockIndex* pindex) const
55785586
{
5587+
AssertLockHeld(GetMutex());
55795588
const ChainTxData& data{GetParams().TxData()};
55805589
if (pindex == nullptr) {
55815590
return 0.0;
@@ -5586,14 +5595,25 @@ double ChainstateManager::GuessVerificationProgress(const CBlockIndex* pindex) c
55865595
return 0.0;
55875596
}
55885597

5589-
int64_t nNow = time(nullptr);
5598+
const int64_t nNow{TicksSinceEpoch<std::chrono::seconds>(NodeClock::now())};
5599+
const auto block_time{
5600+
(Assume(m_best_header) && std::abs(nNow - pindex->GetBlockTime()) <= Ticks<std::chrono::seconds>(2h) &&
5601+
Assume(m_best_header->nHeight >= pindex->nHeight)) ?
5602+
// When the header is known to be recent, switch to a height-based
5603+
// approach. This ensures the returned value is quantized when
5604+
// close to "1.0", because some users expect it to be. This also
5605+
// avoids relying too much on the exact miner-set timestamp, which
5606+
// may be off.
5607+
nNow - (m_best_header->nHeight - pindex->nHeight) * GetConsensus().nPowTargetSpacing :
5608+
pindex->GetBlockTime(),
5609+
};
55905610

55915611
double fTxTotal;
55925612

55935613
if (pindex->m_chain_tx_count <= data.tx_count) {
55945614
fTxTotal = data.tx_count + (nNow - data.nTime) * data.dTxRate;
55955615
} else {
5596-
fTxTotal = pindex->m_chain_tx_count + (nNow - pindex->GetBlockTime()) * data.dTxRate;
5616+
fTxTotal = pindex->m_chain_tx_count + (nNow - block_time) * data.dTxRate;
55975617
}
55985618

55995619
return std::min<double>(pindex->m_chain_tx_count / fTxTotal, 1.0);

0 commit comments

Comments
 (0)