Merge bitcoin/bitcoin#32950: validation: remove BLOCK_FAILED_CHILD

fb3e1bf9c9 test: check LoadBlockIndex correctly recomputes invalidity flags (stratospher)
29740c06ac validation: remove BLOCK_FAILED_MASK (stratospher)
b5b2956bda validation: reset BLOCK_FAILED_CHILD to BLOCK_FAILED_VALID when loading from disk (stratospher)
37bc207852 validation: stop using BLOCK_FAILED_CHILD (stratospher)
120c631e16 refactor: use clearer variables in InvalidateBlock() (stratospher)
18f11695c7 validation: don't update BLOCK_FAILED_VALID to BLOCK_FAILED_CHILD in InvalidateBlock (stratospher)

Pull request description:

  Fixes https://github.com/bitcoin/bitcoin/issues/32173

  even though we have a distinction between `BLOCK_FAILED_VALID` and `BLOCK_FAILED_CHILD` in the codebase,
  we don't use it for anything. Whenever we check for BlockStatus, we use `BLOCK_FAILED_MASK` which encompasses both of them.

  Since there is no functional difference between `BLOCK_FAILED_VALID` and `BLOCK_FAILED_CHILD` and it's added
  code complexity to correctly categorise them (ex: https://github.com/bitcoin/bitcoin/pull/31405#discussion_r1914366243, https://github.com/bitcoin/bitcoin/pull/16856#issuecomment-565506585), we could just remove it.

  Looking for conceptual feedback on whether it's better to improve handling of `BLOCK_FAILED_CHILD` in the codebase or remove `BLOCK_FAILED_CHILD`.

  Of less relevance, but it would also fix a `reconsiderblock` crash that could happen in the situation mentioned in https://github.com/bitcoin/bitcoin/issues/32173#issuecomment-2767030982

  Similar attempt in the past in https://github.com/bitcoin/bitcoin/pull/16856#issuecomment-568073859

ACKs for top commit:
  stickies-v:
    re-ACK fb3e1bf9c9
  alexanderwiederin:
    ACK fb3e1bf9c9
  mzumsande:
    re-ACK fb3e1bf9c9

Tree-SHA512: e97b739885c40a8c021966438e9767cc02bc183056236d6a8c64f6819347ae70c0fbcd71cc2528917560d9f4fd56aed45faf1b6c75d98de7b08b621693a97fbc
This commit is contained in:
merge-script
2026-02-18 15:47:57 +00:00
9 changed files with 83 additions and 68 deletions

View File

@@ -61,7 +61,7 @@ FUZZ_TARGET(block_index_tree, .init = initialize_block_index_tree)
// Receive a header building on an existing valid one. This assumes headers are valid, so PoW is not relevant here.
LOCK(cs_main);
CBlockIndex* prev_block = PickValue(fuzzed_data_provider, blocks);
if (!(prev_block->nStatus & BLOCK_FAILED_MASK)) {
if (!(prev_block->nStatus & BLOCK_FAILED_VALID)) {
CBlockHeader header = ConsumeBlockHeader(fuzzed_data_provider, prev_block->GetBlockHash(), nonce_counter);
CBlockIndex* index = blockman.AddToBlockIndex(header, chainman.m_best_header);
assert(index->nStatus & BLOCK_VALID_TREE);
@@ -74,7 +74,7 @@ FUZZ_TARGET(block_index_tree, .init = initialize_block_index_tree)
LOCK(cs_main);
CBlockIndex* index = PickValue(fuzzed_data_provider, blocks);
// Must be new to us and not known to be invalid (e.g. because of an invalid ancestor).
if (index->nTx == 0 && !(index->nStatus & BLOCK_FAILED_MASK)) {
if (index->nTx == 0 && !(index->nStatus & BLOCK_FAILED_VALID)) {
if (fuzzed_data_provider.ConsumeBool()) { // Invalid
BlockValidationState state;
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "consensus-invalid");
@@ -124,7 +124,7 @@ FUZZ_TARGET(block_index_tree, .init = initialize_block_index_tree)
}
// Connect blocks, possibly fail
for (CBlockIndex* block : to_connect | std::views::reverse) {
assert(!(block->nStatus & BLOCK_FAILED_MASK));
assert(!(block->nStatus & BLOCK_FAILED_VALID));
assert(block->nStatus & BLOCK_HAVE_DATA);
if (!block->IsValid(BLOCK_VALID_SCRIPTS)) {
if (fuzzed_data_provider.ConsumeBool()) { // Invalid

View File

@@ -50,8 +50,6 @@ FUZZ_TARGET(chain)
BlockStatus::BLOCK_HAVE_UNDO,
BlockStatus::BLOCK_HAVE_MASK,
BlockStatus::BLOCK_FAILED_VALID,
BlockStatus::BLOCK_FAILED_CHILD,
BlockStatus::BLOCK_FAILED_MASK,
BlockStatus::BLOCK_OPT_WITNESS,
});
if (block_status & ~BLOCK_VALID_MASK) {