diff --git a/src/budget/budgetmanager.cpp b/src/budget/budgetmanager.cpp index 678bb1fc1f59b..c6e3719161c3f 100644 --- a/src/budget/budgetmanager.cpp +++ b/src/budget/budgetmanager.cpp @@ -1677,13 +1677,10 @@ bool CheckCollateral(const uint256& nTxCollateralHash, const uint256& nExpectedH int nProposalHeight = 0; { LOCK(cs_main); - BlockMap::iterator mi = mapBlockIndex.find(nBlockHash); - if (mi != mapBlockIndex.end() && (*mi).second) { - CBlockIndex* pindex = (*mi).second; - if (chainActive.Contains(pindex)) { - nProposalHeight = pindex->nHeight; - nTime = pindex->nTime; - } + CBlockIndex* pindex = LookupBlockIndex(nBlockHash); + if (pindex && chainActive.Contains(pindex)) { + nProposalHeight = pindex->nHeight; + nTime = pindex->nTime; } } diff --git a/src/budget/finalizedbudget.cpp b/src/budget/finalizedbudget.cpp index da10e61c36fb7..52091a4fce817 100644 --- a/src/budget/finalizedbudget.cpp +++ b/src/budget/finalizedbudget.cpp @@ -311,8 +311,8 @@ bool CFinalizedBudget::IsPaidAlready(const uint256& nProposalHash, const uint256 // -> reject transaction so it gets paid to a masternode instead if (nBlockHash != nPaidBlockHash) { LOCK(cs_main); - auto it = mapBlockIndex.find(nPaidBlockHash); - return it != mapBlockIndex.end() && chainActive.Contains(it->second); + CBlockIndex* pindex = LookupBlockIndex(nPaidBlockHash); + return pindex && chainActive.Contains(pindex); } // Re-checking same block. Not a double payment. diff --git a/src/evo/specialtx_validation.cpp b/src/evo/specialtx_validation.cpp index 10890e0f170c7..f8188552f8601 100644 --- a/src/evo/specialtx_validation.cpp +++ b/src/evo/specialtx_validation.cpp @@ -442,11 +442,10 @@ bool VerifyLLMQCommitment(const llmq::CFinalCommitment& qfc, const CBlockIndex* if (pindexPrev) { // Get quorum index - auto it = mapBlockIndex.find(qfc.quorumHash); - if (it == mapBlockIndex.end()) { + CBlockIndex* pindexQuorum = LookupBlockIndex(qfc.quorumHash); + if (!pindexQuorum) { return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-hash-not-found"); } - const CBlockIndex* pindexQuorum = it->second; // Check height if (pindexQuorum->nHeight % params->dkgInterval != 0) { diff --git a/src/init.cpp b/src/init.cpp index 829f3f5be846a..1e5be6a3f14cf 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1508,8 +1508,9 @@ bool AppInitMain() // If the loaded chain has a wrong genesis, bail out immediately // (we're likely using a testnet datadir, or the other way around). - if (!mapBlockIndex.empty() && mapBlockIndex.count(consensus.hashGenesisBlock) == 0) + if (!mapBlockIndex.empty() && !LookupBlockIndex(consensus.hashGenesisBlock)) { return UIError(_("Incorrect or no genesis block found. Wrong datadir for network?")); + } // Check for changed -txindex state if (fTxIndex != gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { diff --git a/src/net_processing.cpp b/src/net_processing.cpp index bea373090fbcd..e59cf3e827558 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -223,9 +223,9 @@ struct CNodeState { fCurrentlyConnected = false; nMisbehavior = 0; fShouldBan = false; - pindexBestKnownBlock = NULL; + pindexBestKnownBlock = nullptr; hashLastUnknownBlock.SetNull(); - pindexLastCommonBlock = NULL; + pindexLastCommonBlock = nullptr; fSyncStarted = false; nStallingSince = 0; nBlocksInFlight = 0; @@ -310,7 +310,7 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const CBlockIndex* // Make sure it's not listed somewhere already. MarkBlockAsReceived(hash); - QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL}; + QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != nullptr}; nQueuedValidatedHeaders += newentry.fValidatedHeaders; std::list::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); state->nBlocksInFlight++; @@ -324,10 +324,10 @@ void ProcessBlockAvailability(NodeId nodeid) assert(state != nullptr); if (!state->hashLastUnknownBlock.IsNull()) { - BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock); - if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) { - if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) - state->pindexBestKnownBlock = itOld->second; + CBlockIndex* pindex = LookupBlockIndex(state->hashLastUnknownBlock); + if (pindex && pindex->nChainWork > 0) { + if (!state->pindexBestKnownBlock || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) + state->pindexBestKnownBlock = pindex; state->hashLastUnknownBlock.SetNull(); } } @@ -341,11 +341,11 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256& hash) ProcessBlockAvailability(nodeid); - BlockMap::iterator it = mapBlockIndex.find(hash); - if (it != mapBlockIndex.end() && it->second->nChainWork > 0) { + CBlockIndex* pindex = LookupBlockIndex(hash); + if (pindex && pindex->nChainWork > 0) { // An actually better block was announced. - if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) - state->pindexBestKnownBlock = it->second; + if (!state->pindexBestKnownBlock || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) + state->pindexBestKnownBlock = pindex; } else { // An unknown block was announced; just assume that the latest one is the best one. state->hashLastUnknownBlock = hash; @@ -366,12 +366,12 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vectorpindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) { + if (!state->pindexBestKnownBlock || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) { // This peer has nothing interesting. return; } - if (state->pindexLastCommonBlock == NULL) { + if (!state->pindexLastCommonBlock) { // 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())]; @@ -475,7 +475,7 @@ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) { LOCK(cs_main); CNodeState* state = State(nodeid); - if (state == NULL) + if (!state) return false; stats.nMisbehavior = state->nMisbehavior; stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1; @@ -637,9 +637,9 @@ static void CheckBlockSpam(NodeId nodeId, const uint256& hashBlock) nodestate = State(nodeId); if (!nodestate) { return; } - const auto it = mapBlockIndex.find(hashBlock); - if (it == mapBlockIndex.end()) { return; } - blockReceivedHeight = it->second->nHeight; + CBlockIndex* pindex = LookupBlockIndex(hashBlock); + if (!pindex) { return; } + blockReceivedHeight = pindex->nHeight; } nodestate->nodeBlocks.onBlockReceived(blockReceivedHeight); @@ -782,7 +782,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) } case MSG_BLOCK: - return mapBlockIndex.count(inv.hash); + return LookupBlockIndex(inv.hash) != nullptr; case MSG_TXLOCK_REQUEST: // deprecated return true; @@ -972,26 +972,26 @@ void static ProcessGetBlockData(CNode* pfrom, const CInv& inv, CConnman* connman CNetMsgMaker msgMaker(pfrom->GetSendVersion()); bool send = false; - BlockMap::iterator mi = mapBlockIndex.find(inv.hash); - if (mi != mapBlockIndex.end()) { - if (chainActive.Contains(mi->second)) { + CBlockIndex* pindex = LookupBlockIndex(inv.hash); + if (pindex) { + if (chainActive.Contains(pindex)) { send = true; } else { // To prevent fingerprinting attacks, only send blocks outside of the active // chain if they are valid, and no more than a max reorg depth than the best header // chain we know about. - send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && - (chainActive.Height() - mi->second->nHeight < gArgs.GetArg("-maxreorg", DEFAULT_MAX_REORG_DEPTH)); + send = pindex->IsValid(BLOCK_VALID_SCRIPTS) && pindexBestHeader && + (chainActive.Height() - pindex->nHeight < gArgs.GetArg("-maxreorg", DEFAULT_MAX_REORG_DEPTH)); if (!send) { LogPrint(BCLog::NET, "ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId()); } } } // Don't send not-validated blocks - if (send && (mi->second->nStatus & BLOCK_HAVE_DATA)) { + if (send && (pindex->nStatus & BLOCK_HAVE_DATA)) { // Send block from disk CBlock block; - if (!ReadBlockFromDisk(block, (*mi).second)) + if (!ReadBlockFromDisk(block, pindex)) assert(!"cannot load block from disk"); if (inv.type == MSG_BLOCK) connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::BLOCK, block)); @@ -1588,13 +1588,12 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR if (IsInitialBlockDownload()) return true; - CBlockIndex* pindex = NULL; + CBlockIndex* pindex = nullptr; if (locator.IsNull()) { // If locator is null, return the hashStop block - BlockMap::iterator mi = mapBlockIndex.find(hashStop); - if (mi == mapBlockIndex.end()) + CBlockIndex* pindex = LookupBlockIndex(hashStop); + if (!pindex) return true; - pindex = (*mi).second; } else { // Find the last block the caller has in the main chain pindex = FindForkInGlobalIndex(chainActive, locator); @@ -1789,10 +1788,10 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR // Nothing interesting. Stop asking this peers for more headers. return true; } - CBlockIndex* pindexLast = NULL; + CBlockIndex* pindexLast = nullptr; for (const CBlockHeader& header : headers) { CValidationState state; - if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) { + if (pindexLast && header.hashPrevBlock != pindexLast->GetBlockHash()) { Misbehaving(pfrom->GetId(), 20, "non-continuous headers sequence"); return false; } @@ -2188,7 +2187,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic& inter } catch (const std::exception& e) { PrintExceptionContinue(&e, "ProcessMessages()"); } catch (...) { - PrintExceptionContinue(NULL, "ProcessMessages()"); + PrintExceptionContinue(nullptr, "ProcessMessages()"); } if (!fRet) { @@ -2306,7 +2305,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto, std::atomic& interruptM } // Start block sync - if (pindexBestHeader == NULL) + if (!pindexBestHeader) pindexBestHeader = chainActive.Tip(); bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do. if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex && pto->CanRelay()) { diff --git a/src/rest.cpp b/src/rest.cpp index 61c0a0275ba99..e92f6d259ba05 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -131,8 +131,7 @@ static bool rest_headers(HTTPRequest* req, headers.reserve(count); { LOCK(cs_main); - BlockMap::const_iterator it = mapBlockIndex.find(hash); - const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : NULL; + CBlockIndex* pindex = LookupBlockIndex(hash); while (pindex != NULL && chainActive.Contains(pindex)) { headers.push_back(pindex); if (headers.size() == (unsigned long)count) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 84df7d7563e4b..c622ab32811cb 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -733,7 +733,7 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) stats.hashBlock = pcursor->GetBestBlock(); { LOCK(cs_main); - stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight; + stats.nHeight = LookupBlockIndex(stats.hashBlock)->nHeight; } ss << stats.hashBlock; uint256 prevkey; @@ -863,8 +863,7 @@ UniValue gettxout(const JSONRPCRequest& request) } } - BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); - CBlockIndex* pindex = it->second; + CBlockIndex* pindex = LookupBlockIndex(pcoinsTip->GetBestBlock()); assert(pindex != nullptr); ret.pushKV("bestblock", pindex->GetBlockHash().GetHex()); if (coin.nHeight == MEMPOOL_HEIGHT) { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 304b7d1ae4eb7..14f33e8ec0889 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -548,9 +548,8 @@ UniValue getblocktemplate(const JSONRPCRequest& request) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); uint256 hash = block.GetHash(); - BlockMap::iterator mi = mapBlockIndex.find(hash); - if (mi != mapBlockIndex.end()) { - CBlockIndex* pindex = mi->second; + CBlockIndex* pindex = LookupBlockIndex(hash); + if (pindex) { if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) return "duplicate"; if (pindex->nStatus & BLOCK_FAILED_MASK) @@ -761,9 +760,8 @@ UniValue submitblock(const JSONRPCRequest& request) bool fBlockPresent = false; { LOCK(cs_main); - BlockMap::iterator mi = mapBlockIndex.find(hash); - if (mi != mapBlockIndex.end()) { - CBlockIndex* pindex = mi->second; + CBlockIndex* pindex = LookupBlockIndex(hash); + if (pindex) { if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) return "duplicate"; if (pindex->nStatus & BLOCK_FAILED_MASK) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index c479ecc14a3a7..aae6ebe719ab5 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -99,9 +99,8 @@ void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hash if (!hashBlock.IsNull()) { entry.pushKV("blockhash", hashBlock.GetHex()); - BlockMap::iterator mi = mapBlockIndex.find(hashBlock); - if (mi != mapBlockIndex.end() && (*mi).second) { - CBlockIndex* pindex = (*mi).second; + CBlockIndex* pindex = LookupBlockIndex(hashBlock); + if (pindex) { if (chainActive.Contains(pindex)) { entry.pushKV("confirmations", 1 + chainActive.Height() - pindex->nHeight); entry.pushKV("time", pindex->GetBlockTime()); @@ -236,11 +235,10 @@ UniValue getrawtransaction(const JSONRPCRequest& request) if (!request.params[2].isNull()) { uint256 blockhash = ParseHashV(request.params[2], "parameter 3"); - BlockMap::iterator it = mapBlockIndex.find(blockhash); - if (it == mapBlockIndex.end()) { + blockindex = LookupBlockIndex(blockhash); + if (!blockindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block hash not found"); } - blockindex = it->second; in_active_chain = chainActive.Contains(blockindex); } diff --git a/src/validation.cpp b/src/validation.cpp index 8eb63534df348..b27c44cd28051 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -181,11 +181,9 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc AssertLockHeld(cs_main); // Find the first block the caller has in the main chain for (const uint256& hash : locator.vHave) { - BlockMap::iterator mi = mapBlockIndex.find(hash); - if (mi != mapBlockIndex.end()) { - CBlockIndex* pindex = (*mi).second; - if (chain.Contains(pindex)) - return pindex; + CBlockIndex* pindex = LookupBlockIndex(hash); + if (pindex && chain.Contains(pindex)) { + return pindex; } } return chain.Genesis(); @@ -1025,7 +1023,7 @@ bool CScriptCheck::operator()() int GetSpendHeight(const CCoinsViewCache& inputs) { LOCK(cs_main); - CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second; + CBlockIndex* pindexPrev = LookupBlockIndex(inputs.GetBestBlock()); return pindexPrev->nHeight + 1; } @@ -2420,11 +2418,13 @@ bool ReconsiderBlock(CValidationState& state, CBlockIndex* pindex) CBlockIndex* AddToBlockIndex(const CBlock& block) { + AssertLockHeld(cs_main); + // Check for duplicate uint256 hash = block.GetHash(); - BlockMap::iterator it = mapBlockIndex.find(hash); - if (it != mapBlockIndex.end()) - return it->second; + CBlockIndex* pindex = LookupBlockIndex(hash); + if (pindex) + return pindex; // Construct new block index object CBlockIndex* pindexNew = new CBlockIndex(block); @@ -2435,9 +2435,9 @@ CBlockIndex* AddToBlockIndex(const CBlock& block) BlockMap::iterator mi = mapBlockIndex.emplace(hash, pindexNew).first; pindexNew->phashBlock = &((*mi).first); - BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock); - if (miPrev != mapBlockIndex.end()) { - pindexNew->pprev = (*miPrev).second; + CBlockIndex* pprev = LookupBlockIndex(block.hashPrevBlock); + if (pprev) { + pindexNew->pprev = pprev; pindexNew->nHeight = pindexNew->pprev->nHeight + 1; pindexNew->BuildSkip(); @@ -2726,11 +2726,10 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo if (pindexPrev != nullptr && block.hashPrevBlock != UINT256_ZERO) { if (pindexPrev->GetBlockHash() != block.hashPrevBlock) { //out of order - auto mi = mapBlockIndex.find(block.hashPrevBlock); - if (mi == mapBlockIndex.end()) { + CBlockIndex* pindexPrev = LookupBlockIndex(block.hashPrevBlock); + if (!pindexPrev) { return state.Error("blk-out-of-order"); } - pindexPrev = mi->second; } nHeight = pindexPrev->nHeight + 1; @@ -2848,7 +2847,7 @@ bool CheckBlockTime(const CBlockHeader& block, CValidationState& state, CBlockIn return true; } -//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint +//! Returns last CBlockIndex* that is a checkpoint static const CBlockIndex* GetLastCheckpoint() { if (!Checkpoints::fEnabled) @@ -2858,9 +2857,9 @@ static const CBlockIndex* GetLastCheckpoint() for (const auto& i : reverse_iterate(checkpoints)) { const uint256& hash = i.second; - BlockMap::const_iterator t = mapBlockIndex.find(hash); - if (t != mapBlockIndex.end()) - return t->second; + CBlockIndex* pindex = LookupBlockIndex(hash); + if (pindex) + return pindex; } return nullptr; } @@ -2963,12 +2962,11 @@ bool GetPrevIndex(const CBlock& block, CBlockIndex** pindexPrevRet, CValidationS CBlockIndex*& pindexPrev = *pindexPrevRet; pindexPrev = nullptr; if (block.GetHash() != Params().GetConsensus().hashGenesisBlock) { - BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); - if (mi == mapBlockIndex.end()) { + pindexPrev = LookupBlockIndex(block.hashPrevBlock); + if (!pindexPrev) { return state.DoS(0, error("%s : prev block %s not found", __func__, block.hashPrevBlock.GetHex()), 0, "prevblk-not-found"); } - pindexPrev = (*mi).second; if (pindexPrev->nStatus & BLOCK_FAILED_MASK) { //If this "invalid" block is an exact match from the checkpoints, then reconsider it if (Checkpoints::CheckBlock(pindexPrev->nHeight, block.hashPrevBlock, true)) { @@ -2992,13 +2990,11 @@ bool AcceptBlockHeader(const CBlock& block, CValidationState& state, CBlockIndex AssertLockHeld(cs_main); // Check for duplicate const uint256& hash = block.GetHash(); - BlockMap::iterator miSelf = mapBlockIndex.find(hash); - CBlockIndex* pindex = NULL; + CBlockIndex* pindex = LookupBlockIndex(hash); // TODO : ENABLE BLOCK CACHE IN SPECIFIC CASES - if (miSelf != mapBlockIndex.end()) { + if (pindex) { // Block header is already known. - pindex = miSelf->second; if (ppindex) *ppindex = pindex; if (pindex->nStatus & BLOCK_FAILED_MASK) @@ -3457,6 +3453,8 @@ fs::path GetBlockPosFilename(const FlatFilePos &pos) CBlockIndex* InsertBlockIndex(uint256 hash) { + AssertLockHeld(cs_main); + if (hash.IsNull()) return NULL; @@ -3582,6 +3580,8 @@ bool static LoadBlockIndexDB(std::string& strError) bool LoadChainTip(const CChainParams& chainparams) { + AssertLockHeld(cs_main); + if (chainActive.Tip() && chainActive.Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) return true; if (pcoinsTip->GetBestBlock().IsNull() && mapBlockIndex.size() == 1) { @@ -3595,11 +3595,11 @@ bool LoadChainTip(const CChainParams& chainparams) } // Load pointer to end of best chain - BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); - if (it == mapBlockIndex.end()) { + CBlockIndex* pindex = LookupBlockIndex(pcoinsTip->GetBestBlock()); + if (!pindex) { return false; } - chainActive.SetTip(it->second); + chainActive.SetTip(pindex); PruneBlockIndexCandidates(); @@ -3764,18 +3764,16 @@ bool ReplayBlocks(const CChainParams& params, CCoinsView* view) const CBlockIndex* pindexNew; // New tip during the interrupted flush. const CBlockIndex* pindexFork = nullptr; // Latest block common to both the old and the new tip. - auto itIndexNew = mapBlockIndex.find(hashHeads[0]); - if (itIndexNew == mapBlockIndex.end()) { + pindexNew = LookupBlockIndex(hashHeads[0]); + if (!pindexNew) { return error("%s: reorganization to unknown block requested", __func__); } - pindexNew = itIndexNew->second; if (!hashHeads[1].IsNull()) { // The old tip is allowed to be 0, indicating it's the first flush. - auto it = mapBlockIndex.find(hashHeads[1]); - if (it == mapBlockIndex.end()) { + pindexOld = LookupBlockIndex(hashHeads[1]); + if (!pindexOld) { return error("%s: reorganization from unknown block requested", __func__); } - pindexOld = it->second; pindexFork = LastCommonAncestor(pindexOld, pindexNew); assert(pindexFork != nullptr); } @@ -3947,7 +3945,7 @@ bool LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp) // detect out of order blocks, and store them for later uint256 hash = block.GetHash(); - if (hash != Params().GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) { + if (hash != Params().GetConsensus().hashGenesisBlock && !LookupBlockIndex(block.hashPrevBlock)) { LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.GetHex(), block.hashPrevBlock.GetHex()); if (dbp) @@ -3956,7 +3954,8 @@ bool LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp) } // process in case the block isn't known yet - if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) { + CBlockIndex* pindex = LookupBlockIndex(hash); + if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) { std::shared_ptr block_ptr = std::make_shared(block); stateCatcher.setBlockHash(block_ptr->GetHash()); if (ProcessNewBlock(block_ptr, dbp)) { @@ -3965,8 +3964,8 @@ bool LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp) if (stateCatcher.stateErrorFound()) { break; } - } else if (hash != Params().GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) { - LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight); + } else if (hash != Params().GetConsensus().hashGenesisBlock && pindex->nHeight % 1000 == 0) { + LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), pindex->nHeight); } // Recursively process earlier encountered successors of this block diff --git a/src/validation.h b/src/validation.h index 702fd6acaa993..f2bc43a2c478d 100644 --- a/src/validation.h +++ b/src/validation.h @@ -339,6 +339,13 @@ class CVerifyDB /** Replay blocks that aren't fully applied to the database. */ bool ReplayBlocks(const CChainParams& params, CCoinsView* view); +inline CBlockIndex* LookupBlockIndex(const uint256& hash) +{ + AssertLockHeld(cs_main); + BlockMap::const_iterator it = mapBlockIndex.find(hash); + return it == mapBlockIndex.end() ? nullptr : it->second; +} + /** Find the last common block between the parameter chain and a locator. */ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 401cc3f87467d..5e78965d29c5e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -83,7 +83,7 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) if (confirms > 0) { entry.pushKV("blockhash", wtx.m_confirm.hashBlock.GetHex()); entry.pushKV("blockindex", wtx.m_confirm.nIndex); - entry.pushKV("blocktime", mapBlockIndex[wtx.m_confirm.hashBlock]->GetBlockTime()); + entry.pushKV("blocktime", LookupBlockIndex(wtx.m_confirm.hashBlock)->GetBlockTime()); } else { entry.pushKV("trusted", wtx.IsTrusted()); } @@ -3201,9 +3201,7 @@ UniValue listsinceblock(const JSONRPCRequest& request) uint256 blockId; blockId.SetHex(request.params[0].get_str()); - BlockMap::iterator it = mapBlockIndex.find(blockId); - if (it != mapBlockIndex.end()) - pindex = it->second; + pindex = LookupBlockIndex(blockId); } if (request.params.size() > 1) { diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ac1d6e178b689..5d953d1b55422 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -998,8 +998,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) // Internal function for now, this will be part of a chain interface class in the future. Optional getTipBlockHeight(const uint256& hash) { - auto it = mapBlockIndex.find(hash); - CBlockIndex* pindex = it == mapBlockIndex.end() ? nullptr : it->second; + CBlockIndex* pindex = LookupBlockIndex(hash); if (pindex && chainActive.Contains(pindex)) { return Optional(pindex->nHeight); } @@ -3958,11 +3957,11 @@ void CWallet::GetKeyBirthTimes(std::map& mapKeyBirth) const std::vector vAffected; for (const auto& entry : mapWallet) { // iterate over all wallet transactions... - const CWalletTx &wtx = entry.second; - BlockMap::const_iterator blit = mapBlockIndex.find(wtx.m_confirm.hashBlock); - if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) { + const CWalletTx& wtx = entry.second; + CBlockIndex* pindex = LookupBlockIndex(wtx.m_confirm.hashBlock); + if (pindex && chainActive.Contains(pindex)) { // ... which are already in a block - int nHeight = blit->second->nHeight; + int nHeight = pindex->nHeight; for (const CTxOut& txout : wtx.tx->vout) { // iterate over all their outputs CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey); @@ -3970,7 +3969,7 @@ void CWallet::GetKeyBirthTimes(std::map& mapKeyBirth) const // ... and all their affected keys std::map::iterator rit = mapKeyFirstBlock.find(keyid); if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight) - rit->second = blit->second; + rit->second = pindex; } vAffected.clear(); }