AssumeUTXO: multiple chainstates complicate cache allocation and database lifetimes #36499

issue l0rinc opened this issue on October 11, 2026
  1. l0rinc commented at 9:30 AM on October 11, 2026: contributor

    Background validation keeps two UTXO databases open and divides -dbcache between them, shifting the split as their roles change. Snapshot activation gives the loading chainstate 99% and the existing one 1%, then rebalances as soon as loading finishes. From then on, the snapshot chainstate gets 95% until it leaves IBD, the background chainstate gets 95% afterward, and the snapshot chainstate gets everything once background validation completes. On restart, both begin at 20% until MaybeRebalanceCaches() recalculates the split and reopens each database at its intended allocation. A previous cleanup already fixes this reopening and reallocation during ordinary single-chainstate startup. These changing budgets make it hard to presize the coins cache, which would let us allocate its intended capacity during initialization and avoid needless reallocations while the node is running.

    Shrinking a coins cache forces a flush and drops its in-memory map, and resizing the LevelDB cache closes the database and reopens it through a new wrapper. An earlier attempt to preserve the cache after loading a snapshot was abandoned because rebalancing immediately emptied it. Reviewers of the original implementation also questioned the different 99:1 and 95:5 splits used during loading and later rebalancing.

    The database can also be reopened while RPCs such as dumptxoutset, gettxoutsetinfo, and scantxoutset still hold LevelDB iterators after releasing cs_main, so cache rebalancing can destroy the wrapper underneath them. This possible use-after-free and data race prompted an attempted fix, but I closed it because I think we should remove the multiple-chainstate design behind these problems instead of adding workaround after workaround.

    Replacing background validation with independent UTXO hash checks during IBD would remove the cache split and these rebalancing paths, allowing snapshot loading to use the same cache allocation as ordinary single-chainstate validation.


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-10-12 03:51 UTC

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