The coins cache (the CCoinsView* stack, CCoinsViewCache, and friends) is a correctness- and performance-critical part of validation, IBD, and assumeutxo.
Over time it has accumulated subtle invariants and legacy states (around cache entry flags, spent coin handling, and error catching), and we have been chipping away at it through focused refactors, bugfixes, tests, and performance work.
This issue tracks the related PRs to help reviewers see how they fit together. The overall aim is fewer error cases, cleaner cache layering, and parallel validation.
PRs needing review
Testing
- #35850 - fuzz
ConnectBlock()directly without mutating chainstate.
Remove invalid cache states
- #34864 - remove unreachable FRESH-but-not-DIRTY state from code and tests.
Simplify view hierarchy
- #34320 - replace
HaveCoin()withGetCoin(). - #34132 - centralize coins DB read failures in
CDBWrapperand remove the error-catcher layer.
Database and cursor correctness
- #35654 - reject an undecodable first coin cursor key.
- #35744 - prevent AssumeUTXO cache resizing from invalidating coins DB cursors.
- #35714 - stop writing block-index and coins metadata after a blockfile flush failure.
Parallel validation
- #35738 - clean up and fuzz async prevout fetching and its coins-view overlay.
- #35751 - use parallel prevout fetching in
TestBlockValidity().
Optimizations
- #35195 - let libstdc++ cache UTXO outpoint hash codes for faster coins-map operations.
- #35620 - move unused LevelDB block-cache budget to write buffers.
- #35657 - avoid the redundant UTXO lookup pre-pass in
CheckTxInputs().
Other
- #33854 - skip early chain activation during reindex when headers are below minimum chainwork (see #31494).
- #32317 - move UTXO access to
SpendBlock(kernel API, Utreexo, SwiftSync).
Recently merged
- #35767 - stop async prevout-fetch threads before AFL forks.
- #35490 - cover unused mempool space in the coins-cache limit.
- #35572 - restrict coins cursor iteration to DB-backed views.
- #35616 - use 64-bit cache sizes and fix a 32-bit overflow.
- #35594 - fuzz async chainstate compaction.
- #35521 - speed up concurrent
CDBWrapperread fuzzing. - #35465 - compact chainstate regularly after seek compaction was disabled.
- #35455 - improve the concurrent
CDBWrapperread fuzz harness. - #35205 - route node, Qt, and kernel through the shared two-tier
dbcachedefault. - #35180 - narrow the public
CCoinsViewCacheAPI around reset internals. - #35215 - simplified in-memory utxo set key hashing
- #35295 - async input prefetch during
ConnectBlock. - #35200 - replace the oversized-
dbcachewarning cliff with a reserved-memory formula - #34887 - compare
CDBWrapperagainst an in-memory oracle - #34866 - exercise LevelDB reads under concurrent index-like access.
- #31449 -
getblockstatsRPC UTXO overhead fix - #34124 - make
CCoinsViewpurely virtual, add explicitCCoinsViewEmpty. - #34692 - increase the default dbcache value from 450MiB to 1024MiB
- #34576 - batch ThreadPool submissions under one lock for input-fetcher prep
- #34655 - constrain coins-view fuzz inputs to valid cache caller states.
- #34165 - add non-mutating
PeekCoin()to avoid polluting the main cache. - #33512 - track dirty entries so flush progress reflects actual writes.
- #33680 - split
FORCE_SYNC/FORCE_FLUSH, keep cache warm forscantxoutset/gettxoutsetinfo/snapshots. - #34164 - add
Reset()and reusable view to discard failed connects cheaply. - #34207 - ensure
GetCoin()only returns unspent coins, align tests with production. - #34253 - cache IBD status so readers do not take
cs_main. - #33866 - remove always-true return from
BatchWrite. - #33657 - allow reading partial block data (useful for bindex).
- #33602 - reduce map lookups in
BatchWrite. - #33333 - warn when
-dbcacheexceeds RAM cap.
IRC context: https://bitcoin-irc.chaincode.com/bitcoin-core-dev/2026-01-08