Skip to content

Commit

Permalink
Add LookupBlockIndex function
Browse files Browse the repository at this point in the history
Cherry-picked from: 92fabcd
  • Loading branch information
promag authored and xanimo committed Jan 7, 2025
1 parent c4363fa commit 01e7925
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 145 deletions.
7 changes: 4 additions & 3 deletions src/checkpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ namespace Checkpoints {
BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, 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 NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion src/checkpoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct CCheckpointData;
namespace Checkpoints
{

//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
//! Returns last CBlockIndex* that is a checkpoint
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data);

} //namespace Checkpoints
Expand Down
3 changes: 2 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1522,8 +1522,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)

// 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(chainparams.GetConsensus(0).hashGenesisBlock) == 0)
if (!mapBlockIndex.empty() && !LookupBlockIndex(chainparams.GetConsensus(0).hashGenesisBlock)) {
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
}

// Initialize the block index (no-op if non-empty database was already loaded)
if (!InitBlockIndex(chainparams)) {
Expand Down
78 changes: 37 additions & 41 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,10 +402,11 @@ void ProcessBlockAvailability(NodeId nodeid) {
assert(state != NULL);

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;
const CBlockIndex* pindex = LookupBlockIndex(state->hashLastUnknownBlock);
if (pindex && pindex->nChainWork > 0) {
if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
state->pindexBestKnownBlock = pindex;
}
state->hashLastUnknownBlock.SetNull();
}
}
Expand All @@ -418,11 +419,12 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {

ProcessBlockAvailability(nodeid);

BlockMap::iterator it = mapBlockIndex.find(hash);
if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
const 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 == nullptr || 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;
Expand Down Expand Up @@ -978,7 +980,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
}
case MSG_BLOCK:
case MSG_WITNESS_BLOCK:
return mapBlockIndex.count(inv.hash);
return LookupBlockIndex(inv.hash) != nullptr;
}
// Don't know what it is, just say we already got one
return true;
Expand Down Expand Up @@ -1051,11 +1053,11 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK)
{
bool send = false;
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end())
const CBlockIndex* pindex = LookupBlockIndex(inv.hash);
if (pindex)
{
if (mi->second->nChainTx && !mi->second->IsValid(BLOCK_VALID_SCRIPTS) &&
mi->second->IsValid(BLOCK_VALID_TREE)) {
if (pindex->nChainTx && !pindex->IsValid(BLOCK_VALID_SCRIPTS) &&
pindex->IsValid(BLOCK_VALID_TREE)) {
// If we have the block and all of its parents, but have not yet validated it,
// we might be in the middle of connecting it (ie in the unlock of cs_main
// before ActivateBestChain but after AcceptBlock).
Expand All @@ -1069,16 +1071,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
CValidationState dummy;
ActivateBestChain(dummy, Params(), a_recent_block);
}
if (chainActive.Contains(mi->second)) {
if (chainActive.Contains(pindex)) {
send = true;
} else {
static const int nOneMonth = 30 * 24 * 60 * 60;
// To prevent fingerprinting attacks, only send blocks outside of the active
// chain if they are valid, and no more than a month older (both in time, and in
// best equivalent proof of work) than the best header chain we know about.
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
(pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
(GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth);
send = pindex->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
(pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() < nOneMonth) &&
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < nOneMonth);
if (!send) {
LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
}
Expand All @@ -1087,7 +1089,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
// disconnect node in case we have reached the outbound limit for serving historical blocks
// never disconnect whitelisted nodes
static const int nOneWeek = 7 * 24 * 60 * 60; // assume > 1 week = historical
if (send && connman.OutboundTargetReached(true) && ( ((pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > nOneWeek)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted)
if (send && connman.OutboundTargetReached(true) && ( ((pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() > nOneWeek)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted)
{
LogPrint("net", "historical block serving limit reached, disconnect peer=%d\n", pfrom->GetId());

Expand All @@ -1097,11 +1099,11 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
}
// Pruned nodes may have deleted the block, so check whether
// it's available before trying to send.
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, consensusParams, false))
if (!ReadBlockFromDisk(block, pindex, consensusParams, false))
assert(!"cannot load block from disk");
if (inv.type == MSG_BLOCK)
connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block));
Expand Down Expand Up @@ -1141,7 +1143,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
// instead we respond with the full, non-compact block.
bool fPeerWantsWitness = State(pfrom->GetId())->fWantsCmpctWitness;
int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
if (CanDirectFetch(consensusParams) && mi->second->nHeight >= chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) {
if (CanDirectFetch(consensusParams) && pindex->nHeight >= chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) {
CBlockHeaderAndShortTxIDs cmpctblock(block, fPeerWantsWitness);
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
} else
Expand Down Expand Up @@ -1861,13 +1863,13 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr

LOCK(cs_main);

BlockMap::iterator it = mapBlockIndex.find(req.blockhash);
if (it == mapBlockIndex.end() || !(it->second->nStatus & BLOCK_HAVE_DATA)) {
LogPrintf("Peer %d sent us a getblocktxn for a block we don't have", pfrom->id);
const CBlockIndex* pindex = LookupBlockIndex(req.blockhash);
if (!pindex || !(pindex->nStatus & BLOCK_HAVE_DATA)) {
LogPrint("net", "Peer %d sent us a getblocktxn for a block we don't have", pfrom->GetId());
return true;
}

if (it->second->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
Expand All @@ -1880,12 +1882,11 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
inv.type = State(pfrom->GetId())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK;
inv.hash = req.blockhash;
pfrom->vRecvGetData.push_back(inv);
ProcessGetData(pfrom, chainparams.GetConsensus(it->second->nHeight), connman, interruptMsgProc);
return true;
}

CBlock block;
bool ret = ReadBlockFromDisk(block, it->second, chainparams.GetConsensus(it->second->nHeight), false);
bool ret = ReadBlockFromDisk(block, pindex, chainparams.GetConsensus(pindex->nHeight));
assert(ret);

SendBlockTransactions(block, req, pfrom, connman);
Expand Down Expand Up @@ -1915,10 +1916,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
if (locator.IsNull())
{
// If locator is null, return the hashStop block
BlockMap::iterator mi = mapBlockIndex.find(hashStop);
if (mi == mapBlockIndex.end())
pindex = LookupBlockIndex(hashStop);
if (!pindex)
return true;
pindex = (*mi).second;
}
else
{
Expand Down Expand Up @@ -2108,7 +2108,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
{
LOCK(cs_main);

if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) == mapBlockIndex.end()) {
if (!LookupBlockIndex(cmpctblock.header.hashPrevBlock)) {
// Doesn't connect (or is genesis), instead of DoSing in AcceptBlockHeader, request deeper headers
if (!IsInitialBlockDownload())
RequestHeadersFrom(pfrom, connman, pindexBestHeader, uint256(), true);
Expand Down Expand Up @@ -2767,12 +2767,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// Ignore unknown commands for extensibility
LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
}



return true;
}


static bool SendRejectsAndCheckIfBanned(CNode* pnode, CConnman& connman)
{
AssertLockHeld(cs_main);
Expand Down Expand Up @@ -3096,10 +3094,9 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr
// Try to find first header that our peer doesn't have, and
// then send all headers past that one. If we come across any
// headers that aren't on chainActive, give up.
BOOST_FOREACH(const uint256 &hash, pto->vBlockHashesToAnnounce) {
BlockMap::iterator mi = mapBlockIndex.find(hash);
assert(mi != mapBlockIndex.end());
const CBlockIndex *pindex = mi->second;
for (const uint256 &hash : pto->vBlockHashesToAnnounce) {
const CBlockIndex* pindex = LookupBlockIndex(hash);
assert(pindex);
if (chainActive[pindex->nHeight] != pindex) {
// Bail out if we reorged away from this block
fRevertToInv = true;
Expand Down Expand Up @@ -3190,9 +3187,8 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr
// in the past.
if (!pto->vBlockHashesToAnnounce.empty()) {
const uint256 &hashToAnnounce = pto->vBlockHashesToAnnounce.back();
BlockMap::iterator mi = mapBlockIndex.find(hashToAnnounce);
assert(mi != mapBlockIndex.end());
const CBlockIndex *pindex = mi->second;
const CBlockIndex* pindex = LookupBlockIndex(hashToAnnounce);
assert(pindex);

// Warn if we're announcing a block that is not on the main chain.
// This should be very rare and could be optimized out.
Expand Down
5 changes: 1 addition & 4 deletions src/qt/transactionrecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
// Determine transaction status

// Find the block the tx is in
CBlockIndex* pindex = NULL;
BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock);
if (mi != mapBlockIndex.end())
pindex = (*mi).second;
const CBlockIndex* pindex = LookupBlockIndex(wtx.hashBlock);

// Sort order, unrecorded transactions sort to the top
status.sortKey = strprintf("%010d-%01d-%010u-%03d",
Expand Down
10 changes: 5 additions & 5 deletions src/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,8 @@ 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;
while (pindex != NULL && chainActive.Contains(pindex)) {
const CBlockIndex* pindex = LookupBlockIndex(hash);
while (pindex != nullptr && chainActive.Contains(pindex)) {
headers.push_back(pindex);
if (headers.size() == (unsigned long)count)
break;
Expand Down Expand Up @@ -219,10 +218,11 @@ static bool rest_block(HTTPRequest* req,
CBlockIndex* pblockindex = NULL;
{
LOCK(cs_main);
if (mapBlockIndex.count(hash) == 0)
pblockindex = LookupBlockIndex(hash);
if (!pblockindex) {
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
}

pblockindex = mapBlockIndex[hash];
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");

Expand Down
38 changes: 18 additions & 20 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,10 +718,10 @@ UniValue getblockheader(const JSONRPCRequest& request)
if (request.params.size() > 1)
fVerbose = request.params[1].get_bool();

if (mapBlockIndex.count(hash) == 0)
const CBlockIndex* pblockindex = LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

CBlockIndex* pblockindex = mapBlockIndex[hash];
}

if (!fVerbose)
{
Expand Down Expand Up @@ -834,15 +834,13 @@ UniValue getblock(const JSONRPCRequest& request)
}

CBlock block;
const CBlockIndex* pblockindex;
const CBlockIndex* pblockindex = LookupBlockIndex(hash);
{
LOCK(cs_main);

if (mapBlockIndex.count(hash) == 0)
if (!pblockindex)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

pblockindex = mapBlockIndex[hash];

block = GetBlockChecked(pblockindex);
}

Expand Down Expand Up @@ -895,7 +893,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;
Expand Down Expand Up @@ -1076,8 +1074,7 @@ UniValue gettxout(const JSONRPCRequest& request)
}
}

BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
CBlockIndex *pindex = it->second;
const CBlockIndex* pindex = LookupBlockIndex(pcoinsTip->GetBestBlock());
ret.pushKV("bestblock", pindex->GetBlockHash().GetHex());
if ((unsigned int)coin.nHeight == MEMPOOL_HEIGHT)
ret.pushKV("confirmations", 0);
Expand Down Expand Up @@ -1452,10 +1449,10 @@ UniValue preciousblock(const JSONRPCRequest& request)

{
LOCK(cs_main);
if (mapBlockIndex.count(hash) == 0)
pblockindex = LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

pblockindex = mapBlockIndex[hash];
}
}

CValidationState state;
Expand Down Expand Up @@ -1488,10 +1485,11 @@ UniValue invalidateblock(const JSONRPCRequest& request)

{
LOCK(cs_main);
if (mapBlockIndex.count(hash) == 0)
CBlockIndex* pblockindex = LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}

CBlockIndex* pblockindex = mapBlockIndex[hash];
InvalidateBlock(state, Params(), pblockindex);
}

Expand Down Expand Up @@ -1526,10 +1524,11 @@ UniValue reconsiderblock(const JSONRPCRequest& request)

{
LOCK(cs_main);
if (mapBlockIndex.count(hash) == 0)
CBlockIndex* pblockindex = LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}

CBlockIndex* pblockindex = mapBlockIndex[hash];
ResetBlockFailureFlags(pblockindex);
}

Expand Down Expand Up @@ -1660,12 +1659,11 @@ static UniValue getblockstats(const JSONRPCRequest& request)

LOCK(cs_main);

CBlockIndex* pindex;
const uint256 hash = ParseHashV(request.params[0], "hash");
CBlockIndex* pindex = LookupBlockIndex(hash);

if (mapBlockIndex.count(hash) == 0)
if (!pindex)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
pindex = mapBlockIndex[hash];

if (!chainActive.Contains(pindex)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Block is not in chain %s", Params().NetworkIDString()));
Expand Down
Loading

0 comments on commit 01e7925

Please sign in to comment.