Glossary / Nodes & software
Assumeutxo
- What is Assumeutxo?
- Assumeutxo lets a Bitcoin Core node start from a snapshot of the unspent output set at a hardcoded height, then verify the skipped history in the background.
The snapshot lists every coin spendable at one block height, and its hash is compiled into the software rather than downloaded with it. Bitcoin Core 28.0 added mainnet parameters for height 840,000, the first height a snapshot can be loaded against on the live network. Your wallet becomes usable long before the full history has been checked, while the node quietly verifies the skipped blocks behind it.
How it works
Assumeutxo splits one node into two chainstates and runs them at the same time.
You hand a snapshot file to the loadtxoutset RPC. Bitcoin Core creates a second chainstate to load it into, keeping the original one active while the contents are read and checked. Once the snapshot chainstate is loaded and validated it becomes the active one, a directory called chainstate_snapshot appears in the data directory, and the node begins syncing from the snapshot's base block toward the network tip. Inside that directory sits a small file called base_blockhash, which records which block the snapshot was taken at, so the arrangement survives a restart.
The hash is the whole trust story. Core's own documentation states that there is no canonical source for snapshots, and that any snapshot you download is checked against a value hardcoded in the source code. You are therefore not trusting whoever hosted the file. You are trusting the same release you already chose to run, and a file that does not hash to the compiled value is rejected before it ever becomes your chainstate.
Meanwhile the original chainstate keeps grinding forward from the genesis block with every rule applied. When it reaches the snapshot's base block it hashes its own unspent output set and compares the result against the compiled parameter. Cache is handed to whichever chain needs it more: the snapshot chain gets priority while it races for the tip, and the background chain gets the larger share afterwards. The getchainstates RPC shows both.
Cleanup happens on the next restart rather than immediately. Core renames chainstate_snapshot to chainstate, deletes the background data, and from that point the node is indistinguishable from one built the traditional way. The base_blockhash file stays behind as a record of where it started.
Why this matters when you buy bitcoin
Assumeutxo attacks the one drawback that keeps most buyers from validating their own coins.
Of the 41 wallets reviewed on this site, Bitcoin Core is the only one that downloads and checks the entire chain itself, which is why our review rates it 4.7 and still lists as its first drawback that the first sync downloads and verifies the whole chain, costing hours and a lot of disk space. That sentence is the reason most people never try. A snapshot does not make the cost disappear, it moves it: the hours still happen, they just happen after your wallet already works instead of before.
The moment this pays off is the withdrawal. You buy on one of the 63 exchanges recorded here, you send the coins to keys you control, and then you want to know they arrived. Without a node of your own, the two parties you can ask are the exchange that just sent them and a public block explorer that now knows your address. With one, the answer comes from arithmetic your own machine performed.
It also changes what a serious setup costs to start. Our Sparrow review, rated 4.7 as well, describes connecting straight to Bitcoin Core as a backend, and that pairing used to mean waiting out a full sync before Sparrow had anything to talk to. A snapshot compresses the setup day into a usable evening, and the verification you postponed finishes on its own while you sleep.
Worked example: generating a snapshot with dumptxoutset
Generating an assumeutxo snapshot is a deliberate operation on a node you already trust, not a file you go and fetch.
The dumptxoutset RPC produces it, either at the current tip using type "latest" or at a recent height using type "rollback". For most of the time it runs, the node sits in a temporary state that does not reflect reality, marking blocks invalid that it knows are fine, and network activity is switched off and every peer disconnected because of that state. Core's documentation recommends -rpcclienttimeout=0 because the dump takes a while whatever the hardware and whichever type you chose, and it discourages touching the node for anything else in the meantime.
Two details catch people out. A snapshot is usable only if its height already has a hash listed in the chain parameters, so choosing any other height means editing that code and recompiling, and the "rollback" type doubles as the way to check a hardcoded hash by regenerating the snapshot and comparing. And Bitcoin Core 28.0 changed the serialization: dumps in the old format are no longer supported and have to be recreated on a 28.0 or later node before loadtxoutset will accept them.
Bitcoin Core 29.0 added a related tool, contrib/utxo-tools/utxo_to_sqlite.py, which converts a compact-serialized snapshot into a SQLite3 database. That has nothing to do with syncing a node and everything to do with what a snapshot actually is: a complete, self-contained picture of who owns what at one height, which turns out to be a useful thing to query.
Assumeutxo vs initial block download
Assumeutxo does not replace initial block download, it changes the order the work happens in.
A node that loaded a snapshot still performs a complete initial block download from the genesis block in its background chainstate, which is the chainstate charged with full validation of the stretch of chain the snapshot let it assume. Nothing is permanently skipped. What the snapshot buys is that the wallet stops being useless during the wait, because the active chainstate already knows the current state of every address you care about. The region between genesis and the snapshot height is tracked as assumed-valid rather than quietly counted as verified, which is why Core carries two chainstates instead of one flag on a single one. A node that loaded a snapshot and never finished the background sync is in a real and named state, not a hidden one.
Assumeutxo vs a pruned node
Assumeutxo and pruning both shrink what a node has to cope with, and they shrink opposite things.
Pruning is about disk after validation: a pruned node checks every block, then deletes the raw files it no longer needs. Assumeutxo is about time before validation: it defers checks that it will still carry out. The two compose, and Core bends one of its own rules to let them. The usual floor for -prune is 550 MiB, and a node loading a snapshot ignores that minimum and uses at least 1100 MiB instead. Space is not the only line item: while the background sync runs there are temporarily two chainstate directories, each of them multiple gigabytes and likely to grow larger than the snapshot you downloaded.
Indexes are where the two diverge most. An index gains nothing from a snapshot, because indexes always start building from the genesis block and can only apply blocks in order, so an index reaches the tip only once background validation has carried the node past the snapshot block. Pruning sharpens that: an index that supports pruning at all lets the node delete only blocks it has already indexed, so an old snapshot leaves a heap of downloaded, unindexed, undeletable blocks on disk until indexing catches up.