Skip to content

Commit 403e677

Browse files
committed
refactoring: IsInitialBlockDownload -> CChainState
We introduce CChainState.m_cached_finished_ibd because the static state it replaces would've been shared across all CChainState instances.
1 parent 3ccbc37 commit 403e677

File tree

7 files changed

+41
-29
lines changed

7 files changed

+41
-29
lines changed

src/interfaces/chain.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,8 @@ class ChainImpl : public Chain
321321
CFeeRate relayDustFee() override { return ::dustRelayFee; }
322322
bool getPruneMode() override { return ::fPruneMode; }
323323
bool p2pEnabled() override { return g_connman != nullptr; }
324-
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !IsInitialBlockDownload(); }
325-
bool isInitialBlockDownload() override { return IsInitialBlockDownload(); }
324+
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); }
325+
bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
326326
bool shutdownRequested() override { return ShutdownRequested(); }
327327
int64_t getAdjustedTime() override { return GetAdjustedTime(); }
328328
void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }

src/interfaces/node.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class NodeImpl : public Node
197197
}
198198
return GuessVerificationProgress(Params().TxData(), tip);
199199
}
200-
bool isInitialBlockDownload() override { return IsInitialBlockDownload(); }
200+
bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
201201
bool getReindex() override { return ::fReindex; }
202202
bool getImporting() override { return ::fImporting; }
203203
void setNetworkActive(bool active) override

src/net_processing.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationSta
12401240
// the tip yet so we have no way to check this directly here. Instead we
12411241
// just check that there are currently no other blocks in flight.
12421242
else if (state.IsValid() &&
1243-
!IsInitialBlockDownload() &&
1243+
!::ChainstateActive().IsInitialBlockDownload() &&
12441244
mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
12451245
if (it != mapBlockSource.end()) {
12461246
MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first, connman);
@@ -1728,7 +1728,7 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
17281728
}
17291729
// If we're in IBD, we want outbound peers that will serve us a useful
17301730
// chain. Disconnect peers that are on chains with insufficient work.
1731-
if (IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
1731+
if (::ChainstateActive().IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
17321732
// When nCount < MAX_HEADERS_RESULTS, we know we have no more
17331733
// headers to fetch from this peer.
17341734
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
@@ -1994,7 +1994,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
19941994
if (!pfrom->fInbound)
19951995
{
19961996
// Advertise our address
1997-
if (fListen && !IsInitialBlockDownload())
1997+
if (fListen && !::ChainstateActive().IsInitialBlockDownload())
19981998
{
19991999
CAddress addr = GetLocalAddress(&pfrom->addr, pfrom->GetLocalServices());
20002000
FastRandomContext insecure_rand;
@@ -2229,7 +2229,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
22292229
pfrom->AddInventoryKnown(inv);
22302230
if (fBlocksOnly) {
22312231
LogPrint(BCLog::NET, "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->GetId());
2232-
} else if (!fAlreadyHave && !fImporting && !fReindex && !IsInitialBlockDownload()) {
2232+
} else if (!fAlreadyHave && !fImporting && !fReindex && !::ChainstateActive().IsInitialBlockDownload()) {
22332233
RequestTx(State(pfrom->GetId()), inv.hash, nNow);
22342234
}
22352235
}
@@ -2387,7 +2387,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
23872387
}
23882388

23892389
LOCK(cs_main);
2390-
if (IsInitialBlockDownload() && !pfrom->fWhitelisted) {
2390+
if (::ChainstateActive().IsInitialBlockDownload() && !pfrom->fWhitelisted) {
23912391
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->GetId());
23922392
return true;
23932393
}
@@ -2609,7 +2609,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
26092609

26102610
if (!LookupBlockIndex(cmpctblock.header.hashPrevBlock)) {
26112611
// Doesn't connect (or is genesis), instead of DoSing in AcceptBlockHeader, request deeper headers
2612-
if (!IsInitialBlockDownload())
2612+
if (!::ChainstateActive().IsInitialBlockDownload())
26132613
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexBestHeader), uint256()));
26142614
return true;
26152615
}
@@ -3525,7 +3525,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
35253525

35263526
// Address refresh broadcast
35273527
int64_t nNow = GetTimeMicros();
3528-
if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
3528+
if (!::ChainstateActive().IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
35293529
AdvertiseLocal(pto);
35303530
pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
35313531
}
@@ -3926,7 +3926,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
39263926
// Message: getdata (blocks)
39273927
//
39283928
std::vector<CInv> vGetData;
3929-
if (!pto->fClient && ((fFetch && !pto->m_limited_node) || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
3929+
if (!pto->fClient && ((fFetch && !pto->m_limited_node) || !::ChainstateActive().IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
39303930
std::vector<const CBlockIndex*> vToDownload;
39313931
NodeId staller = -1;
39323932
FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams);

src/rpc/blockchain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,7 +1342,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
13421342
obj.pushKV("difficulty", (double)GetDifficulty(tip));
13431343
obj.pushKV("mediantime", (int64_t)tip->GetMedianTimePast());
13441344
obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
1345-
obj.pushKV("initialblockdownload", IsInitialBlockDownload());
1345+
obj.pushKV("initialblockdownload", ::ChainstateActive().IsInitialBlockDownload());
13461346
obj.pushKV("chainwork", tip->nChainWork.GetHex());
13471347
obj.pushKV("size_on_disk", CalculateCurrentUsage());
13481348
obj.pushKV("pruned", fPruneMode);

src/rpc/mining.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
442442
if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0)
443443
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!");
444444

445-
if (IsInitialBlockDownload())
445+
if (::ChainstateActive().IsInitialBlockDownload())
446446
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks...");
447447

448448
static unsigned int nTransactionsUpdatedLast;

src/validation.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
321321
static bool IsCurrentForFeeEstimation() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
322322
{
323323
AssertLockHeld(cs_main);
324-
if (IsInitialBlockDownload())
324+
if (::ChainstateActive().IsInitialBlockDownload())
325325
return false;
326326
if (::ChainActive().Tip()->GetBlockTime() < (GetTime() - MAX_FEE_ESTIMATION_TIP_AGE))
327327
return false;
@@ -1022,27 +1022,30 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
10221022
return nSubsidy;
10231023
}
10241024

1025-
bool IsInitialBlockDownload()
1025+
// Note that though this is marked const, we may end up modifying `m_cached_finished_ibd`, which
1026+
// is a performance-related implementation detail. This function must be marked
1027+
// `const` so that `CValidationInterface` clients (which are given a `const CChainState*`)
1028+
// can call it.
1029+
//
1030+
bool CChainState::IsInitialBlockDownload() const
10261031
{
1027-
// Once this function has returned false, it must remain false.
1028-
static std::atomic<bool> latchToFalse{false};
10291032
// Optimization: pre-test latch before taking the lock.
1030-
if (latchToFalse.load(std::memory_order_relaxed))
1033+
if (m_cached_finished_ibd.load(std::memory_order_relaxed))
10311034
return false;
10321035

10331036
LOCK(cs_main);
1034-
if (latchToFalse.load(std::memory_order_relaxed))
1037+
if (m_cached_finished_ibd.load(std::memory_order_relaxed))
10351038
return false;
10361039
if (fImporting || fReindex)
10371040
return true;
1038-
if (::ChainActive().Tip() == nullptr)
1041+
if (m_chain.Tip() == nullptr)
10391042
return true;
1040-
if (::ChainActive().Tip()->nChainWork < nMinimumChainWork)
1043+
if (m_chain.Tip()->nChainWork < nMinimumChainWork)
10411044
return true;
1042-
if (::ChainActive().Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
1045+
if (m_chain.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
10431046
return true;
10441047
LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
1045-
latchToFalse.store(true, std::memory_order_relaxed);
1048+
m_cached_finished_ibd.store(true, std::memory_order_relaxed);
10461049
return false;
10471050
}
10481051

@@ -1071,7 +1074,7 @@ static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
10711074
AssertLockHeld(cs_main);
10721075
// Before we get past initial download, we cannot reliably alert about forks
10731076
// (we assume we don't get stuck on a fork before finishing our initial sync)
1074-
if (IsInitialBlockDownload())
1077+
if (::ChainstateActive().IsInitialBlockDownload())
10751078
return;
10761079

10771080
// 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
21012104
}
21022105

21032106
std::string warningMessages;
2104-
if (!IsInitialBlockDownload())
2107+
if (!::ChainstateActive().IsInitialBlockDownload())
21052108
{
21062109
int nUpgraded = 0;
21072110
const CBlockIndex* pindex = pindexNew;
@@ -2492,7 +2495,7 @@ static void NotifyHeaderTip() LOCKS_EXCLUDED(cs_main) {
24922495

24932496
if (pindexHeader != pindexHeaderOld) {
24942497
fNotify = true;
2495-
fInitialBlockDownload = IsInitialBlockDownload();
2498+
fInitialBlockDownload = ::ChainstateActive().IsInitialBlockDownload();
24962499
pindexHeaderOld = pindexHeader;
24972500
}
24982501
}
@@ -3621,7 +3624,7 @@ static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfte
36213624
// To avoid excessive prune events negating the benefit of high dbcache
36223625
// values, we should not prune too rapidly.
36233626
// So when pruning in IBD, increase the buffer a bit to avoid a re-prune too soon.
3624-
if (IsInitialBlockDownload()) {
3627+
if (::ChainstateActive().IsInitialBlockDownload()) {
36253628
// Since this is only relevant during IBD, we use a fixed 10%
36263629
nBuffer += nPruneTarget / 10;
36273630
}

src/validation.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,6 @@ bool LoadChainTip(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_m
249249
void UnloadBlockIndex();
250250
/** Run an instance of the script checking thread */
251251
void ThreadScriptCheck(int worker_num);
252-
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
253-
bool IsInitialBlockDownload();
254252
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
255253
bool GetTransaction(const uint256& hash, CTransactionRef& tx, const Consensus::Params& params, uint256& hashBlock, const CBlockIndex* const blockIndex = nullptr);
256254
/**
@@ -503,6 +501,14 @@ class CChainState {
503501
*/
504502
CCriticalSection m_cs_chainstate;
505503

504+
/**
505+
* Whether this chainstate is undergoing initial block download.
506+
*
507+
* Mutable because we need to be able to mark IsInitialBlockDownload()
508+
* const, which latches this for caching purposes.
509+
*/
510+
mutable std::atomic<bool> m_cached_finished_ibd{false};
511+
506512
public:
507513
//! The current chain of blockheaders we consult and build on.
508514
//! @see CChain, CBlockIndex.
@@ -565,6 +571,9 @@ class CChainState {
565571

566572
void UnloadBlockIndex();
567573

574+
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
575+
bool IsInitialBlockDownload() const;
576+
568577
private:
569578
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);
570579
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);

0 commit comments

Comments
 (0)