Peer Feature Negotiation
4 messages, 19 Dec 2025 to 12 May 2026. Started by Anthony Towns.
Anthony Towns (2), Antoine Riard (2)
Hello world,
I've been thinking recently about a few ideas that would benefit from new p2p messages, namely template sharing [0], updating the bip324-one-byte-message-types [1], and sharing recent stale blocks [2]. That's made me want to make sure that we've got a good way of negotiating new features, and revisiting the ideas from the 2020 thread [3] has me still liking the "FEATURE" message idea [4].
As such, and with Ava's recent exhortation that everyone should be writing BIPs [5] in mind, I've written a BIP:
https://github.com/ajtowns/bips/blob/202512-p2p-feature/bip-peer-feature-negotiation.md
Sample code, though that part isn't really very interesting:
https://github.com/ajtowns/bitcoin/commit/80301f0040fe6048a85b89d0fdf0ffcca836a1d0
The BIP is perhaps a bit over-engineered at this point for what it does, but I figure better to be over-engineered than under-. And in any event, there was some degree of breakage with the SENDADDRV2's deployment [6,7] which would be good to avoid repeating. In any event, the BIP text has a bunch more background, etc.
Comments welcome.
Cheers, aj
[0] https://github.com/bitcoin/bitcoin/issues/33691
[1] https://github.com/bitcoin/bips/pull/1378#discussion_r2585766526
[2] https://github.com/bitcoin-data/stale-blocks The idea behind sharing stale blocks (or headers) more proactively, is it better insight into the orphan rate, and whether hashrate is extending the chain vs potentially creating a reorg; and also potentially makes syncing to the new tip after a reorgs more efficient, as you'll have already downloaded the parent of the new tip
[3] https://gnusha.org/pi/bitcoindev/CAFp6fsE=HPFUMFhyuZkroBO_QJ-dUWNJqCPg9=fMJ3Jqnu1hnw@mail.gmail.com/
[4] https://gnusha.org/pi/bitcoindev/20200821023647.7eat4goqqrtaqnna@erisian.com.au/
[5] https://x.com/btcplusplus/status/2000489894515253529
[6] https://github.com/btcsuite/btcd/issues/1661
[7] https://github.com/bitcoin/bitcoin/pull/20564
Hello AJ, I had finally a read on your BIP434 proposal, and here few thoughts on the design and the novel processing rules proposed. I'm thinking that one drawback with the multiple feature / signaling messages approach compared to the fixed-size length verack payload comes with the novel feature messages becoming a novel if not a least a vector of denial-of-service, at least some vector of annoyance. One peer can always throw a number of `feature` message only bounded by the 80^2 information space of the `featureid` string length. If if I'm understanding correctly your proposal, this would be an acceptable valid behavior and this raises the question, if incidentally peers do not have to agree on dos-limit even for feature negotiation, that is moving us away from the "permissionlessly goal" you're laying out. I don't think there is an easy or obvious answer to this issue, other than introducing a verack negotiation timeout (with all the frictions of the lack of an easy to use coordinated clock among peers...). I do see the idea with that it's indeed allowing some form of interactive feature negotiation, where one peer can always make the announcement of feature_XYZ conditional on the previous announcement of feature_ABC, which is also possible with verack payload by reconnecting / disconnecting. I don't think we should consider connect / reconnect as free, as even if you're a peer doing legit interactive feature negotiation there might be friction with the underlying socket eviction logic (i.e for bitcoin core `SelectNodeToEvict()`). This is unclear from the "Considerations" of your proposal if it's taking the position that interactive feature negotation is either a valuable or not mechanism to have at the p2p protocol-level. Personally, I'm thinking it's interesting to have as it would enable deployment of complex feature tier by tier where you're using the messages of feature_ABC as direct messages in the flow of feature_XYZ, and it does bring some flexibility in the network deployment of said features. One last high level remark, I'm wondering if the protocol versioning shouldn't be "frozen" in itself, and reserved solely for signaling changes in the "peer feature negotiation" mechanism (or the usage of the service bits ?). More low level remarks on some BIP proposed processing rules in itself: - the BIP is silent on unknown messages received before `version` reception - same if a recipient MAY disconnect a peer if unsupported messages received post-verack - imho would be better to canonically define namespace section "...be a globally unique id..." - the re-interpretation of BIP324 messages as `feature` sounds gross, already the service bit While the proposal might appear as over-engineered, I don't think otherwise, though it would won to laid out better the design trade-off compared to verack in the "Considerations" section, and potentially to define more if the service bit can be indifferently use to signal feature, without going through the explicit feature negotiation mechanism. If I have misunderstood some aspect of your BIP proposal, please let me know. Best, Antoine OTS hash: 2a9215d42ee79a30ccc31b3410f74ab486d99f99408ad705b244d0dd8822ce53 Le Friday, December 19, 2025 à 11:35:52 AM UTC, Anthony Towns a écrit :
Quoted text (56 lines)
> Hello world, > > I've been thinking recently about a few ideas that would benefit > from new p2p messages, namely template sharing [0], updating the > bip324-one-byte-message-types [1], and sharing recent stale blocks [2]. > That's made me want to make sure that we've got a good way of negotiating > new features, and revisiting the ideas from the 2020 thread [3] has me > still liking the "FEATURE" message idea [4]. > > As such, and with Ava's recent exhortation that everyone should be > writing BIPs [5] in mind, I've written a BIP: > > > https://github.com/ajtowns/bips/blob/202512-p2p-feature/bip-peer-feature-negotiation.md > > Sample code, though that part isn't really very interesting: > > > https://github.com/ajtowns/bitcoin/commit/80301f0040fe6048a85b89d0fdf0ffcca836a1d0 > > The BIP is perhaps a bit over-engineered at this point for what it does, > but I figure better to be over-engineered than under-. And in any event, > there was some degree of breakage with the SENDADDRV2's deployment [6,7] > which would be good to avoid repeating. In any event, the BIP text has > a bunch more background, etc. > > Comments welcome. > > Cheers, > aj > > [0] https://github.com/bitcoin/bitcoin/issues/33691 > > [1] https://github.com/bitcoin/bips/pull/1378#discussion_r2585766526 > > [2] https://github.com/bitcoin-data/stale-blocks > The idea behind sharing stale blocks (or headers) more proactively, > is it better insight into the orphan rate, and whether hashrate > is extending the chain vs potentially creating a reorg; and also > potentially makes syncing to the new tip after a reorgs more > efficient, as you'll have already downloaded the parent of the new tip > > [3] > https://gnusha.org/pi/bitcoindev/CAFp6fsE=HPFUMFhyuZkroBO_QJ-dUWNJqCPg9=fMJ3Jq...@mail.gmail.com/ > <https://gnusha.org/pi/bitcoindev/CAFp6fsE=HPFUMFhyuZkroBO_QJ-dUWNJqCPg9=fMJ3Jqnu1hnw@mail.gmail.com/> > > [4] https://gnusha.org/pi/bitcoindev/20200821023647....@erisian.com.au/ > <https://gnusha.org/pi/bitcoindev/20200821023647.7eat4goqqrtaqnna@erisian.com.au/> > > [5] https://x.com/btcplusplus/status/2000489894515253529 > > [6] https://github.com/btcsuite/btcd/issues/1661 > > [7] https://github.com/bitcoin/bitcoin/pull/20564 > >
On Sun, Mar 01, 2026 at 10:06:20AM -0800, Antoine Riard wrote:
Quoted text (7 lines)
> I'm > thinking that one drawback with the multiple feature / signaling messages > approach compared to the fixed-size length verack payload comes with the > novel feature messages becoming a novel if not a least a vector of > denial-of-service, at least some vector of annoyance. One peer can always > throw a number of `feature` message only bounded by the 80^2 information > space of the `featureid` string length.
There's nothing stopping a peer from sending the same FEATURE message multiple times prior to sending a VERACK, or sending the a FEATURE message with the same featureid but different featuredata.
However these aren't a DoS concern, because such messages are either expected to be ignored (if the featureid isn't recognised by the peer) or can be rejected as invalid (if the featureid is recognised but isn't in compliance with the feature's specification).
Sending a bunch of FEATURE messages that are immediately ignored is no different from receiving a bunch of INV messages for txs you've already seen, or sending any other payload that you expect the peer to ignore.
Quoted text (4 lines)
> I don't think there is an easy or obvious answer > to this issue, other than introducing a verack negotiation timeout (with > all the frictions of the lack of an easy to use coordinated clock among > peers...).
A VERACK timeout is a pretty normal thing to have -- eg `-peertimeout` already exists and defaults to 60 seconds. It's not clever to waste a connection slot on a peer that's delaying ever getting into the part where you relay bitcoin information to each other.
Quoted text (2 lines)
> I do see the idea with that it's indeed allowing some form of > interactive feature negotiation,
In my opinion, interactive feature negotiation (of the form "I'll only tell you I support X if you first tell me you do/don't support Y") is massively overcomplicating things, and essentially an anti-pattern.
Quoted text (2 lines)
> One last high level remark, I'm wondering if the protocol > versioning shouldn't be "frozen" in itself,
There's no way to "freeze" development -- if BIP x says "you can't do Y", then doing Y just means you aren't implementing BIP x; you're not in any way inhibited from doing Y.
Quoted text (2 lines)
> - the BIP is silent on unknown messages received before `version` > reception
Messages received before `version` will generally already result in a disconnect, as that's how nodes recognise they're talking to another bitcoin node.
Cheers, aj
Hi AJ,
Sorry for the late answer here.
Quoted text (3 lines)
> Sending a bunch of FEATURE messages that are immediately ignored is no > different from receiving a bunch of INV messages for txs you've already > seen, or sending any other payload that you expect the peer to ignore.
It's true that for INV messages we have already the MAX_INV_SZ limit. Witht he current BIP text, there is limit laid out that `featuredata`'s byte-vector must not be superior to 512 bytes. However, there is no indication that declared `featureid` must be consistent with `featuredata`, so I don't see why a peer couldn't iterate _multiple times_ over the 80^2 `feature_id` space to repeatedly attach 512 byte payload.
One if a peer can escalate one of your inbound slot (i.e win over `ConsiderEviction`), and from then cloak your CPU processing with dumb FEATURE message. Recommending some time-bounded processing window for a fairly generous number of FEATURE would make sense.
I'm taking the caveat that it might be a bit early to add such p2p limit, that it will add too much rigidity for a not even experimentally deployed proposal (and "early optimization is the rule of all evil").
Quoted text (4 lines)
> A VERACK timeout is a pretty normal thing to have -- eg `-peertimeout` > already exists and defaults to 60 seconds. It's not clever to waste a > connection slot on a peer that's delaying ever getting into the part > where you relay bitcoin information to each other.
Right, may I note that your `-peertimeout` should make a distinction between in-handshake (before VERACK) versus post-handshake. If you look at bitcoind core, I'm not sure if `InactivityCheck` / `ReceivedMsgBytes` make that distinction.
Quoted text (3 lines)
> In my opinion, interactive feature negotiation (of the form "I'll only > tell you I support X if you first tell me you do/don't support Y") > is massively overcomplicating things, and essentially an anti-pattern.
Here I was thinking more about cryptographic schemes upgrade. Let's say you have a p2p v3 encryption (or we wish to upgrade some cryptographic primitive e.g the hash func in BIP330 for the short ids). Here, you can see first if your peer supports the simple version, and then propose the upgrade. This would allow to make smoother upgrade over the network.
Quoted text (3 lines)
> There's no way to "freeze" development -- if BIP x says "you can't do > Y", then doing Y just means you aren't implementing BIP x; you're not > in any way inhibited from doing Y.
I believe we do have consensus fields reserved for future usage e.g not using the taproot annex which is checked by its own policy rule. Of course, it's policy only, there is difference between inhibition and encouragement of good practice.
Quoted text (3 lines)
> Messages received before `version` will generally already result in a > disconnect, as that's how nodes recognise they're talking to another > bitcoin node.
Yeah, this proposal is still tightening the `version` message protocol field bump with signaling support for BIP434. One way to disentangle would be to version-feature the FEATURE message with a 1-byte field (which for a 1-byte connection only doesn't seem a high bw cost).
Not sure if there is really a hard constraint to bump the protocol version here and it wouldn't be more elegant to add an optional byte in `version` message.
Best, Antoine OTS hash: 408e1c06080fa6b53c1ab076f9e881b5b1d9f971b984d12f9eaaf06bf5fb8d3c
Le dim. 8 mars 2026 à 12:14, Anthony Towns <aj@erisian•com•au> a écrit :
Quoted text (56 lines)
> On Sun, Mar 01, 2026 at 10:06:20AM -0800, Antoine Riard wrote: > > I'm > > thinking that one drawback with the multiple feature / signaling messages > > approach compared to the fixed-size length verack payload comes with the > > novel feature messages becoming a novel if not a least a vector of > > denial-of-service, at least some vector of annoyance. One peer can always > > throw a number of `feature` message only bounded by the 80^2 information > > space of the `featureid` string length. > > There's nothing stopping a peer from sending the same FEATURE message > multiple times prior to sending a VERACK, or sending the a FEATURE > message with the same featureid but different featuredata. > > However these aren't a DoS concern, because such messages are either > expected to be ignored (if the featureid isn't recognised by the peer) > or can be rejected as invalid (if the featureid is recognised but isn't > in compliance with the feature's specification). > > Sending a bunch of FEATURE messages that are immediately ignored is no > different from receiving a bunch of INV messages for txs you've already > seen, or sending any other payload that you expect the peer to ignore. > > > I don't think there is an easy or obvious answer > > to this issue, other than introducing a verack negotiation timeout (with > > all the frictions of the lack of an easy to use coordinated clock among > > peers...). > > A VERACK timeout is a pretty normal thing to have -- eg `-peertimeout` > already exists and defaults to 60 seconds. It's not clever to waste a > connection slot on a peer that's delaying ever getting into the part > where you relay bitcoin information to each other. > > > I do see the idea with that it's indeed allowing some form of > > interactive feature negotiation, > > In my opinion, interactive feature negotiation (of the form "I'll only > tell you I support X if you first tell me you do/don't support Y") > is massively overcomplicating things, and essentially an anti-pattern. > > > One last high level remark, I'm wondering if the protocol > > versioning shouldn't be "frozen" in itself, > > There's no way to "freeze" development -- if BIP x says "you can't do > Y", then doing Y just means you aren't implementing BIP x; you're not > in any way inhibited from doing Y. > > > - the BIP is silent on unknown messages received before `version` > > reception > > Messages received before `version` will generally already result in a > disconnect, as that's how nodes recognise they're talking to another > bitcoin node. > > Cheers, > aj >