| 5902 | } |
| 5903 | |
| 5904 | static void CheckBlockIndex(const Consensus::Params& consensusParams) |
| 5905 | { |
| 5906 | if (!fCheckBlockIndex) return; |
| 5907 | |
| 5908 | //LOCK(cs_main); |
| 5909 | |
| 5910 | // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain, |
| 5911 | // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when |
| 5912 | // iterating the block tree require that chainActive has been initialized.) |
| 5913 | if (chainActive.Height() < 0) { |
| 5914 | assert(mapBlockIndex.size() <= 1); |
| 5915 | return; |
| 5916 | } |
| 5917 | |
| 5918 | // Build forward-pointing map of the entire block tree. |
| 5919 | std::multimap<CBlockIndex*, CBlockIndex*> forward; |
| 5920 | for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) { |
| 5921 | forward.insert(std::make_pair(it->second->pprev, it->second)); |
| 5922 | } |
| 5923 | |
| 5924 | assert(forward.size() == mapBlockIndex.size()); |
| 5925 | |
| 5926 | std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL); |
| 5927 | CBlockIndex* pindex = rangeGenesis.first->second; |
| 5928 | rangeGenesis.first++; |
| 5929 | assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL. |
| 5930 | |
| 5931 | // Iterate over the entire block tree, using depth-first search. |
| 5932 | // Along the way, remember whether there are blocks on the path from genesis |
| 5933 | // block being explored which are the first to have certain properties. |
| 5934 | size_t nNodes = 0; |
| 5935 | int nHeight = 0; |
| 5936 | CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid. |
| 5937 | CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA. |
| 5938 | CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0. |
| 5939 | CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not). |
| 5940 | CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not) |
| 5941 | CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not). |
| 5942 | CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not). |
| 5943 | while (pindex != NULL) { |
| 5944 | nNodes++; |
| 5945 | if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex; |
| 5946 | if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex; |
| 5947 | if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex; |
| 5948 | if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex; |
| 5949 | if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex; |
| 5950 | if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex; |
| 5951 | if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex; |
| 5952 | |
| 5953 | // Begin: actual consistency checks. |
| 5954 | if (pindex->pprev == NULL) { |
| 5955 | // Genesis block checks. |
| 5956 | assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match. |
| 5957 | assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block. |
| 5958 | } |
| 5959 | |
| 5960 | if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked |
| 5961 | // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred). |
no test coverage detected