MCPcopy Create free account
hub / github.com/BTCGPU/BTCGPU / FindMostWorkChain

Method FindMostWorkChain

src/validation.cpp:2627–2696  ·  view source on GitHub ↗

* Return the tip of the chain with the most work in it, that isn't * known to be invalid (it's however far from certain to be valid). */

Source from the content-addressed store, hash-verified

2625 * known to be invalid (it's however far from certain to be valid).
2626 */
2627CBlockIndex* CChainState::FindMostWorkChain() {
2628 do {
2629 CBlockIndex *pindexNew = nullptr;
2630
2631 // Find the best candidate header.
2632 {
2633 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
2634 if (it == setBlockIndexCandidates.rend())
2635 return nullptr;
2636 pindexNew = *it;
2637 }
2638
2639 // If this block will cause a finalized block to be reorged, then we
2640 // mark it as invalid.
2641 if (pindexFinalized && !AreOnTheSameFork(pindexNew, pindexFinalized)) {
2642 LogPrintf("Mark block %s invalid because it forks prior to the finalization point %d.\n",
2643 pindexNew->GetBlockHash().ToString(),
2644 pindexFinalized->nHeight);
2645 pindexNew->nStatus |= BLOCK_FAILED_VALID;
2646 InvalidChainFound(pindexNew);
2647 }
2648
2649 // Check whether all blocks on the path between the currently active chain and the candidate are valid.
2650 // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
2651 CBlockIndex *pindexTest = pindexNew;
2652 bool fInvalidAncestor = false;
2653 while (pindexTest && !chainActive.Contains(pindexTest)) {
2654 assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
2655
2656 // Pruned nodes may have entries in setBlockIndexCandidates for
2657 // which block files have been deleted. Remove those as candidates
2658 // for the most work chain if we come across them; we can't switch
2659 // to a chain unless we have all the non-active-chain parent blocks.
2660 bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
2661 bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
2662 if (fFailedChain || fMissingData) {
2663 // Candidate chain is not usable (either invalid or missing data)
2664 if (fFailedChain && (pindexBestInvalid == nullptr || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
2665 pindexBestInvalid = pindexNew;
2666 CBlockIndex *pindexFailed = pindexNew;
2667 // Remove the entire chain from the set.
2668 while (pindexTest != pindexFailed) {
2669 if (fFailedChain) {
2670 pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
2671 } else if (fMissingData) {
2672 // If we're missing data, then add back to mapBlocksUnlinked,
2673 // so that if the block arrives in the future we can try adding
2674 // to setBlockIndexCandidates again.
2675 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
2676 }
2677 setBlockIndexCandidates.erase(pindexFailed);
2678 pindexFailed = pindexFailed->pprev;
2679 }
2680
2681 if (fFailedChain) {
2682 // We discovered a new chain tip that is either parked or
2683 // invalid, we may want to warn.
2684 CheckForkWarningConditionsOnNewFork(pindexNew);

Callers

nothing calls this directly

Calls 10

AreOnTheSameForkFunction · 0.85
InvalidChainFoundFunction · 0.85
rbeginMethod · 0.80
rendMethod · 0.80
ToStringMethod · 0.45
GetBlockHashMethod · 0.45
ContainsMethod · 0.45
insertMethod · 0.45
eraseMethod · 0.45

Tested by

no test coverage detected