refactoring: IsInitialBlockDownload -> CChainState
We introduce CChainState.m_cached_finished_ibd because the static state it replaces would've been shared across all CChainState instances.
This commit is contained in:
parent
3ccbc376dd
commit
403e677c9e
7 changed files with 41 additions and 29 deletions
|
@ -321,8 +321,8 @@ public:
|
|||
CFeeRate relayDustFee() override { return ::dustRelayFee; }
|
||||
bool getPruneMode() override { return ::fPruneMode; }
|
||||
bool p2pEnabled() override { return g_connman != nullptr; }
|
||||
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !IsInitialBlockDownload(); }
|
||||
bool isInitialBlockDownload() override { return IsInitialBlockDownload(); }
|
||||
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); }
|
||||
bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
|
||||
bool shutdownRequested() override { return ShutdownRequested(); }
|
||||
int64_t getAdjustedTime() override { return GetAdjustedTime(); }
|
||||
void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }
|
||||
|
|
|
@ -197,7 +197,7 @@ public:
|
|||
}
|
||||
return GuessVerificationProgress(Params().TxData(), tip);
|
||||
}
|
||||
bool isInitialBlockDownload() override { return IsInitialBlockDownload(); }
|
||||
bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
|
||||
bool getReindex() override { return ::fReindex; }
|
||||
bool getImporting() override { return ::fImporting; }
|
||||
void setNetworkActive(bool active) override
|
||||
|
|
|
@ -1240,7 +1240,7 @@ void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationSta
|
|||
// the tip yet so we have no way to check this directly here. Instead we
|
||||
// just check that there are currently no other blocks in flight.
|
||||
else if (state.IsValid() &&
|
||||
!IsInitialBlockDownload() &&
|
||||
!::ChainstateActive().IsInitialBlockDownload() &&
|
||||
mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
|
||||
if (it != mapBlockSource.end()) {
|
||||
MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first, connman);
|
||||
|
@ -1728,7 +1728,7 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
|
|||
}
|
||||
// If we're in IBD, we want outbound peers that will serve us a useful
|
||||
// chain. Disconnect peers that are on chains with insufficient work.
|
||||
if (IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
|
||||
if (::ChainstateActive().IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
|
||||
// When nCount < MAX_HEADERS_RESULTS, we know we have no more
|
||||
// headers to fetch from this peer.
|
||||
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
|
||||
|
@ -1994,7 +1994,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||
if (!pfrom->fInbound)
|
||||
{
|
||||
// Advertise our address
|
||||
if (fListen && !IsInitialBlockDownload())
|
||||
if (fListen && !::ChainstateActive().IsInitialBlockDownload())
|
||||
{
|
||||
CAddress addr = GetLocalAddress(&pfrom->addr, pfrom->GetLocalServices());
|
||||
FastRandomContext insecure_rand;
|
||||
|
@ -2229,7 +2229,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||
pfrom->AddInventoryKnown(inv);
|
||||
if (fBlocksOnly) {
|
||||
LogPrint(BCLog::NET, "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->GetId());
|
||||
} else if (!fAlreadyHave && !fImporting && !fReindex && !IsInitialBlockDownload()) {
|
||||
} else if (!fAlreadyHave && !fImporting && !fReindex && !::ChainstateActive().IsInitialBlockDownload()) {
|
||||
RequestTx(State(pfrom->GetId()), inv.hash, nNow);
|
||||
}
|
||||
}
|
||||
|
@ -2387,7 +2387,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
if (IsInitialBlockDownload() && !pfrom->fWhitelisted) {
|
||||
if (::ChainstateActive().IsInitialBlockDownload() && !pfrom->fWhitelisted) {
|
||||
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->GetId());
|
||||
return true;
|
||||
}
|
||||
|
@ -2609,7 +2609,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||
|
||||
if (!LookupBlockIndex(cmpctblock.header.hashPrevBlock)) {
|
||||
// Doesn't connect (or is genesis), instead of DoSing in AcceptBlockHeader, request deeper headers
|
||||
if (!IsInitialBlockDownload())
|
||||
if (!::ChainstateActive().IsInitialBlockDownload())
|
||||
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexBestHeader), uint256()));
|
||||
return true;
|
||||
}
|
||||
|
@ -3525,7 +3525,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
|
|||
|
||||
// Address refresh broadcast
|
||||
int64_t nNow = GetTimeMicros();
|
||||
if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
|
||||
if (!::ChainstateActive().IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
|
||||
AdvertiseLocal(pto);
|
||||
pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
|
||||
}
|
||||
|
@ -3926,7 +3926,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
|
|||
// Message: getdata (blocks)
|
||||
//
|
||||
std::vector<CInv> vGetData;
|
||||
if (!pto->fClient && ((fFetch && !pto->m_limited_node) || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
if (!pto->fClient && ((fFetch && !pto->m_limited_node) || !::ChainstateActive().IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
std::vector<const CBlockIndex*> vToDownload;
|
||||
NodeId staller = -1;
|
||||
FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams);
|
||||
|
|
|
@ -1342,7 +1342,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
|
|||
obj.pushKV("difficulty", (double)GetDifficulty(tip));
|
||||
obj.pushKV("mediantime", (int64_t)tip->GetMedianTimePast());
|
||||
obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
|
||||
obj.pushKV("initialblockdownload", IsInitialBlockDownload());
|
||||
obj.pushKV("initialblockdownload", ::ChainstateActive().IsInitialBlockDownload());
|
||||
obj.pushKV("chainwork", tip->nChainWork.GetHex());
|
||||
obj.pushKV("size_on_disk", CalculateCurrentUsage());
|
||||
obj.pushKV("pruned", fPruneMode);
|
||||
|
|
|
@ -442,7 +442,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
|||
if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0)
|
||||
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!");
|
||||
|
||||
if (IsInitialBlockDownload())
|
||||
if (::ChainstateActive().IsInitialBlockDownload())
|
||||
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks...");
|
||||
|
||||
static unsigned int nTransactionsUpdatedLast;
|
||||
|
|
|
@ -321,7 +321,7 @@ static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
|
|||
static bool IsCurrentForFeeEstimation() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
if (IsInitialBlockDownload())
|
||||
if (::ChainstateActive().IsInitialBlockDownload())
|
||||
return false;
|
||||
if (::ChainActive().Tip()->GetBlockTime() < (GetTime() - MAX_FEE_ESTIMATION_TIP_AGE))
|
||||
return false;
|
||||
|
@ -1022,27 +1022,30 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
|
|||
return nSubsidy;
|
||||
}
|
||||
|
||||
bool IsInitialBlockDownload()
|
||||
// Note that though this is marked const, we may end up modifying `m_cached_finished_ibd`, which
|
||||
// is a performance-related implementation detail. This function must be marked
|
||||
// `const` so that `CValidationInterface` clients (which are given a `const CChainState*`)
|
||||
// can call it.
|
||||
//
|
||||
bool CChainState::IsInitialBlockDownload() const
|
||||
{
|
||||
// Once this function has returned false, it must remain false.
|
||||
static std::atomic<bool> latchToFalse{false};
|
||||
// Optimization: pre-test latch before taking the lock.
|
||||
if (latchToFalse.load(std::memory_order_relaxed))
|
||||
if (m_cached_finished_ibd.load(std::memory_order_relaxed))
|
||||
return false;
|
||||
|
||||
LOCK(cs_main);
|
||||
if (latchToFalse.load(std::memory_order_relaxed))
|
||||
if (m_cached_finished_ibd.load(std::memory_order_relaxed))
|
||||
return false;
|
||||
if (fImporting || fReindex)
|
||||
return true;
|
||||
if (::ChainActive().Tip() == nullptr)
|
||||
if (m_chain.Tip() == nullptr)
|
||||
return true;
|
||||
if (::ChainActive().Tip()->nChainWork < nMinimumChainWork)
|
||||
if (m_chain.Tip()->nChainWork < nMinimumChainWork)
|
||||
return true;
|
||||
if (::ChainActive().Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
|
||||
if (m_chain.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
|
||||
return true;
|
||||
LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
|
||||
latchToFalse.store(true, std::memory_order_relaxed);
|
||||
m_cached_finished_ibd.store(true, std::memory_order_relaxed);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1071,7 +1074,7 @@ static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|||
AssertLockHeld(cs_main);
|
||||
// Before we get past initial download, we cannot reliably alert about forks
|
||||
// (we assume we don't get stuck on a fork before finishing our initial sync)
|
||||
if (IsInitialBlockDownload())
|
||||
if (::ChainstateActive().IsInitialBlockDownload())
|
||||
return;
|
||||
|
||||
// If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it)
|
||||
|
@ -2101,7 +2104,7 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar
|
|||
}
|
||||
|
||||
std::string warningMessages;
|
||||
if (!IsInitialBlockDownload())
|
||||
if (!::ChainstateActive().IsInitialBlockDownload())
|
||||
{
|
||||
int nUpgraded = 0;
|
||||
const CBlockIndex* pindex = pindexNew;
|
||||
|
@ -2492,7 +2495,7 @@ static void NotifyHeaderTip() LOCKS_EXCLUDED(cs_main) {
|
|||
|
||||
if (pindexHeader != pindexHeaderOld) {
|
||||
fNotify = true;
|
||||
fInitialBlockDownload = IsInitialBlockDownload();
|
||||
fInitialBlockDownload = ::ChainstateActive().IsInitialBlockDownload();
|
||||
pindexHeaderOld = pindexHeader;
|
||||
}
|
||||
}
|
||||
|
@ -3621,7 +3624,7 @@ static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfte
|
|||
// To avoid excessive prune events negating the benefit of high dbcache
|
||||
// values, we should not prune too rapidly.
|
||||
// So when pruning in IBD, increase the buffer a bit to avoid a re-prune too soon.
|
||||
if (IsInitialBlockDownload()) {
|
||||
if (::ChainstateActive().IsInitialBlockDownload()) {
|
||||
// Since this is only relevant during IBD, we use a fixed 10%
|
||||
nBuffer += nPruneTarget / 10;
|
||||
}
|
||||
|
|
|
@ -249,8 +249,6 @@ bool LoadChainTip(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_m
|
|||
void UnloadBlockIndex();
|
||||
/** Run an instance of the script checking thread */
|
||||
void ThreadScriptCheck(int worker_num);
|
||||
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
||||
bool IsInitialBlockDownload();
|
||||
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
|
||||
bool GetTransaction(const uint256& hash, CTransactionRef& tx, const Consensus::Params& params, uint256& hashBlock, const CBlockIndex* const blockIndex = nullptr);
|
||||
/**
|
||||
|
@ -503,6 +501,14 @@ private:
|
|||
*/
|
||||
CCriticalSection m_cs_chainstate;
|
||||
|
||||
/**
|
||||
* Whether this chainstate is undergoing initial block download.
|
||||
*
|
||||
* Mutable because we need to be able to mark IsInitialBlockDownload()
|
||||
* const, which latches this for caching purposes.
|
||||
*/
|
||||
mutable std::atomic<bool> m_cached_finished_ibd{false};
|
||||
|
||||
public:
|
||||
//! The current chain of blockheaders we consult and build on.
|
||||
//! @see CChain, CBlockIndex.
|
||||
|
@ -565,6 +571,9 @@ public:
|
|||
|
||||
void UnloadBlockIndex();
|
||||
|
||||
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
||||
bool IsInitialBlockDownload() const;
|
||||
|
||||
private:
|
||||
bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions &disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
|
Loading…
Reference in a new issue