validation: `Assertion failed: ((pindexFirstNeverProcessed == nullptr || pindex == snap_base) == pindex->HaveNumChainTxs())` #36021

issue marcofleon opened this issue on August 19, 2026
  1. marcofleon commented at 12:12 PM on August 19, 2026: contributor

    Can be triggered by submitting the missing parent block at the end of the feature_prune_stale_block functional test. The restart isn't even needed.

    
    diff --git a/test/functional/feature_prune_stale_fork.py b/test/functional/feature_prune_stale_fork.py
    index 5badca0a7c..0ecb9f2b47 100755
    --- a/test/functional/feature_prune_stale_fork.py
    +++ b/test/functional/feature_prune_stale_fork.py
    @@ -30,8 +30,12 @@ class FeaturePruneStaleForkTest(BitcoinTestFramework):
             node.pruneblockchain(node.getblockcount() - 100)
             assert_raises_rpc_error(-1, "Block not available (pruned data)", node.getblock, side_child.hash_hex)
     
    -        self.log.info("Restart and mine; node must reload cleanly after the stale-fork child was pruned")
    -        self.restart_node(0)
    +        self.log.info("Submit the missing parent block")
    +        node.submitblock(side_parent.serialize().hex())
    +
             self.generate(node, 1)
    
    

    So it’s the same stale-fork pruned block setup as #35050 and #35168, but without the restart requirement.

    This was found with a test running on Antithesis.

  2. marcofleon commented at 12:17 PM on August 19, 2026: contributor

    Still figuring out the best fix, but posting the issue in the meantime.

    When pruning, we remove the pruned child from m_blocks_unlinked. When the missing parent arrives, ReceivedBlockTransactions() uses m_blocks_unlinked to find descendants and calculate their m_chain_tx_count. Because the child was removed during pruning, its m_chain_tx_count remains unset, causing the assertion failure.

  3. marcofleon renamed this:
    validation: `Assertion failed: ((pindexFirstNeverProcessed == nullptr || pindex == snap_base) == pindex->HaveNumChainTxs()`)
    validation: `Assertion failed: ((pindexFirstNeverProcessed == nullptr || pindex == snap_base) == pindex->HaveNumChainTxs())`
    on Aug 19, 2026
  4. mzumsande commented at 12:25 PM on August 19, 2026: contributor

    Is this the same as #31512 ?

  5. dergoegge commented at 10:19 AM on August 20, 2026: member

    Is this the same as #31512 ?

    I think it is the same (at least by the sound of the issue description).

    To quote the other issue:

    we don't usually request parents of already pruned blocks like in step 3, unless we do getblockfrompeer or similar - so it can't be triggered remotely

    In Antithesis this was triggered through normal p2p interactions of the nodes in the test (i.e. getblockfrompeer wasn't used)

  6. mzumsande commented at 11:25 AM on August 20, 2026: contributor

    In Antithesis this was triggered through normal p2p interactions of the nodes in the test (i.e. getblockfrompeer wasn't used)

    Hmm, in order to trigger this you need to somehow request the parent of the pruned block because unrequested blocks would not be accepted due to fHasMoreOrSameWork. Since we don't prune blocks near the tip, I think this would have to happen through 1.) an extremely large reorg deeper than the pruned range (in which case a pruned node would become useless anyway). 2.) artificial means (getblockfrompeer, submitblock)

    Maybe the Antithesis test was creating some variation of 1)?

  7. dergoegge commented at 1:56 PM on August 20, 2026: member

    Maybe the Antithesis test was creating some variation of 1)?

    Yes, the nodes will go through crazy reorg scenarios in those tests. It's fine for a pruned node not to be able to perform the reorg but at least it shouldn't crash.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-08-21 04:51 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me