From mboxrd@z Thu Jan 1 00:00:00 1970 Delivery-date: Thu, 07 May 2026 14:40:05 -0700 Received: from mail-oo1-f58.google.com ([209.85.161.58]) by mail.fairlystable.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1wL6Rw-0001dJ-2d for bitcoindev@gnusha.org; Thu, 07 May 2026 14:40:05 -0700 Received: by mail-oo1-f58.google.com with SMTP id 006d021491bc7-69996a2944dsf3023009eaf.1 for ; Thu, 07 May 2026 14:40:03 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1778189998; cv=pass; d=google.com; s=arc-20240605; b=HzOdy9vQ87Cb3gTuAk9T2TRozkm1vhMRehyBfcpshu83HCG289h3A2tfveaMBYELoW o4nONUI8xJM5oPzTWZD4M6uB725NVHL7Ax/mCN/3RBWx3P9UXrgPflUCfTMGXh1jcFCI R1hj7YYpGuseSN6PxHfGlF5LoZVGLS6/vXgkLjbs4jWiMtwNUk/+sbBB5XLWRoGZR2hx 4bVKXtAw/K2DCUXYosISi6TSlXZ253SCUoom4TPqMPG9hmUH19j+GTqkEX1WFUrmdmew TuRRO/+AQKkzWgQUYOiqcjV783Wx9nL/asNlV66ywmUn3vdFrqtzMryiRJVW/G+DJOLB YaOA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to:mime-version:feedback-id :references:in-reply-to:message-id:subject:cc:from:to:date :dkim-signature; bh=4sGn0xXtrlfPD+XZNAXZBv9kh6QS4IVS6lY5SRPqL0E=; fh=tiTysb0l0B/UKLBOQP7nihk0PlfQ0DEbc2nnvAwU2MY=; b=IHMBY2jCYcX5xvuic8QvWJOGMLNefsPpddS/XYTiYlHdlRBuQEMkmWszMc+J3VO694 WU7her3xPiar3qC5VggnrkLuLhBtWQu64MvNy+iWODJ6nLDpp8FhH8q8b/d0fw54duEk STS8N/gqjS1ufltdC+hVLG4koewDDtLLryjdc8XpzL5VjM0YSIG2RTY6XV257wQ3aTIV zCU2ycoFZh/Wb17e4bOJSDTbPSXX7hgJephvmJod+KEZeNp4d3fGZPZ49T8EtDkQvfN7 k+rPhM7fWn9U9l9ajN6UooZ2LKmJTwGA/3/3nqjfKmuWVN3EE/wyiUx1LtSACRHcHnx1 xfAw==; darn=gnusha.org ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@protonmail.com header.s=protonmail3 header.b=RmxWND3h; spf=pass (google.com: domain of fjahr@protonmail.com designates 109.224.244.116 as permitted sender) smtp.mailfrom=fjahr@protonmail.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=protonmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20251104; t=1778189998; x=1778794798; darn=gnusha.org; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender:mime-version :feedback-id:references:in-reply-to:message-id:subject:cc:from:to :date:from:to:cc:subject:date:message-id:reply-to; bh=4sGn0xXtrlfPD+XZNAXZBv9kh6QS4IVS6lY5SRPqL0E=; b=CgqrW7mniKqsfK5OnJEfNc3u3KYeOlEA9RijCKJS5ha58GaHhbwh2gS0xH5M1139AN t8n6Qu/xRdP9nS9gKp6XQmgyhyLfp6Y7/pC6g36FFnvJkgaT/Js8rpJK1xfGzv773zd4 BKkB7Gt8eywOHBSSi8yiHnvtkFAZvsmU2ohBBfdVoTHpThz47SdJNz0mxb2Qwaql1wlj 5Ks+Qai/h8DKKOfQnqAx332YCkMXt2Eqo5ilJu4QurqZUjOBv4MqP2/EtxJP4ugxle2v 1jpkQoGMmVbx4OxDF2JuCoaopjhhHOQRiY82lJYQ5nSYILTOnUxwftkebGWqPKAvl6rU pf1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778189998; x=1778794798; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender:mime-version :feedback-id:references:in-reply-to:message-id:subject:cc:from:to :date:x-beenthere:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=4sGn0xXtrlfPD+XZNAXZBv9kh6QS4IVS6lY5SRPqL0E=; b=XNs99mBYe/ANdxuYfT1JzLIb38DgWD6gabb2aKrf0kEmN2sq1udM3IoeaSZYsd54Ff D1vhmkqjBjnccjILSk/ZjCf65w8EjGIJCNZLqJ9471LeEx+CsFapcQnSLqL8lP2RauVX De4q9HoJJh67kevFMAJkxldusx9si/2ace5LtxATYF4t2V0uAqBiyN8ZYVNtLxvZUEkc BYlB0EbSzRypOEgXT+RxikXyV8gsBHsjGgfk0y2rkEjhmmTo9DvJZnwEqW9xZC/Zn3kC JfhHWbH5K4UnaU5tqSY3V6zT7DlglCSvEv1nSBwzn/ySGnSnLCSympIGfQ+JmBhwtKEf 8ybg== X-Forwarded-Encrypted: i=2; AFNElJ9/0mbZ84lqHVYsHm6JJxm5m+fpVg0iPuR0HhL3uE8PgRJStb4suDkv+B7xxYQf2vI+gRharfFPRWuX@gnusha.org X-Gm-Message-State: AOJu0YzB6Jf+tbazJWO7yK3ez60roJ9IZdwtF2JTNI10MvOxAV849jjZ V0trbbDef29Z0bu60B4lI5yDx5OMQ6/CVphBnkzF95VBceLEyLDdb53V X-Received: by 2002:a05:6820:1897:b0:694:9071:b60d with SMTP id 006d021491bc7-69998d428f6mr6005416eaf.44.1778189997643; Thu, 07 May 2026 14:39:57 -0700 (PDT) X-BeenThere: bitcoindev@googlegroups.com; h="AUV6zMNkzs5LA0cOR7MAGG2+eNkUfp897lw19IVWqQF7ioR0wQ==" Received: by 2002:a05:6820:1519:b0:696:17a7:39dd with SMTP id 006d021491bc7-699aa5750a8ls395416eaf.2.-pod-prod-07-us; Thu, 07 May 2026 14:39:52 -0700 (PDT) X-Received: by 2002:a05:6808:6f85:b0:467:268d:31cc with SMTP id 5614622812f47-48042479c17mr6433934b6e.26.1778189992512; Thu, 07 May 2026 14:39:52 -0700 (PDT) Received: by 2002:a05:6808:8181:10b0:479:f465:c131 with SMTP id 5614622812f47-4807b306732msb6e; Thu, 7 May 2026 14:34:42 -0700 (PDT) X-Received: by 2002:a05:7301:168b:b0:2ed:e14:7f54 with SMTP id 5a478bee46e88-2f54e47ec98mr4217839eec.30.1778189681423; Thu, 07 May 2026 14:34:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1778189681; cv=none; d=google.com; s=arc-20240605; b=K+MyC2ElUsQERGhz2wOryUl0xlfaRrlMlSCXezvZsRi0mAFFW8sauZN8dRqIhsK5oe pkszsNURhTzlteRsOtaL+EqeGVa2u2OcsQfYjGkR61OqySSmNCIhDzCRZ3NKIDjFHy9h gaFjFFkW3hMssj00tjjy9VzpasTiVIuQfw/nLlqeHKf9xvCnBtULYjkD+UCG8GA5B4Iv KGclkPmQziJnsy50H13lw7YnQoCe3IFa0YHZOqY59o5JWBJTqHSMuNCo3kCa3l3jdRFZ PdiZQ4CQ9LlloOx4bvCBS3l+igiVa1wHXEoi2BugEkwjp024ubi7mUoTTLwxn2yBdaog HIGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=mime-version:feedback-id:references:in-reply-to:message-id:subject :cc:from:to:date:dkim-signature; bh=IhuEu+DtP/FLWlaIl+QXcR9HjjhbK4rCIUOSJzsPxbk=; fh=VUyRMGDsLDyKXHBc8DWjokFBiSMTvXavinKdBJZhUls=; b=SeKGGTh2V8J+6npBRJ7iHrz8bF480EhFY/JiTOU+WGr0dzjOsQIKggwEhBncmNjYTd Xvu+R0hT941VhOL9KzcIIA+2lLaW68lBOHJwr1s2SYw7a4ewfsqUoE6wO++Om6UhKxoT qAEzofIUwImw6Qa+vs5+P0GvQjypzxhExwV9w74RkOfNSXqfyI60F8nIPQbTNtit+QCD PfKhfSBq+JuEZOsB8T4HraanjO1YGfyOobzO0neer8/RoMhMQhYY95GgE5HsXwx8hEDD AhAS48lndbMp/W8kAYJO/ybSe9YAVpstNRIBorccryuAY7GcUKCMDfhq2X63pEmS+P/q P0Xw==; dara=google.com ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@protonmail.com header.s=protonmail3 header.b=RmxWND3h; spf=pass (google.com: domain of fjahr@protonmail.com designates 109.224.244.116 as permitted sender) smtp.mailfrom=fjahr@protonmail.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=protonmail.com Received: from mail-244116.protonmail.ch (mail-244116.protonmail.ch. [109.224.244.116]) by gmr-mx.google.com with ESMTPS id 5a478bee46e88-2f8647e6935si174eec.2.2026.05.07.14.34.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 14:34:41 -0700 (PDT) Received-SPF: pass (google.com: domain of fjahr@protonmail.com designates 109.224.244.116 as permitted sender) client-ip=109.224.244.116; Date: Thu, 07 May 2026 21:34:34 +0000 To: Eric Voskuil From: "'Fabian' via Bitcoin Development Mailing List" Cc: Bitcoin Development Mailing List Subject: Re: [bitcoindev] Re: [BIP Draft] P2P UTXO Set Sharing Message-ID: In-Reply-To: <19616822-8a03-4de1-99be-72d50479208fn@googlegroups.com> References: <19616822-8a03-4de1-99be-72d50479208fn@googlegroups.com> Feedback-ID: 5067558:user:proton X-Pm-Message-ID: 773fe82180e7fd5d7c59a4ae18fcd69726d5a45e MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="b1=_ka0CwVvfPR5tGz2xSx8g34DMyT6hksEeVPUp9rWwis" X-Original-Sender: fjahr@protonmail.com X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@protonmail.com header.s=protonmail3 header.b=RmxWND3h; spf=pass (google.com: domain of fjahr@protonmail.com designates 109.224.244.116 as permitted sender) smtp.mailfrom=fjahr@protonmail.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=protonmail.com X-Original-From: Fabian Reply-To: Fabian Precedence: list Mailing-list: list bitcoindev@googlegroups.com; contact bitcoindev+owners@googlegroups.com List-ID: X-Google-Group-Id: 786775582512 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , X-Spam-Score: -1.0 (-) --b1=_ka0CwVvfPR5tGz2xSx8g34DMyT6hksEeVPUp9rWwis Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Eric, Thanks for sharing your feedback. I also read conversations on X so I am an= swering with those in mind as well even though not everything may have been= spelled out in this thread explicitly. Of course, the proposal is opt-in, just like AssumeUTXO itself. A node that= does not use this feature is unaffected by it. Assumeutxo doesn=E2=80=99t = change consensus, the header chain is validated before loading the UTXO set= and full IBD still happens in the background. AssumeUTXOis a UX improvemen= t for those interested in running a fully validating node. The option to ge= t started in a very limited amount of time even under significant hardware = constraints can motivate users to choose a full node over an SPV client if = startup time is relevant for their decision. And at some point of hardware = constraints it definitely is, I think. In addition, it is a much easier dec= ision for users to do IBD with assumevalid=3D0 as they are not required to = wait for the completion of background IBD to take the next steps in their s= etup. Also, this proposal only improves the sourcing of the UTXO set. Currently t= his needs to happen through some third party source and loaded into the nod= e manually which comes with it=E2=80=99s own set of potential risks (privac= y, malware), being able to rely on the P2P network as a secure source is pr= eferable to that. I think your main critique boils down to =E2=80=9Cthis is a slippery slope= =E2=80=9D aside from your critique of assumeutxo and the Bitcoin Core archi= tecture in general (see https://x.com/evoskuil/status/2052027207032164488).= I can not refute critique of something that is not part of this proposal e= xcept for pointing out that what you are insinuating is not something I am = working on or plan on working on and I am not aware of anyone working on sk= ipping IBD and I would not endorse such a proposal if it were to be publish= ed. In contrast to some hypothetical dangerous future extension of this pro= posal that you are warning about, I am convinced that it does have real pos= itive impact on users today, as I pointed out above. Fabian On Tuesday, May 5th, 2026 at 6:18 PM, Eric Voskuil wrote= : > Concept NACK. It's bad enough that nodes are formalizing this off network= , but incorporating it into p2p is another level of awful. > > On Tuesday, May 5, 2026 at 11:39:56=E2=80=AFAM UTC-4 Fabian wrote: > >> Dear list, >> >> I am sharing a BIP draft for sharing the UTXO set over the P2P network, = an old idea that makes it possible to utilize AssumeUTXO without sourcing a= UTXO set dump from a third party source. You can find the full text below = or comment on the BIPs repository pull directly: https://github.com/bitcoin= /bips/pull/2137 >> >> Fabian >> >> ``` >> BIP: ? >> Layer: Peer Services >> Title: P2P UTXO Set Sharing >> Authors: Fabian Jahr >> Status: Draft >> Type: Specification >> Assigned: ? >> Discussion: ? >> Version: 0.2.0 >> License: BSD-2-Clause >> ``` >> >> ## Abstract >> >> This BIP defines a P2P protocol extension for sharing full UTXO sets bet= ween peers. It introduces >> a new service bit `NODE_UTXO_SET`, four new P2P messages (`getutxotree`,= `utxotree`, `getutxoset`, >> `utxoset`), and a chunk-hash list anchored to a Merkle root known to the= requesting node, enabling >> per-chunk verification. This allows nodes to bootstrap from a recent hei= ght by obtaining the >> required UTXO set directly from the P2P network via mechanisms such as a= ssumeutxo. >> >> ## Motivation >> >> The assumeutxo feature (implemented in Bitcoin Core) allows nodes to beg= in operating from a serialized >> UTXO set while validating >> historical blocks in the background. However, there is currently no cano= nical source for obtaining this >> data. Users must either generate one themselves from a fully synced node= (using `dumptxoutset` in >> Bitcoin Core), or download one from a third party. >> >> By enabling UTXO set sharing over the P2P network, new nodes can obtain = the data directly from >> peers, removing the dependency on external infrastructure. >> >> ## Specification >> >> The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" in t= his document are to be >> interpreted as described in RFC 2119. >> >> ### Service Bit >> >> | Name | Bit | Description | >> |------|-----|-------------| >> | `NODE_UTXO_SET` | 12 (0x1000) | The node can serve complete UTXO set d= ata for at least one height. | >> >> A node MUST NOT set this bit unless it has at least one full UTXO set av= ailable to serve. >> A node signaling `NODE_UTXO_SET` MUST be capable of responding to `getut= xotree` and `getutxoset` >> requests for every UTXO set it is willing to serve, including the full c= hunk-hash list and every >> chunk of those sets. >> >> ### Data Structures >> >> #### Serialized UTXO Set >> >> The serialized UTXO set uses the format established by the Bitcoin Core = RPC `dumptxoutset` (as of Bitcoin Core v31). >> >> **Header (55 bytes):** >> >> | Field | Type | Size | Description | >> |-------|------|------|-------------| >> | `magic` | `bytes` | 5 | `0x7574786fff` (ASCII `utxo` + `0xff`). | >> | `version` | `uint16_t` | 2 | Format version. | >> | `network_magic` | `bytes` | 4 | Network message start bytes. | >> | `base_height` | `uint32_t` | 4 | Block height of the UTXO set. | >> | `base_blockhash` | `uint256` | 32 | Block hash of the UTXO set. | >> | `coins_count` | `uint64_t` | 8 | Total number of coins (UTXOs) in the = set. | >> >> **Body (coin data):** >> >> Coins are grouped by transaction hash. For each group: >> >> | Field | Type | Size | Description | >> |-------|------|------|-------------| >> | `txid` | `uint256` | 32 | Transaction hash. | >> | `num_coins` | `compact_size` | 1=E2=80=939 | Number of outputs for thi= s txid. | >> >> For each coin in the group: >> >> | Field | Type | Size | Description | >> |-------|------|------|-------------| >> | `vout_index` | `compact_size` | 1=E2=80=939 | Output index. | >> | `coin` | `Coin` | variable | Serialized coin (varint-encoded code for = height/coinbase, then compressed txout). | >> >> Coins are ordered lexicographically by outpoint (txid, then vout index),= matching the LevelDB iteration >> order of the coins database. >> >> #### Chunk Merkle Tree >> >> The serialized UTXO set (header + body) is split into chunks of exactly = 3,900,000 bytes (3.9 MB). The >> last chunk contains the remaining bytes and may be smaller. >> >> The leaf hash for each chunk is `SHA256d(chunk_data)`. The tree is built= as a balanced binary tree. When >> the number of nodes at a level is odd, the last node is duplicated befor= e hashing the next level. >> Interior nodes are computed as `SHA256d(left_child || right_child)`. >> >> The leaves are delivered to the node in a single `utxotree` response. A = node that knows >> the Merkle root for a given UTXO set checks a received list of leaves by= recomputing the root and >> comparing. The Merkle root is the sole trust input required to verify th= e integrity of the received UTXO set. >> >> `SHA256d` denotes double-SHA256: `SHA256d(x) =3D SHA256(SHA256(x))`. >> >> ### Messages >> >> #### `getutxotree` >> >> Sent to request the chunk-hash list for a specific UTXO set. >> >> | Field | Type | Size | Description | >> |-------|------|------|-------------| >> | `block_hash` | `uint256` | 32 | Block hash identifying the requested U= TXO set. | >> >> A node that has advertised `NODE_UTXO_SET` and can serve the requested U= TXO set MUST respond with >> `utxotree`. If the serving node cannot fulfill the request, it MUST NOT = respond. The requesting >> node SHOULD apply a reasonable timeout and try another peer. >> >> #### `utxotree` >> >> Sent in response to `getutxotree`, delivering the full chunk-hash list a= long with per-snapshot >> metadata. >> >> | Field | Type | Size | Description | >> |-------|------|------|-------------| >> | `block_hash` | `uint256` | 32 | Block hash this data corresponds to. | >> | `version` | `uint16_t` | 2 | Format version of the serialized UTXO set= . | >> | `data_length` | `uint64_t` | 8 | Total size of the serialized UTXO set= in bytes (header + body). | >> | `num_chunks` | `compact_size` | 1=E2=80=939 | Number of chunks the ser= ialized UTXO set is split into. | >> | `chunk_hashes` | `uint256[]` | 32 =C3=97 `num_chunks` | The ordered li= st of chunk hashes. | >> >> Upon receiving a `utxotree` message, the node MUST recompute the Merkle = root from >> `chunk_hashes` and compare it against the Merkle root it knows for the c= orresponding UTXO set. If >> the roots do not match, the node MUST discard the response and MUST disc= onnect the peer. >> >> #### `getutxoset` >> >> Sent to request a single chunk of UTXO set data. The requesting node MUS= T have received a `utxotree` >> for the corresponding UTXO set before sending this message. >> >> | Field | Type | Size | Description | >> |-------|------|------|-------------| >> | `block_hash` | `uint256` | 32 | Block hash identifying the requested U= TXO set. | >> | `chunk_index` | `uint32_t` | 4 | Zero-based index of the requested chu= nk. | >> >> If the serving node cannot fulfill the request, it MUST NOT respond. The= requesting node SHOULD apply >> a reasonable timeout and try another peer. >> >> #### `utxoset` >> >> Sent in response to `getutxoset`, delivering one chunk. >> >> | Field | Type | Size | Description | >> |-------|------|------|-------------| >> | `block_hash` | `uint256` | 32 | Block hash this data corresponds to. | >> | `chunk_index` | `uint32_t` | 4 | Zero-based index of this chunk. | >> | `data` | `bytes` | variable | Chunk payload, exactly 3.9 MB except for= the last chunk. | >> >> The transfer is receiver-driven: the requesting node sends one `getutxos= et` per chunk. Chunks MAY be >> requested in any order and from different peers. >> >> Upon receiving a `utxoset` message, the node MUST compute `SHA256d(data)= ` and compare it against >> `chunk_hashes[chunk_index]` from the `utxotree` it accepted for this UTX= O set. If the hashes do not >> match, the node MUST discard the chunk and MUST disconnect the peer. A n= ode SHOULD also disconnect >> a peer that sends a `utxoset` message with fields (`chunk_index`, `block= _hash`) that do not match >> the outstanding request. >> >> After all chunks have been received, the node SHOULD parse the reassembl= ed UTXO set against the >> serialized UTXO set format to confirm it is well-formed. >> >> ### Protocol Flow >> >> 1. The requesting node identifies peers advertising `NODE_UTXO_SET`. >> 2. The requesting node sends `getutxotree` for the desired block hash to= one or more of these peers. >> 3. Each peer responds with `utxotree`. The requesting node verifies the = response by recomputing >> the Merkle root against a value it knows for the given UTXO set, either = from a trusted source >> or by selecting a root with agreement among multiple peers. >> 4. The requesting node downloads chunks via `getutxoset`/`utxoset` excha= nges, verifying each chunk >> against its entry in the accepted `utxotree` on receipt. On verification= failure the peer is >> disconnected and download continues from another peer without losing alr= eady-verified chunks. >> 5. After all chunks are received, the node parses the reassembled UTXO s= et against the serialized >> UTXO set format to confirm that it is well-formed. >> >> Serving nodes are free to limit the number of concurrent and repeated tr= ansfers per peer at their own >> discretion to manage resource consumption. >> >> ## Rationale >> >> **Usage of service bit 12:** Service bits allow selective peer discovery= through >> DNS seeds and addr relay. Bit 12 is chosen as the next unassigned bit af= ter `NODE_P2P_V2` (bit 11, BIP 324). >> >> **Direct request model:** Peers signal availability of UTXO sets via the= `NODE_UTXO_SET` >> service bit; the requesting node identifies the desired UTXO set by bloc= k hash when sending >> `getutxotree`. The serving node responds only if it can serve that speci= fic UTXO set. >> >> **Per-chunk verification:** The chunk-hash list returned in `utxotree` e= nables each chunk to be verified >> by direct lookup against the accepted list as it arrives, allowing immed= iate detection of corrupt data, >> peer switching without data loss, and parallel download from multiple pe= ers. The list itself is small >> (~80 KB for a ~10 GB set). The specified serialization is deterministic,= so all honest nodes produce >> byte-identical output, guaranteeing Merkle root agreement. >> >> **3.9 MB chunk size:** The number balances round trips (~2,560 for a ~10= GB set) against memory usage >> for buffering and verifying a single chunk. Smaller chunks would increas= e protocol overhead; larger >> chunks would increase memory pressure on constrained devices commonly us= ed to run Bitcoin nodes. >> Together with the additional message overhead, the `utxoset` message inc= luding the chunk data also >> sits just below the theoretical maximum block size which means any imple= mentation should be able to >> handle messages of this size. >> >> **Reusing the `dumptxoutset` format:** Avoids introducing a new serializ= ation format and ensures >> compatibility with UTXO sets already being generated and shared. >> >> **Relationship to BIP 64:** BIP 64 defined a protocol for querying indiv= idual UTXOs by outpoint and is >> now closed. This BIP addresses a different use case: bulk transfer of th= e entire UTXO set for node >> bootstrapping. >> >> ## Reference Implementation >> >> [Bitcoin Core implementation pull request](https://github.com/bitcoin/bi= tcoin/pull/35054) >> >> ## Copyright >> >> This BIP is made available under the terms of the 2-clause BSD license. = See >> https://opensource.org/license/BSD-2-Clause for more information. >> >> ## Changelog >> >> * __0.2.0__ (2026-05-04): >> * Dropped discovery before download approach, instead request the chunk-= hash list via `getutxotree`/`utxotree` >> * Dropped per-chunk Merkle proofs; chunks verified directly against the = chunk-hash list >> * Dropped `height` from requests (`block_hash` is the sole identifier); = added format `version` to `utxotree` >> * Dropped references to the serialized hash; the Merkle root is the sole= integrity check >> * __0.1.0__ (2026-04-10): * Initial draft > > -- > You received this message because you are subscribed to the Google Groups= "Bitcoin Development Mailing List" group. > To unsubscribe from this group and stop receiving emails from it, send an= email to bitcoindev+unsubscribe@googlegroups.com. > To view this discussion visit https://groups.google.com/d/msgid/bitcoinde= v/19616822-8a03-4de1-99be-72d50479208fn%40googlegroups.com. --=20 You received this message because you are subscribed to the Google Groups "= Bitcoin Development Mailing List" group. To unsubscribe from this group and stop receiving emails from it, send an e= mail to bitcoindev+unsubscribe@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/= KwFUBuvfLZdJTpAEO-BIK9YEFZcKTiJhWWNcjP3kEtvHOeWaxQMaMTO2pbRknTbtTKZFq_Zekjx= SECNR7i3u9j_Z7PcFmL428FEDORl1BE8%3D%40protonmail.com. --b1=_ka0CwVvfPR5tGz2xSx8g34DMyT6hksEeVPUp9rWwis Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

Hi Eric,


<= /p>

Thanks for = sharing your feedback. I also read conversations on X so I am answering wit= h those in mind as well even though not everything may have been spelled ou= t in this thread explicitly.


Of course, the proposal is opt-in, just like As= sumeUTXO itself. A node that does not use this feature is unaffected by it.= Assumeutxo doesn=E2=80=99t change consensus, the header chain is validated= before loading the UTXO set and full IBD still happens in the background. = AssumeUTXO  is a UX improvement for those interested in r= unning a fully validating node. The option to get started in a very limited= amount of time even under significant hardware constraints can motivate us= ers to choose a full node over an SPV client if startup time is relevant fo= r their decision. And at some point of hardware constraints it definitely i= s, I think. In addition, it is a much easier decision for users to do IBD w= ith assumevalid=3D0 as they are not required to wait for the completion of = background IBD to take the next steps in their setup.


Also, this proposal on= ly improves the sourcing of the UTXO set. Currently this needs to happen th= rough some third party source and loaded into the node manually which comes= with it=E2=80=99s own set of potential risks (privacy, malware), being abl= e to rely on the P2P network as a secure source is preferable to that.

<= p style=3D"margin:0px;font:13px "Helvetica Neue";min-height:15px"= >

I thi= nk your main critique boils down to =E2=80=9Cthis is a slippery slope=E2=80= =9D aside from your critique of assumeutxo and the Bitcoin Core architectur= e in general (see https://x.com/evoskuil/status/2052027207032164488). I can not refu= te critique of something that is not part of this proposal except for point= ing out that what you are insinuating is not something I am working on or p= lan on working on and I am not aware of anyone working on skipping IBD and = I would not endorse such a proposal if it were to be published. In contrast= to some hypothetical dangerous future extension of this proposal that you = are warning about, I am convinced that it does have real positive impact on= users today, as I pointed out above.


Fabian


On Tuesday, May 5th, 2026 at 6:18 PM, Eric Voskuil <eric@voskuil= .org> wrote:
Concept NACK. It's bad enough that nodes are formalizing this o= ff network, but incorporating it into p2p is another level of awful.
On Tuesd= ay, May 5, 2026 at 11:39:56=E2=80=AFAM UTC-4 Fabian wrote:
Dear list,

I am sharing a BIP draft for sharing the UTXO set= over the P2P network, an old idea that makes it possible to utilize Assume= UTXO without sourcing a UTXO set dump from a third party source. You can fi= nd the full text below or comment on the BIPs repository pull directly: https://github.com/bitcoin/bips/pu= ll/2137

Fabian


```
BIP: ?
= Layer: Peer Services
Title: P2P UTXO Set Sharing=
Authors: Fabian Jahr <fj...@protonmail.com>
Status: Draft
Type: Specification
Assign= ed: ?
Discussion: ?
Versi= on: 0.2.0
License: BSD-2-Clause
<= span>```

## Abstract

This BIP defines a P2P protocol extension for sharing= full UTXO sets between peers. It introduces
a new s= ervice bit `NODE_UTXO_SET`, four new P2P messages (`getutxotree`, `utxotree= `, `getutxoset`,
`utxoset`), and a chunk-hash list a= nchored to a Merkle root known to the requesting node, enabling
per-chunk verification. This allows nodes to bootstrap from a r= ecent height by obtaining the
required UTXO set dire= ctly from the P2P network via mechanisms such as assumeutxo.

## Motivation

The assumeutxo feature (implemented in Bitcoin Core) allows nodes to begin= operating from a serialized
UTXO set while validati= ng
historical blocks in the background. However, the= re is currently no canonical source for obtaining this
data. Users must either generate one themselves from a fully synced node= (using `dumptxoutset` in
Bitcoin Core), or downloa= d one from a third party.

By enabling= UTXO set sharing over the P2P network, new nodes can obtain the data direc= tly from
peers, removing the dependency on external = infrastructure.

## Specification

The key words "MUST", "MUST NOT", "SHOULD= ", "SHOULD NOT", and "MAY" in this document are to be
interpreted as described in RFC 2119.

### Service Bit

| Name | Bit | Des= cription |
|------|-----|-------------|
=
| `NODE_UTXO_SET` | 12 (0x1000) | The node can serve complete UT= XO set data for at least one height. |

A node MUST NOT set this bit unless it has at least one full UTXO set ava= ilable to serve.
A node signaling `NODE_UTXO_SET` MU= ST be capable of responding to `getutxotree` and `getutxoset`
<= div>requests for every UTXO set it is willing to serve, including the= full chunk-hash list and every
chunk of those sets.=

### Data Structures

#### Serialized UTXO Set

<= div>The serialized UTXO set uses the format established by the Bitcoi= n Core RPC `dumptxoutset` (as of Bitcoin Core v31).

**Header (55 bytes):**

| Field | Type | Size | Description |
|-------|----= --|------|-------------|
| `magic` | `bytes` | 5 | `= 0x7574786fff` (ASCII `utxo` + `0xff`). |
| `version`= | `uint16_t` | 2 | Format version. |
| `network_mag= ic` | `bytes` | 4 | Network message start bytes. |
|= `base_height` | `uint32_t` | 4 | Block height of the UTXO set. |
| `base_blockhash` | `uint256` | 32 | Block hash of the UTXO = set. |
| `coins_count` | `uint64_t` | 8 | Total numb= er of coins (UTXOs) in the set. |

**B= ody (coin data):**

Coins are grouped = by transaction hash. For each group:

= | Field | Type | Size | Description |
|-------|-----= -|------|-------------|
| `txid` | `uint256` | 32 | = Transaction hash. |
| `num_coins` | `compact_size` |= 1=E2=80=939 | Number of outputs for this txid. |

For each coin in the group:

| Field | Type | Size | Description |
|-------|-= -----|------|-------------|
| `vout_index` | `compac= t_size` | 1=E2=80=939 | Output index. |
| `coin` | `= Coin` | variable | Serialized coin (varint-encoded code for height/coinbase= , then compressed txout). |

Coins are= ordered lexicographically by outpoint (txid, then vout index), matching th= e LevelDB iteration
order of the coins database.

#### Chunk Merkle Tree
=
The serialized UTXO set (header + body) is split into = chunks of exactly 3,900,000 bytes (3.9 MB). The
last= chunk contains the remaining bytes and may be smaller.
The leaf hash for each chunk is `SHA256d(chunk_data)`. T= he tree is built as a balanced binary tree. When
the= number of nodes at a level is odd, the last node is duplicated before hash= ing the next level.
Interior nodes are computed as `= SHA256d(left_child || right_child)`.

= The leaves are delivered to the node in a single `utxotree` response. A nod= e that knows
the Merkle root for a given UTXO set ch= ecks a received list of leaves by recomputing the root and
comparing. The Merkle root is the sole trust input required to verif= y the integrity of the received UTXO set.

<= span>`SHA256d` denotes double-SHA256: `SHA256d(x) =3D SHA256(SHA256(x))`.

### Messages

#### `getutxotree`

Sent = to request the chunk-hash list for a specific UTXO set.
| Field | Type | Size | Description |
<= span>|-------|------|------|-------------|
| `block_= hash` | `uint256` | 32 | Block hash identifying the requested UTXO set. |

A node that has advertised `NODE_UTXO_= SET` and can serve the requested UTXO set MUST respond with
`utxotree`. If the serving node cannot fulfill the request, it MUST= NOT respond. The requesting
node SHOULD apply a rea= sonable timeout and try another peer.

#### `utxotree`

Sent in response to = `getutxotree`, delivering the full chunk-hash list along with per-snapshot<= /span>
metadata.

| Fi= eld | Type | Size | Description |
|-------|------|--= ----|-------------|
| `block_hash` | `uint256` | 32 = | Block hash this data corresponds to. |
| `version`= | `uint16_t` | 2 | Format version of the serialized UTXO set. |
| `data_length` | `uint64_t` | 8 | Total size of the serialize= d UTXO set in bytes (header + body). |
| `num_chunks= ` | `compact_size` | 1=E2=80=939 | Number of chunks the serialized UTXO set= is split into. |
| `chunk_hashes` | `uint256[]` | 3= 2 =C3=97 `num_chunks` | The ordered list of chunk hashes. |

Upon receiving a `utxotree` message, the node MUST r= ecompute the Merkle root from
`chunk_hashes` and com= pare it against the Merkle root it knows for the corresponding UTXO set. If=
the roots do not match, the node MUST discard the r= esponse and MUST disconnect the peer.

#### `getutxoset`

Sent to request a = single chunk of UTXO set data. The requesting node MUST have received a `ut= xotree`
for the corresponding UTXO set before sendin= g this message.

| Field | Type | Size= | Description |
|-------|------|------|------------= -|
| `block_hash` | `uint256` | 32 | Block hash iden= tifying the requested UTXO set. |
| `chunk_index` | = `uint32_t` | 4 | Zero-based index of the requested chunk. |

If the serving node cannot fulfill the request, it M= UST NOT respond. The requesting node SHOULD apply
a = reasonable timeout and try another peer.

#### `utxoset`

Sent in response t= o `getutxoset`, delivering one chunk.

| Field | Type | Size | Description |
|-------|----= --|------|-------------|
| `block_hash` | `uint256` = | 32 | Block hash this data corresponds to. |
| `chu= nk_index` | `uint32_t` | 4 | Zero-based index of this chunk. |
=
| `data` | `bytes` | variable | Chunk payload, exactly 3.9 MB ex= cept for the last chunk. |

The transf= er is receiver-driven: the requesting node sends one `getutxoset` per chunk= . Chunks MAY be
requested in any order and from diff= erent peers.

Upon receiving a `utxose= t` message, the node MUST compute `SHA256d(data)` and compare it against
`chunk_hashes[chunk_index]` from the `utxotree` it acc= epted for this UTXO set. If the hashes do not
match,= the node MUST discard the chunk and MUST disconnect the peer. A node SHOUL= D also disconnect
a peer that sends a `utxoset` mess= age with fields (`chunk_index`, `block_hash`) that do not match
the outstanding request.

= After all chunks have been received, the node SHOULD parse the reassembled = UTXO set against the
serialized UTXO set format to c= onfirm it is well-formed.

### Protoco= l Flow

1. The requesting node identif= ies peers advertising `NODE_UTXO_SET`.
2. The reques= ting node sends `getutxotree` for the desired block hash to one or more of = these peers.
3. Each peer responds with `utxotree`. = The requesting node verifies the response by recomputing
<= span> the Merkle root against a value it knows for the given UTXO set, ei= ther from a trusted source
or by selecting a root= with agreement among multiple peers.
4. The request= ing node downloads chunks via `getutxoset`/`utxoset` exchanges, verifying e= ach chunk
against its entry in the accepted `utxo= tree` on receipt. On verification failure the peer is
disconnected and download continues from another peer without losing a= lready-verified chunks.
5. After all chunks are rece= ived, the node parses the reassembled UTXO set against the serialized
UTXO set format to confirm that it is well-formed.

Serving nodes are free to limit the numb= er of concurrent and repeated transfers per peer at their own
<= div>discretion to manage resource consumption.

<= /div>
## Rationale

**Usage = of service bit 12:** Service bits allow selective peer discovery through
DNS seeds and addr relay. Bit 12 is chosen as the next= unassigned bit after `NODE_P2P_V2` (bit 11, BIP 324).
**Direct request model:** Peers signal availability of UT= XO sets via the `NODE_UTXO_SET`
service bit; the req= uesting node identifies the desired UTXO set by block hash when sending
`getutxotree`. The serving node responds only if it can= serve that specific UTXO set.

**Per-= chunk verification:** The chunk-hash list returned in `utxotree` enables ea= ch chunk to be verified
by direct lookup against the= accepted list as it arrives, allowing immediate detection of corrupt data,=
peer switching without data loss, and parallel down= load from multiple peers. The list itself is small
(= ~80 KB for a ~10 GB set). The specified serialization is deterministic, so = all honest nodes produce
byte-identical output, guar= anteeing Merkle root agreement.

**3.9= MB chunk size:** The number balances round trips (~2,560 for a ~10 GB set)= against memory usage
for buffering and verifying a = single chunk. Smaller chunks would increase protocol overhead; larger
chunks would increase memory pressure on constrained devi= ces commonly used to run Bitcoin nodes.
Together wit= h the additional message overhead, the `utxoset` message including the chun= k data also
sits just below the theoretical maximum = block size which means any implementation should be able to
handle messages of this size.

**Reusing the `dumptxoutset` format:** Avoids introducing a new serializat= ion format and ensures
compatibility with UTXO sets = already being generated and shared.

*= *Relationship to BIP 64:** BIP 64 defined a protocol for querying individua= l UTXOs by outpoint and is
now closed. This BIP addr= esses a different use case: bulk transfer of the entire UTXO set for node
bootstrapping.

= ## Reference Implementation

[Bitcoin = Core implementation pull request](https://github.com/bitcoin/bitcoin/pull/35054)
## Copyright

This = BIP is made available under the terms of the 2-clause BSD license. See
## Changelog

* __0= .2.0__ (2026-05-04):
* Dropped discovery before = download approach, instead request the chunk-hash list via `getutxotree`/`u= txotree`
* Dropped per-chunk Merkle proofs; chun= ks verified directly against the chunk-hash list
= * Dropped `height` from requests (`block_hash` is the sole identifier); ad= ded format `version` to `utxotree`
* Dropped ref= erences to the serialized hash; the Merkle root is the sole integrity check=
* __0.1.0__ (2026-04-10):
* I= nitial draft

--
You received this message because you are subscribed to the Google Groups "= Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to bitcoindev+u= nsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/19616822-8a03-4de1-99b= e-72d50479208fn%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups &= quot;Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to bitcoind= ev+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/= KwFUBuvfLZdJTpAEO-BIK9YEFZcKTiJhWWNcjP3kEtvHOeWaxQMaMTO2pbRknTbtTKZFq_Zekjx= SECNR7i3u9j_Z7PcFmL428FEDORl1BE8%3D%40protonmail.com.
--b1=_ka0CwVvfPR5tGz2xSx8g34DMyT6hksEeVPUp9rWwis--