| 4083 | } |
| 4084 | |
| 4085 | bool CChainState::LoadBlockIndex(const Consensus::Params& consensus_params, CBlockTreeDB& blocktree) |
| 4086 | { |
| 4087 | if (!blocktree.LoadBlockIndexGuts(consensus_params, [this](const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return this->InsertBlockIndex(hash); })) |
| 4088 | return false; |
| 4089 | |
| 4090 | boost::this_thread::interruption_point(); |
| 4091 | |
| 4092 | // Calculate nChainWork |
| 4093 | std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight; |
| 4094 | vSortedByHeight.reserve(mapBlockIndex.size()); |
| 4095 | for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex) |
| 4096 | { |
| 4097 | CBlockIndex* pindex = item.second; |
| 4098 | vSortedByHeight.push_back(std::make_pair(pindex->nHeight, pindex)); |
| 4099 | } |
| 4100 | sort(vSortedByHeight.begin(), vSortedByHeight.end()); |
| 4101 | for (const std::pair<int, CBlockIndex*>& item : vSortedByHeight) |
| 4102 | { |
| 4103 | CBlockIndex* pindex = item.second; |
| 4104 | pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex); |
| 4105 | pindex->nTimeMax = (pindex->pprev ? std::max(pindex->pprev->nTimeMax, pindex->nTime) : pindex->nTime); |
| 4106 | // We can link the chain of blocks for which we've received transactions at some point. |
| 4107 | // Pruned nodes may have deleted the block. |
| 4108 | if (pindex->nTx > 0) { |
| 4109 | if (pindex->pprev) { |
| 4110 | if (pindex->pprev->nChainTx) { |
| 4111 | pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx; |
| 4112 | } else { |
| 4113 | pindex->nChainTx = 0; |
| 4114 | mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex)); |
| 4115 | } |
| 4116 | } else { |
| 4117 | pindex->nChainTx = pindex->nTx; |
| 4118 | } |
| 4119 | } |
| 4120 | if (!(pindex->nStatus & BLOCK_FAILED_MASK) && pindex->pprev && (pindex->pprev->nStatus & BLOCK_FAILED_MASK)) { |
| 4121 | pindex->nStatus |= BLOCK_FAILED_CHILD; |
| 4122 | setDirtyBlockIndex.insert(pindex); |
| 4123 | } |
| 4124 | if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == nullptr)) |
| 4125 | setBlockIndexCandidates.insert(pindex); |
| 4126 | if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork)) |
| 4127 | pindexBestInvalid = pindex; |
| 4128 | if (pindex->pprev) |
| 4129 | pindex->BuildSkip(); |
| 4130 | if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == nullptr || CBlockIndexWorkComparator()(pindexBestHeader, pindex))) |
| 4131 | pindexBestHeader = pindex; |
| 4132 | } |
| 4133 | |
| 4134 | return true; |
| 4135 | } |
| 4136 | |
| 4137 | bool static LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main) |
| 4138 | { |
no test coverage detected