p2p: UTXO set sharing #35054

pull fjahr wants to merge 13 commits into bitcoin:master from fjahr:2026-02-utxo-set-share-safe-take-2 changing 27 files +1714 −1
  1. fjahr commented at 9:58 PM on April 10, 2026: contributor

    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 downloadutxoset with 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 share folder 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:

    1. Build this branch (duh)
    2. Start with a fresh node (datadir) and -connect=178.104.141.103:8333 -debug=utxosetshare. You can also use addnode but 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.
    3. Wait until the headers have synced, then use bitcoin-cli downloadutxoset 935000
    4. Watch the logs to see the the chunks come in and then see the completed snapshot getting activated
  2. net: Add NODE_UTXO_SET service bit and message types
    Add NODE_UTXO_SET (bit 12) service flag indicating the node can
    serve a UTXO set over P2P.
    
    Also add the P2P message types for UTXO set sharing.
    350985da5e
  3. log: Add UTXOSETSHARE category 34fd9f6c3e
  4. consensus: Expose ComputeMerklePath and add merkle proof verification
    Allows reuse of ComputeMerklePath() for UTXO set chunk Merkle proofs.
    78969203f5
  5. net: Define P2P message serialization for UTXO set sharing 9a6fd56aea
  6. node: Implement UTXO set share provider
    Scans a share directory for valid dumptxoutset snapshot files, validates
    them against known assumeutxo parameters and then serves chunks with Merkle
    proofs. A sidecar file is generated to cache the necessary data and
    signal the file has already been verified in future restarts.
    d16e35ac62
  7. init: Scan share folder in datadir for sharable snapshots 3f8e5c0dc9
  8. net: Handle getutxostinf and getutxoset P2P messages ef15e22d58
  9. node: Implement UTXO set download manager
    The fetched UTXO set is written to the share dir so the node can
    serve the downloaded snapshot afterwards.
    a00eebc6b5
  10. rpc: Add downloadutxoset RPC 0943ed1f17
  11. contrib: Add snapshot merkle root tool
    Standalone script that computes the merkle root of a
    dumptxoutset snapshot file. The output can be used to set
    the chunk_merkle_root field in the assumeutxo chain params.
    0cda5f60a1
  12. net: Validate chunk Merkle root against assumeutxo chain params
    Add chunk_merkle_root to AssumeutxoData so the download manager can
    reject peers that advertise a different Merkle root than expected.
    This prevents a peer serving a UTXO set where the merkle root does
    not correspond to the UTXO set a the expected height or has the
    correct serialized hash.
    
    Check is skipped for now if no value is set for easier testing and
    backwards compatibility.
    b131adeb25
  13. test: Add functional test for P2P UTXO set sharing
    Makes the necessary changes to the functional test framework
    like adding constants.
    
    Also tests common failure cases:
    - Disconnect on wrong block hash
    - Disconnect on wrong height
    - Non-serving node doesn't advertise NODE_UTXO_SET
    - Non-serving node ignores getutxostinf
    - RPC error on downloadutxoset with invalid height
    - RPC error on duplicate downloadutxoset calls
    3fffb9f085
  14. chainparams: Add missing snapshot merkle roots cf5d5b9533
  15. DrahtBot added the label P2P on Apr 10, 2026
  16. DrahtBot commented at 9:59 PM on April 10, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35054.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    Concept NACK eynhaender, l0rinc, stickies-v, evoskuil
    Concept ACK andrewtoth, svanstaa, danielabrozzoni

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #35148 (refactor: Remove confusing DataStream::in_avail() alias by maflcko)
    • #34860 (mining: always pad scriptSig at low heights, drop include_dummy_extranonce by Sjors)
    • #34628 (p2p: Replace per-peer transaction rate-limiting with global rate limits by ajtowns)
    • #34075 (fees: Introduce Mempool Based Fee Estimation to reduce overestimation by ismaelsadeeq)
    • #33421 (node: add BlockTemplateCache by ismaelsadeeq)
    • #31974 (Drop testnet3 by Sjors)
    • #28690 (build: Introduce internal kernel library by sedited)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • Compute leaf hashes by from snapshot file. -> Compute leaf hashes from snapshot file. [“by from” is a grammatical error that obscures the intended meaning]
    • the peer is be accepted. -> the peer is accepted. [“is be” is a typo that breaks the grammar]

    <sup>2026-04-10 21:59:29</sup>

  17. DrahtBot added the label CI failed on Apr 10, 2026
  18. fanquake added this to a project on Apr 11, 2026
  19. fanquake changed the project status on Apr 11, 2026
  20. andrewtoth commented at 7:50 PM on April 12, 2026: contributor

    Concept ACK

    Why invoke an RPC, instead of a configuration option (which can be set by default at a later point)?

    If ActivateSnapshot fails, download manager is forever in COMPLETE state. Not sure what we should do in that case. It would mean something is very wrong if our committed merkle root doesn't result in a correct snapshot, or there's disk error. Probably want to abort?

    DoS on downloading side: Server can set utxosetinfo's data_length field to 10 PB, which causes the receiving node to allocate >60 GB immediately. Recommend committing the data_length field alongside the merkle root.

  21. svanstaa commented at 5:30 PM on April 20, 2026: none

    Concept ACK

    Built the branch, set up fresh data dir, connected exclusively to the demo node (-connect=178.104.141.103:8333 -debug=utxosetshare). Waited for headers to sync, then started the snapshot download: bitcoin-cli downloadutxoset 935000.

    Observations:

    • snapshot was activated and node came up at height 935000
    • restarted without -connect to reconnect to the broader network
    • Node synced from the snapshot to current tip normally
    • Background validation from genesis also started

    Overall feature works as advertised.

    Also tried to shoot down the test node via several methods, but it survived all attempts. Will do another post later with the details.

  22. DrahtBot commented at 10:19 AM on April 25, 2026: contributor

    <!--cf906140f33d8803c4a75a2196329ecb-->

    🐙 This pull request conflicts with the target branch and needs rebase.

  23. DrahtBot added the label Needs rebase on Apr 25, 2026
  24. in src/rpc/blockchain.cpp:3462 in cf5d5b9533
    3457 | +        "downloadutxoset",
    3458 | +        "Download a UTXO set snapshot from peers through P2P network.\n"
    3459 | +        "The download happens asynchronously in the background. Once complete, the snapshot is automatically activated. "
    3460 | +        "The snapshot is saved to the share directory inside the data dir, so the node can re-serve it to other peers.",
    3461 | +        {
    3462 | +            {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block height of the UTXO set to download."},
    


    danielabrozzoni commented at 4:21 PM on April 29, 2026:

    I think this is fine for the first implementation, but do you think that in the future we could be smarter and decide the height by ourselves, without the user specifying it? Based on what we have in chainparams, or what we see in utxosetinfo


    stickies-v commented at 12:52 PM on May 13, 2026:

    This parameter confuses me. Don't we only allow the specific hardcoded CChainParams::m_assumeutxo_data::hash_serialized to be activated? Then why allow the user to specify block height?

  25. in src/node/utxo_set_share.cpp:263 in cf5d5b9533
     258 | +                     peer_id, entry.merkle_root.ToString(),
     259 | +                     m_expected_chunk_merkle_root.ToString());
     260 | +            continue;
     261 | +        }
     262 | +
     263 | +        m_data_length = entry.data_length;
    


    danielabrozzoni commented at 5:02 PM on April 29, 2026:

    @andrewtoth said:

    Recommend committing the data_length field alongside the merkle root.

    Yes, I think right now if a peer sends us a utxosetinfo with the wrong data length, we would record it and never notice the mistake, since we are currently only processing the first utxosetinfo message that we receive that contains the merkle_root we're interested in (we switch to DOWNLOADING state in L268)


    andrewtoth commented at 4:50 PM on April 30, 2026:

    It's also a little worse than that currently, maybe I wasn't clear. If they specify a size of say 10 petabytes (or just uint64 max) then the receiving node will allocate 60 GB or more just to track the chunks. So immediate OOM DoS by a malicious server.

  26. danielabrozzoni commented at 4:45 PM on April 30, 2026: member

    Concept ACK!

    I'm slowly going through the BIP and the code, haven't tested yet :) I left a couple of questions.

  27. evoskuil commented at 4:44 PM on May 5, 2026: none

    Concept NACK. One is free to add trust vectors to his own node implementation. Shoving that into the p2p network is not acceptable.

  28. fjahr marked this as a draft on May 5, 2026
  29. fjahr commented at 10:57 PM on May 5, 2026: contributor

    Temporarily moving this to draft status since it's out of sync with the latest version of the BIP and I will need a few days until I can get to it catch up the code.

  30. eynhaender commented at 2:53 PM on May 6, 2026: none

    Concept NACK

    This PR violates "don't trust, verify" by introducing a new protocol-level dependency on trusted, hardcoded data (Merkle roots in chainparams) for accepting a UTXO set snapshot from untrusted P2P peers.

  31. l0rinc commented at 1:05 PM on May 13, 2026: contributor

    I'm also leaning towards a concept NACK, I'd rather see a proposal to completely remove assumeUTXO from our codebase. Barely anyone uses it (I'm one of the torrent seeders), it downloads more total data than a normal IBD, and the dual chainstate complicates every code path that touches validation - reorgs, wallet rescanning, pruning, the *DANGER suffixed methods. All for a short-lived security downgrade that users may not even realize they're operating under. Adding P2P distribution on top makes this even more complex without addressing the fundamental issues.

  32. stickies-v commented at 1:24 PM on May 13, 2026: contributor

    I'm increasingly convinced that AssumeUTXO and having multiple chainstates was directionally a mistake for this project. It adds a ton of validation complexity, and the benefits to me seem limited. It also seems like more of a wallet than a node concern.

    For that reason, I'm Concept NACK any changes that add more AssumeUTXO complexity.

  33. fjahr commented at 9:52 PM on May 16, 2026: contributor

    @evoskuil @eynhaender Your NACKs are noted but I think your critique is better addressed by my responses on the mailing list. I would like to keep the conversation here focussed on the code being added here and it's impact on the code base. If you disagree and have specific critique based on the code here please continue to respond here, of course.

  34. fjahr commented at 10:08 PM on May 16, 2026: contributor

    @l0rinc @stickies-v

    Thanks for sharing your thoughts. You make almost identical points, so I will respond to you both together.

    Barely anyone uses it (I'm one of the torrent seeders)

    and the benefits to me seem limited

    I don't think the torrent seeders are a good indication for usage but certainly it isn't where we hoped it would be when we added the support for it. This proposal addresses that, projects like prepackaged nodes and BTCPayServer have had AssumeUTXO on their wishlists for a long time but since implementation was much harder without this change, they have kept pushing it back.

    the dual chainstate complicates every code path that touches validation

    I'm increasingly convinced that AssumeUTXO and having multiple chainstates was directionally a mistake for this project.

    It adds a ton of validation complexity

    I would say this was probably true when the initial assumeutxo PR was merged. But since then a ton of cleanup has been done and I find the current state of the assumeutxo code quite easy to reason about. Can you point at specific projects or PRs that have been slowed down by assumeutxo being present in the project?

    I'm Concept NACK any changes that add more AssumeUTXO complexity.

    Adding P2P distribution on top makes this even more complex

    Even if assumeutxo adds notable complexity to this project's other code paths this PR certainly does not make it worse. This is the most self-contained piece of code I have ever worked on in Bitcoin Core I think. It barely touches any other lines of code outside of what it adds.

    It also seems like more of a wallet than a node concern. @stickies-v Can you explain how a wallet would implement this?

    that users may not even realize they're operating under. @l0rinc Please provide evidence for this claim.

    without addressing the fundamental issues @l0rinc What are "the fundamental issues"?

  35. danielabrozzoni commented at 2:04 PM on May 18, 2026: member

    Expanding a little bit on my initial concept ACK:

    I think assumeutxo is a useful feature, and sharing the UTXO set over p2p makes the UX more intuitive, since users don't need to get it through external channels.

    That said, I think it's more important to work on ways to speed up initial IBD, like SwiftSync. I'm also wondering how many contributors see these two projects as competing with each other: maybe we can realistically have one but not the other, because supporting both would make the validation code too complex and spread contributor time too thin.

    So my concept ACK was a bit uninformed. It was more like: "I really like the idea in theory, but I don't know whether this should be the direction the project takes"

    Barely anyone uses it (I'm one of the torrent seeders)

    I wonder why this is the case!

    • Is it simply not a well-known feature among users? I honestly didn't know that assumeutxo was already merged in Bitcoin Core until a few months ago, and I found out only because I saw some assumeutxo PRs :sweat_smile:
    • Maybe it seems dangerous to download utxoset from torrent?
    • A lot of users I know run Bitcoin Core together with an Electrum server, so they can use Sparrow or Electrum as wallets. IIUC, you need to complete full IBD before the Electrum server is usable, so maybe assumeutxo just isn't useful for many of them.
  36. stickies-v commented at 3:59 PM on May 18, 2026: contributor

    Can you point at specific projects or PRs that have been slowed down by assumeutxo being present in the project?

    In my experience, many PRs involving validation logic are made more complex simply by having to reason about multiple chainstates, e.g. this is the most recent example that comes to mind.

    It's also generally slowing down kernel development, for example forcing us to expose the ChainstateManager in the interface until further (non-trivial) decoupling work is completed. (I recognize that the historical AssumeUTXO work probably also improved certain aspects wrt increased decoupling etc).

    I recently came across this branch that removes AssumeUTXO. I didn't author it and I presume it's not heavily reviewed / may be incorrect, but glossing over it it seems directionally correct and I think it again highlights how AssumeUTXO is a significant code patch, still affecting lots of critical code. If we prioritize avoiding consensus failure, making consensus code trivial to understand by current and future contributors is an important step.

    Can you explain how a wallet would implement this?

    Let a new user get started quickly with increased trust assumptions, by e.g. running an SPV node or trust (a quorum of) third parties with clear disclaimers until the full node has fully validated. Obviously, I would prefer users to be able to use a full node as soon as possible, my point is that I think the current set of trade-offs for AssumeUTXO don't make sense. I'm not against the concept of AssumeUTXO, I think it's reasonable to let users choose to make certain trade-offs for e.g. faster startup times. However, I don't think it's wise to add this much code complexity to do so, especially when it can be handled by higher-level layers in ways that make sense for the use case.

  37. josibake commented at 10:46 AM on May 19, 2026: member

    I don't think the torrent seeders are a good indication for usage but certainly it isn't where we hoped it would be when we added the support for it. This proposal addresses that

    Why aren't torrent seeders a good indication of usage? And the fact that usage isn't where we hoped it would be is a metric that should be seriously considered before building further on the project. "People aren't using it because its not distributed via p2p" seems like a bit of a leap to me. As I mentioned on the mailing list, why can't prepackaged nodes just ship the snapshots directly, provide them via their websites, or get them via bitcoincore.org?

  38. fjahr commented at 11:07 AM on May 19, 2026: contributor

    Why aren't torrent seeders a good indication of usage?

    Because it would require projects like prepackaged nodes to add Torrenting as a dependency to their nodes, which seems like a terrible idea to me and I don't think it's something they are interested in doing.

    As I mentioned on the mailing list, why can't prepackaged nodes just ship the snapshots directly, provide them via their websites, or get them via bitcoincore.org?

    I haven't seen a response from you on the ML but this is what BTCPayServer has been doing with FastSync for example. But of course we would like them to not do that but rather use assumeutxo because it is safer. The projects I have spoken with say that have it high on their wishlist but they were just not able to get to it yet.

  39. josibake commented at 11:20 AM on May 19, 2026: member

    Because it would require projects like prepackaged nodes to add Torrenting as a dependency to their nodes, which seems like a terrible idea to me and I don't think it's something they are interested in doing.

    This feels like a very subjective response to me. If people really needed assumeutxo, as in it was solving a real problem for them, I would expect people to use whatever means are available to them. That then creates momentum to further support the project. It seems like the opposite is happening: no one is using it, and we keep building on it trying to get people to use it.

    I haven't seen a response from you on the ML but this is what BTCPayServer has been doing with FastSync for example. But of course we would like them to not do that but rather use assumeutxo because it is safer.

    Likely still pending. But I don't understand how this is safer? BTCPayServer gets a snapshot, likely from a fully validating node they own? This seems safer, trust wise, than getting it from the p2p network to then be compared against a hash they did not create. But regardless, we already have a hash snapshot in the binary, why can't BTCPayServer just download the snapshot from bitcoincore.org? If it doesn't match the hash in the binary, they don't use it. This is exactly the same trust model you are proposing here, without requiring us to change our p2p code.

  40. l0rinc commented at 1:53 PM on May 19, 2026: contributor

    First, I want to separate a few things: I appreciate the work @fjahr is doing here, and I think the implementation itself looks careful and very well done. I also agree that startup cost is a real problem - it is why I have been working full time on validation optimizations for years. I also do not think assumeUTXO is useless: I use it all the time for benchmarking serialization and UTXO-set related code - even if that use case is not enough to justify the feature by itself.

    My objection is that assumeUTXO makes the most critical part of the codebase harder to read and reason about, and this PR extends that model further. That is the part I do not think is justified. It looks like sunk cost reasoning: we added assumeUTXO, usage is not where we hoped, and now we keep adding the next missing piece hoping this one will finally make it broadly adopted.

    Concrete examples, since you asked:

    • In #32975 (review), a simple assumevalid logging change became chainstate-specific. A global/static state would have produced confusing output with assumeUTXO, because one chainstate can be validating new blocks while the background chainstate is still in IBD. The end result was that, for simplicity, warnings are not generated during assumeUTXO.
    • #31703#pullrequestreview-2566967750 is another example. Pieter's PR was not primarily about assumeUTXO, but it exposed an assumeUTXO-specific path where the warning did not trigger the way I expected. Pieter was focused on the main change rather than the snapshot-specific path, so I ended up taking over the assumeUTXO part to make sure the warning covered that path as well. This blocked the review path for months.
    • #34521#pullrequestreview-3761920357 was an ordinary UB fix in LoadChainTip, but review found an extra issue because assumeUTXO can have two Chainstates, each with its own setBlockIndexCandidates. That is not theoretical complexity; it affected a concrete validation PR.
    • #33259 is a user-facing example. getblockchaininfo could report verificationprogress=1 and initialblockdownload=false while background validation was still running. That required adding explicit backgroundvalidation state.
    • #28598 and #28616 show the same issue from the wallet side. We had to be careful not to present transactions as normally confirmed while background validation was incomplete.
    • #32029 (comment) is another example of this being confusing even to developers. After a snapshot had supposedly been fully validated, I expected all traces of assumeUTXO seeding to be gone, but restart behavior still looked assumeUTXO-specific.
    • #32377 (comment) is related too. If we want the baked-in snapshot hashes to be more defensible, we could theoretically harden them by checking the committed assumeUTXO values during normal IBD/reindex/reindex-chainstate as well. That would make the commitments less one-sided. But that idea did not get much traction. So we are adding more functionality on top of these commitments before doing the obvious consistency checks during ordinary validation.

    None of these are catastrophic individually. The problem is that the complexity accumulates in validation-adjacent code, where readability and reviewer confidence matter most.

    On the claim that users may not realize the temporary security downgrade: the evidence is not a user study. The evidence is that we already needed extra RPC and wallet state to avoid misleading users and developers. Before background validation finishes, the node is in a confusing dual state: it is validating current transactions on top of an assumed base state, while we still cannot say that this node has independently validated that base state. That may be an acceptable tradeoff for some users, but it is not the same security model as a normally synced full node.

    So when I say "fundamental issues", I mean:

    • The node is temporarily operating in a weird partial-validation state: it is not providing the same security as a normally synced full node until background validation completes.
    • The dual-chainstate model has a continuing maintenance cost in validation-adjacent code.
    • Demand still seems weak relative to the complexity. Torrent usage may not be a perfect metric, but it is a smell.
    • This does not solve the bandwidth- or CPU-constrained cases in the way it is sometimes presented. If background validation completes, the user still downloads the UTXO snapshot plus historical blocks, so total bandwidth is higher than normal IBD. For CPU-constrained users, moving validation to the background does not remove the work. It just makes the node usable earlier under an assumption. But you all know this.

    If the gain is mostly that a normal node avoids waiting overnight, I do not think that justifies extending this model further into P2P and chainparams. If the user is genuinely CPU- or bandwidth-starved, then the historical work still takes a long time in the background, and the user remains in this purgatory state during that period.

    For a bandwidth-constrained user, downloading no UTXO set is better than downloading a multi-GB UTXO set. For a CPU-constrained user, putting the CPU work in the background does not remove it. If the problem is really the UTXO set or the cost of keeping state, then UTXO-less or accumulator-based experiments such as Utreexo seem like a cleaner direction to explore. They have their own tradeoffs, but they attack the state problem directly instead of adding P2P transport for assumed state blobs.

    My objection is to extending assumeUTXO further into P2P and chainparams because I do not see why assumeUTXO is the right solution to that problem. I would rather see it removed and provided as an external service; I do not think it is "Core".

  41. fjahr commented at 8:05 PM on May 19, 2026: contributor

    @josibake

    no one is using it

    That is not the case, and I don't think such exaggerations are helpful for the discourse.

    Some prepackaged nodes or node setups do use it: https://github.com/Start9Labs/bitcoin-core-startos/blob/31.x/README.md https://github.com/FreeOnlineUser/bitcoin-pocket-node#-path-3-download-from-internet-assumeutxo-3-6-hours

    And there is quite some educational content available as well: https://blog.lopp.net/bitcoin-node-sync-with-utxo-snapshots/ "Sync your full node in an hour" workshop @ https://btcplusplus.dev/ba24/talks https://yourdevice.ch/fullnode-schneller-syncen-mit-utxo-snapshots/

    So I do think there is clear evidence that it is used, but it could be used more, and part of the barrier is the sourcing hoop that users have to jump through, which is the very thing this PR tries to fix. We don't have any telemetry on Bitcoin Core so the "nobody uses it" claim can probably be made about 90% of user-facing features that are not signaled on the network itself.

    I don't think this line of arguing will lead anywhere. If I showed evidence of more usage, you would simply flip your argument that this is evidence the change isn't needed because adoption is good enough. There will be no usage statistic that will convince you that this change is warranted.

    What actually matters in terms of usage is the following: Adoption could be better, and lowering the barrier for its usage will undoubtedly have a positive impact on it. Whether that justifies adding a sizable chunk of code (while very self-contained) is the question reviewers have to decide on. I am rather focused on the conditions that people try to set up nodes in and struggle with long IBD wait times and what AssumeUTXO could do for them if it were more accessible to them.

    But I don't understand how this is safer? BTCPayServer gets a snapshot, likely from a fully validating node they own? This seems safer, trust wise, than getting it from the p2p network to then be compared against a hash they did not create.

    You think an unverified utxo set dump from a single HTTP server, where it's unclear how safe it is, who hosts it, and who has access, is safer than this proposal? You also want their users to get the actual bitcoin core release build and verify the signatures, right? Not some custom bitcoin core build from BTCPayServer.

    There are several websites that provide snapshots if you are looking for a centralized provider, by the way: https://bitcoin-snapshots.jaonoctus.dev/ https://utxo.download/

    I would rather not send users to a centrally hosted server where they only know if the snapshot is valid when they have already loaded it into Bitcoin Core.

    But regardless, we already have a hash snapshot in the binary, why can't BTCPayServer just download the snapshot from bitcoincore.org? This is exactly the same trust model you are proposing here, without requiring us to change our p2p code.

    Because bitcoincore.org doesn't host the snapshot. And I don't think we want to do that because it's another server we have to maintain, a centralizing entity and a single source of failure. But if this is something you would like to pursue as an alternative approach to help adoption of AssumeUTXO, of course you can. To me personally, this seems like a lot more work than maintaining the code I am proposing here.

  42. yancyribbens commented at 11:30 PM on May 19, 2026: contributor

    You think an unverified utxo set dump from a single HTTP server, where it's unclear how safe it is, who hosts it, and who has access, is safer than this proposal?

    Why would that be the case? Even if true, it could easily be https/ssh/ftps or other encrypted internal mechanism, possibly even distributed.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-05-20 06:52 UTC