Skip to content

Commit e868a6e

Browse files
committed
doc: Improve assumeutxo guide and add more docs/comments
Also fixes some outdated information in the remaining design doc.
1 parent b29c21f commit e868a6e

File tree

3 files changed

+94
-43
lines changed

3 files changed

+94
-43
lines changed

doc/assumeutxo.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Assumeutxo Usage
2+
3+
Assumeutxo is a feature that allows fast bootstrapping of a validating bitcoind
4+
instance.
5+
6+
For notes on the design of Assumeutxo, please refer to [the design doc](/doc/assumeutxo.md).
7+
8+
## Loading a snapshot
9+
10+
There is currently no canonical source for snapshots, but any downloaded snapshot
11+
will be checked against a hash that's been hardcoded in source code. If there is
12+
no source for the snapshot you need, you can generate it yourself using
13+
`dumptxoutset` on another node that is already synced (see
14+
[Generating a snapshot](#generating-a-snapshot)).
15+
16+
Once you've obtained the snapshot, you can use the RPC command `loadtxoutset` to
17+
load it.
18+
19+
```
20+
$ bitcoin-cli loadtxoutset /path/to/input
21+
```
22+
23+
After the snapshot has loaded, the syncing process of both the snapshot chain
24+
and the background IBD chain can be monitored with the `getchainstates` RPC.
25+
26+
### Pruning
27+
28+
A pruned node can load a snapshot. To save space, it's possible to delete the
29+
snapshot file as soon as `loadtxoutset` finishes.
30+
31+
The minimum `-prune` setting is 550 MiB, but this functionality ignores that
32+
minimum and uses at least 1100 MiB.
33+
34+
As the background sync continues there will be temporarily two chainstate
35+
directories, each multiple gigabytes in size (likely growing larger than the
36+
downloaded snapshot).
37+
38+
### Indexes
39+
40+
Indexes work but don't take advantage of this feature. They always start building
41+
from the genesis block and can only apply blocks in order. Once the background
42+
validation reaches the snapshot block, indexes will continue to build all the
43+
way to the tip.
44+
45+
46+
For indexes that support pruning, note that these indexes only allow blocks that
47+
were already indexed to be pruned. Blocks that are not indexed yet will also
48+
not be pruned.
49+
50+
This means that, if the snapshot is old, then a lot of blocks after the snapshot
51+
block will need to be downloaded, and these blocks can't be pruned until they
52+
are indexed, so they could consume a lot of disk space until indexing catches up
53+
to the snapshot block.
54+
55+
## Generating a snapshot
56+
57+
The RPC command `dumptxoutset` can be used to generate a snapshot for the current
58+
tip (using type "latest") or a recent height (using type "rollback"). A generated
59+
snapshot from one node can then be loaded
60+
on any other node. However, keep in mind that the snapshot hash needs to be
61+
listed in the chainparams to make it usable. If there is no snapshot hash for
62+
the height you have chosen already, you will need to change the code there and
63+
re-compile.
64+
65+
Using the type parameter "rollback", `dumptxoutset` can also be used to verify the
66+
hardcoded snapshot hash in the source code by regenerating the snapshot and
67+
comparing the hash.
68+
69+
Example usage:
70+
71+
```
72+
$ bitcoin-cli -rpcclienttimeout=0 dumptxoutset /path/to/output rollback
73+
```
74+
75+
For most of the duration of `dumptxoutset` running the node is in a temporary
76+
state that does not actually reflect reality, i.e. blocks are marked invalid
77+
although we know they are not invalid. Because of this it is discouraged to
78+
interact with the node in any other way during this time to avoid inconsistent
79+
results and race conditions, particularly RPCs that interact with blockstorage.
80+
This inconsistent state is also why network activity is temporarily disabled,
81+
causing us to disconnect from all peers.
82+
83+
`dumptxoutset` takes some time to complete, independent of hardware and
84+
what parameter is chosen. Because of that it is recommended to increase the RPC
85+
client timeout value (use `-rpcclienttimeout=0` for no timeout).

doc/design/assumeutxo.md

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,6 @@
1-
# assumeutxo
1+
# Assumeutxo Design
22

3-
Assumeutxo is a feature that allows fast bootstrapping of a validating bitcoind
4-
instance.
5-
6-
## Loading a snapshot
7-
8-
There is currently no canonical source for snapshots, but any downloaded snapshot
9-
will be checked against a hash that's been hardcoded in source code.
10-
11-
Once you've obtained the snapshot, you can use the RPC command `loadtxoutset` to
12-
load it.
13-
14-
### Pruning
15-
16-
A pruned node can load a snapshot. To save space, it's possible to delete the
17-
snapshot file as soon as `loadtxoutset` finishes.
18-
19-
The minimum `-prune` setting is 550 MiB, but this functionality ignores that
20-
minimum and uses at least 1100 MiB.
21-
22-
As the background sync continues there will be temporarily two chainstate
23-
directories, each multiple gigabytes in size (likely growing larger than the
24-
downloaded snapshot).
25-
26-
### Indexes
27-
28-
Indexes work but don't take advantage of this feature. They always start building
29-
from the genesis block. Once the background validation reaches the snapshot block,
30-
indexes will continue to build all the way to the tip.
31-
32-
For indexes that support pruning, note that no pruning will take place between
33-
the snapshot and the tip, until the background sync has completed - after which
34-
everything is pruned. Depending on how old the snapshot is, this may temporarily
35-
use a significant amount of disk space.
36-
37-
## Generating a snapshot
38-
39-
The RPC command `dumptxoutset` can be used to generate a snapshot for the current
40-
tip or a recent height. This can be used
41-
to create a snapshot on one node that you wish to load on another node.
42-
It can also be used to verify the hardcoded snapshot hash in the source code.
3+
For notes on the usage of Assumeutxo, please refer to [the usage doc](/doc/assumeutxo.md).
434

445
## General background
456

@@ -77,7 +38,7 @@ data.
7738
### "Normal" operation via initial block download
7839

7940
`ChainstateManager` manages a single Chainstate object, for which
80-
`m_snapshot_blockhash` is null. This chainstate is (maybe obviously)
41+
`m_from_snapshot_blockhash` is `std::nullopt`. This chainstate is (maybe obviously)
8142
considered active. This is the "traditional" mode of operation for bitcoind.
8243

8344
| | |

src/rpc/blockchain.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2676,7 +2676,10 @@ static RPCHelpMan dumptxoutset()
26762676
{
26772677
return RPCHelpMan{
26782678
"dumptxoutset",
2679-
"Write the serialized UTXO set to a file.",
2679+
"Write the serialized UTXO set to a file. This can be used in loadtxoutset afterwards if this snapshot height is supported in the chainparams as well.\n\n"
2680+
"Unless the the \"latest\" type is requested, the node will roll back to the requested height and network activity will be suspended during this process. "
2681+
"Because of this it is discouraged to interact with the node in any other way during the execution of this call to avoid inconsistent results and race conditions, particularly RPCs that interact with blockstorage.\n\n"
2682+
"This call may take several minutes. Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
26802683
{
26812684
{"path", RPCArg::Type::STR, RPCArg::Optional::NO, "Path to the output file. If relative, will be prefixed by datadir."},
26822685
{"type", RPCArg::Type::STR, RPCArg::Default(""), "The type of snapshot to create. Can be \"latest\" to create a snapshot of the current UTXO set or \"rollback\" to temporarily roll back the state of the node to a historical block before creating the snapshot of a historical UTXO set. This parameter can be omitted if a separate \"rollback\" named parameter is specified indicating the height or hash of a specific historical block. If \"rollback\" is specified and separate \"rollback\" named parameter is not specified, this will roll back to the latest valid snapshot block that currently be loaded with loadtxoutset."},
@@ -2773,6 +2776,8 @@ static RPCHelpMan dumptxoutset()
27732776
// would be classified as a block connecting an invalid block.
27742777
disable_network = std::make_unique<NetworkDisable>(connman);
27752778

2779+
// Note: Unlocking cs_main before CreateUTXOSnapshot might be racy
2780+
// if the user interacts with any other *block RPCs.
27762781
invalidate_index = WITH_LOCK(::cs_main, return node.chainman->ActiveChain().Next(target_index));
27772782
InvalidateBlock(*node.chainman, invalidate_index->GetBlockHash());
27782783
const CBlockIndex* new_tip_index{WITH_LOCK(::cs_main, return node.chainman->ActiveChain().Tip())};

0 commit comments

Comments
 (0)