Skip to content

Commit 3177af3

Browse files
authored
Merge pull request #2076 from ajtowns/202512-p2p-feature
BIP 434: Peer Feature Negotiation
2 parents 4c2f656 + 9630c4c commit 3177af3

File tree

2 files changed

+327
-0
lines changed

2 files changed

+327
-0
lines changed

README.mediawiki

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,13 @@ users (see also: [https://en.bitcoin.it/wiki/Economic_majority economic majority
13671367
| Informational
13681368
| Draft
13691369
|-
1370+
| [[bip-0434.md|434]]
1371+
| Peer Services
1372+
| Peer Feature Negotiation
1373+
| Anthony Towns
1374+
| Specification
1375+
| Draft
1376+
|-
13701377
| [[bip-0443.mediawiki|443]]
13711378
| Consensus (soft fork)
13721379
| OP_CHECKCONTRACTVERIFY

bip-0434.md

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
```
2+
BIP: 434
3+
Layer: Peer Services
4+
Title: Peer Feature Negotiation
5+
Authors: Anthony Towns <[email protected]>
6+
Status: Draft
7+
Type: Specification
8+
Assigned: 2026-01-14
9+
License: BSD-3-Clause
10+
Discussion: 2025-12-19: https://gnusha.org/pi/bitcoindev/[email protected]/T/#u
11+
2020-08-21: https://gnusha.org/pi/bitcoindev/[email protected]/
12+
Version: 0.1.0
13+
```
14+
15+
## Abstract
16+
17+
This BIP defines a peer-to-peer (P2P) message that can be used for
18+
announcements and negotiation related to support of new peer-to-peer
19+
features.
20+
21+
## Motivation
22+
23+
Historically, new peer-to-peer protocol changes have been tied to
24+
bumping the protocol version, so that nodes know to only attempt
25+
feature negotiation with peers that support the feature. Coordinating
26+
the protocol version across implementations, when different clients may
27+
have different priorities for features to implement, is an unnecessary
28+
burden in the upgrade process for P2P features that do not require
29+
universal support. And at a more philosophical level, having the P2P
30+
protocol be [permissionlessly extensible][permless-extensible], with no
31+
coordination required between implementations or developers, seems ideal
32+
for a decentralized system.
33+
34+
Many earlier P2P protocol upgrades were implemented as new messages
35+
sent after a peer connection is set up (ie, after receipt of a `verack`
36+
message by both sides). See [BIP 130 (sendheaders)][BIP130], [BIP 133
37+
(feefilter)][BIP133], and [BIP 152 (compact blocks)][BIP152] for some
38+
examples. However, for some P2P upgrades, it is helpful to perform
39+
feature negotiation prior to a connection being fully established
40+
(ie, prior to the `verack` being received by both sides). [BIP 155
41+
(addrv2)][BIP155] and [BIP 339 (wtxid-relay)][BIP339] are examples of
42+
this approach, which involves sending and receiving a single new message
43+
(`sendaddrv2` and `wtxidrelay` respectively), in between `version` and
44+
`verack` to indicate support of the new feature.
45+
46+
In all these cases, sending new messages on the network raises the
47+
question of what non-implementing software will do with such messages. The
48+
common behavior observed on the network was for software to ignore
49+
unknown messages received from a peer, so these proposals posed minimal
50+
risk of potential network partitioning. In fact, supporting protocol
51+
extensibility in this manner was given as an explicit reason to ignore
52+
unknown messages in Bitcoin's [first release][0.1-extensibility].
53+
54+
However, if nodes respond to unknown messages by disconnecting, then
55+
the network might partition in the future as incompatible software is
56+
deployed. And in fact, some clients on the network have historically
57+
discouraged or disallowed unknown messages, both between `version`
58+
and `verack` (eg, Bitcoin Core discouraged such messages between
59+
[PR#9720][PR#9720] and [PR#19723][PR#19723], and btcd disallowed
60+
such messages until [PR#1812][btcd#1812], but see also discussion in
61+
[#1661][btcd#1661]), as well as after `verack`.
62+
63+
To maximise compatibility with such clients, most of these BIPs require
64+
that peers bump the protocol version:
65+
66+
* [BIP 130][BIP130] requires version 70012 or higher,
67+
* [BIP 133][BIP133] requires version 70013 or higher,
68+
* [BIP 152][BIP152] recommends version 70014/70015 or higher, and
69+
* [BIP 339][BIP339] requires version 70016 or higher.
70+
71+
And while [BIP 155][BIP155] does not specify a minimum protocol version,
72+
implementations have [added][PR#20564] a de facto requirement of version
73+
70016 or higher.
74+
75+
In this BIP, we propose codifying and generalising the mechanism used by
76+
[BIP 339][BIP339] for future P2P upgrades, by adding a single new feature
77+
negotiation message that can be reused for advertising arbitrary new
78+
features, and requiring that implementing software ignore unknown features
79+
that might be advertised. This allows future upgrades to negotiate new
80+
features by exchanging messages prior to exchanging `verack` messages,
81+
without concerns of being unnecessarily disconnected by a peer which
82+
doesn't understand the messages, and without needing to coordinate
83+
updating the protocol version.
84+
85+
## Specification
86+
87+
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
88+
"RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
89+
interpreted as described in RFC 2119.
90+
91+
For the purposes of this section, `CompactSize` refers to the
92+
variable-length integer encoding used across the existing P2P protocol
93+
to encode array lengths, among other things, in 1, 3, 5 or 9 bytes. Only
94+
`CompactSize` encodings which are minimally-encoded (ie the shortest
95+
length possible) are used by this specification.
96+
97+
Nodes implementing this BIP:
98+
99+
* MUST advertise a protocol version number `>= 70017`,
100+
* MUST NOT send `feature` messages to peers that advertise a protocol
101+
version number `< 70017`,
102+
* MUST accept `feature` messages received after the `version` message
103+
and before the `verack` message, and
104+
* MUST NOT send `feature` messages after sending the `verack` message.
105+
106+
In addition, nodes implementing this BIP:
107+
108+
* SHOULD ignore unknown messages received after the `version` message
109+
and before the `verack` message,
110+
* MAY ignore `feature` messages sent after `verack`, and
111+
* MAY disconnect peers who send `feature` messages after `verack`.
112+
113+
Feature specifications based on this BIP:
114+
115+
* MUST forbid sending messages it introduces after `verack` to a peer
116+
that has not indicated support for the feature via a `feature`
117+
message.
118+
119+
### `feature` message
120+
121+
The payload of the `feature` message contains exactly the following data:
122+
123+
| Type | Name | Description |
124+
| ----------- | ------------- | ----------- |
125+
| string | `featureid` | Unique identifier for the feature |
126+
| byte-vector | `featuredata` | Feature-specific configuration data |
127+
128+
The `featureid` is encoded in the usual way, that is, as a `CompactSize`
129+
specifying the string length, followed by that many bytes. The string
130+
length MUST be between 4 and 80, inclusive. The string SHOULD include
131+
only printable ASCII characters (ie, each byte should have a value
132+
between 32 and 126, inclusive).
133+
134+
Likewise, `featuredata` is encoded as a `CompactSize` specifying the
135+
byte-vector size, followed by that many bytes. How these bytes are
136+
interpreted is part of the feature's specification. The byte-vector size
137+
MUST NOT be more than 512 bytes. Note that the `featuredata` field is not
138+
optional, so if no data is required, an empty vector should be provided,
139+
ie serialized as `CompactSize` of 0.
140+
141+
Nodes implementing this BIP MUST ignore `feature` messages specifying a
142+
`featureid` they do not support, so long as the payload conforms to the
143+
requirements above.
144+
145+
Nodes implementing this BIP MAY disconnect peers that send `feature`
146+
messages where the `feature` message's payload cannot be correctly
147+
parsed (including having missing or additional data), even if they do
148+
not recognise the `featureid`.
149+
150+
The `featureid` MUST be a globally unique identifier for the feature.
151+
For features published as a BIP, the `featureid` SHOULD be the assigned
152+
BIP number, eg "BIP434", or be based on the BIP number (eg, "BIP434v2"
153+
where the "v2" suffix covers versioning, or "BIP434.3" where the ".3"
154+
suffix covers part 3 of the BIP). For experimental features that do not
155+
(yet) have a BIP number assigned, some other unique identifier MUST be
156+
chosen, such as a URL to the repository where development is taking place,
157+
or the sha256 digest of some longer reference.
158+
159+
Nodes implementing both this BIP and [BIP 324 (v2 P2P encrypted
160+
transport)][BIP324] MUST treat a message with a 1-byte `message_type`
161+
equal to `XXX` that is received prior to `verack` as the `feature` message.
162+
163+
### Feature negotiation
164+
165+
It is RECOMMENDED that feature negotiation be designed and implemented
166+
as follows:
167+
168+
* all `feature` messages and the `verack` message should be sent
169+
immediately on receipt of the peer's `version` message
170+
* any negotiation calculations should be performed immediately on
171+
receipt of the peer's `verack` message
172+
173+
This structure is fairly easy to implement, and avoids introducing any
174+
significant latency that might result from more interactive negotiation
175+
methods.
176+
177+
Feature specifications defining a `featureid` MAY make use of the
178+
following approaches:
179+
180+
#### Feature advertisement:
181+
182+
1. Send a `feature` message advertising the `featureid` unconditionally
183+
2. Accept messages related to the feature unconditionally
184+
3. Only send messages defined by the feature if the peer sent
185+
a valid `feature` message for the `featureid`.
186+
187+
This approach is appropriate for many simple features that define
188+
new messages, particularly where an implementation might only
189+
implement sending or receiving a message, but not both, eg [BIP 35
190+
(mempool)][BIP35].
191+
192+
#### Feature coordination:
193+
194+
1. Send a `feature` message advertising the `featureid` unconditionally
195+
2. Check if the peer sends the same `feature` message (or a compatible
196+
one), and enable the feature for this peer if so.
197+
3. Only send/accept messages or encode data items according to the
198+
feature's specification if the feature is enabled for this peer.
199+
200+
This approach is appropriate for upgrades to data encoding in
201+
P2P messages, eg [BIP 339 (wtxidrelay)][BIP339] or [BIP 155
202+
(addrv2)][BIP155].
203+
204+
#### Feature versioning:
205+
206+
1. Send `feature` messages for multiple incompatible features, eg
207+
`BIP434v3`, `BIP434v2`, `BIP434v1`, ordered from most preferred
208+
to least.
209+
2. Track the corresponding `feature` messages from your peer.
210+
3. If you were the listening peer, enable your highest preference feature
211+
that your peer also supports.
212+
4. If you were the initiating peer, enable the first feature that your
213+
peer announced, that you also support.
214+
5. For example if the listening peer sends `BIP434v3`, `BIP434v2`,
215+
`BIP434v1`, and the initiating peer sends `BIP434v1`, `BIP434v2`,
216+
then the listening peer should select `BIP434v2` when `verack`
217+
is received, and the initiating peer should select `BIP434v2`
218+
as soon as `feature BIP434v2` is received.
219+
6. Conversely, if the initiating peer sends `BIP434v3`, `BIP434v2`,
220+
`BIP434v1`, and the listening peer sends `BIP434v1`, `BIP434v2`,
221+
then the listening peer should select `BIP434v1` when `verack`
222+
is received, and the initiating peer should select `BIP434v1`
223+
as soon as `feature BIP434v1` is received.
224+
7. In most cases, implementations should simply advertise incompatible
225+
features in order from most recent to oldest, on the basis that
226+
the only reason to make incompatible updates is because there are
227+
significant improvements. Exceptions to that may occur when two
228+
incompatible features are both receiving active development, or
229+
when an implementation has only partially implemented the latest
230+
spec, and the older spec is better supported (and thus should be
231+
listed first, as the preferred protocol to adopt).
232+
233+
This approach may be appropriate when making substantial changes to a
234+
deployed protocol and backwards compatibility is desirable on a short-term
235+
basis, or when there is disagreement amongst implementations or users
236+
as to which approach is most desirable.
237+
238+
## Considerations
239+
240+
The advantage this approach has over bumping the protocol version
241+
number when introducing new P2P messages or data structures, is that no
242+
coordination is required (that is, there is no longer a question whether
243+
version "n+1" belongs to Alice's new feature, or Bob's new feature),
244+
and there is no implication that supporting each new feature means all
245+
prior features are also supported.
246+
247+
The advantage this approach has over defining new messages for each
248+
feature is that the `featureid` can be much longer (at up to 80
249+
bytes) than a message type id (which are limited to 12 bytes). With a
250+
[BIP 324][BIP324] one-byte `message_type`, the overhead compared to that
251+
approach is also kept small.
252+
253+
This approach is largely equivalent to adding a [payload to the `verack`
254+
message][verack-payload] (eg, a vector of `featureid`, `featuredata`
255+
pairs). It was chosen because:
256+
257+
* it retains compatibility with any implementations that expect `verack`
258+
to have no payload;
259+
* it allows peers to process each feature request individually, rather than
260+
having to first load the configuration information for all features into
261+
memory at once (in order to validate the message's checksum), and then
262+
deal with each feature's configuration;
263+
* limiting the maximum message payload size you accept (eg to 4MB)
264+
does not limit the number of features you can accept; and
265+
* we have experience with negotiating features with individual messages,
266+
but no experience with doing so via `verack` payload.
267+
268+
A mild disadvantage compared to using a `verack` payload is that this
269+
approach allows the possibility of interactive feature negotiation prior
270+
to `verack`. However interactive feature negotiation is always possible
271+
simply by having the initiating peer disconnect and reconnect after
272+
discovering the listening peer's supported features.
273+
274+
This specification attempts to maximise compatibility with implementations
275+
that prefer to fully validate each message received:
276+
277+
* `feature` messages, even for unknown features, must always be fully
278+
parseable into a `featureid` and `featuredata`
279+
* Ignoring unknown messages prior to `verack` is only a recommendation,
280+
not a requirement, so compliant implementations may disconnect on an
281+
unknown message that cannot be validated.
282+
* Sending unknown messages after `verack` is explicitly forbidden,
283+
in so far as that is possible.
284+
285+
## Backward compatibility
286+
287+
Clients specifying a version number prior to `70017` remain fully
288+
compatible with this change.
289+
290+
Clients specifying a version number of `70017` or higher that do not
291+
implement this BIP remain fully compatible provided they do not disconnect
292+
peers upon receiving unexpected messages received between `version` and
293+
`verack`.
294+
295+
## Acknowledgements
296+
297+
Much of the logic here, and much of the text in the motivation section,
298+
is based on Suhas Daftuar's 2020 post on [Generalizing feature
299+
negotiation][suhas-draft].
300+
301+
## Copyright
302+
303+
This BIP is licensed under the 2-clause BSD license.
304+
305+
[BIP130]: https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki
306+
[BIP133]: https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki
307+
[BIP152]: https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
308+
[BIP155]: https://github.com/bitcoin/bips/blob/master/bip-0155.mediawiki
309+
[BIP339]: https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki
310+
[BIP35]: https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki
311+
[BIP324]: https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki
312+
[verack-payload]: https://gnusha.org/pi/bitcoindev/[email protected]/
313+
[PR#20564]: https://github.com/bitcoin/bitcoin/pull/20564
314+
[PR#9720]: https://github.com/bitcoin/bitcoin/pull/9720
315+
[PR#19723]: https://github.com/bitcoin/bitcoin/pull/19723
316+
[btcd#1812]: https://github.com/btcsuite/btcd/pull/1812
317+
[btcd#1661]: https://github.com/btcsuite/btcd/issues/1661
318+
[permless-extensible]: https://github.com/bitcoin/bitcoin/pull/20564#issuecomment-738456560
319+
[0.1-extensibility]: https://github.com/benjiqq/bitcoinArchive/blob/master/bitcoin0.1/src/main.cpp#L2035-L2039
320+
[suhas-draft]: https://gnusha.org/pi/bitcoindev/CAFp6fsE=HPFUMFhyuZkroBO_QJ-dUWNJqCPg9=fMJ3Jqnu1hnw@mail.gmail.com/

0 commit comments

Comments
 (0)