@@ -5126,19 +5126,42 @@ void ChainstateManager::CheckBlockIndex()
51265126 // Chainstate-specific checks on setBlockIndexCandidates
51275127 for (auto c : GetAll ()) {
51285128 if (c->m_chain .Tip () == nullptr ) continue ;
5129+ // Two main factors determine whether pindex is a candidate in
5130+ // setBlockIndexCandidates:
5131+ //
5132+ // - If pindex has less work than the chain tip, it should not be a
5133+ // candidate, and this will be asserted below. Otherwise it is a
5134+ // potential candidate.
5135+ //
5136+ // - If pindex or one of its parent blocks never downloaded
5137+ // transactions (pindexFirstNeverProcessed is non-null), it should
5138+ // not be a candidate, and this will be asserted below. Otherwise
5139+ // it is a potential candidate.
51295140 if (!CBlockIndexWorkComparator ()(pindex, c->m_chain .Tip ()) && pindexFirstNeverProcessed == nullptr ) {
5141+ // If pindex was detected as invalid (pindexFirstInvalid is
5142+ // non-null), it is not required to be in
5143+ // setBlockIndexCandidates.
51305144 if (pindexFirstInvalid == nullptr ) {
5131- const bool is_active = c == &ActiveChainstate ();
5132- // If this block sorts at least as good as the current tip and
5133- // is valid and we have all data for its parents, it must be in
5134- // setBlockIndexCandidates. m_chain.Tip() must also be there
5135- // even if some data has been pruned.
5145+ // If pindex and all its parents downloaded transactions,
5146+ // and the transactions were not pruned (pindexFirstMissing
5147+ // is null), it is a potential candidate. The check
5148+ // excludes pruned blocks, because if any blocks were
5149+ // pruned between pindex the current chain tip, pindex will
5150+ // only temporarily be added to setBlockIndexCandidates,
5151+ // before being moved to m_blocks_unlinked. This check
5152+ // could be improved to verify that if all blocks between
5153+ // the chain tip and pindex have data, pindex must be a
5154+ // candidate.
51365155 //
5156+ // If pindex is the chain tip, it also is a potential
5157+ // candidate.
51375158 if ((pindexFirstMissing == nullptr || pindex == c->m_chain .Tip ())) {
5138- // The active chainstate should always have this block
5139- // as a candidate, but a background chainstate should
5140- // only have it if it is an ancestor of the snapshot base.
5141- if (is_active || GetSnapshotBaseBlock ()->GetAncestor (pindex->nHeight ) == pindex) {
5159+ // If this chainstate is the active chainstate, pindex
5160+ // must be in setBlockIndexCandidates. Otherwise, this
5161+ // chainstate is a background validation chainstate, and
5162+ // pindex only needs to be added if it is an ancestor of
5163+ // the snapshot that is being validated.
5164+ if (c == &ActiveChainstate () || GetSnapshotBaseBlock ()->GetAncestor (pindex->nHeight ) == pindex) {
51425165 assert (c->setBlockIndexCandidates .count (pindex));
51435166 }
51445167 }
0 commit comments