validation: CheckBlockIndex can fail in combination with pruning #31512

issue mzumsande openend this issue on December 16, 2024
  1. mzumsande commented at 10:29 pm on December 16, 2024: contributor

    Found this situation while fuzzing validation / CheckBlockIndex():

    1. Full block C (child) is received, so nTx, but not m_chain_tx_count will be set because we only know the header of the previous block P (parent).
    2. Block C gets pruned
    3. We request / receive full data for parent P.
    4. Error in CheckBlockIndex() - multiple checks in CheckBlockIndex() fail, for example we expect m_chain_tx_count to be set for C.

    There is a simple functional test to trigger this in https://github.com/mzumsande/bitcoin/commit/b75577544c8f9e7e2b90d269de2a6d9bec438433.

    This is mostly a theoretical 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
    • also, situations where we have full data for a child block but no data for the parent tend to not persist for long.
    • CheckBlockIndex is not active by default on mainnet

    However I think it’s good to understand the possible constellations in validation in depth and formulate our expectations (i.e. CheckBlockIndex) accordingly.

  2. ryanofsky commented at 4:48 pm on December 17, 2024: contributor

    Practically speaking, I guess options are:

    1 - Allow m_chain_tx_count to be 0 in CheckBlockIndex when a block is pruned 2 - Set m_chain_tx_count on pruned block when parent block is downloaded 3 - (not sure about this, seems not good) set nTx to 0 when block is pruned

  3. mzumsande commented at 3:41 pm on December 18, 2024: contributor
    Thanks - I was also thinking of option 1. Option 2 has the problem that we can’t easily find all descendants of the parents (without iterating over the entire block tree, which I think wouldn’t be acceptable everytime we receive a full block). We avoid this problem in master by caching all potential children that might need an update in m_blocks_unlinked - but entries are removed from m_blocks_unlinked when we prune.

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: 2024-12-21 12:12 UTC

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