diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1177,6 +1177,8 @@ ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); + CChainState &active_chainstate = chainman.ActiveChainstate(); + CChain &active_chain = active_chainstate.m_chain; int heightParam = request.params[0].get_int(); if (heightParam < 0) { @@ -1190,9 +1192,8 @@ if (heightParam > 1000000000) { // Add a 2 hour buffer to include blocks which might have had // old timestamps - CBlockIndex *pindex = - chainman.ActiveChain().FindEarliestAtLeast( - heightParam - TIMESTAMP_WINDOW, 0); + CBlockIndex *pindex = active_chain.FindEarliestAtLeast( + heightParam - TIMESTAMP_WINDOW, 0); if (!pindex) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the " @@ -1202,7 +1203,7 @@ } unsigned int height = (unsigned int)heightParam; - unsigned int chainHeight = (unsigned int)chainman.ActiveHeight(); + unsigned int chainHeight = (unsigned int)active_chain.Height(); if (chainHeight < config.GetChainParams().PruneAfterHeight()) { throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning."); @@ -1217,8 +1218,8 @@ height = chainHeight - MIN_BLOCKS_TO_KEEP; } - PruneBlockFilesManual(chainman.ActiveChainstate(), height); - const CBlockIndex *block = chainman.ActiveTip(); + PruneBlockFilesManual(active_chainstate, height); + const CBlockIndex *block = active_chain.Tip(); CHECK_NONFATAL(block); while (block->pprev && (block->pprev->nStatus.hasData())) { block = block->pprev; @@ -1650,8 +1651,9 @@ ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); + CChainState &active_chainstate = chainman.ActiveChainstate(); - const CBlockIndex *tip = chainman.ActiveTip(); + const CBlockIndex *tip = active_chainstate.m_chain.Tip(); CHECK_NONFATAL(tip); const int height = tip->nHeight; @@ -1666,7 +1668,7 @@ obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip)); obj.pushKV("initialblockdownload", - chainman.ActiveChainstate().IsInitialBlockDownload()); + active_chainstate.IsInitialBlockDownload()); obj.pushKV("chainwork", tip->nChainWork.GetHex()); obj.pushKV("size_on_disk", CalculateCurrentUsage()); obj.pushKV("pruned", fPruneMode); @@ -1757,6 +1759,7 @@ const JSONRPCRequest &request) -> UniValue { ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); + CChain &active_chain = chainman.ActiveChain(); /** * Idea: The set of chain tips is the active chain tip, plus orphan @@ -1775,7 +1778,7 @@ for (const std::pair &item : chainman.BlockIndex()) { - if (!chainman.ActiveChain().Contains(item.second)) { + if (!active_chain.Contains(item.second)) { setOrphans.insert(item.second); setPrevs.insert(item.second->pprev); } @@ -1790,7 +1793,7 @@ } // Always report the currently active tip. - setTips.insert(chainman.ActiveChain().Tip()); + setTips.insert(active_chain.Tip()); /* Construct the output array. */ UniValue res(UniValue::VARR); @@ -1800,12 +1803,11 @@ obj.pushKV("hash", block->phashBlock->GetHex()); const int branchLen = - block->nHeight - - chainman.ActiveChain().FindFork(block)->nHeight; + block->nHeight - active_chain.FindFork(block)->nHeight; obj.pushKV("branchlen", branchLen); std::string status; - if (chainman.ActiveChain().Contains(block)) { + if (active_chain.Contains(block)) { // This block is part of the currently active chain. status = "active"; } else if (block->nStatus.isInvalid()) { @@ -2388,11 +2390,12 @@ const JSONRPCRequest &request) -> UniValue { ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); + CChain &active_chain = chainman.ActiveChain(); CBlockIndex *pindex; if (request.params[0].isNum()) { const int height = request.params[0].get_int(); - const int current_tip = chainman.ActiveHeight(); + const int current_tip = active_chain.Height(); if (height < 0) { throw JSONRPCError( RPC_INVALID_PARAMETER, @@ -2406,7 +2409,7 @@ height, current_tip)); } - pindex = chainman.ActiveChain()[height]; + pindex = active_chain[height]; } else { const BlockHash hash( ParseHashV(request.params[0], "hash_or_height")); @@ -2415,7 +2418,7 @@ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); } - if (!chainman.ActiveChain().Contains(pindex)) { + if (!active_chain.Contains(pindex)) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Block is not in chain %s", Params().NetworkIDString())); @@ -2873,11 +2876,13 @@ { ChainstateManager &chainman = EnsureChainman(node); LOCK(cs_main); - chainman.ActiveChainstate().ForceFlushStateToDisk(); + CChainState &active_chainstate = + chainman.ActiveChainstate(); + active_chainstate.ForceFlushStateToDisk(); pcursor = std::unique_ptr( - chainman.ActiveChainstate().CoinsDB().Cursor()); + active_chainstate.CoinsDB().Cursor()); CHECK_NONFATAL(pcursor); - tip = chainman.ActiveTip(); + tip = active_chainstate.m_chain.Tip(); CHECK_NONFATAL(tip); } bool res = FindScriptPubKey( diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -803,6 +803,8 @@ std::string strMode = "template"; UniValue lpval = NullUniValue; std::set setClientRules; + CChainState &active_chainstate = chainman.ActiveChainstate(); + CChain &active_chain = active_chainstate.m_chain; if (!request.params[0].isNull()) { const UniValue &oparam = request.params[0].get_obj(); const UniValue &modeval = find_value(oparam, "mode"); @@ -842,16 +844,15 @@ return "duplicate-inconclusive"; } - CBlockIndex *const pindexPrev = chainman.ActiveTip(); + CBlockIndex *const pindexPrev = active_chain.Tip(); // TestBlockValidity only supports blocks built on the // current Tip if (block.hashPrevBlock != pindexPrev->GetBlockHash()) { return "inconclusive-not-best-prevblk"; } BlockValidationState state; - TestBlockValidity(state, chainparams, - chainman.ActiveChainstate(), block, - pindexPrev, + TestBlockValidity(state, chainparams, active_chainstate, + block, pindexPrev, BlockValidationOptions(config) .withCheckPoW(false) .withCheckMerkleRoot(true)); @@ -874,7 +875,7 @@ "Bitcoin is not connected!"); } - if (chainman.ActiveChainstate().IsInitialBlockDownload()) { + if (active_chainstate.IsInitialBlockDownload()) { throw JSONRPCError( RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks..."); @@ -900,7 +901,7 @@ } else { // NOTE: Spec does not specify behaviour for non-string // longpollid, but this makes testing easier - hashWatchedChain = chainman.ActiveTip()->GetBlockHash(); + hashWatchedChain = active_chain.Tip()->GetBlockHash(); nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } @@ -939,7 +940,7 @@ static CBlockIndex *pindexPrev; static int64_t nStart; static std::unique_ptr pblocktemplate; - if (pindexPrev != chainman.ActiveTip() || + if (pindexPrev != active_chain.Tip() || (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5)) { // Clear pindexPrev so future calls make a new block, despite @@ -949,13 +950,13 @@ // Store the pindexBest used before CreateNewBlock, to avoid // races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex *pindexPrevNew = chainman.ActiveTip(); + CBlockIndex *pindexPrevNew = active_chain.Tip(); nStart = GetTime(); // Create new block CScript scriptDummy = CScript() << OP_TRUE; pblocktemplate = - BlockAssembler(config, chainman.ActiveChainstate(), mempool) + BlockAssembler(config, active_chainstate, mempool) .CreateNewBlock(scriptDummy); if (!pblocktemplate) { throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); @@ -1054,7 +1055,7 @@ result.pushKV("coinbasetxn", coinbasetxn); result.pushKV("coinbasevalue", int64_t(coinbasevalue / SATOSHI)); result.pushKV("longpollid", - chainman.ActiveTip()->GetBlockHash().GetHex() + + active_chain.Tip()->GetBlockHash().GetHex() + ToString(nTransactionsUpdatedLast)); result.pushKV("target", hashTarget.GetHex()); result.pushKV("mintime", diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -343,13 +343,15 @@ } } else { LOCK(cs_main); + CChainState &active_chainstate = chainman.ActiveChainstate(); // Loop through txids and try to find which block they're in. // Exit loop once a block is found. for (const auto &txid : setTxIds) { - const Coin &coin = AccessByTxid( - chainman.ActiveChainstate().CoinsTip(), txid); + const Coin &coin = + AccessByTxid(active_chainstate.CoinsTip(), txid); if (!coin.IsSpent()) { - pblockindex = chainman.ActiveChain()[coin.GetHeight()]; + pblockindex = + active_chainstate.m_chain[coin.GetHeight()]; break; } }