mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-07 14:18:18 +02:00
Merge bitcoin/bitcoin#34521: validation: fix UB in LoadChainTip
20ae9b98eaExtend functional test for setBlockIndexCandidates UB (marcofleon)854a6d5a9avalidation: fix UB in LoadChainTip (marcofleon)9249e6089evalidation: remove LoadChainTip call from ActivateSnapshot (marcofleon) Pull request description: Addresses https://github.com/bitcoin/bitcoin/issues/34503. See this issue for more details as well. Fixes a bug where, under certain conditions, `setBlockIndexCandidates` had blocks in it that were worse than the tip. The block index candidate set uses `nSequenceId` as a sort key, so modifying this field while blocks are in the set results in undefined behavior. This PR populates `setBlockIndexCandidates` after the `nSequenceId` modifications, avoiding the UB. ACKs for top commit: achow101: ACK20ae9b98easedited: Re-ACK20ae9b98easipa: Code review ACK20ae9b98eaTree-SHA512: 121c170bb70fb6365089d578db63c811e7926e129d7206e569947f7a1f6c5ddc8d5f4937b80f1ba1b7d7daa42789b143ca5b56f154b7ab968a1cd55f925f378d
This commit is contained in:
@@ -126,6 +126,13 @@ static ChainstateLoadResult CompleteChainstateInitialization(
|
||||
}
|
||||
}
|
||||
|
||||
// Populate setBlockIndexCandidates in a separate loop, after all LoadChainTip()
|
||||
// calls have finished modifying nSequenceId. Because nSequenceId is used in the
|
||||
// set's comparator, changing it while blocks are in the set would be UB.
|
||||
for (const auto& chainstate : chainman.m_chainstates) {
|
||||
chainstate->PopulateBlockIndexCandidates();
|
||||
}
|
||||
|
||||
const auto& chainstates{chainman.m_chainstates};
|
||||
if (std::any_of(chainstates.begin(), chainstates.end(),
|
||||
[](const auto& cs) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return cs->NeedsRedownload(); })) {
|
||||
|
||||
Reference in New Issue
Block a user