mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Merge bitcoin#11041 Add LookupBlockIndex
Contains both the changes done upstream and changes done in Dash codebase Signed-off-by: pasta <pasta@dashboost.org>
This commit is contained in:
parent
c7a5be4d6b
commit
0efc03deb0
@ -22,9 +22,10 @@ namespace Checkpoints {
|
||||
for (const MapCheckpoints::value_type& 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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -187,19 +187,18 @@ bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& bloc
|
||||
|
||||
const CBlockIndex* baseBlockIndex = chainActive.Genesis();
|
||||
if (!baseBlockHash.IsNull()) {
|
||||
auto it = mapBlockIndex.find(baseBlockHash);
|
||||
if (it == mapBlockIndex.end()) {
|
||||
baseBlockIndex = LookupBlockIndex(blockHash);
|
||||
if (!baseBlockIndex) {
|
||||
errorRet = strprintf("block %s not found", baseBlockHash.ToString());
|
||||
return false;
|
||||
}
|
||||
baseBlockIndex = it->second;
|
||||
}
|
||||
auto blockIt = mapBlockIndex.find(blockHash);
|
||||
if (blockIt == mapBlockIndex.end()) {
|
||||
|
||||
const CBlockIndex* blockIndex = LookupBlockIndex(blockHash);
|
||||
if (!blockIndex) {
|
||||
errorRet = strprintf("block %s not found", blockHash.ToString());
|
||||
return false;
|
||||
}
|
||||
const CBlockIndex* blockIndex = blockIt->second;
|
||||
|
||||
if (!chainActive.Contains(baseBlockIndex) || !chainActive.Contains(blockIndex)) {
|
||||
errorRet = strprintf("block %s and %s are not in the same chain", baseBlockHash.ToString(), blockHash.ToString());
|
||||
|
@ -585,12 +585,9 @@ bool CGovernanceObject::IsCollateralValid(std::string& strError, bool& fMissingC
|
||||
AssertLockHeld(cs_main);
|
||||
int nConfirmationsIn = 0;
|
||||
if (nBlockHash != uint256()) {
|
||||
BlockMap::iterator mi = mapBlockIndex.find(nBlockHash);
|
||||
if (mi != mapBlockIndex.end() && (*mi).second) {
|
||||
CBlockIndex* pindex = (*mi).second;
|
||||
if (chainActive.Contains(pindex)) {
|
||||
nConfirmationsIn += chainActive.Height() - pindex->nHeight + 1;
|
||||
}
|
||||
CBlockIndex* pindex = LookupBlockIndex(nBlockHash);
|
||||
if (pindex && chainActive.Contains(pindex)) {
|
||||
nConfirmationsIn += chainActive.Height() - pindex->nHeight + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
22
src/init.cpp
22
src/init.cpp
@ -1925,6 +1925,8 @@ bool AppInitMain()
|
||||
|
||||
uiInterface.InitMessage(_("Loading block index..."));
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
do {
|
||||
const int64_t load_block_index_start_time = GetTimeMillis();
|
||||
try {
|
||||
@ -1971,8 +1973,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(chainparams.GetConsensus().hashGenesisBlock) == 0)
|
||||
if (!mapBlockIndex.empty() && !LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) {
|
||||
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
|
||||
}
|
||||
|
||||
if (!chainparams.GetConsensus().hashDevnetGenesisBlock.IsNull() && !mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashDevnetGenesisBlock) == 0)
|
||||
return InitError(_("Incorrect or no devnet genesis block found. Wrong datadir for devnet specified?"));
|
||||
@ -2073,16 +2076,13 @@ bool AppInitMain()
|
||||
MIN_BLOCKS_TO_KEEP);
|
||||
}
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
CBlockIndex* tip = chainActive.Tip();
|
||||
RPCNotifyBlockChange(true, tip);
|
||||
if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) {
|
||||
strLoadError = _("The block database contains a block which appears to be from the future. "
|
||||
"This may be due to your computer's date and time being set incorrectly. "
|
||||
"Only rebuild the block database if you are sure that your computer's date and time are correct");
|
||||
break;
|
||||
}
|
||||
CBlockIndex* tip = chainActive.Tip();
|
||||
RPCNotifyBlockChange(true, tip);
|
||||
if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) {
|
||||
strLoadError = _("The block database contains a block which appears to be from the future. "
|
||||
"This may be due to your computer's date and time being set incorrectly. "
|
||||
"Only rebuild the block database if you are sure that your computer's date and time are correct");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview.get(), gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
|
||||
|
@ -338,13 +338,12 @@ CQuorumCPtr CQuorumManager::GetQuorum(Consensus::LLMQType llmqType, const uint25
|
||||
CBlockIndex* pindexQuorum;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
auto quorumIt = mapBlockIndex.find(quorumHash);
|
||||
|
||||
if (quorumIt == mapBlockIndex.end()) {
|
||||
pindexQuorum = LookupBlockIndex(quorumHash);
|
||||
if (!pindexQuorum) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- block %s not found\n", __func__, quorumHash.ToString());
|
||||
return nullptr;
|
||||
}
|
||||
pindexQuorum = quorumIt->second;
|
||||
}
|
||||
return GetQuorum(llmqType, pindexQuorum);
|
||||
}
|
||||
|
@ -58,14 +58,14 @@ void CQuorumBlockProcessor::ProcessMessage(CNode* pfrom, const std::string& strC
|
||||
const CBlockIndex* pquorumIndex;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if (!mapBlockIndex.count(qc.quorumHash)) {
|
||||
pquorumIndex = LookupBlockIndex(qc.quorumHash);
|
||||
if (!pquorumIndex) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- unknown block %s in commitment, peer=%d\n", __func__,
|
||||
qc.quorumHash.ToString(), pfrom->GetId());
|
||||
// can't really punish the node here, as we might simply be the one that is on the wrong chain or not
|
||||
// fully synced
|
||||
return;
|
||||
}
|
||||
pquorumIndex = mapBlockIndex[qc.quorumHash];
|
||||
if (chainActive.Tip()->GetAncestor(pquorumIndex->nHeight) != pquorumIndex) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s not in active chain, peer=%d\n", __func__,
|
||||
qc.quorumHash.ToString(), pfrom->GetId());
|
||||
@ -212,7 +212,7 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH
|
||||
return state.DoS(100, false, REJECT_INVALID, "bad-qc-height");
|
||||
}
|
||||
|
||||
auto quorumIndex = mapBlockIndex.at(qc.quorumHash);
|
||||
auto quorumIndex = LookupBlockIndex(qc.quorumHash);
|
||||
auto members = CLLMQUtils::GetAllQuorumMembers(params.type, quorumIndex);
|
||||
|
||||
if (!qc.Verify(members, true)) {
|
||||
@ -303,7 +303,7 @@ bool CQuorumBlockProcessor::UpgradeDB()
|
||||
if (qc.IsNull()) {
|
||||
continue;
|
||||
}
|
||||
auto quorumIndex = mapBlockIndex.at(qc.quorumHash);
|
||||
auto quorumIndex = LookupBlockIndex(qc.quorumHash);
|
||||
evoDb.GetRawDB().Write(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(qc.llmqType, qc.quorumHash)), std::make_pair(qc, pindex->GetBlockHash()));
|
||||
evoDb.GetRawDB().Write(BuildInversedHeightKey((Consensus::LLMQType)qc.llmqType, pindex->nHeight), quorumIndex->nHeight);
|
||||
}
|
||||
|
@ -151,21 +151,20 @@ void CChainLocksHandler::ProcessNewChainLock(NodeId from, const llmq::CChainLock
|
||||
CInv inv(MSG_CLSIG, hash);
|
||||
g_connman->RelayInv(inv, LLMQS_PROTO_VERSION);
|
||||
|
||||
auto blockIt = mapBlockIndex.find(clsig.blockHash);
|
||||
if (blockIt == mapBlockIndex.end()) {
|
||||
const CBlockIndex* pindex = LookupBlockIndex(clsig.blockHash);
|
||||
if (!pindex) {
|
||||
// we don't know the block/header for this CLSIG yet, so bail out for now
|
||||
// when the block or the header later comes in, we will enforce the correct chain
|
||||
return;
|
||||
}
|
||||
|
||||
if (blockIt->second->nHeight != clsig.nHeight) {
|
||||
if (pindex->nHeight != clsig.nHeight) {
|
||||
// Should not happen, same as the conflict check from above.
|
||||
LogPrintf("CChainLocksHandler::%s -- height of CLSIG (%s) does not match the specified block's height (%d)\n",
|
||||
__func__, clsig.ToString(), blockIt->second->nHeight);
|
||||
__func__, clsig.ToString(), pindex->nHeight);
|
||||
return;
|
||||
}
|
||||
|
||||
const CBlockIndex* pindex = blockIt->second;
|
||||
bestChainLockWithKnownBlock = bestChainLock;
|
||||
bestChainLockBlockIndex = pindex;
|
||||
}
|
||||
@ -431,7 +430,7 @@ CChainLocksHandler::BlockTxs::mapped_type CChainLocksHandler::GetBlockTxs(const
|
||||
uint32_t blockTime;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
auto pindex = mapBlockIndex.at(blockHash);
|
||||
auto pindex = LookupBlockIndex(blockHash);
|
||||
CBlock block;
|
||||
if (!ReadBlockFromDisk(block, pindex, Params().GetConsensus())) {
|
||||
return nullptr;
|
||||
@ -536,7 +535,7 @@ void CChainLocksHandler::EnforceBestChainLock()
|
||||
// the trigger later appears, this should bring us to the correct chain eventually. Please note that this does
|
||||
// NOT enforce invalid blocks in any way, it just causes re-validation.
|
||||
if (!currentBestChainLockBlockIndex->IsValid()) {
|
||||
ResetBlockFailureFlags(mapBlockIndex.at(currentBestChainLockBlockIndex->GetBlockHash()));
|
||||
ResetBlockFailureFlags(LookupBlockIndex(currentBestChainLockBlockIndex->GetBlockHash()));
|
||||
}
|
||||
|
||||
activateNeeded = chainActive.Tip()->GetAncestor(currentBestChainLockBlockIndex->nHeight) != currentBestChainLockBlockIndex;
|
||||
@ -596,7 +595,7 @@ void CChainLocksHandler::DoInvalidateBlock(const CBlockIndex* pindex)
|
||||
auto& params = Params();
|
||||
|
||||
// get the non-const pointer
|
||||
CBlockIndex* pindex2 = mapBlockIndex[pindex->GetBlockHash()];
|
||||
CBlockIndex* pindex2 = LookupBlockIndex(pindex->GetBlockHash());
|
||||
|
||||
CValidationState state;
|
||||
if (!InvalidateBlock(state, params, pindex2)) {
|
||||
@ -693,7 +692,7 @@ void CChainLocksHandler::Cleanup()
|
||||
}
|
||||
|
||||
for (auto it = blockTxs.begin(); it != blockTxs.end(); ) {
|
||||
auto pindex = mapBlockIndex.at(it->first);
|
||||
auto pindex = LookupBlockIndex(it->first);
|
||||
if (InternalHasChainLock(pindex->nHeight, pindex->GetBlockHash())) {
|
||||
for (auto& txid : *it->second) {
|
||||
txFirstSeenTime.erase(txid);
|
||||
@ -712,7 +711,7 @@ void CChainLocksHandler::Cleanup()
|
||||
// tx has vanished, probably due to conflicts
|
||||
it = txFirstSeenTime.erase(it);
|
||||
} else if (!hashBlock.IsNull()) {
|
||||
auto pindex = mapBlockIndex.at(hashBlock);
|
||||
auto pindex = LookupBlockIndex(hashBlock);
|
||||
if (chainActive.Tip()->GetAncestor(pindex->nHeight) == pindex && chainActive.Height() - pindex->nHeight >= 6) {
|
||||
// tx got confirmed >= 6 times, so we can stop keeping track of it
|
||||
it = txFirstSeenTime.erase(it);
|
||||
|
@ -145,11 +145,11 @@ bool CheckLLMQCommitment(const CTransaction& tx, const CBlockIndex* pindexPrev,
|
||||
return state.DoS(100, false, REJECT_INVALID, "bad-qc-height");
|
||||
}
|
||||
|
||||
if (!mapBlockIndex.count(qcTx.commitment.quorumHash)) {
|
||||
const CBlockIndex* pindexQuorum = LookupBlockIndex(qcTx.commitment.quorumHash);
|
||||
if (!pindexQuorum) {
|
||||
return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-hash");
|
||||
}
|
||||
|
||||
const CBlockIndex* pindexQuorum = mapBlockIndex[qcTx.commitment.quorumHash];
|
||||
|
||||
if (pindexQuorum != pindexPrev->GetAncestor(pindexQuorum->nHeight)) {
|
||||
// not part of active chain
|
||||
|
@ -27,10 +27,7 @@ UniValue CDKGDebugSessionStatus::ToJson(int detailLevel) const
|
||||
const CBlockIndex* pindex = nullptr;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
auto it = mapBlockIndex.find(quorumHash);
|
||||
if (it != mapBlockIndex.end()) {
|
||||
pindex = it->second;
|
||||
}
|
||||
pindex = LookupBlockIndex(quorumHash);
|
||||
}
|
||||
if (pindex != nullptr) {
|
||||
dmnMembers = CLLMQUtils::GetAllQuorumMembers((Consensus::LLMQType) llmqType, pindex);
|
||||
|
@ -518,7 +518,7 @@ void CDKGSessionHandler::HandleDKGRound()
|
||||
const CBlockIndex* pindexQuorum;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindexQuorum = mapBlockIndex.at(curQuorumHash);
|
||||
pindexQuorum = LookupBlockIndex(curQuorumHash);
|
||||
}
|
||||
|
||||
if (!InitNewQuorum(pindexQuorum)) {
|
||||
|
@ -527,7 +527,7 @@ bool CInstantSendManager::CheckCanLock(const COutPoint& outpoint, bool printDebu
|
||||
int nTxAge;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindexMined = mapBlockIndex.at(hashBlock);
|
||||
pindexMined = LookupBlockIndex(hashBlock);
|
||||
nTxAge = chainActive.Height() - pindexMined->nHeight + 1;
|
||||
}
|
||||
|
||||
@ -895,7 +895,7 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has
|
||||
if (!hashBlock.IsNull()) {
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindexMined = mapBlockIndex.at(hashBlock);
|
||||
pindexMined = LookupBlockIndex(hashBlock);
|
||||
}
|
||||
|
||||
// Let's see if the TX that was locked by this islock is already mined in a ChainLocked block. If yes,
|
||||
@ -1308,7 +1308,7 @@ void CInstantSendManager::ResolveBlockConflicts(const uint256& islockHash, const
|
||||
LOCK(cs_main);
|
||||
CValidationState state;
|
||||
// need non-const pointer
|
||||
auto pindex2 = mapBlockIndex.at(pindex->GetBlockHash());
|
||||
auto pindex2 = LookupBlockIndex(pindex->GetBlockHash());
|
||||
if (!InvalidateBlock(state, Params(), pindex2)) {
|
||||
LogPrintf("CInstantSendManager::%s -- InvalidateBlock failed: %s\n", __func__, FormatStateMessage(state));
|
||||
// This should not have happened and we are in a state were it's not safe to continue anymore
|
||||
|
@ -518,10 +518,11 @@ void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
|
||||
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 == nullptr || 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();
|
||||
}
|
||||
}
|
||||
@ -534,11 +535,12 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) EXCLUSIVE_LOCKS
|
||||
|
||||
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 == nullptr || 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;
|
||||
@ -1351,7 +1353,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;
|
||||
|
||||
/*
|
||||
Dash Related Inventory Messages
|
||||
@ -1443,11 +1445,10 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
|
||||
bool need_activate_chain = false;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
|
||||
if (mi != mapBlockIndex.end())
|
||||
{
|
||||
if (mi->second->nChainTx && !mi->second->IsValid(BLOCK_VALID_SCRIPTS) &&
|
||||
mi->second->IsValid(BLOCK_VALID_TREE)) {
|
||||
const CBlockIndex* pindex = LookupBlockIndex(inv.hash);
|
||||
if (pindex) {
|
||||
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).
|
||||
@ -1465,9 +1466,9 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
|
||||
if (mi != mapBlockIndex.end()) {
|
||||
send = BlockRequestAllowed(mi->second, consensusParams);
|
||||
const CBlockIndex* pindex = LookupBlockIndex(inv.hash);
|
||||
if (pindex) {
|
||||
send = BlockRequestAllowed(pindex, consensusParams);
|
||||
if (!send) {
|
||||
LogPrint(BCLog::NET,"%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
|
||||
}
|
||||
@ -1475,7 +1476,7 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
|
||||
const CNetMsgMaker msgMaker(pfrom->GetSendVersion());
|
||||
// disconnect node in case we have reached the outbound limit for serving historical blocks
|
||||
// never disconnect whitelisted nodes
|
||||
if (send && connman->OutboundTargetReached(true) && ( ((pindexBestHeader != nullptr) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted)
|
||||
if (send && connman->OutboundTargetReached(true) && ( ((pindexBestHeader != nullptr) && (pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted)
|
||||
{
|
||||
LogPrint(BCLog::NET, "historical block serving limit reached, disconnect peer=%d\n", pfrom->GetId());
|
||||
|
||||
@ -1485,7 +1486,7 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
|
||||
}
|
||||
// Avoid leaking prune-height by never sending blocks below the NODE_NETWORK_LIMITED threshold
|
||||
if (send && !pfrom->fWhitelisted && (
|
||||
(((pfrom->GetLocalServices() & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom->GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && (chainActive.Tip()->nHeight - mi->second->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) )
|
||||
(((pfrom->GetLocalServices() & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom->GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && (chainActive.Tip()->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) )
|
||||
)) {
|
||||
LogPrint(BCLog::NET, "Ignore block request below NODE_NETWORK_LIMITED threshold from peer=%d\n", pfrom->GetId());
|
||||
|
||||
@ -1495,15 +1496,15 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
|
||||
}
|
||||
// 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))
|
||||
{
|
||||
std::shared_ptr<const CBlock> pblock;
|
||||
if (a_recent_block && a_recent_block->GetHash() == (*mi).second->GetBlockHash()) {
|
||||
if (a_recent_block && a_recent_block->GetHash() == pindex->GetBlockHash()) {
|
||||
pblock = a_recent_block;
|
||||
} else {
|
||||
// Send block from disk
|
||||
std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
|
||||
if (!ReadBlockFromDisk(*pblockRead, (*mi).second, consensusParams))
|
||||
if (!ReadBlockFromDisk(*pblockRead, pindex, consensusParams))
|
||||
assert(!"cannot load block from disk");
|
||||
pblock = pblockRead;
|
||||
}
|
||||
@ -1540,9 +1541,9 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
|
||||
// and we don't feel like constructing the object for them, so
|
||||
// instead we respond with the full, non-compact block.
|
||||
if (CanDirectFetch(consensusParams) &&
|
||||
mi->second->nHeight >= chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) {
|
||||
pindex->nHeight >= chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) {
|
||||
if (a_recent_compact_block &&
|
||||
a_recent_compact_block->header.GetHash() == mi->second->GetBlockHash()) {
|
||||
a_recent_compact_block->header.GetHash() == pindex->GetBlockHash()) {
|
||||
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
|
||||
} else {
|
||||
CBlockHeaderAndShortTxIDs cmpctblock(*pblock);
|
||||
@ -1798,7 +1799,7 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
|
||||
// don't connect before giving DoS points
|
||||
// - Once a headers message is received that is valid and does connect,
|
||||
// nUnconnectingHeaders gets reset back to 0.
|
||||
if (mapBlockIndex.find(headers[0].hashPrevBlock) == mapBlockIndex.end() && nCount < MAX_BLOCKS_TO_ANNOUNCE) {
|
||||
if (!LookupBlockIndex(headers[0].hashPrevBlock) && nCount < MAX_BLOCKS_TO_ANNOUNCE) {
|
||||
nodestate->nUnconnectingHeaders++;
|
||||
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()));
|
||||
LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
|
||||
@ -1828,7 +1829,7 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
|
||||
|
||||
// If we don't have the last header, then they'll have given us
|
||||
// something new (if these headers are valid).
|
||||
if (mapBlockIndex.find(hashLastBlock) == mapBlockIndex.end()) {
|
||||
if (!LookupBlockIndex(hashLastBlock)) {
|
||||
received_new_header = true;
|
||||
}
|
||||
}
|
||||
@ -1844,7 +1845,7 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
|
||||
} else {
|
||||
LogPrint(BCLog::NET, "peer=%d: invalid header received\n", pfrom->GetId());
|
||||
}
|
||||
if (punish_duplicate_invalid && mapBlockIndex.find(first_invalid_header.GetHash()) != mapBlockIndex.end()) {
|
||||
if (punish_duplicate_invalid && LookupBlockIndex(first_invalid_header.GetHash())) {
|
||||
// Goal: don't allow outbound peers to use up our outbound
|
||||
// connection slots if they are on incompatible chains.
|
||||
//
|
||||
@ -2688,13 +2689,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)) {
|
||||
const CBlockIndex* pindex = LookupBlockIndex(req.blockhash);
|
||||
if (!pindex || !(pindex->nStatus & BLOCK_HAVE_DATA)) {
|
||||
LogPrint(BCLog::NET, "Peer %d sent us a getblocktxn for a block we don't have\n", 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
|
||||
@ -2712,7 +2713,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
||||
}
|
||||
|
||||
CBlock block;
|
||||
bool ret = ReadBlockFromDisk(block, it->second, chainparams.GetConsensus());
|
||||
bool ret = ReadBlockFromDisk(block, pindex, chainparams.GetConsensus());
|
||||
assert(ret);
|
||||
|
||||
SendBlockTransactions(block, req, pfrom, connman);
|
||||
@ -2741,10 +2742,10 @@ 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;
|
||||
}
|
||||
|
||||
if (!BlockRequestAllowed(pindex, chainparams.GetConsensus())) {
|
||||
LogPrint(BCLog::NET, "%s: ignoring request from peer=%i for old block header that isn't in the main chain\n", __func__, pfrom->GetId());
|
||||
@ -2993,14 +2994,14 @@ 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())
|
||||
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mapBlockIndex.find(cmpctblock.header.GetHash()) == mapBlockIndex.end()) {
|
||||
if (!LookupBlockIndex(cmpctblock.header.GetHash())) {
|
||||
received_new_header = true;
|
||||
}
|
||||
}
|
||||
@ -4047,9 +4048,8 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
|
||||
// then send all headers past that one. If we come across any
|
||||
// headers that aren't on chainActive, give up.
|
||||
for (const uint256 &hash : pto->vBlockHashesToAnnounce) {
|
||||
BlockMap::iterator mi = mapBlockIndex.find(hash);
|
||||
assert(mi != mapBlockIndex.end());
|
||||
const CBlockIndex *pindex = mi->second;
|
||||
const CBlockIndex* pindex = LookupBlockIndex(hash);
|
||||
assert(pindex);
|
||||
if (chainActive[pindex->nHeight] != pindex) {
|
||||
// Bail out if we reorged away from this block
|
||||
fRevertToInv = true;
|
||||
@ -4142,9 +4142,8 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
|
||||
// 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.
|
||||
|
@ -49,8 +49,7 @@ bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
|
||||
stats.hashBlock = pcursor->GetBestBlock();
|
||||
{
|
||||
LOCK(cs_main);
|
||||
// stats.nHeight = LookupBlockIndex(stats.hashBlock)->nHeight;
|
||||
stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
|
||||
stats.nHeight = LookupBlockIndex(stats.hashBlock)->nHeight;
|
||||
}
|
||||
ss << stats.hashBlock;
|
||||
uint256 prevkey;
|
||||
|
@ -147,8 +147,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 : nullptr;
|
||||
const CBlockIndex* pindex = LookupBlockIndex(hash);
|
||||
while (pindex != nullptr && chainActive.Contains(pindex)) {
|
||||
headers.push_back(pindex);
|
||||
if (headers.size() == (unsigned long)count)
|
||||
@ -212,10 +211,11 @@ static bool rest_block(HTTPRequest* req,
|
||||
CBlockIndex* pblockindex = nullptr;
|
||||
{
|
||||
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 (IsBlockPruned(pblockindex))
|
||||
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
|
||||
|
||||
|
@ -795,10 +795,10 @@ UniValue getblockheader(const JSONRPCRequest& request)
|
||||
if (!request.params[1].isNull())
|
||||
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)
|
||||
{
|
||||
@ -1064,10 +1064,11 @@ UniValue getblock(const JSONRPCRequest& request)
|
||||
verbosity = request.params[1].get_bool() ? 1 : 0;
|
||||
}
|
||||
|
||||
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];
|
||||
const CBlock block = GetBlockChecked(pblockindex);
|
||||
|
||||
if (verbosity <= 0)
|
||||
@ -1235,8 +1236,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 (coin.nHeight == MEMPOOL_HEIGHT) {
|
||||
ret.pushKV("confirmations", 0);
|
||||
@ -1661,10 +1661,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;
|
||||
@ -1697,10 +1697,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);
|
||||
}
|
||||
|
||||
@ -1735,10 +1736,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);
|
||||
}
|
||||
|
||||
@ -1785,11 +1787,10 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
|
||||
} else {
|
||||
uint256 hash = uint256S(request.params[1].get_str());
|
||||
LOCK(cs_main);
|
||||
auto it = mapBlockIndex.find(hash);
|
||||
if (it == mapBlockIndex.end()) {
|
||||
pindex = LookupBlockIndex(hash);
|
||||
if (!pindex) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
}
|
||||
pindex = it->second;
|
||||
if (!chainActive.Contains(pindex)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
|
||||
}
|
||||
|
@ -419,9 +419,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;
|
||||
const 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;
|
||||
const CBlockIndex* pindex = LookupBlockIndex(hash);
|
||||
if (pindex) {
|
||||
if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
|
||||
return "duplicate";
|
||||
}
|
||||
|
@ -78,9 +78,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
|
||||
bool chainLock = false;
|
||||
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("height", pindex->nHeight);
|
||||
entry.pushKV("confirmations", 1 + chainActive.Height() - pindex->nHeight);
|
||||
@ -202,11 +201,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);
|
||||
}
|
||||
|
||||
@ -285,9 +283,10 @@ UniValue gettxoutproof(const JSONRPCRequest& request)
|
||||
if (!request.params[1].isNull())
|
||||
{
|
||||
hashBlock = uint256S(request.params[1].get_str());
|
||||
if (!mapBlockIndex.count(hashBlock))
|
||||
pblockindex = LookupBlockIndex(hashBlock);
|
||||
if (!pblockindex) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
pblockindex = mapBlockIndex[hashBlock];
|
||||
}
|
||||
} else {
|
||||
// Loop through txids and try to find which block they're in. Exit loop once a block is found.
|
||||
for (const auto& tx : setTxids) {
|
||||
@ -304,9 +303,10 @@ UniValue gettxoutproof(const JSONRPCRequest& request)
|
||||
CTransactionRef tx;
|
||||
if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
|
||||
if (!mapBlockIndex.count(hashBlock))
|
||||
pblockindex = LookupBlockIndex(hashBlock);
|
||||
if (!pblockindex) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
|
||||
pblockindex = mapBlockIndex[hashBlock];
|
||||
}
|
||||
}
|
||||
|
||||
CBlock block;
|
||||
@ -357,8 +357,10 @@ UniValue verifytxoutproof(const JSONRPCRequest& request)
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
|
||||
const CBlockIndex* pindex = LookupBlockIndex(merkleBlock.header.GetHash());
|
||||
if (!pindex || !chainActive.Contains(pindex)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
|
||||
}
|
||||
|
||||
for (const uint256& hash : vMatch)
|
||||
res.push_back(hash.GetHex());
|
||||
|
@ -292,13 +292,13 @@ namespace {
|
||||
|
||||
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
// Find the latest block common to locator and chain - we expect that
|
||||
// locator.vHave is sorted descending by height.
|
||||
for (const uint256& hash : locator.vHave) {
|
||||
BlockMap::iterator mi = mapBlockIndex.find(hash);
|
||||
if (mi != mapBlockIndex.end())
|
||||
{
|
||||
CBlockIndex* pindex = (*mi).second;
|
||||
CBlockIndex* pindex = LookupBlockIndex(hash);
|
||||
if (pindex) {
|
||||
if (chain.Contains(pindex))
|
||||
return pindex;
|
||||
}
|
||||
@ -1427,7 +1427,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;
|
||||
}
|
||||
|
||||
@ -3324,6 +3324,8 @@ bool ResetBlockFailureFlags(CBlockIndex *pindex) {
|
||||
|
||||
CBlockIndex* CChainState::AddToBlockIndex(const CBlockHeader& block, enum BlockStatus nStatus)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
// Check for duplicate
|
||||
uint256 hash = block.GetHash();
|
||||
BlockMap::iterator it = mapBlockIndex.find(hash);
|
||||
@ -3717,7 +3719,6 @@ bool CChainState::AcceptBlockHeader(const CBlockHeader& block, CValidationState&
|
||||
|
||||
// TODO : ENABLE BLOCK CACHE IN SPECIFIC CASES
|
||||
if (hash != chainparams.GetConsensus().hashGenesisBlock) {
|
||||
|
||||
if (miSelf != mapBlockIndex.end()) {
|
||||
// Block header is already known.
|
||||
pindex = miSelf->second;
|
||||
@ -4198,6 +4199,8 @@ fs::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
|
||||
|
||||
CBlockIndex * CChainState::InsertBlockIndex(const uint256& hash)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
if (hash.IsNull())
|
||||
return nullptr;
|
||||
|
||||
@ -4342,6 +4345,8 @@ bool static LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_RE
|
||||
|
||||
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) {
|
||||
@ -4356,10 +4361,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);
|
||||
|
||||
g_chainstate.PruneBlockIndexCandidates();
|
||||
|
||||
@ -4749,26 +4755,31 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
|
||||
blkdat >> block;
|
||||
nRewind = blkdat.GetPos();
|
||||
|
||||
// detect out of order blocks, and store them for later
|
||||
uint256 hash = block.GetHash();
|
||||
if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
|
||||
LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
|
||||
block.hashPrevBlock.ToString());
|
||||
if (dbp)
|
||||
mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
|
||||
continue;
|
||||
}
|
||||
|
||||
// process in case the block isn't known yet
|
||||
if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
|
||||
{
|
||||
LOCK(cs_main);
|
||||
CValidationState state;
|
||||
if (g_chainstate.AcceptBlock(pblock, state, chainparams, nullptr, true, dbp, nullptr))
|
||||
nLoaded++;
|
||||
if (state.IsError())
|
||||
break;
|
||||
} else if (hash != chainparams.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);
|
||||
// detect out of order blocks, and store them for later
|
||||
if (hash != chainparams.GetConsensus().hashGenesisBlock && !LookupBlockIndex(block.hashPrevBlock)) {
|
||||
LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
|
||||
block.hashPrevBlock.ToString());
|
||||
if (dbp)
|
||||
mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
|
||||
continue;
|
||||
}
|
||||
|
||||
// process in case the block isn't known yet
|
||||
CBlockIndex* pindex = LookupBlockIndex(hash);
|
||||
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
|
||||
CValidationState state;
|
||||
if (g_chainstate.AcceptBlock(pblock, state, chainparams, nullptr, true, dbp, nullptr)) {
|
||||
nLoaded++;
|
||||
}
|
||||
if (state.IsError()) {
|
||||
break;
|
||||
}
|
||||
} else if (hash != chainparams.GetConsensus().hashGenesisBlock && pindex->nHeight % 1000 == 0) {
|
||||
LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), pindex->nHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// Activate the genesis block so normal node progress can continue
|
||||
|
@ -441,6 +441,13 @@ public:
|
||||
/** 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);
|
||||
|
||||
|
@ -343,9 +343,10 @@ UniValue importprunedfunds(const JSONRPCRequest& request)
|
||||
if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) == merkleBlock.header.hashMerkleRoot) {
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
|
||||
const CBlockIndex* pindex = LookupBlockIndex(merkleBlock.header.GetHash());
|
||||
if (!pindex || !chainActive.Contains(pindex)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
|
||||
}
|
||||
|
||||
std::vector<uint256>::const_iterator it;
|
||||
if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx))==vMatch.end()) {
|
||||
|
@ -106,7 +106,7 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
|
||||
{
|
||||
entry.pushKV("blockhash", wtx.hashBlock.GetHex());
|
||||
entry.pushKV("blockindex", wtx.nIndex);
|
||||
entry.pushKV("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime());
|
||||
entry.pushKV("blocktime", LookupBlockIndex(wtx.hashBlock)->GetBlockTime());
|
||||
} else {
|
||||
entry.pushKV("trusted", wtx.IsTrusted());
|
||||
}
|
||||
@ -1943,11 +1943,10 @@ UniValue listsinceblock(const JSONRPCRequest& request)
|
||||
uint256 blockId;
|
||||
|
||||
blockId.SetHex(request.params[0].get_str());
|
||||
BlockMap::iterator it = mapBlockIndex.find(blockId);
|
||||
if (it == mapBlockIndex.end()) {
|
||||
paltindex = pindex = LookupBlockIndex(blockId);
|
||||
if (!pindex) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
}
|
||||
paltindex = pindex = it->second;
|
||||
if (chainActive[pindex->nHeight] != pindex) {
|
||||
// the block being asked for is a part of a deactivated chain;
|
||||
// we don't want to depend on its perceived height in the block
|
||||
|
@ -1369,11 +1369,9 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
|
||||
LOCK2(cs_main, cs_wallet); // check "LOCK2(cs_main, pwallet->cs_wallet);" in WalletBatch::LoadWallet()
|
||||
|
||||
int conflictconfirms = 0;
|
||||
if (mapBlockIndex.count(hashBlock)) {
|
||||
CBlockIndex* pindex = mapBlockIndex[hashBlock];
|
||||
if (chainActive.Contains(pindex)) {
|
||||
conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1);
|
||||
}
|
||||
CBlockIndex* pindex = LookupBlockIndex(hashBlock);
|
||||
if (pindex && chainActive.Contains(pindex)) {
|
||||
conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1);
|
||||
}
|
||||
// If number of conflict confirms cannot be determined, this means
|
||||
// that the block is still unknown or not yet part of the main chain,
|
||||
@ -4918,10 +4916,10 @@ void CWallet::GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) c
|
||||
for (const auto& entry : mapWallet) {
|
||||
// iterate over all wallet transactions...
|
||||
const CWalletTx &wtx = entry.second;
|
||||
BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
|
||||
if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
|
||||
CBlockIndex* pindex = LookupBlockIndex(wtx.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);
|
||||
@ -4929,7 +4927,7 @@ void CWallet::GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) c
|
||||
// ... and all their affected keys
|
||||
std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
|
||||
if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
|
||||
rit->second = blit->second;
|
||||
rit->second = pindex;
|
||||
}
|
||||
vAffected.clear();
|
||||
}
|
||||
@ -4966,7 +4964,12 @@ unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
|
||||
{
|
||||
unsigned int nTimeSmart = wtx.nTimeReceived;
|
||||
if (!wtx.hashUnset()) {
|
||||
if (mapBlockIndex.count(wtx.hashBlock)) {
|
||||
const CBlockIndex* pindex = nullptr;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindex = LookupBlockIndex(wtx.hashBlock);
|
||||
}
|
||||
if (pindex) {
|
||||
int64_t latestNow = wtx.nTimeReceived;
|
||||
int64_t latestEntry = 0;
|
||||
|
||||
@ -4997,7 +5000,7 @@ unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
|
||||
}
|
||||
}
|
||||
|
||||
int64_t blocktime = mapBlockIndex[wtx.hashBlock]->GetBlockTime();
|
||||
int64_t blocktime = pindex->GetBlockTime();
|
||||
nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
|
||||
} else {
|
||||
LogPrintf("%s: found %s in block %s not in index\n", __func__, wtx.GetHash().ToString(), wtx.hashBlock.ToString());
|
||||
@ -5245,6 +5248,8 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
|
||||
// Try to top up keypool. No-op if the wallet is locked.
|
||||
walletInstance->TopUpKeyPool();
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
CBlockIndex *pindexRescan = chainActive.Genesis();
|
||||
if (!gArgs.GetBoolArg("-rescan", false))
|
||||
{
|
||||
@ -5569,29 +5574,17 @@ int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
|
||||
int nResult;
|
||||
|
||||
if (hashUnset())
|
||||
nResult = 0;
|
||||
else {
|
||||
AssertLockHeld(cs_main);
|
||||
return 0;
|
||||
|
||||
// Find the block it claims to be in
|
||||
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
|
||||
if (mi == mapBlockIndex.end())
|
||||
nResult = 0;
|
||||
else {
|
||||
CBlockIndex* pindex = (*mi).second;
|
||||
if (!pindex || !chainActive.Contains(pindex))
|
||||
nResult = 0;
|
||||
else {
|
||||
pindexRet = pindex;
|
||||
nResult = ((nIndex == -1) ? (-1) : 1) * (chainActive.Height() - pindex->nHeight + 1);
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
if (nResult == 0 && !mempool.exists(GetHash()))
|
||||
return -1; // Not in chain, not in mempool
|
||||
}
|
||||
}
|
||||
}
|
||||
// Find the block it claims to be in
|
||||
CBlockIndex* pindex = LookupBlockIndex(hashBlock);
|
||||
if (!pindex || !chainActive.Contains(pindex))
|
||||
return 0;
|
||||
|
||||
return nResult;
|
||||
pindexRet = pindex;
|
||||
return ((nIndex == -1) ? (-1) : 1) * (chainActive.Height() - pindex->nHeight + 1);
|
||||
}
|
||||
|
||||
bool CMerkleTx::IsLockedByInstantSend() const
|
||||
|
Loading…
Reference in New Issue
Block a user