refactor: use clearer variables in InvalidateBlock()
Improve upon the variable name for `invalid_walk_tip` to make the InvalidateBlock logic easier to read. Block tip before disconnection is now tracked directly via `disconnected_tip`, and `new_tip` is the tip after the disconnect. Co-authored-by: stickies-v <stickies-v@protonmail.com>
This commit is contained in:
1 parent
18f11695c7
commit
120c631e16
1 file changed
+18
-17
+18
-17
@@ -3565,10 +3565,6 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
|||||||
assert(pindex);
|
assert(pindex);
|
||||||
if (pindex->nHeight == 0) return false;
|
if (pindex->nHeight == 0) return false;
|
||||||
|
|
||||||
CBlockIndex* to_mark_failed = pindex;
|
|
||||||
bool pindex_was_in_chain = false;
|
|
||||||
int disconnected = 0;
|
|
||||||
|
|
||||||
// We do not allow ActivateBestChain() to run while InvalidateBlock() is
|
// We do not allow ActivateBestChain() to run while InvalidateBlock() is
|
||||||
// running, as that could cause the tip to change while we disconnect
|
// running, as that could cause the tip to change while we disconnect
|
||||||
// blocks.
|
// blocks.
|
||||||
@@ -3600,6 +3596,10 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CBlockIndex* to_mark_failed = pindex;
|
||||||
|
bool pindex_was_in_chain = false;
|
||||||
|
int disconnected = 0;
|
||||||
|
|
||||||
// Disconnect (descendants of) pindex, and mark them invalid.
|
// Disconnect (descendants of) pindex, and mark them invalid.
|
||||||
while (true) {
|
while (true) {
|
||||||
if (m_chainman.m_interrupt) break;
|
if (m_chainman.m_interrupt) break;
|
||||||
@@ -3613,7 +3613,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
|||||||
LOCK(MempoolMutex());
|
LOCK(MempoolMutex());
|
||||||
if (!m_chain.Contains(pindex)) break;
|
if (!m_chain.Contains(pindex)) break;
|
||||||
pindex_was_in_chain = true;
|
pindex_was_in_chain = true;
|
||||||
CBlockIndex *invalid_walk_tip = m_chain.Tip();
|
CBlockIndex* disconnected_tip{m_chain.Tip()};
|
||||||
|
|
||||||
// ActivateBestChain considers blocks already in m_chain
|
// ActivateBestChain considers blocks already in m_chain
|
||||||
// unconditionally valid already, so force disconnect away from it.
|
// unconditionally valid already, so force disconnect away from it.
|
||||||
@@ -3626,32 +3626,33 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
|||||||
// keeping the mempool up to date is probably futile anyway).
|
// keeping the mempool up to date is probably futile anyway).
|
||||||
MaybeUpdateMempoolForReorg(disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret);
|
MaybeUpdateMempoolForReorg(disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret);
|
||||||
if (!ret) return false;
|
if (!ret) return false;
|
||||||
assert(invalid_walk_tip->pprev == m_chain.Tip());
|
CBlockIndex* new_tip{m_chain.Tip()};
|
||||||
|
assert(disconnected_tip->pprev == new_tip);
|
||||||
|
|
||||||
// We immediately mark the disconnected blocks as invalid.
|
// We immediately mark the disconnected blocks as invalid.
|
||||||
// This prevents a case where pruned nodes may fail to invalidateblock
|
// This prevents a case where pruned nodes may fail to invalidateblock
|
||||||
// and be left unable to start as they have no tip candidates (as there
|
// and be left unable to start as they have no tip candidates (as there
|
||||||
// are no blocks that meet the "have data and are not invalid per
|
// are no blocks that meet the "have data and are not invalid per
|
||||||
// nStatus" criteria for inclusion in setBlockIndexCandidates).
|
// nStatus" criteria for inclusion in setBlockIndexCandidates).
|
||||||
invalid_walk_tip->nStatus |= BLOCK_FAILED_VALID;
|
disconnected_tip->nStatus |= BLOCK_FAILED_VALID;
|
||||||
m_blockman.m_dirty_blockindex.insert(invalid_walk_tip);
|
m_blockman.m_dirty_blockindex.insert(disconnected_tip);
|
||||||
setBlockIndexCandidates.erase(invalid_walk_tip);
|
setBlockIndexCandidates.erase(disconnected_tip);
|
||||||
setBlockIndexCandidates.insert(invalid_walk_tip->pprev);
|
setBlockIndexCandidates.insert(new_tip);
|
||||||
|
|
||||||
// Mark out-of-chain descendants of the invalidated block as invalid
|
// Mark out-of-chain descendants of the invalidated block as invalid
|
||||||
// Add any equal or more work headers that are not invalidated to setBlockIndexCandidates
|
// Add any equal or more work headers that are not invalidated to setBlockIndexCandidates
|
||||||
// Recalculate m_best_header if it became invalid.
|
// Recalculate m_best_header if it became invalid.
|
||||||
auto candidate_it = highpow_outofchain_headers.lower_bound(invalid_walk_tip->pprev->nChainWork);
|
auto candidate_it = highpow_outofchain_headers.lower_bound(new_tip->nChainWork);
|
||||||
|
|
||||||
const bool best_header_needs_update{m_chainman.m_best_header->GetAncestor(invalid_walk_tip->nHeight) == invalid_walk_tip};
|
const bool best_header_needs_update{m_chainman.m_best_header->GetAncestor(disconnected_tip->nHeight) == disconnected_tip};
|
||||||
if (best_header_needs_update) {
|
if (best_header_needs_update) {
|
||||||
// pprev is definitely still valid at this point, but there may be better ones
|
// new_tip is definitely still valid at this point, but there may be better ones
|
||||||
m_chainman.m_best_header = invalid_walk_tip->pprev;
|
m_chainman.m_best_header = new_tip;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (candidate_it != highpow_outofchain_headers.end()) {
|
while (candidate_it != highpow_outofchain_headers.end()) {
|
||||||
CBlockIndex* candidate{candidate_it->second};
|
CBlockIndex* candidate{candidate_it->second};
|
||||||
if (candidate->GetAncestor(invalid_walk_tip->nHeight) == invalid_walk_tip) {
|
if (candidate->GetAncestor(disconnected_tip->nHeight) == disconnected_tip) {
|
||||||
// Children of failed blocks are marked as BLOCK_FAILED_VALID.
|
// Children of failed blocks are marked as BLOCK_FAILED_VALID.
|
||||||
candidate->nStatus |= BLOCK_FAILED_VALID;
|
candidate->nStatus |= BLOCK_FAILED_VALID;
|
||||||
m_blockman.m_dirty_blockindex.insert(candidate);
|
m_blockman.m_dirty_blockindex.insert(candidate);
|
||||||
@@ -3660,7 +3661,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
|||||||
candidate_it = highpow_outofchain_headers.erase(candidate_it);
|
candidate_it = highpow_outofchain_headers.erase(candidate_it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!CBlockIndexWorkComparator()(candidate, invalid_walk_tip->pprev) &&
|
if (!CBlockIndexWorkComparator()(candidate, new_tip) &&
|
||||||
candidate->IsValid(BLOCK_VALID_TRANSACTIONS) &&
|
candidate->IsValid(BLOCK_VALID_TRANSACTIONS) &&
|
||||||
candidate->HaveNumChainTxs()) {
|
candidate->HaveNumChainTxs()) {
|
||||||
setBlockIndexCandidates.insert(candidate);
|
setBlockIndexCandidates.insert(candidate);
|
||||||
@@ -3675,7 +3676,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Track the last disconnected block to call InvalidChainFound on it.
|
// Track the last disconnected block to call InvalidChainFound on it.
|
||||||
to_mark_failed = invalid_walk_tip;
|
to_mark_failed = disconnected_tip;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_chainman.CheckBlockIndex();
|
m_chainman.CheckBlockIndex();
|
||||||
|
|||||||
Reference in new issue
Block a user