diff --git a/src/avalanche.cpp b/src/avalanche.cpp --- a/src/avalanche.cpp +++ b/src/avalanche.cpp @@ -139,7 +139,7 @@ return false; } - isAccepted = chainActive.Contains(pindex); + isAccepted = ::ChainActive().Contains(pindex); } return vote_records.getWriteView() diff --git a/src/bench/duplicate_inputs.cpp b/src/bench/duplicate_inputs.cpp --- a/src/bench/duplicate_inputs.cpp +++ b/src/bench/duplicate_inputs.cpp @@ -50,14 +50,14 @@ LoadGenesisBlock(chainparams); CValidationState cvstate; ActivateBestChain(config, cvstate); - assert(::chainActive.Tip() != nullptr); + assert(::ChainActive().Tip() != nullptr); } CBlock block{}; CMutableTransaction coinbaseTx{}; CMutableTransaction naughtyTx{}; - CBlockIndex *pindexPrev = ::chainActive.Tip(); + CBlockIndex *pindexPrev = ::ChainActive().Tip(); assert(pindexPrev != nullptr); block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus()); diff --git a/src/index/base.cpp b/src/index/base.cpp --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -60,9 +60,9 @@ if (locator.IsNull()) { m_best_block_index = nullptr; } else { - m_best_block_index = FindForkInGlobalIndex(chainActive, locator); + m_best_block_index = FindForkInGlobalIndex(::ChainActive(), locator); } - m_synced = m_best_block_index.load() == chainActive.Tip(); + m_synced = m_best_block_index.load() == ::ChainActive().Tip(); return true; } @@ -71,15 +71,15 @@ AssertLockHeld(cs_main); if (!pindex_prev) { - return chainActive.Genesis(); + return ::ChainActive().Genesis(); } - const CBlockIndex *pindex = chainActive.Next(pindex_prev); + const CBlockIndex *pindex = ::ChainActive().Next(pindex_prev); if (pindex) { return pindex; } - return chainActive.Next(chainActive.FindFork(pindex_prev)); + return ::ChainActive().Next(::ChainActive().FindFork(pindex_prev)); } void BaseIndex::ThreadSync() { @@ -143,7 +143,7 @@ bool BaseIndex::WriteBestBlock(const CBlockIndex *block_index) { LOCK(cs_main); - if (!GetDB().WriteBestBlock(chainActive.GetLocator(block_index))) { + if (!GetDB().WriteBestBlock(::ChainActive().GetLocator(block_index))) { return error("%s: Failed to write locator to disk", __func__); } return true; @@ -239,9 +239,9 @@ { // Skip the queue-draining stuff if we know we're caught up with - // chainActive.Tip(). + // ::ChainActive().Tip(). LOCK(cs_main); - const CBlockIndex *chain_tip = chainActive.Tip(); + const CBlockIndex *chain_tip = ::ChainActive().Tip(); const CBlockIndex *best_block_index = m_best_block_index.load(); if (best_block_index->GetAncestor(chain_tip->nHeight) == chain_tip) { return true; diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp --- a/src/index/txindex.cpp +++ b/src/index/txindex.cpp @@ -238,7 +238,7 @@ // Attempt to migrate txindex from the old database to the new one. Even if // chain_tip is null, the node could be reindexing and we still want to // delete txindex records in the old database. - if (!m_db->MigrateData(*pblocktree, chainActive.GetLocator())) { + if (!m_db->MigrateData(*pblocktree, ::ChainActive().GetLocator())) { return false; } diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -701,7 +701,7 @@ true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, " - "setBlockIndexCandidates, chainActive and " + "setBlockIndexCandidates, ::ChainActive() and " "mapBlocksUnlinked occasionally. (default: %u)", defaultChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); @@ -2214,13 +2214,13 @@ bool is_coinsview_empty = fReset || fReindexChainState || pcoinsTip->GetBestBlock().IsNull(); if (!is_coinsview_empty) { - // LoadChainTip sets chainActive based on pcoinsTip's best - // block + // LoadChainTip sets ::ChainActive() based on pcoinsTip's + // best block if (!LoadChainTip(config)) { strLoadError = _("Error initializing block database"); break; } - assert(chainActive.Tip() != nullptr); + assert(::ChainActive().Tip() != nullptr); uiInterface.InitMessage(_("Verifying blocks...")); if (fHavePruned && @@ -2232,7 +2232,7 @@ MIN_BLOCKS_TO_KEEP); } - CBlockIndex *tip = chainActive.Tip(); + CBlockIndex *tip = ::ChainActive().Tip(); RPCNotifyBlockChange(true, tip); if (tip && tip->nTime > GetAdjustedTime() + MAX_FUTURE_BLOCK_TIME) { @@ -2342,7 +2342,7 @@ // Either install a handler to notify us when genesis activates, or set // fHaveGenesis directly. // No locking, as this happens before any background thread is started. - if (chainActive.Tip() == nullptr) { + if (::ChainActive().Tip() == nullptr) { uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait); } else { fHaveGenesis = true; @@ -2384,7 +2384,7 @@ { LOCK(cs_main); LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size()); - chain_active_height = chainActive.Height(); + chain_active_height = ::ChainActive().Height(); } LogPrintf("nBestHeight = %d\n", chain_active_height); diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp new file mode 100644 --- /dev/null +++ b/src/interfaces/chain.cpp @@ -0,0 +1,404 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace interfaces { +namespace { + + class LockImpl : public Chain::Lock { + Optional getHeight() override { + int height = ::ChainActive().Height(); + if (height >= 0) { + return height; + } + return nullopt; + } + Optional getBlockHeight(const uint256 &hash) override { + CBlockIndex *block = LookupBlockIndex(hash); + if (block && ::ChainActive().Contains(block)) { + return block->nHeight; + } + return nullopt; + } + int getBlockDepth(const uint256 &hash) override { + const Optional tip_height = getHeight(); + const Optional height = getBlockHeight(hash); + return tip_height && height ? *tip_height - *height + 1 : 0; + } + uint256 getBlockHash(int height) override { + CBlockIndex *block = ::ChainActive()[height]; + assert(block != nullptr); + return block->GetBlockHash(); + } + int64_t getBlockTime(int height) override { + CBlockIndex *block = ::ChainActive()[height]; + assert(block != nullptr); + return block->GetBlockTime(); + } + int64_t getBlockMedianTimePast(int height) override { + CBlockIndex *block = ::ChainActive()[height]; + assert(block != nullptr); + return block->GetMedianTimePast(); + } + bool haveBlockOnDisk(int height) override { + CBlockIndex *block = ::ChainActive()[height]; + return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && + block->nTx > 0; + } + Optional findFirstBlockWithTimeAndHeight(int64_t time, int height, + uint256 *hash) override { + CBlockIndex *block = + ::ChainActive().FindEarliestAtLeast(time, height); + if (block) { + if (hash) *hash = block->GetBlockHash(); + return block->nHeight; + } + return nullopt; + } + Optional findPruned(int start_height, + Optional stop_height) override { + if (::fPruneMode) { + CBlockIndex *block = stop_height ? ::ChainActive()[*stop_height] + : ::ChainActive().Tip(); + while (block && block->nHeight >= start_height) { + if ((block->nStatus & BLOCK_HAVE_DATA) == 0) { + return block->nHeight; + } + block = block->pprev; + } + } + return nullopt; + } + Optional findFork(const uint256 &hash, + Optional *height) override { + const CBlockIndex *block = LookupBlockIndex(hash); + const CBlockIndex *fork = + block ? ::ChainActive().FindFork(block) : nullptr; + if (height) { + if (block) { + *height = block->nHeight; + } else { + height->reset(); + } + } + if (fork) { + return fork->nHeight; + } + return nullopt; + } + CBlockLocator getTipLocator() override { + return ::ChainActive().GetLocator(); + } + Optional findLocatorFork(const CBlockLocator &locator) override { + LockAnnotation lock(::cs_main); + if (CBlockIndex *fork = + FindForkInGlobalIndex(::ChainActive(), locator)) { + return fork->nHeight; + } + return nullopt; + } + bool checkFinalTx(const CTransaction &tx) override { + LockAnnotation lock(::cs_main); + return CheckFinalTx(tx); + } + bool submitToMemoryPool(const CTransactionRef &tx, CAmount absurd_fee, + CValidationState &state) override { + LockAnnotation lock(::cs_main); + return AcceptToMemoryPool(::mempool, state, tx, + nullptr /* missing inputs */, + nullptr /* txn replaced */, + false /* bypass limits */, absurd_fee); + } + }; + + class LockingStateImpl : public LockImpl, + public UniqueLock { + using UniqueLock::UniqueLock; + }; + + class NotificationsHandlerImpl : public Handler, CValidationInterface { + public: + explicit NotificationsHandlerImpl(Chain &chain, + Chain::Notifications ¬ifications) + : m_chain(chain), m_notifications(¬ifications) { + RegisterValidationInterface(this); + } + ~NotificationsHandlerImpl() override { disconnect(); } + void disconnect() override { + if (m_notifications) { + m_notifications = nullptr; + UnregisterValidationInterface(this); + } + } + void TransactionAddedToMempool(const CTransactionRef &tx) override { + m_notifications->TransactionAddedToMempool(tx); + } + void TransactionRemovedFromMempool(const CTransactionRef &tx) override { + m_notifications->TransactionRemovedFromMempool(tx); + } + void BlockConnected( + const std::shared_ptr &block, + const CBlockIndex *index, + const std::vector &tx_conflicted) override { + m_notifications->BlockConnected(*block, tx_conflicted); + } + void + BlockDisconnected(const std::shared_ptr &block) override { + m_notifications->BlockDisconnected(*block); + } + void UpdatedBlockTip(const CBlockIndex *index, + const CBlockIndex *fork_index, + bool is_ibd) override { + m_notifications->UpdatedBlockTip(); + } + void ChainStateFlushed(const CBlockLocator &locator) override { + m_notifications->ChainStateFlushed(locator); + } + Chain &m_chain; + Chain::Notifications *m_notifications; + }; + + class RpcHandlerImpl : public Handler { + public: + RpcHandlerImpl(const CRPCCommand &command) + : m_command(command), m_wrapped_command(&command) { + m_command.actor = [this](const JSONRPCRequest &request, + UniValue &result, bool last_handler) { + if (!m_wrapped_command) return false; + try { + return m_wrapped_command->actor(request, result, + last_handler); + } catch (const UniValue &e) { + // If this is not the last handler and a wallet not found + // exception was thrown, return false so the next handler + // can try to handle the request. Otherwise, reraise the + // exception. + if (!last_handler) { + const UniValue &code = e["code"]; + if (code.isNum() && + code.get_int() == RPC_WALLET_NOT_FOUND) { + return false; + } + } + throw; + } + }; + ::tableRPC.appendCommand(m_command.name, &m_command); + } + + void disconnect() override final { + if (m_wrapped_command) { + m_wrapped_command = nullptr; + ::tableRPC.removeCommand(m_command.name, &m_command); + } + } + + ~RpcHandlerImpl() override { disconnect(); } + + CRPCCommand m_command; + const CRPCCommand *m_wrapped_command; + }; + + class ChainImpl : public Chain { + public: + std::unique_ptr lock(bool try_lock) override { + auto result = MakeUnique( + ::cs_main, "cs_main", __FILE__, __LINE__, try_lock); + if (try_lock && result && !*result) return {}; + // std::move necessary on some compilers due to conversion from + // LockingStateImpl to Lock pointer + return std::move(result); + } + std::unique_ptr assumeLocked() override { + return MakeUnique(); + } + bool findBlock(const uint256 &hash, CBlock *block, int64_t *time, + int64_t *time_max) override { + CBlockIndex *index; + { + LOCK(cs_main); + index = LookupBlockIndex(hash); + if (!index) { + return false; + } + if (time) { + *time = index->GetBlockTime(); + } + if (time_max) { + *time_max = index->GetBlockTimeMax(); + } + } + if (block && + !ReadBlockFromDisk(*block, index, Params().GetConsensus())) { + block->SetNull(); + } + return true; + } + void findCoins(std::map &coins) override { + return FindCoins(coins); + } + double guessVerificationProgress(const uint256 &block_hash) override { + LOCK(cs_main); + return GuessVerificationProgress(Params().TxData(), + LookupBlockIndex(block_hash)); + } + RBFTransactionState isRBFOptIn(const CTransaction &tx) override { + LOCK(::mempool.cs); + return IsRBFOptIn(tx, ::mempool); + } + bool hasDescendantsInMempool(const uint256 &txid) override { + LOCK(::mempool.cs); + auto it = ::mempool.GetIter(txid); + return it && (*it)->GetCountWithDescendants() > 1; + } + void relayTransaction(const uint256 &txid) override { + CInv inv(MSG_TX, txid); + g_connman->ForEachNode( + [&inv](CNode *node) { node->PushInventory(inv); }); + } + void getTransactionAncestry(const uint256 &txid, size_t &ancestors, + size_t &descendants) override { + ::mempool.GetTransactionAncestry(txid, ancestors, descendants); + } + bool checkChainLimits(const CTransactionRef &tx) override { + LockPoints lp; + CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp); + CTxMemPool::setEntries ancestors; + auto limit_ancestor_count = + gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); + auto limit_ancestor_size = + gArgs.GetArg("-limitancestorsize", + DEFAULT_ANCESTOR_SIZE_LIMIT) * + 1000; + auto limit_descendant_count = + gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT); + auto limit_descendant_size = + gArgs.GetArg("-limitdescendantsize", + DEFAULT_DESCENDANT_SIZE_LIMIT) * + 1000; + std::string unused_error_string; + LOCK(::mempool.cs); + return ::mempool.CalculateMemPoolAncestors( + entry, ancestors, limit_ancestor_count, limit_ancestor_size, + limit_descendant_count, limit_descendant_size, + unused_error_string); + } + CFeeRate estimateSmartFee(int num_blocks, bool conservative, + FeeCalculation *calc) override { + return ::feeEstimator.estimateSmartFee(num_blocks, calc, + conservative); + } + unsigned int estimateMaxBlocks() override { + return ::feeEstimator.HighestTargetTracked( + FeeEstimateHorizon::LONG_HALFLIFE); + } + CFeeRate mempoolMinFee() override { + return ::mempool.GetMinFee( + gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * + 1000000); + } + CFeeRate relayMinFee() override { return ::minRelayTxFee; } + CFeeRate relayIncrementalFee() override { + return ::incrementalRelayFee; + } + 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 shutdownRequested() override { return ShutdownRequested(); } + int64_t getAdjustedTime() override { return GetAdjustedTime(); } + void initMessage(const std::string &message) override { + ::uiInterface.InitMessage(message); + } + void initWarning(const std::string &message) override { + InitWarning(message); + } + void initError(const std::string &message) override { + InitError(message); + } + void loadWallet(std::unique_ptr wallet) override { + ::uiInterface.LoadWallet(wallet); + } + void showProgress(const std::string &title, int progress, + bool resume_possible) override { + ::uiInterface.ShowProgress(title, progress, resume_possible); + } + std::unique_ptr + handleNotifications(Notifications ¬ifications) override { + return MakeUnique(*this, notifications); + } + void waitForNotificationsIfNewBlocksConnected( + const uint256 &old_tip) override { + if (!old_tip.IsNull()) { + LOCK(::cs_main); + if (old_tip == ::ChainActive().Tip()->GetBlockHash()) return; + CBlockIndex *block = LookupBlockIndex(old_tip); + if (block && block->GetAncestor(::ChainActive().Height()) == + ::ChainActive().Tip()) + return; + } + SyncWithValidationInterfaceQueue(); + } + std::unique_ptr + handleRpc(const CRPCCommand &command) override { + return MakeUnique(command); + } + bool rpcEnableDeprecated(const std::string &method) override { + return IsDeprecatedRPCEnabled(method); + } + void rpcRunLater(const std::string &name, std::function fn, + int64_t seconds) override { + RPCRunLater(name, std::move(fn), seconds); + } + int rpcSerializationFlags() override { return RPCSerializationFlags(); } + void requestMempoolTransactions(Notifications ¬ifications) override { + LOCK2(::cs_main, ::mempool.cs); + for (const CTxMemPoolEntry &entry : ::mempool.mapTx) { + notifications.TransactionAddedToMempool(entry.GetSharedTx()); + } + } + }; +} // namespace + +std::unique_ptr MakeChain() { + return MakeUnique(); +} + +} // namespace interfaces diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -187,12 +187,12 @@ } int getNumBlocks() override { LOCK(::cs_main); - return ::chainActive.Height(); + return ::ChainActive().Height(); } int64_t getLastBlockTime() override { LOCK(::cs_main); - if (::chainActive.Tip()) { - return ::chainActive.Tip()->GetBlockTime(); + if (::ChainActive().Tip()) { + return ::ChainActive().Tip()->GetBlockTime(); } // Genesis block's time of current network return Params().GenesisBlock().GetBlockTime(); @@ -201,7 +201,7 @@ const CBlockIndex *tip; { LOCK(::cs_main); - tip = ::chainActive.Tip(); + tip = ::ChainActive().Tip(); } return GuessVerificationProgress(Params().TxData(), tip); } diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -288,8 +288,8 @@ if (mi == m_wallet.mapWallet.end()) { return false; } - num_blocks = ::chainActive.Height(); - block_time = ::chainActive.Tip()->GetBlockTime(); + num_blocks = ::ChainActive().Height(); + block_time = ::ChainActive().Tip()->GetBlockTime(); tx_status = MakeWalletTxStatus(mi->second); return true; } @@ -300,7 +300,7 @@ LOCK2(::cs_main, m_wallet.cs_wallet); auto mi = m_wallet.mapWallet.find(txid); if (mi != m_wallet.mapWallet.end()) { - num_blocks = ::chainActive.Height(); + num_blocks = ::ChainActive().Height(); in_mempool = mi->second.InMempool(); order_form = mi->second.vOrderForm; tx_status = MakeWalletTxStatus(mi->second); @@ -335,7 +335,7 @@ return false; } balances = getBalances(); - num_blocks = ::chainActive.Height(); + num_blocks = ::ChainActive().Height(); return true; } Amount getBalance() override { return m_wallet.GetBalance(); } diff --git a/src/miner.cpp b/src/miner.cpp --- a/src/miner.cpp +++ b/src/miner.cpp @@ -136,7 +136,7 @@ pblocktemplate->entries.emplace_back(CTransactionRef(), -SATOSHI, -1); LOCK2(cs_main, mempool->cs); - CBlockIndex *pindexPrev = chainActive.Tip(); + CBlockIndex *pindexPrev = ::ChainActive().Tip(); assert(pindexPrev != nullptr); nHeight = pindexPrev->nHeight + 1; diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -707,7 +707,7 @@ static bool CanDirectFetch(const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { - return chainActive.Tip()->GetBlockTime() > + return ::ChainActive().Tip()->GetBlockTime() > GetAdjustedTime() - consensusParams.nPowTargetSpacing * 20; } @@ -746,7 +746,7 @@ if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < - chainActive.Tip()->nChainWork || + ::ChainActive().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < nMinimumChainWork) { // This peer has nothing interesting. return; @@ -755,8 +755,8 @@ if (state->pindexLastCommonBlock == nullptr) { // Bootstrap quickly by guessing a parent of our best tip is the forking // point. Guessing wrong in either direction is not a problem. - state->pindexLastCommonBlock = chainActive[std::min( - state->pindexBestKnownBlock->nHeight, chainActive.Height())]; + state->pindexLastCommonBlock = ::ChainActive()[std::min( + state->pindexBestKnownBlock->nHeight, ::ChainActive().Height())]; } // If the peer reorganized, our previous pindexLastCommonBlock may not be an @@ -803,7 +803,7 @@ // We consider the chain that this peer is on invalid. return; } - if (pindex->nStatus.hasData() || chainActive.Contains(pindex)) { + if (pindex->nStatus.hasData() || ::ChainActive().Contains(pindex)) { if (pindex->HaveTxsDownloaded()) { state->pindexLastCommonBlock = pindex; } @@ -1179,7 +1179,7 @@ const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); - if (chainActive.Contains(pindex)) { + if (::ChainActive().Contains(pindex)) { return true; } return pindex->IsValid(BlockValidity::SCRIPTS) && @@ -1321,7 +1321,7 @@ /** * Update our best height and announce any block hashes which weren't previously - * in chainActive to our peers. + * in ::ChainActive() to our peers. */ void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, @@ -1416,13 +1416,14 @@ switch (inv.type) { case MSG_TX: { assert(recentRejects); - if (chainActive.Tip()->GetBlockHash() != + if (::ChainActive().Tip()->GetBlockHash() != hashRecentRejectsChainTip) { // If the chain tip has changed previously rejected transactions // might be now valid, e.g. due to a nLockTime'd tx becoming // valid, or a double-spend. Reset the rejects filter and give // those txs a second chance. - hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash(); + hashRecentRejectsChainTip = + ::ChainActive().Tip()->GetBlockHash(); recentRejects->reset(); } @@ -1577,7 +1578,7 @@ ((((pfrom->GetLocalServices() & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom->GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && - (chainActive.Tip()->nHeight - pindex->nHeight > + (::ChainActive().Tip()->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2)))) { LogPrint(BCLog::NET, "Ignore block request below NODE_NETWORK_LIMITED " @@ -1646,7 +1647,7 @@ int nSendFlags = 0; if (CanDirectFetch(consensusParams) && pindex->nHeight >= - chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) { + ::ChainActive().Height() - MAX_CMPCTBLOCK_DEPTH) { CBlockHeaderAndShortTxIDs cmpctblock(*pblock); connman->PushMessage( pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, @@ -1665,7 +1666,8 @@ // want it right after the last block so they don't wait for other // stuff first. std::vector vInv; - vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash())); + vInv.push_back( + CInv(MSG_BLOCK, ::ChainActive().Tip()->GetBlockHash())); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::INV, vInv)); pfrom->hashContinue = BlockHash(); } @@ -1805,9 +1807,10 @@ nCount < MAX_BLOCKS_TO_ANNOUNCE) { nodestate->nUnconnectingHeaders++; connman->PushMessage( - pfrom, msgMaker.Make(NetMsgType::GETHEADERS, - chainActive.GetLocator(pindexBestHeader), - uint256())); + pfrom, + msgMaker.Make(NetMsgType::GETHEADERS, + ::ChainActive().GetLocator(pindexBestHeader), + uint256())); LogPrint( BCLog::NET, "received header %s: missing prev block %s, sending getheaders " @@ -1912,35 +1915,36 @@ // still present, however, as belt-and-suspenders. if (received_new_header && - pindexLast->nChainWork > chainActive.Tip()->nChainWork) { + pindexLast->nChainWork > ::ChainActive().Tip()->nChainWork) { nodestate->m_last_block_announcement = GetTime(); } if (nCount == MAX_HEADERS_RESULTS) { // Headers message had its maximum size; the peer may have more // headers. - // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip - // or pindexBestHeader, continue from there instead. + // TODO: optimize: if pindexLast is an ancestor of + // ::ChainActive().Tip or pindexBestHeader, continue from there + // instead. LogPrint( BCLog::NET, "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->GetId(), pfrom->nStartingHeight); connman->PushMessage( - pfrom, - msgMaker.Make(NetMsgType::GETHEADERS, - chainActive.GetLocator(pindexLast), uint256())); + pfrom, msgMaker.Make(NetMsgType::GETHEADERS, + ::ChainActive().GetLocator(pindexLast), + uint256())); } bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus()); // If this set of headers is valid and ends in a block with at least as // much work as our tip, download as much as possible. if (fCanDirectFetch && pindexLast->IsValid(BlockValidity::TREE) && - chainActive.Tip()->nChainWork <= pindexLast->nChainWork) { + ::ChainActive().Tip()->nChainWork <= pindexLast->nChainWork) { std::vector vToFetch; const CBlockIndex *pindexWalk = pindexLast; // Calculate all the blocks we'd need to switch to pindexLast, up to // a limit. - while (pindexWalk && !chainActive.Contains(pindexWalk) && + while (pindexWalk && !::ChainActive().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { if (!pindexWalk->nStatus.hasData() && !mapBlocksInFlight.count(pindexWalk->GetBlockHash())) { @@ -1953,7 +1957,7 @@ // very large reorg at a time we think we're close to caught up to // the main chain -- this shouldn't really happen. Bail out on the // direct fetch and rely on parallel download instead. - if (!chainActive.Contains(pindexWalk)) { + if (!::ChainActive().Contains(pindexWalk)) { LogPrint( BCLog::NET, "Large reorg, won't direct fetch to %s (%d)\n", pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); @@ -2005,7 +2009,7 @@ // us sync -- disconnect if using an outbound slot (unless // whitelisted or addnode). // Note: We compare their tip to nMinimumChainWork (rather than - // chainActive.Tip()) because we won't start block download + // ::ChainActive().Tip()) because we won't start block download // until we have a headers chain that has at least // nMinimumChainWork, even if a peer has a chain past our tip, // as an anti-DoS measure. @@ -2025,7 +2029,7 @@ if (g_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= - chainActive.Tip()->nChainWork && + ::ChainActive().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) { LogPrint(BCLog::NET, "Protecting outbound peer=%d from eviction\n", @@ -2490,10 +2494,10 @@ // getheaders response here. When we receive the headers, we // will then ask for the blocks we need. connman->PushMessage( - pfrom, - msgMaker.Make(NetMsgType::GETHEADERS, - chainActive.GetLocator(pindexBestHeader), - hash)); + pfrom, msgMaker.Make( + NetMsgType::GETHEADERS, + ::ChainActive().GetLocator(pindexBestHeader), + hash)); LogPrint(BCLog::NET, "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, hash.ToString(), pfrom->GetId()); @@ -2573,18 +2577,19 @@ LOCK(cs_main); // Find the last block the caller has in the main chain - const CBlockIndex *pindex = FindForkInGlobalIndex(chainActive, locator); + const CBlockIndex *pindex = + FindForkInGlobalIndex(::ChainActive(), locator); // Send the rest of the chain if (pindex) { - pindex = chainActive.Next(pindex); + pindex = ::ChainActive().Next(pindex); } int nLimit = 500; LogPrint(BCLog::NET, "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->GetId()); - for (; pindex; pindex = chainActive.Next(pindex)) { + for (; pindex; pindex = ::ChainActive().Next(pindex)) { if (pindex->GetBlockHash() == hashStop) { LogPrint(BCLog::NET, " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); @@ -2598,8 +2603,8 @@ 3600 / chainparams.GetConsensus().nPowTargetSpacing; if (fPruneMode && (!pindex->nStatus.hasData() || - pindex->nHeight <= - chainActive.Tip()->nHeight - nPrunedBlocksLikelyToHave)) { + pindex->nHeight <= ::ChainActive().Tip()->nHeight - + nPrunedBlocksLikelyToHave)) { LogPrint( BCLog::NET, " getblocks stopping, pruned or too old block at %d %s\n", @@ -2647,7 +2652,7 @@ return true; } - if (pindex->nHeight < chainActive.Height() - MAX_BLOCKTXN_DEPTH) { + if (pindex->nHeight < ::ChainActive().Height() - MAX_BLOCKTXN_DEPTH) { // If an older block is requested (should never happen in practice, // but can happen in tests) send a block response instead of a // blocktxn response. Sending a full block response instead of a @@ -2715,9 +2720,9 @@ } } else { // Find the last block the caller has in the main chain - pindex = FindForkInGlobalIndex(chainActive, locator); + pindex = FindForkInGlobalIndex(::ChainActive(), locator); if (pindex) { - pindex = chainActive.Next(pindex); + pindex = ::ChainActive().Next(pindex); } } @@ -2729,15 +2734,15 @@ (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), pfrom->GetId()); - for (; pindex; pindex = chainActive.Next(pindex)) { + for (; pindex; pindex = ::ChainActive().Next(pindex)) { vHeaders.push_back(pindex->GetBlockHeader()); if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) { break; } } - // pindex can be nullptr either if we sent chainActive.Tip() OR - // if our peer has chainActive.Tip() (and thus we are sending an empty - // headers message). In both cases it's safe to update + // pindex can be nullptr either if we sent ::ChainActive().Tip() OR + // if our peer has ::ChainActive().Tip() (and thus we are sending an + // empty headers message). In both cases it's safe to update // pindexBestHeaderSent to be our tip. // // It is important that we simply reset the BestHeaderSent value here, @@ -2747,7 +2752,8 @@ // without the new block. By resetting the BestHeaderSent, we ensure we // will re-announce the new block via headers (or compact blocks again) // in the SendMessages logic. - nodestate->pindexBestHeaderSent = pindex ? pindex : chainActive.Tip(); + nodestate->pindexBestHeaderSent = + pindex ? pindex : ::ChainActive().Tip(); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::HEADERS, vHeaders)); return true; @@ -2997,10 +3003,10 @@ // AcceptBlockHeader, request deeper headers if (!IsInitialBlockDownload()) { connman->PushMessage( - pfrom, - msgMaker.Make(NetMsgType::GETHEADERS, - chainActive.GetLocator(pindexBestHeader), - uint256())); + pfrom, msgMaker.Make( + NetMsgType::GETHEADERS, + ::ChainActive().GetLocator(pindexBestHeader), + uint256())); } return true; } @@ -3058,7 +3064,7 @@ // If this was a new header with more work than our tip, update the // peer's last block announcement time if (received_new_header && - pindex->nChainWork > chainActive.Tip()->nChainWork) { + pindex->nChainWork > ::ChainActive().Tip()->nChainWork) { nodestate->m_last_block_announcement = GetTime(); } @@ -3074,7 +3080,9 @@ } if (pindex->nChainWork <= - chainActive.Tip()->nChainWork || // We know something better + ::ChainActive() + .Tip() + ->nChainWork || // We know something better pindex->nTx != 0) { // We had this block at some point, but pruned it if (fAlreadyInFlight) { @@ -3098,7 +3106,7 @@ // We want to be a bit conservative just to be extra careful about // DoS possibilities in compact block processing... - if (pindex->nHeight <= chainActive.Height() + 2) { + if (pindex->nHeight <= ::ChainActive().Height() + 2) { if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) || (fAlreadyInFlight && @@ -3868,7 +3876,7 @@ // them elsewhere). if (state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= - chainActive.Tip()->nChainWork) { + ::ChainActive().Tip()->nChainWork) { if (state.m_chain_sync.m_timeout != 0) { state.m_chain_sync.m_timeout = 0; state.m_chain_sync.m_work_header = nullptr; @@ -3884,7 +3892,7 @@ // catch up to some earlier point where we checked against our tip. // Either way, set a new timeout based on current tip. state.m_chain_sync.m_timeout = time_in_seconds + CHAIN_SYNC_TIMEOUT; - state.m_chain_sync.m_work_header = chainActive.Tip(); + state.m_chain_sync.m_work_header = ::ChainActive().Tip(); state.m_chain_sync.m_sent_getheaders = false; } else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) { @@ -3918,7 +3926,7 @@ connman->PushMessage( pto, msgMaker.Make(NetMsgType::GETHEADERS, - chainActive.GetLocator( + ::ChainActive().GetLocator( state.m_chain_sync.m_work_header->pprev), uint256())); state.m_chain_sync.m_sent_getheaders = true; @@ -4158,7 +4166,7 @@ // Start block sync if (pindexBestHeader == nullptr) { - pindexBestHeader = chainActive.Tip(); + pindexBestHeader = ::ChainActive().Tip(); } // Download if this is a nice peer, or we have no nice peers and this one @@ -4196,9 +4204,9 @@ "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->GetId(), pto->nStartingHeight); connman->PushMessage( - pto, - msgMaker.Make(NetMsgType::GETHEADERS, - chainActive.GetLocator(pindexStart), uint256())); + pto, msgMaker.Make(NetMsgType::GETHEADERS, + ::ChainActive().GetLocator(pindexStart), + uint256())); } } @@ -4234,11 +4242,11 @@ bool fFoundStartingHeader = false; // Try to find first header that our peer doesn't have, and then // send all headers past that one. If we come across an headers that - // aren't on chainActive, give up. + // aren't on ::ChainActive(), give up. for (const BlockHash &hash : pto->vBlockHashesToAnnounce) { const CBlockIndex *pindex = LookupBlockIndex(hash); assert(pindex); - if (chainActive[pindex->nHeight] != pindex) { + if (::ChainActive()[pindex->nHeight] != pindex) { // Bail out if we reorged away from this block fRevertToInv = true; break; @@ -4346,11 +4354,11 @@ // Warn if we're announcing a block that is not on the main // chain. This should be very rare and could be optimized out. // Just log for now. - if (chainActive[pindex->nHeight] != pindex) { + if (::ChainActive()[pindex->nHeight] != pindex) { LogPrint(BCLog::NET, "Announcing block %s not on main chain (tip=%s)\n", hashToAnnounce.ToString(), - chainActive.Tip()->GetBlockHash().ToString()); + ::ChainActive().Tip()->GetBlockHash().ToString()); } // If the peer's chain has this block, don't inv it back. diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -126,7 +126,7 @@ LOCK(cs_main); WalletRescanReserver reserver(wallet.get()); reserver.reserve(); - wallet->ScanForWalletTransactions(chainActive.Genesis(), nullptr, + wallet->ScanForWalletTransactions(::ChainActive().Genesis(), nullptr, reserver, true); } wallet->SetBroadcastTransactions(true); diff --git a/src/rest.cpp b/src/rest.cpp --- a/src/rest.cpp +++ b/src/rest.cpp @@ -165,14 +165,14 @@ headers.reserve(count); { LOCK(cs_main); - tip = chainActive.Tip(); + tip = ::ChainActive().Tip(); const CBlockIndex *pindex = LookupBlockIndex(hash); - while (pindex != nullptr && chainActive.Contains(pindex)) { + while (pindex != nullptr && ::ChainActive().Contains(pindex)) { headers.push_back(pindex); if (headers.size() == size_t(count)) { break; } - pindex = chainActive.Next(pindex); + pindex = ::ChainActive().Next(pindex); } } @@ -234,7 +234,7 @@ CBlockIndex *tip = nullptr; { LOCK(cs_main); - tip = chainActive.Tip(); + tip = ::ChainActive().Tip(); pblockindex = LookupBlockIndex(hash); if (!pblockindex) { return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); @@ -593,8 +593,8 @@ // serialize data // use exact same output as mentioned in Bip64 CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); - ssGetUTXOResponse << chainActive.Height() - << chainActive.Tip()->GetBlockHash() << bitmap + ssGetUTXOResponse << ::ChainActive().Height() + << ::ChainActive().Tip()->GetBlockHash() << bitmap << outs; std::string ssGetUTXOResponseString = ssGetUTXOResponse.str(); @@ -605,8 +605,8 @@ case RetFormat::HEX: { CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); - ssGetUTXOResponse << chainActive.Height() - << chainActive.Tip()->GetBlockHash() << bitmap + ssGetUTXOResponse << ::ChainActive().Height() + << ::ChainActive().Tip()->GetBlockHash() << bitmap << outs; std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + @@ -622,9 +622,9 @@ // pack in some essentials // use more or less the same output as mentioned in Bip64 - objGetUTXOResponse.pushKV("chainHeight", chainActive.Height()); + objGetUTXOResponse.pushKV("chainHeight", ::ChainActive().Height()); objGetUTXOResponse.pushKV( - "chaintipHash", chainActive.Tip()->GetBlockHash().GetHex()); + "chaintipHash", ::ChainActive().Tip()->GetBlockHash().GetHex()); objGetUTXOResponse.pushKV("bitmap", bitmapStringRepresentation); UniValue utxos(UniValue::VARR); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -164,7 +164,7 @@ } LOCK(cs_main); - return chainActive.Height(); + return ::ChainActive().Height(); } static UniValue getbestblockhash(const Config &config, @@ -182,7 +182,7 @@ } LOCK(cs_main); - return chainActive.Tip()->GetBlockHash().GetHex(); + return ::ChainActive().Tip()->GetBlockHash().GetHex(); } UniValue getfinalizedblockhash(const Config &config, @@ -405,7 +405,7 @@ } LOCK(cs_main); - return GetDifficulty(chainActive.Tip()); + return GetDifficulty(::ChainActive().Tip()); } static std::string EntryDescriptionString() { @@ -757,11 +757,11 @@ LOCK(cs_main); int nHeight = request.params[0].get_int(); - if (nHeight < 0 || nHeight > chainActive.Height()) { + if (nHeight < 0 || nHeight > ::ChainActive().Height()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); } - CBlockIndex *pblockindex = chainActive[nHeight]; + CBlockIndex *pblockindex = ::ChainActive()[nHeight]; return pblockindex->GetBlockHash().GetHex(); } @@ -840,7 +840,7 @@ return strHex; } - return blockheaderToJSON(chainActive.Tip(), pblockindex); + return blockheaderToJSON(::ChainActive().Tip(), pblockindex); } static CBlock GetBlockChecked(const Config &config, @@ -959,7 +959,8 @@ return strHex; } - return blockToJSON(block, chainActive.Tip(), pblockindex, verbosity >= 2); + return blockToJSON(block, ::ChainActive().Tip(), pblockindex, + verbosity >= 2); } struct CCoinsStats { @@ -1073,7 +1074,7 @@ // Add a 2 hour buffer to include blocks which might have had old // timestamps CBlockIndex *pindex = - chainActive.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW); + ::ChainActive().FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW); if (!pindex) { throw JSONRPCError( RPC_INVALID_PARAMETER, @@ -1083,7 +1084,7 @@ } unsigned int height = (unsigned int)heightParam; - unsigned int chainHeight = (unsigned int)chainActive.Height(); + unsigned int chainHeight = (unsigned int)::ChainActive().Height(); if (chainHeight < config.GetChainParams().PruneAfterHeight()) { throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning."); @@ -1316,10 +1317,10 @@ LOCK(cs_main); - const CBlockIndex *tip = chainActive.Tip(); + const CBlockIndex *tip = ::ChainActive().Tip(); UniValue obj(UniValue::VOBJ); obj.pushKV("chain", config.GetChainParams().NetworkIDString()); - obj.pushKV("blocks", int(chainActive.Height())); + obj.pushKV("blocks", int(::ChainActive().Height())); obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1); obj.pushKV("bestblockhash", tip->GetBlockHash().GetHex()); obj.pushKV("difficulty", double(GetDifficulty(tip))); @@ -1411,14 +1412,13 @@ LOCK(cs_main); /** - * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which - * do not have another orphan building off of them. - * Algorithm: + * Idea: the set of chain tips is ::ChainActive().tip, plus orphan blocks + * which do not have another orphan building off of them. Algorithm: * - Make one pass through mapBlockIndex, picking out the orphan blocks, * and also storing a set of the orphan block's pprev pointers. * - Iterate through the orphan blocks. If the block isn't pointed to by * another orphan, it is a chain tip. - * - add chainActive.Tip() + * - add ::ChainActive().Tip() */ std::set setTips; std::set setOrphans; @@ -1426,7 +1426,7 @@ for (const std::pair &item : mapBlockIndex) { - if (!chainActive.Contains(item.second)) { + if (!::ChainActive().Contains(item.second)) { setOrphans.insert(item.second); setPrevs.insert(item.second->pprev); } @@ -1440,7 +1440,7 @@ } // Always report the currently active tip. - setTips.insert(chainActive.Tip()); + setTips.insert(::ChainActive().Tip()); /* Construct the output array. */ UniValue res(UniValue::VARR); @@ -1450,11 +1450,11 @@ obj.pushKV("hash", block->phashBlock->GetHex()); const int branchLen = - block->nHeight - chainActive.FindFork(block)->nHeight; + block->nHeight - ::ChainActive().FindFork(block)->nHeight; obj.pushKV("branchlen", branchLen); std::string status; - if (chainActive.Contains(block)) { + if (::ChainActive().Contains(block)) { // This block is part of the currently active chain. status = "active"; } else if (block->nStatus.isInvalid()) { @@ -1822,7 +1822,7 @@ if (request.params[1].isNull()) { LOCK(cs_main); - pindex = chainActive.Tip(); + pindex = ::ChainActive().Tip(); } else { BlockHash hash(uint256S(request.params[1].get_str())); LOCK(cs_main); @@ -1830,7 +1830,7 @@ if (!pindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); } - if (!chainActive.Contains(pindex)) { + if (!::ChainActive().Contains(pindex)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain"); } @@ -1984,7 +1984,7 @@ CBlockIndex *pindex; if (request.params[0].isNum()) { const int height = request.params[0].get_int(); - const int current_tip = chainActive.Height(); + const int current_tip = ::ChainActive().Height(); if (height < 0) { throw JSONRPCError( RPC_INVALID_PARAMETER, @@ -1997,7 +1997,7 @@ current_tip)); } - pindex = chainActive[height]; + pindex = ::ChainActive()[height]; } else { const std::string strHash = request.params[0].get_str(); const BlockHash hash(uint256S(strHash)); @@ -2005,7 +2005,7 @@ if (!pindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); } - if (!chainActive.Contains(pindex)) { + if (!::ChainActive().Contains(pindex)) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Block is not in chain %s", Params().NetworkIDString())); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -39,10 +39,10 @@ * nonnegative, compute the estimate at the time when a given block was found. */ static UniValue GetNetworkHashPS(int lookup, int height) { - CBlockIndex *pb = chainActive.Tip(); + CBlockIndex *pb = ::ChainActive().Tip(); - if (height >= 0 && height < chainActive.Height()) { - pb = chainActive[height]; + if (height >= 0 && height < ::ChainActive().Height()) { + pb = ::ChainActive()[height]; } if (pb == nullptr || !pb->nHeight) { @@ -122,7 +122,7 @@ { // Don't keep cs_main locked. LOCK(cs_main); - nHeight = chainActive.Height(); + nHeight = ::ChainActive().Height(); nHeightEnd = nHeight + nGenerate; } @@ -141,7 +141,7 @@ { LOCK(cs_main); - IncrementExtraNonce(pblock, chainActive.Tip(), + IncrementExtraNonce(pblock, ::ChainActive().Tip(), config.GetMaxBlockSize(), nExtraNonce); } @@ -250,10 +250,10 @@ LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.pushKV("blocks", int(chainActive.Height())); + obj.pushKV("blocks", int(::ChainActive().Height())); obj.pushKV("currentblocksize", uint64_t(nLastBlockSize)); obj.pushKV("currentblocktx", uint64_t(nLastBlockTx)); - obj.pushKV("difficulty", double(GetDifficulty(chainActive.Tip()))); + obj.pushKV("difficulty", double(GetDifficulty(::ChainActive().Tip()))); obj.pushKV("networkhashps", getnetworkhashps(config, request)); obj.pushKV("pooledtx", uint64_t(g_mempool.size())); obj.pushKV("chain", config.GetChainParams().NetworkIDString()); @@ -485,7 +485,7 @@ return "duplicate-inconclusive"; } - CBlockIndex *const pindexPrev = chainActive.Tip(); + CBlockIndex *const pindexPrev = ::ChainActive().Tip(); // TestBlockValidity only supports blocks built on the current Tip if (block.hashPrevBlock != pindexPrev->GetBlockHash()) { return "inconclusive-not-best-prevblk"; @@ -537,7 +537,7 @@ } else { // NOTE: Spec does not specify behaviour for non-string longpollid, // but this makes testing easier - hashWatchedChain = chainActive.Tip()->GetBlockHash(); + hashWatchedChain = ::ChainActive().Tip()->GetBlockHash(); nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } @@ -573,7 +573,7 @@ static CBlockIndex *pindexPrev; static int64_t nStart; static std::unique_ptr pblocktemplate; - if (pindexPrev != chainActive.Tip() || + if (pindexPrev != ::ChainActive().Tip() || (g_mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5)) { // Clear pindexPrev so future calls make a new block, despite any @@ -582,7 +582,7 @@ // Store the pindexBest used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = g_mempool.GetTransactionsUpdated(); - CBlockIndex *pindexPrevNew = chainActive.Tip(); + CBlockIndex *pindexPrevNew = ::ChainActive().Tip(); nStart = GetTime(); // Create new block @@ -653,7 +653,7 @@ result.pushKV("coinbaseaux", aux); result.pushKV("coinbasevalue", int64_t(pblock->vtx[0]->vout[0].nValue / SATOSHI)); - result.pushKV("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + + result.pushKV("longpollid", ::ChainActive().Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)); result.pushKV("target", hashTarget.GetHex()); result.pushKV("mintime", int64_t(pindexPrev->GetMedianTimePast()) + 1); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -51,9 +51,9 @@ entry.pushKV("blockhash", hashBlock.GetHex()); CBlockIndex *pindex = LookupBlockIndex(hashBlock); if (pindex) { - if (chainActive.Contains(pindex)) { + if (::ChainActive().Contains(pindex)) { entry.pushKV("confirmations", - 1 + chainActive.Height() - pindex->nHeight); + 1 + ::ChainActive().Height() - pindex->nHeight); entry.pushKV("time", pindex->GetBlockTime()); entry.pushKV("blocktime", pindex->GetBlockTime()); } else { @@ -194,7 +194,7 @@ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block hash not found"); } - in_active_chain = chainActive.Contains(blockindex); + in_active_chain = ::ChainActive().Contains(blockindex); } bool f_txindex_ready = false; @@ -306,7 +306,7 @@ for (const auto &txid : setTxIds) { const Coin &coin = AccessByTxid(*pcoinsTip, txid); if (!coin.IsSpent()) { - pblockindex = chainActive[coin.GetHeight()]; + pblockindex = ::ChainActive()[coin.GetHeight()]; break; } } @@ -394,7 +394,7 @@ LOCK(cs_main); const CBlockIndex *pindex = LookupBlockIndex(merkleBlock.header.GetHash()); - if (!pindex || !chainActive.Contains(pindex) || pindex->nTx == 0) { + if (!pindex || !::ChainActive().Contains(pindex) || pindex->nTx == 0) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain"); } diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp new file mode 100644 --- /dev/null +++ b/src/test/blockfilter_index_tests.cpp @@ -0,0 +1,321 @@ +// Copyright (c) 2017-2019 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include +#include +#include +#include