mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-05-13 15:33:51 +02:00
Merge bitcoin/bitcoin#34884: validation: remove unused code in FindMostWorkChain
ba01b00d45refactor: use for loops in FindMostWorkChain (stratospher)aa0eef735btest: add InvalidateBlock/ReconsiderBlock asymmetry test (stratospher)1b0b3e2c2cvalidation: remove redundant marking in FindMostWorkChain (stratospher) Pull request description: recent PRs like #31405, #30666 mark all `m_block_index` descendants as invalid immediately whenever an invalid block is encountered in `SetBlockFailureFlags`. so by the time we reach `FindMostWorkChain`, the block in `setBlockIndexCandidates` already has `BLOCK_FAILED_VALID` set on it - not just on its ancestor. this means `pindexTest = pindexFailed` whenever `fFailedChain` fires, and the inner `while (pindexTest != pindexFailed)` loop body is never reached! I think we can remove it but I've just replaced it with `Assume` in this PR for safety + good to document this invariant in case the code changes in future. (noticed by @ stickies-v in https://github.com/bitcoin/bitcoin/pull/32950#discussion_r2815053885) the second commit is unrelated and adds a unit test for the situation in https://github.com/bitcoin/bitcoin/issues/32173 ACKs for top commit: fjahr: re-ACKba01b00d45optout21: crACKba01b00d45w0xlt: ACKba01b00d45ryanofsky: Code review ACKba01b00d45, just tweaking comment and for loop condition since last review. Tree-SHA512: a8be3c30b1c41b76690d16d850e87e9e71fa6a1ecaa8b90ec997ffee1aace48b336a7009a480cd016103759d79c964b3d761a13ae936523808b2930beb68dae5
This commit is contained in:
@@ -3127,9 +3127,8 @@ CBlockIndex* Chainstate::FindMostWorkChain()
|
||||
|
||||
// Check whether all blocks on the path between the currently active chain and the candidate are valid.
|
||||
// Just going until the active chain is an optimization, as we know all blocks in it are valid already.
|
||||
CBlockIndex *pindexTest = pindexNew;
|
||||
bool fInvalidAncestor = false;
|
||||
while (pindexTest && !m_chain.Contains(pindexTest)) {
|
||||
for (CBlockIndex *pindexTest = pindexNew; pindexTest && !m_chain.Contains(pindexTest); pindexTest = pindexTest->pprev) {
|
||||
assert(pindexTest->HaveNumChainTxs() || pindexTest->nHeight == 0);
|
||||
|
||||
// Pruned nodes may have entries in setBlockIndexCandidates for
|
||||
@@ -3143,27 +3142,21 @@ CBlockIndex* Chainstate::FindMostWorkChain()
|
||||
if (fFailedChain && (m_chainman.m_best_invalid == nullptr || pindexNew->nChainWork > m_chainman.m_best_invalid->nChainWork)) {
|
||||
m_chainman.m_best_invalid = pindexNew;
|
||||
}
|
||||
CBlockIndex *pindexFailed = pindexNew;
|
||||
// Remove the entire chain from the set.
|
||||
while (pindexTest != pindexFailed) {
|
||||
if (fFailedChain) {
|
||||
pindexFailed->nStatus |= BLOCK_FAILED_VALID;
|
||||
m_blockman.m_dirty_blockindex.insert(pindexFailed);
|
||||
} else if (fMissingData) {
|
||||
// If we're missing data, then add back to m_blocks_unlinked,
|
||||
// so that if the block arrives in the future we can try adding
|
||||
// to setBlockIndexCandidates again.
|
||||
for (CBlockIndex *pindexFailed = pindexNew; pindexFailed != pindexTest; pindexFailed = pindexFailed->pprev) {
|
||||
if (fMissingData && !fFailedChain) {
|
||||
// If we're missing data and not a descendant of an invalid block,
|
||||
// then add back to m_blocks_unlinked, so that if the block arrives in the future
|
||||
// we can try adding to setBlockIndexCandidates again.
|
||||
m_blockman.m_blocks_unlinked.insert(
|
||||
std::make_pair(pindexFailed->pprev, pindexFailed));
|
||||
}
|
||||
setBlockIndexCandidates.erase(pindexFailed);
|
||||
pindexFailed = pindexFailed->pprev;
|
||||
}
|
||||
setBlockIndexCandidates.erase(pindexTest);
|
||||
fInvalidAncestor = true;
|
||||
break;
|
||||
}
|
||||
pindexTest = pindexTest->pprev;
|
||||
}
|
||||
if (!fInvalidAncestor)
|
||||
return pindexNew;
|
||||
|
||||
Reference in New Issue
Block a user