Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0.17] Fix progress reporting issue #516

Merged
merged 1 commit into from
Mar 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/interfaces/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ class NodeImpl : public Node
LOCK(::cs_main);
tip = ::chainActive.Tip();
}
return GuessVerificationProgress(Params().TxData(), tip);
return GuessVerificationProgress(tip, Params().GetConsensus().nPowTargetSpacing);
}
bool isInitialBlockDownload() override { return IsInitialBlockDownload(); }
bool getReindex() override { return ::fReindex; }
Expand Down Expand Up @@ -266,15 +266,15 @@ class NodeImpl : public Node
{
return MakeHandler(::uiInterface.NotifyBlockTip_connect([fn](bool initial_download, const CBlockIndex* block) {
fn(initial_download, block->nHeight, block->GetBlockTime(),
GuessVerificationProgress(Params().TxData(), block));
GuessVerificationProgress(block, Params().GetConsensus().nPowTargetSpacing));
}));
}
std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
{
return MakeHandler(
::uiInterface.NotifyHeaderTip_connect([fn](bool initial_download, const CBlockIndex* block) {
fn(initial_download, block->nHeight, block->GetBlockTime(),
GuessVerificationProgress(Params().TxData(), block));
GuessVerificationProgress(block, Params().GetConsensus().nPowTargetSpacing));
}));
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1292,7 +1292,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
obj.pushKV("difficulty", (double)GetDifficulty(chainActive.Tip()));
}
obj.pushKV("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast());
obj.pushKV("verificationprogress", GuessVerificationProgress(chainparams.TxData(), chainActive.Tip()));
obj.pushKV("verificationprogress", GuessVerificationProgress(chainActive.Tip(), chainparams.GetConsensus().nPowTargetSpacing));
obj.pushKV("initialblockdownload", IsInitialBlockDownload());
if (!g_signed_blocks) {
obj.pushKV("chainwork", chainActive.Tip()->nChainWork.GetHex());
Expand Down
34 changes: 17 additions & 17 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2394,7 +2394,8 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
log(pindexNew->nChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx,
FormatISO8601DateTime(pindexNew->GetBlockTime()),
GuessVerificationProgress(chainParams.TxData(), pindexNew), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
GuessVerificationProgress(pindexNew, chainParams.GetConsensus().nPowTargetSpacing),
pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
if (!warningMessages.empty())
LogPrintf(" warning='%s'", warningMessages); /* Continued */
LogPrintf("\n");
Expand Down Expand Up @@ -4203,10 +4204,10 @@ bool LoadChainTip(const CChainParams& chainparams)

g_chainstate.PruneBlockIndexCandidates();

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

Expand Down Expand Up @@ -5067,23 +5068,22 @@ bool DumpMempool(void)
return true;
}

//! 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 nChainTx might be unset)
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pindex) {
if (pindex == nullptr)
//! Guess how far we are in the verification process at the given block index.
//! Since we have signed fixed-interval blocks, estimating progress is a very easy.
//! We can extrapolate the last block time to the current time to estimate how many more blocks
//! we expect.
double GuessVerificationProgress(const CBlockIndex* pindex, int64_t blockInterval) {
if (pindex == NULL || pindex->nHeight < 1) {
return 0.0;

int64_t nNow = time(nullptr);

double fTxTotal;

if (pindex->nChainTx <= data.nTxCount) {
fTxTotal = data.nTxCount + (nNow - data.nTime) * data.dTxRate;
} else {
fTxTotal = pindex->nChainTx + (nNow - pindex->GetBlockTime()) * data.dTxRate;
}

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

class CMainCleanup
Expand Down
2 changes: 1 addition & 1 deletion src/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams,
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);

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

/** Calculate the amount of disk space the block & undo files currently use */
uint64_t CalculateCurrentUsage();
Expand Down
10 changes: 5 additions & 5 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1708,12 +1708,12 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
double progress_end;
{
LOCK(cs_main);
progress_begin = GuessVerificationProgress(chainParams.TxData(), pindex);
progress_begin = GuessVerificationProgress(pindex, chainParams.GetConsensus().nPowTargetSpacing);
if (pindexStop == nullptr) {
tip = chainActive.Tip();
progress_end = GuessVerificationProgress(chainParams.TxData(), tip);
progress_end = GuessVerificationProgress(tip, chainParams.GetConsensus().nPowTargetSpacing);
} else {
progress_end = GuessVerificationProgress(chainParams.TxData(), pindexStop);
progress_end = GuessVerificationProgress(pindexStop, chainParams.GetConsensus().nPowTargetSpacing);
}
}
double progress_current = progress_begin;
Expand Down Expand Up @@ -1748,11 +1748,11 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
{
LOCK(cs_main);
pindex = chainActive.Next(pindex);
progress_current = GuessVerificationProgress(chainParams.TxData(), pindex);
progress_current = GuessVerificationProgress(pindex, chainParams.GetConsensus().nPowTargetSpacing);
if (pindexStop == nullptr && tip != chainActive.Tip()) {
tip = chainActive.Tip();
// in case the tip has changed, update progress max
progress_end = GuessVerificationProgress(chainParams.TxData(), tip);
progress_end = GuessVerificationProgress(tip, chainParams.GetConsensus().nPowTargetSpacing);
}
}
}
Expand Down
59 changes: 59 additions & 0 deletions test/functional/feature_progress.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

#
# Test progress code
#

import time

from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
Decimal,
)

def assert_close(f1, f2):
assert(abs(Decimal(f1)-f2) < 0.1)

class ProgressTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
self.extra_args = [["-debug", "-con_npowtargetspacing=1", "-maxtimeadjustment=0"]] * self.num_nodes

def setup_network(self):
self.setup_nodes()
self.is_network_split = True
self.starttime = int(time.time())

def setmocktime(self, ntime):
for node in self.nodes:
node.setmocktime(self.starttime + ntime)

def run_test(self):
node1 = self.nodes[0]
node2 = self.nodes[1]
self.setmocktime(0)

blocks = []
for i in range(10):
self.setmocktime(i)
blocks.extend(node1.generate(1))

self.setmocktime(19)
assert_close(0.5, node1.getblockchaininfo()["verificationprogress"])

assert(node2.getblockchaininfo()["initialblockdownload"])

self.setmocktime(10)
for i in range(10):
node2.submitblock(node1.getblock(blocks[i], False))
progress = node2.getblockchaininfo()["verificationprogress"]
assert_close(i/10.0, progress)

assert(not node2.getblockchaininfo()["initialblockdownload"])

if __name__ == '__main__':
ProgressTest().main()
1 change: 1 addition & 0 deletions test/functional/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
'feature_default_asset_name.py',
'feature_assetsdir.py',
'feature_initial_reissuance_token.py',
'feature_progress.py',
# Longest test should go first, to favor running tests in parallel
'wallet_hd.py',
'wallet_backup.py',
Expand Down