Skip to content

Commit 4ea4401

Browse files
committed
Merge #516: [0.17] Fix progress reporting issue
5b8c79a Fix progress reporting issue (Steven Roose) Pull request description: Based on #515 Reimplementation of Blockstream/liquid#6 Tree-SHA512: 292be614802d0ca74bc9a19080bce46812bc4d5c386ed01f87e74898830946276359100d404868dda8fd4b4087699a9be804370a8ad387c7d92f4a3f5572d0b0
2 parents efd6164 + 5b8c79a commit 4ea4401

File tree

7 files changed

+87
-27
lines changed

7 files changed

+87
-27
lines changed

src/interfaces/node.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class NodeImpl : public Node
179179
LOCK(::cs_main);
180180
tip = ::chainActive.Tip();
181181
}
182-
return GuessVerificationProgress(Params().TxData(), tip);
182+
return GuessVerificationProgress(tip, Params().GetConsensus().nPowTargetSpacing);
183183
}
184184
bool isInitialBlockDownload() override { return IsInitialBlockDownload(); }
185185
bool getReindex() override { return ::fReindex; }
@@ -266,15 +266,15 @@ class NodeImpl : public Node
266266
{
267267
return MakeHandler(::uiInterface.NotifyBlockTip_connect([fn](bool initial_download, const CBlockIndex* block) {
268268
fn(initial_download, block->nHeight, block->GetBlockTime(),
269-
GuessVerificationProgress(Params().TxData(), block));
269+
GuessVerificationProgress(block, Params().GetConsensus().nPowTargetSpacing));
270270
}));
271271
}
272272
std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
273273
{
274274
return MakeHandler(
275275
::uiInterface.NotifyHeaderTip_connect([fn](bool initial_download, const CBlockIndex* block) {
276276
fn(initial_download, block->nHeight, block->GetBlockTime(),
277-
GuessVerificationProgress(Params().TxData(), block));
277+
GuessVerificationProgress(block, Params().GetConsensus().nPowTargetSpacing));
278278
}));
279279
}
280280
};

src/rpc/blockchain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
12921292
obj.pushKV("difficulty", (double)GetDifficulty(chainActive.Tip()));
12931293
}
12941294
obj.pushKV("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast());
1295-
obj.pushKV("verificationprogress", GuessVerificationProgress(chainparams.TxData(), chainActive.Tip()));
1295+
obj.pushKV("verificationprogress", GuessVerificationProgress(chainActive.Tip(), chainparams.GetConsensus().nPowTargetSpacing));
12961296
obj.pushKV("initialblockdownload", IsInitialBlockDownload());
12971297
if (!g_signed_blocks) {
12981298
obj.pushKV("chainwork", chainActive.Tip()->nChainWork.GetHex());

src/validation.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,7 +2394,8 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar
23942394
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
23952395
(unsigned long)pindexNew->nChainTx,
23962396
FormatISO8601DateTime(pindexNew->GetBlockTime()),
2397-
GuessVerificationProgress(chainParams.TxData(), pindexNew), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
2397+
GuessVerificationProgress(pindexNew, chainParams.GetConsensus().nPowTargetSpacing),
2398+
pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
23982399
if (!warningMessages.empty())
23992400
LogPrintf(" warning='%s'", warningMessages); /* Continued */
24002401
LogPrintf("\n");
@@ -4203,10 +4204,10 @@ bool LoadChainTip(const CChainParams& chainparams)
42034204

42044205
g_chainstate.PruneBlockIndexCandidates();
42054206

4206-
LogPrintf("Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
4207+
LogPrintf("Loaded best chain: hashBestChain=%s height=%d date=%s progress=%.3f\n",
42074208
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
42084209
FormatISO8601DateTime(chainActive.Tip()->GetBlockTime()),
4209-
GuessVerificationProgress(chainparams.TxData(), chainActive.Tip()));
4210+
GuessVerificationProgress(chainActive.Tip(), chainparams.GetConsensus().nPowTargetSpacing));
42104211
return true;
42114212
}
42124213

@@ -5067,23 +5068,22 @@ bool DumpMempool(void)
50675068
return true;
50685069
}
50695070

5070-
//! Guess how far we are in the verification process at the given block index
5071-
//! require cs_main if pindex has not been validated yet (because nChainTx might be unset)
5072-
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pindex) {
5073-
if (pindex == nullptr)
5071+
//! Guess how far we are in the verification process at the given block index.
5072+
//! Since we have signed fixed-interval blocks, estimating progress is a very easy.
5073+
//! We can extrapolate the last block time to the current time to estimate how many more blocks
5074+
//! we expect.
5075+
double GuessVerificationProgress(const CBlockIndex* pindex, int64_t blockInterval) {
5076+
if (pindex == NULL || pindex->nHeight < 1) {
50745077
return 0.0;
5075-
5076-
int64_t nNow = time(nullptr);
5077-
5078-
double fTxTotal;
5079-
5080-
if (pindex->nChainTx <= data.nTxCount) {
5081-
fTxTotal = data.nTxCount + (nNow - data.nTime) * data.dTxRate;
5082-
} else {
5083-
fTxTotal = pindex->nChainTx + (nNow - pindex->GetBlockTime()) * data.dTxRate;
50845078
}
50855079

5086-
return pindex->nChainTx / fTxTotal;
5080+
int64_t nNow = GetTime();
5081+
int64_t moreBlocksExpected = (nNow - pindex->GetBlockTime()) / blockInterval;
5082+
double progress = (pindex->nHeight + 0.0) / (pindex->nHeight + moreBlocksExpected);
5083+
// Round to 3 digits to avoid 0.999999 when finished.
5084+
progress = ceil(progress * 1000.0) / 1000.0;
5085+
// Avoid higher than one if last block is newer than current time.
5086+
return std::min(1.0, progress);
50875087
}
50885088

50895089
class CMainCleanup

src/validation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams,
289289
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
290290

291291
/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */
292-
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex* pindex);
292+
double GuessVerificationProgress(const CBlockIndex* pindex, int64_t blockInterval);
293293

294294
/** Calculate the amount of disk space the block & undo files currently use */
295295
uint64_t CalculateCurrentUsage();

src/wallet/wallet.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,12 +1708,12 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
17081708
double progress_end;
17091709
{
17101710
LOCK(cs_main);
1711-
progress_begin = GuessVerificationProgress(chainParams.TxData(), pindex);
1711+
progress_begin = GuessVerificationProgress(pindex, chainParams.GetConsensus().nPowTargetSpacing);
17121712
if (pindexStop == nullptr) {
17131713
tip = chainActive.Tip();
1714-
progress_end = GuessVerificationProgress(chainParams.TxData(), tip);
1714+
progress_end = GuessVerificationProgress(tip, chainParams.GetConsensus().nPowTargetSpacing);
17151715
} else {
1716-
progress_end = GuessVerificationProgress(chainParams.TxData(), pindexStop);
1716+
progress_end = GuessVerificationProgress(pindexStop, chainParams.GetConsensus().nPowTargetSpacing);
17171717
}
17181718
}
17191719
double progress_current = progress_begin;
@@ -1748,11 +1748,11 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
17481748
{
17491749
LOCK(cs_main);
17501750
pindex = chainActive.Next(pindex);
1751-
progress_current = GuessVerificationProgress(chainParams.TxData(), pindex);
1751+
progress_current = GuessVerificationProgress(pindex, chainParams.GetConsensus().nPowTargetSpacing);
17521752
if (pindexStop == nullptr && tip != chainActive.Tip()) {
17531753
tip = chainActive.Tip();
17541754
// in case the tip has changed, update progress max
1755-
progress_end = GuessVerificationProgress(chainParams.TxData(), tip);
1755+
progress_end = GuessVerificationProgress(tip, chainParams.GetConsensus().nPowTargetSpacing);
17561756
}
17571757
}
17581758
}

test/functional/feature_progress.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2015-2016 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#
7+
# Test progress code
8+
#
9+
10+
import time
11+
12+
from test_framework.test_framework import BitcoinTestFramework
13+
from test_framework.util import (
14+
Decimal,
15+
)
16+
17+
def assert_close(f1, f2):
18+
assert(abs(Decimal(f1)-f2) < 0.1)
19+
20+
class ProgressTest(BitcoinTestFramework):
21+
def set_test_params(self):
22+
self.setup_clean_chain = True
23+
self.num_nodes = 2
24+
self.extra_args = [["-debug", "-con_npowtargetspacing=1", "-maxtimeadjustment=0"]] * self.num_nodes
25+
26+
def setup_network(self):
27+
self.setup_nodes()
28+
self.is_network_split = True
29+
self.starttime = int(time.time())
30+
31+
def setmocktime(self, ntime):
32+
for node in self.nodes:
33+
node.setmocktime(self.starttime + ntime)
34+
35+
def run_test(self):
36+
node1 = self.nodes[0]
37+
node2 = self.nodes[1]
38+
self.setmocktime(0)
39+
40+
blocks = []
41+
for i in range(10):
42+
self.setmocktime(i)
43+
blocks.extend(node1.generate(1))
44+
45+
self.setmocktime(19)
46+
assert_close(0.5, node1.getblockchaininfo()["verificationprogress"])
47+
48+
assert(node2.getblockchaininfo()["initialblockdownload"])
49+
50+
self.setmocktime(10)
51+
for i in range(10):
52+
node2.submitblock(node1.getblock(blocks[i], False))
53+
progress = node2.getblockchaininfo()["verificationprogress"]
54+
assert_close(i/10.0, progress)
55+
56+
assert(not node2.getblockchaininfo()["initialblockdownload"])
57+
58+
if __name__ == '__main__':
59+
ProgressTest().main()

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
'feature_default_asset_name.py',
7474
'feature_assetsdir.py',
7575
'feature_initial_reissuance_token.py',
76+
'feature_progress.py',
7677
# Longest test should go first, to favor running tests in parallel
7778
'wallet_hd.py',
7879
'wallet_backup.py',

0 commit comments

Comments
 (0)