| 4260 | } |
| 4261 | |
| 4262 | void static CheckBlockIndex() |
| 4263 | { |
| 4264 | const Consensus::Params& consensusParams = Params().GetConsensus(); |
| 4265 | if (!fCheckBlockIndex) { |
| 4266 | return; |
| 4267 | } |
| 4268 | |
| 4269 | LOCK(cs_main); |
| 4270 | |
| 4271 | // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain, |
| 4272 | // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when |
| 4273 | // iterating the block tree require that chainActive has been initialized.) |
| 4274 | if (chainActive.Height() < 0) { |
| 4275 | assert(mapBlockIndex.size() <= 1); |
| 4276 | return; |
| 4277 | } |
| 4278 | |
| 4279 | // Build forward-pointing map of the entire block tree. |
| 4280 | std::multimap<CBlockIndex*,CBlockIndex*> forward; |
| 4281 | for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) { |
| 4282 | forward.insert(std::make_pair(it->second->pprev, it->second)); |
| 4283 | } |
| 4284 | |
| 4285 | assert(forward.size() == mapBlockIndex.size()); |
| 4286 | |
| 4287 | std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL); |
| 4288 | CBlockIndex *pindex = rangeGenesis.first->second; |
| 4289 | rangeGenesis.first++; |
| 4290 | assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL. |
| 4291 | |
| 4292 | // Iterate over the entire block tree, using depth-first search. |
| 4293 | // Along the way, remember whether there are blocks on the path from genesis |
| 4294 | // block being explored which are the first to have certain properties. |
| 4295 | size_t nNodes = 0; |
| 4296 | int nHeight = 0; |
| 4297 | CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid. |
| 4298 | CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA. |
| 4299 | CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0. |
| 4300 | CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not). |
| 4301 | CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not). |
| 4302 | CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not). |
| 4303 | CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not). |
| 4304 | while (pindex != NULL) { |
| 4305 | nNodes++; |
| 4306 | if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex; |
| 4307 | if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex; |
| 4308 | if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex; |
| 4309 | if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex; |
| 4310 | if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex; |
| 4311 | if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex; |
| 4312 | if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex; |
| 4313 | |
| 4314 | // Begin: actual consistency checks. |
| 4315 | if (pindex->pprev == NULL) { |
| 4316 | // Genesis block checks. |
| 4317 | assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match. |
| 4318 | assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block. |
| 4319 | } |