Skip to content

Commit

Permalink
doc: Improve comments describing setBlockIndexCandidates checks
Browse files Browse the repository at this point in the history
The checks are changing slightly in the next commit, so try to explains the
ones that exist to avoid confusion
(bitcoin#29370 (comment))
  • Loading branch information
ryanofsky committed Mar 18, 2024
1 parent 0fd915e commit 9b97d5b
Showing 1 changed file with 32 additions and 9 deletions.
41 changes: 32 additions & 9 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5126,19 +5126,42 @@ void ChainstateManager::CheckBlockIndex()
// Chainstate-specific checks on setBlockIndexCandidates
for (auto c : GetAll()) {
if (c->m_chain.Tip() == nullptr) continue;
// Two main factors determine whether pindex is a candidate in
// setBlockIndexCandidates:
//
// - If pindex has less work than the chain tip, it should not be a
// candidate, and this will be asserted below. Otherwise it is a
// potential candidate.
//
// - If pindex or one of its parent blocks never downloaded
// transactions (pindexFirstNeverProcessed is non-null), it should
// not be a candidate, and this will be asserted below. Otherwise
// it is a potential candidate.
if (!CBlockIndexWorkComparator()(pindex, c->m_chain.Tip()) && pindexFirstNeverProcessed == nullptr) {
// If pindex was detected as invalid (pindexFirstInvalid is
// non-null), it is not required to be in
// setBlockIndexCandidates.
if (pindexFirstInvalid == nullptr) {
const bool is_active = c == &ActiveChainstate();
// If this block sorts at least as good as the current tip and
// is valid and we have all data for its parents, it must be in
// setBlockIndexCandidates. m_chain.Tip() must also be there
// even if some data has been pruned.
// If pindex and all its parents downloaded transactions,
// and the transactions were not pruned (pindexFirstMissing
// is null), it is a potential candidate. The check
// excludes pruned blocks, because if any blocks were
// pruned between pindex the current chain tip, pindex will
// only temporarily be added to setBlockIndexCandidates,
// before being moved to m_blocks_unlinked. This check
// could be improved to verify that if all blocks between
// the chain tip and pindex have data, pindex must be a
// candidate.
//
// If pindex is the chain tip, it also is a potential
// candidate.
if ((pindexFirstMissing == nullptr || pindex == c->m_chain.Tip())) {
// The active chainstate should always have this block
// as a candidate, but a background chainstate should
// only have it if it is an ancestor of the snapshot base.
if (is_active || GetSnapshotBaseBlock()->GetAncestor(pindex->nHeight) == pindex) {
// If this chainstate is the active chainstate, pindex
// must be in setBlockIndexCandidates. Otherwise, this
// chainstate is a background validation chainstate, and
// pindex only needs to be added if it is an ancestor of
// the snapshot that is being validated.
if (c == &ActiveChainstate() || GetSnapshotBaseBlock()->GetAncestor(pindex->nHeight) == pindex) {
assert(c->setBlockIndexCandidates.count(pindex));
}
}
Expand Down

0 comments on commit 9b97d5b

Please sign in to comment.