This implements a draft BIP for a protocol to share a UTXO set over P2P. Ideally, please review the BIP draft along side this PR if you already want to look at the code.
Motivation
The motivation is to make it possible to use the assumeutxo feature without having to acquire a snapshot from a third party.
UX
The UX for the user is very similar to how loadtxoutset works today:
- The user starts their new node and has to wait until the headers have synced
- The user then invokes the RPC
downloadutxosetwith their selected height - The utxo set download finishes in the background
- Upon completion the snapshot is compared to assumeutxo params and if those match, it is activated
Design choices
- Capability to serve UTXO sets is signaled with a service bit
- The UTXO set is shared in chunks of 3.9 MB
- A merkle root of these chunks serves as integrity check to prevent sending useless data as a trivial DoS vector
- UTXO set snapshots for sharing are placed in a
sharefolder in the datadir, they are atomically loaded on startup and then shared - A node that downloaded a snapshot will share it themselves until the snapshot has been deleted from their share folder
- The merkle root is introduced to the assumeutxo data in the chainparams to ensure peers can not lie to us about it
Status
This is certainly still rough around the edges and the merkle roots in the chain params have not all been filled in yet. I am primarily looking for concept and approach feedback as well as potentially overlooked DoS vectors to start.
If you find a DoS vector on the serving side feel free to crash the live demo node below for bragging rights. Just please give me a heads up afterwards :)
Live demo
The feature can be tried out on mainnet:
- Build this branch (duh)
- Start with a fresh node (datadir) and
-connect=178.104.141.103:8333 -debug=utxosetshare. You can also useaddnodebut this will make it harder to watch the logs since historical blocks are still synced at the same time. Note that since the demo node is pruned, your node will need to be restarted to sync blocks after snapshot validation if you are using-connect. - Wait until the headers have synced, then use
bitcoin-cli downloadutxoset 935000 - Watch the logs to see the the chunks come in and then see the completed snapshot getting activated