Make chainMostWork correspond to the chain with the most work in it, that isn't known to be invalid (it's however far from certain to be valid).
| 1433 | // Make chainMostWork correspond to the chain with the most work in it, that isn't |
| 1434 | // known to be invalid (it's however far from certain to be valid). |
| 1435 | void static FindMostWorkChain() { |
| 1436 | CBlockIndex *pIndexNew = nullptr; |
| 1437 | |
| 1438 | // In case the current best is invalid, do not consider it. |
| 1439 | while (chainMostWork.Tip() && (chainMostWork.Tip()->nStatus & BLOCK_FAILED_MASK)) { |
| 1440 | setBlockIndexValid.erase(chainMostWork.Tip()); |
| 1441 | chainMostWork.SetTip(chainMostWork.Tip()->pprev); |
| 1442 | } |
| 1443 | |
| 1444 | do { |
| 1445 | // Find the best candidate header. |
| 1446 | { |
| 1447 | set<CBlockIndex *, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexValid.rbegin(); |
| 1448 | if (it == setBlockIndexValid.rend()) |
| 1449 | return; |
| 1450 | pIndexNew = *it; |
| 1451 | } |
| 1452 | |
| 1453 | // Check whether all blocks on the path between the currently active chain and the candidate are valid. |
| 1454 | // Just going until the active chain is an optimization, as we know all blocks in it are valid already. |
| 1455 | CBlockIndex *pindexTest = pIndexNew; |
| 1456 | bool fInvalidAncestor = false; |
| 1457 | while (pindexTest && !chainActive.Contains(pindexTest)) { |
| 1458 | if (pindexTest->nStatus & BLOCK_FAILED_MASK) { |
| 1459 | // Candidate has an invalid ancestor, remove entire chain from the set. |
| 1460 | if (pIndexBestInvalid == nullptr || pIndexNew->height > pIndexBestInvalid->height) |
| 1461 | pIndexBestInvalid = pIndexNew; |
| 1462 | CBlockIndex *pindexFailed = pIndexNew; |
| 1463 | while (pindexTest != pindexFailed) { |
| 1464 | pindexFailed->nStatus |= BLOCK_FAILED_CHILD; |
| 1465 | setBlockIndexValid.erase(pindexFailed); |
| 1466 | pindexFailed = pindexFailed->pprev; |
| 1467 | } |
| 1468 | fInvalidAncestor = true; |
| 1469 | break; |
| 1470 | } |
| 1471 | pindexTest = pindexTest->pprev; |
| 1472 | } |
| 1473 | if (fInvalidAncestor) |
| 1474 | continue; |
| 1475 | |
| 1476 | break; |
| 1477 | } while (true); |
| 1478 | |
| 1479 | // Check whether it's actually an improvement. |
| 1480 | if (chainMostWork.Tip() && !CBlockIndexWorkComparator()(chainMostWork.Tip(), pIndexNew)) |
| 1481 | return; |
| 1482 | |
| 1483 | // We have a new best. |
| 1484 | chainMostWork.SetTip(pIndexNew); |
| 1485 | } |
| 1486 | |
| 1487 | bool ConnectBlockOnFinChain(CBlockIndex* pNewIndex, CValidationState& state) { |
| 1488 | if (pNewIndex && (chainActive.Tip() == pNewIndex->pprev)) { |
no test coverage detected