@@ -5126,19 +5126,42 @@ void ChainstateManager::CheckBlockIndex()
5126
5126
// Chainstate-specific checks on setBlockIndexCandidates
5127
5127
for (auto c : GetAll ()) {
5128
5128
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.
5129
5140
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.
5130
5144
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.
5136
5155
//
5156
+ // If pindex is the chain tip, it also is a potential
5157
+ // candidate.
5137
5158
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) {
5142
5165
assert (c->setBlockIndexCandidates .count (pindex));
5143
5166
}
5144
5167
}
0 commit comments