Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1# Assumeutxo Design3For notes on the usage of Assumeutxo, please refer to [the usage doc](/doc/assumeutxo.md).5## General background7- [assumeutxo proposal](https://github.com/jamesob/assumeutxo-docs/tree/2019-04-proposal/proposal)8- [Github issue](https://github.com/bitcoin/bitcoin/issues/15605)9- [draft PR](https://github.com/bitcoin/bitcoin/pull/15606)11## Design notes13- The concept of UTXO snapshots is treated as an implementation detail that lives14behind the ChainstateManager interface. The external presentation of the changes15required to facilitate the use of UTXO snapshots is the understanding that there are16now certain regions of the chain that can be temporarily assumed to be valid.17In certain cases, e.g. wallet rescanning, this is very similar to dealing with18a pruned chain.20Logic outside ChainstateManager should try not to know about snapshots, instead21preferring to work in terms of more general states like assumed-valid.24## Chainstate phases26Chainstate within the system goes through a number of phases when UTXO snapshots are27used, as managed by `ChainstateManager`. At various points there can be multiple28`Chainstate` objects in existence to facilitate both maintaining the network tip and29performing historical validation of the assumed-valid chain.31It is worth noting that though there are multiple separate chainstates, those32chainstates share use of a common block index (i.e. they hold the same `BlockManager`33reference).35The subheadings below outline the phases and the corresponding changes to chainstate36data.38### "Normal" operation via initial block download40`ChainstateManager` manages a single Chainstate object, for which41`m_from_snapshot_blockhash` is `std::nullopt`. This chainstate is (maybe obviously)42considered active. This is the "traditional" mode of operation for bitcoind.44| | |45| ---------- | ----------- |46| number of chainstates | 1 |47| active chainstate | ibd |49### User loads a UTXO snapshot via `loadtxoutset` RPC51`ChainstateManager` initializes a new chainstate (see `ActivateSnapshot()`) to load the52snapshot contents into. During snapshot load and validation (see53`PopulateAndValidateSnapshot()`), the new chainstate is not considered active and the54original chainstate remains in use as active.56| | |57| ---------- | ----------- |58| number of chainstates | 2 |59| active chainstate | ibd |61Once the snapshot chainstate is loaded and validated, it is promoted to active62chainstate and a sync to tip begins. A new chainstate directory is created in the63datadir for the snapshot chainstate called `chainstate_snapshot`.65When this directory is present in the datadir, the snapshot chainstate will be detected66and loaded as active on node startup (via `LoadAssumeutxoChainstate()`).68A special file is created within that directory, `base_blockhash`, which contains the69serialized `uint256` of the base block of the snapshot. This is used to reinitialize70the snapshot chainstate on subsequent inits. Otherwise, the directory is a normal71leveldb database.73| | |74| ---------- | ----------- |75| number of chainstates | 2 |76| active chainstate | snapshot |78The snapshot begins to sync to tip from its base block, technically in parallel with79the original chainstate, but it is given priority during block download and is80allocated most of the cache (see `MaybeRebalanceCaches()` and usages) as our chief81goal is getting to network tip.83**Failure consideration:** if shutdown happens at any point during this phase, both84chainstates will be detected during the next init and the process will resume.86### Snapshot chainstate hits network tip88Once the snapshot chainstate leaves IBD, caches are rebalanced89(via `MaybeRebalanceCaches()` in `ActivateBestChain()`) and more cache is given90to the background chainstate, which is responsible for doing full validation of the91assumed-valid parts of the chain.93**Note:** at this point, ValidationInterface callbacks will be coming in from both94chainstates. Considerations here must be made for indexing, which may no longer be happening95sequentially.97### Background chainstate hits snapshot base block99Once the tip of the background chainstate hits the base block of the snapshot100chainstate, we hash the101background chainstate's UTXO set contents and ensure it matches the compiled value in102`CMainParams::m_assumeutxo_data`.104| | |105| ---------- | ----------- |106| number of chainstates | 2 |107| active chainstate | snapshot |109The background chainstate data lingers on disk until the program is restarted.111### Bitcoind restarts sometime after snapshot validation has completed113After a shutdown and subsequent restart, `LoadChainstate()` cleans up the background114chainstate with `ValidatedSnapshotCleanup()`, which renames the `chainstate_snapshot`115datadir as `chainstate` and removes the now unnecessary background chainstate data.117| | |118| ---------- | ----------- |119| number of chainstates | 1 |120| active chainstate | ibd (was snapshot, but is now fully validated) |122What began as the snapshot chainstate is now indistinguishable from a chainstate that123has been built from the traditional IBD process, and will be initialized as such.125A file will be left in `chainstate/base_blockhash`, which indicates that the126chainstate, even though now fully validated, was originally started from a snapshot127with the corresponding base blockhash.
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.