mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Fix progress reporting issue
Reimplementation of https://github.com/Blockstream/liquid/pull/6
This commit is contained in:
parent
e9f6e82bbf
commit
5b8c79ac9d
7 changed files with 87 additions and 27 deletions
|
|
@ -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; }
|
||||
|
|
@ -266,7 +266,7 @@ 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
|
||||
|
|
@ -274,7 +274,7 @@ class NodeImpl : public Node
|
|||
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));
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
59
test/functional/feature_progress.py
Executable file
59
test/functional/feature_progress.py
Executable file
|
|
@ -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()
|
||||
|
|
@ -73,6 +73,7 @@ BASE_SCRIPTS = [
|
|||
'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',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue