rpc: Round verificationprogress to exactly 1 for a recent tip
This requires a new lock annotation, but all relevant callers already held the lock.
This commit is contained in:
4 files changed
+23
-5
No files matched your search
@@ -326,7 +326,8 @@ public:
|
|||||||
}
|
}
|
||||||
double getVerificationProgress() override
|
double getVerificationProgress() override
|
||||||
{
|
{
|
||||||
return chainman().GuessVerificationProgress(WITH_LOCK(chainman().GetMutex(), return chainman().ActiveChain().Tip()));
|
LOCK(chainman().GetMutex());
|
||||||
|
return chainman().GuessVerificationProgress(chainman().ActiveTip());
|
||||||
}
|
}
|
||||||
bool isInitialBlockDownload() override
|
bool isInitialBlockDownload() override
|
||||||
{
|
{
|
||||||
@@ -409,6 +410,7 @@ public:
|
|||||||
std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
|
std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
|
||||||
{
|
{
|
||||||
return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn, this](SynchronizationState sync_state, const CBlockIndex* block) {
|
return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn, this](SynchronizationState sync_state, const CBlockIndex* block) {
|
||||||
|
LOCK(chainman().GetMutex());
|
||||||
fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
|
fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
|
||||||
chainman().GuessVerificationProgress(block));
|
chainman().GuessVerificationProgress(block));
|
||||||
}));
|
}));
|
||||||
|
|||||||
+13
-3
@@ -5558,10 +5558,9 @@ bool Chainstate::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
|
|||||||
return ret;
|
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
|
double ChainstateManager::GuessVerificationProgress(const CBlockIndex* pindex) const
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(GetMutex());
|
||||||
const ChainTxData& data{GetParams().TxData()};
|
const ChainTxData& data{GetParams().TxData()};
|
||||||
if (pindex == nullptr) {
|
if (pindex == nullptr) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
@@ -5573,13 +5572,24 @@ double ChainstateManager::GuessVerificationProgress(const CBlockIndex* pindex) c
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int64_t nNow{TicksSinceEpoch<std::chrono::seconds>(NodeClock::now())};
|
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;
|
double fTxTotal;
|
||||||
|
|
||||||
if (pindex->m_chain_tx_count <= data.tx_count) {
|
if (pindex->m_chain_tx_count <= data.tx_count) {
|
||||||
fTxTotal = data.tx_count + (nNow - data.nTime) * data.dTxRate;
|
fTxTotal = data.tx_count + (nNow - data.nTime) * data.dTxRate;
|
||||||
} else {
|
} 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);
|
return std::min<double>(pindex->m_chain_tx_count / fTxTotal, 1.0);
|
||||||
|
|||||||
+1
-1
@@ -1147,7 +1147,7 @@ public:
|
|||||||
bool IsInitialBlockDownload() const;
|
bool IsInitialBlockDownload() const;
|
||||||
|
|
||||||
/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */
|
/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */
|
||||||
double GuessVerificationProgress(const CBlockIndex* pindex) const;
|
double GuessVerificationProgress(const CBlockIndex* pindex) const EXCLUSIVE_LOCKS_REQUIRED(GetMutex());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import blocks from an external file
|
* Import blocks from an external file
|
||||||
|
|||||||
@@ -286,7 +286,13 @@ class BlockchainTest(BitcoinTestFramework):
|
|||||||
future = 2 * 60 * 60
|
future = 2 * 60 * 60
|
||||||
self.nodes[0].setmocktime(self.nodes[0].getblockchaininfo()["time"] + future + 1)
|
self.nodes[0].setmocktime(self.nodes[0].getblockchaininfo()["time"] + future + 1)
|
||||||
assert_greater_than(1, self.nodes[0].getblockchaininfo()["verificationprogress"])
|
assert_greater_than(1, self.nodes[0].getblockchaininfo()["verificationprogress"])
|
||||||
|
|
||||||
|
self.log.info("Check that verificationprogress is exactly 1 for a recent block tip")
|
||||||
self.nodes[0].setmocktime(self.nodes[0].getblockchaininfo()["time"] + future)
|
self.nodes[0].setmocktime(self.nodes[0].getblockchaininfo()["time"] + future)
|
||||||
|
assert_equal(1, self.nodes[0].getblockchaininfo()["verificationprogress"])
|
||||||
|
|
||||||
|
self.log.info("Check that verificationprogress is less than 1 as soon as a new header comes in")
|
||||||
|
self.nodes[0].submitheader(self.generateblock(self.nodes[0], output="raw(55)", transactions=[], submit=False, sync_fun=self.no_op)["hex"])
|
||||||
assert_greater_than(1, self.nodes[0].getblockchaininfo()["verificationprogress"])
|
assert_greater_than(1, self.nodes[0].getblockchaininfo()["verificationprogress"])
|
||||||
|
|
||||||
def _test_y2106(self):
|
def _test_y2106(self):
|
||||||
|
|||||||
Reference in new issue
Block a user