You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
3242
+
3243
+
// Iterate over the entire block tree, using depth-first search.
3244
+
// Along the way, remember whether there are blocks on the path from genesis
3245
+
// block being explored which are the first to have certain properties.
3246
+
size_t nNodes = 0;
3247
+
int nHeight = 0;
3248
+
CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
3249
+
CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
3250
+
CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
3251
+
CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
3252
+
CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
assert(pindex->GetBlockHash() == Params().HashGenesisBlock()); // Genesis block's hash must match.
3265
+
assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
3266
+
}
3267
+
assert((pindexFirstMissing != NULL) == (pindex->nChainTx == 0)); // nChainTx == 0 is used to signal that all parent block's transaction data is available.
3268
+
assert(pindex->nHeight == nHeight); // nHeight must be consistent.
3269
+
assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
3270
+
assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
3271
+
assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
3272
+
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
3273
+
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
3274
+
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
3275
+
if (pindexFirstInvalid == NULL) {
3276
+
// Checks for not-invalid blocks.
3277
+
assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
3278
+
}
3279
+
if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstMissing == NULL) {
3280
+
if (pindexFirstInvalid == NULL) { // If this block sorts at least as good as the current tip and is valid, it must be in setBlockIndexCandidates.
3281
+
assert(setBlockIndexCandidates.count(pindex));
3282
+
}
3283
+
} else { // If this block sorts worse than the current tip, it cannot be in setBlockIndexCandidates.
if (pindexFirstInvalid == NULL) { // If this block has block data available, some parent doesn't, and has no invalid parents, it must be in mapBlocksUnlinked.
3299
+
assert(foundInUnlinked);
3300
+
}
3301
+
} else { // If this block does not have block data available, or all parents do, it cannot be in mapBlocksUnlinked.
3302
+
assert(!foundInUnlinked);
3303
+
}
3304
+
// assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
3305
+
// End: actual consistency checks.
3306
+
3307
+
// Try descending into the first subnode.
3308
+
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
3309
+
if (range.first != range.second) {
3310
+
// A subnode was found.
3311
+
pindex = range.first->second;
3312
+
nHeight++;
3313
+
continue;
3314
+
}
3315
+
// This is a leaf node.
3316
+
// Move upwards until we reach a node of which we have not yet visited the last child.
3317
+
while (pindex) {
3318
+
// We are going to either move to a parent or a sibling of pindex.
3319
+
// If pindex was the first with a certain property, unset the corresponding variable.
3320
+
if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
3321
+
if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
3322
+
if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
3323
+
if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
3324
+
if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
0 commit comments