diff --git a/README.mediawiki b/README.mediawiki index ed4e1dd24a..43ab339bb3 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1360,6 +1360,13 @@ users (see also: [https://en.bitcoin.it/wiki/Economic_majority economic majority | Informational | Draft |- +| [[bip-0434.md|434]] +| Peer Services +| Peer Feature Negotiation +| Anthony Towns +| Specification +| Draft +|- | [[bip-0443.mediawiki|443]] | Consensus (soft fork) | OP_CHECKCONTRACTVERIFY diff --git a/bip-0434.md b/bip-0434.md new file mode 100644 index 0000000000..3cf53995eb --- /dev/null +++ b/bip-0434.md @@ -0,0 +1,320 @@ +``` + BIP: 434 + Layer: Peer Services + Title: Peer Feature Negotiation + Authors: Anthony Towns + Status: Draft + Type: Specification + Assigned: 2026-01-14 + License: BSD-3-Clause + Discussion: 2025-12-19: https://gnusha.org/pi/bitcoindev/aUUXLgEUCgGb122o@erisian.com.au/T/#u + 2020-08-21: https://gnusha.org/pi/bitcoindev/20200821023647.7eat4goqqrtaqnna@erisian.com.au/ + Version: 0.1.0 +``` + +## Abstract + +This BIP defines a peer-to-peer (P2P) message that can be used for +announcements and negotiation related to support of new peer-to-peer +features. + +## Motivation + +Historically, new peer-to-peer protocol changes have been tied to +bumping the protocol version, so that nodes know to only attempt +feature negotiation with peers that support the feature. Coordinating +the protocol version across implementations, when different clients may +have different priorities for features to implement, is an unnecessary +burden in the upgrade process for P2P features that do not require +universal support. And at a more philosophical level, having the P2P +protocol be [permissionlessly extensible][permless-extensible], with no +coordination required between implementations or developers, seems ideal +for a decentralized system. + +Many earlier P2P protocol upgrades were implemented as new messages +sent after a peer connection is set up (ie, after receipt of a `verack` +message by both sides). See [BIP 130 (sendheaders)][BIP130], [BIP 133 +(feefilter)][BIP133], and [BIP 152 (compact blocks)][BIP152] for some +examples. However, for some P2P upgrades, it is helpful to perform +feature negotiation prior to a connection being fully established +(ie, prior to the `verack` being received by both sides). [BIP 155 +(addrv2)][BIP155] and [BIP 339 (wtxid-relay)][BIP339] are examples of +this approach, which involves sending and receiving a single new message +(`sendaddrv2` and `wtxidrelay` respectively), in between `version` and +`verack` to indicate support of the new feature. + +In all these cases, sending new messages on the network raises the +question of what non-implementing software will do with such messages. The +common behavior observed on the network was for software to ignore +unknown messages received from a peer, so these proposals posed minimal +risk of potential network partitioning. In fact, supporting protocol +extensibility in this manner was given as an explicit reason to ignore +unknown messages in Bitcoin's [first release][0.1-extensibility]. + +However, if nodes respond to unknown messages by disconnecting, then +the network might partition in the future as incompatible software is +deployed. And in fact, some clients on the network have historically +discouraged or disallowed unknown messages, both between `version` +and `verack` (eg, Bitcoin Core discouraged such messages between +[PR#9720][PR#9720] and [PR#19723][PR#19723], and btcd disallowed +such messages until [PR#1812][btcd#1812], but see also discussion in +[#1661][btcd#1661]), as well as after `verack`. + +To maximise compatibility with such clients, most of these BIPs require +that peers bump the protocol version: + + * [BIP 130][BIP130] requires version 70012 or higher, + * [BIP 133][BIP133] requires version 70013 or higher, + * [BIP 152][BIP152] recommends version 70014/70015 or higher, and + * [BIP 339][BIP339] requires version 70016 or higher. + +And while [BIP 155][BIP155] does not specify a minimum protocol version, +implementations have [added][PR#20564] a de facto requirement of version +70016 or higher. + +In this BIP, we propose codifying and generalising the mechanism used by +[BIP 339][BIP339] for future P2P upgrades, by adding a single new feature +negotiation message that can be reused for advertising arbitrary new +features, and requiring that implementing software ignore unknown features +that might be advertised. This allows future upgrades to negotiate new +features by exchanging messages prior to exchanging `verack` messages, +without concerns of being unnecessarily disconnected by a peer which +doesn't understand the messages, and without needing to coordinate +updating the protocol version. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", +"RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be +interpreted as described in RFC 2119. + +For the purposes of this section, `CompactSize` refers to the +variable-length integer encoding used across the existing P2P protocol +to encode array lengths, among other things, in 1, 3, 5 or 9 bytes. Only +`CompactSize` encodings which are minimally-encoded (ie the shortest +length possible) are used by this specification. + +Nodes implementing this BIP: + + * MUST advertise a protocol version number `>= 70017`, + * MUST NOT send `feature` messages to peers that advertise a protocol + version number `< 70017`, + * MUST accept `feature` messages received after the `version` message + and before the `verack` message, and + * MUST NOT send `feature` messages after sending the `verack` message. + +In addition, nodes implementing this BIP: + + * SHOULD ignore unknown messages received after the `version` message + and before the `verack` message, + * MAY ignore `feature` messages sent after `verack`, and + * MAY disconnect peers who send `feature` messages after `verack`. + +Feature specifications based on this BIP: + + * MUST forbid sending messages it introduces after `verack` to a peer + that has not indicated support for the feature via a `feature` + message. + +### `feature` message + +The payload of the `feature` message contains exactly the following data: + +| Type | Name | Description | +| ----------- | ------------- | ----------- | +| string | `featureid` | Unique identifier for the feature | +| byte-vector | `featuredata` | Feature-specific configuration data | + +The `featureid` is encoded in the usual way, that is, as a `CompactSize` +specifying the string length, followed by that many bytes. The string +length MUST be between 4 and 80, inclusive. The string SHOULD include +only printable ASCII characters (ie, each byte should have a value +between 32 and 126, inclusive). + +Likewise, `featuredata` is encoded as a `CompactSize` specifying the +byte-vector size, followed by that many bytes. How these bytes are +interpreted is part of the feature's specification. The byte-vector size +MUST NOT be more than 512 bytes. Note that the `featuredata` field is not +optional, so if no data is required, an empty vector should be provided, +ie serialized as `CompactSize` of 0. + +Nodes implementing this BIP MUST ignore `feature` messages specifying a +`featureid` they do not support, so long as the payload conforms to the +requirements above. + +Nodes implementing this BIP MAY disconnect peers that send `feature` +messages where the `feature` message's payload cannot be correctly +parsed (including having missing or additional data), even if they do +not recognise the `featureid`. + +The `featureid` MUST be a globally unique identifier for the feature. +For features published as a BIP, the `featureid` SHOULD be the assigned +BIP number, eg "BIP434", or be based on the BIP number (eg, "BIP434v2" +where the "v2" suffix covers versioning, or "BIP434.3" where the ".3" +suffix covers part 3 of the BIP). For experimental features that do not +(yet) have a BIP number assigned, some other unique identifier MUST be +chosen, such as a URL to the repository where development is taking place, +or the sha256 digest of some longer reference. + +Nodes implementing both this BIP and [BIP 324 (v2 P2P encrypted +transport)][BIP324] MUST treat a message with a 1-byte `message_type` +equal to `XXX` that is received prior to `verack` as the `feature` message. + +### Feature negotiation + +It is RECOMMENDED that feature negotiation be designed and implemented +as follows: + + * all `feature` messages and the `verack` message should be sent + immediately on receipt of the peer's `version` message + * any negotiation calculations should be performed immediately on + receipt of the peer's `verack` message + +This structure is fairly easy to implement, and avoids introducing any +significant latency that might result from more interactive negotiation +methods. + +Feature specifications defining a `featureid` MAY make use of the +following approaches: + +#### Feature advertisement: + + 1. Send a `feature` message advertising the `featureid` unconditionally + 2. Accept messages related to the feature unconditionally + 3. Only send messages defined by the feature if the peer sent + a valid `feature` message for the `featureid`. + +This approach is appropriate for many simple features that define +new messages, particularly where an implementation might only +implement sending or receiving a message, but not both, eg [BIP 35 +(mempool)][BIP35]. + +#### Feature coordination: + + 1. Send a `feature` message advertising the `featureid` unconditionally + 2. Check if the peer sends the same `feature` message (or a compatible + one), and enable the feature for this peer if so. + 3. Only send/accept messages or encode data items according to the + feature's specification if the feature is enabled for this peer. + +This approach is appropriate for upgrades to data encoding in +P2P messages, eg [BIP 339 (wtxidrelay)][BIP339] or [BIP 155 +(addrv2)][BIP155]. + +#### Feature versioning: + + 1. Send `feature` messages for multiple incompatible features, eg + `BIP434v3`, `BIP434v2`, `BIP434v1`, ordered from most preferred + to least. + 2. Track the corresponding `feature` messages from your peer. + 3. If you were the listening peer, enable your highest preference feature + that your peer also supports. + 4. If you were the initiating peer, enable the first feature that your + peer announced, that you also support. + 5. For example if the listening peer sends `BIP434v3`, `BIP434v2`, + `BIP434v1`, and the initiating peer sends `BIP434v1`, `BIP434v2`, + then the listening peer should select `BIP434v2` when `verack` + is received, and the initiating peer should select `BIP434v2` + as soon as `feature BIP434v2` is received. + 6. Conversely, if the initiating peer sends `BIP434v3`, `BIP434v2`, + `BIP434v1`, and the listening peer sends `BIP434v1`, `BIP434v2`, + then the listening peer should select `BIP434v1` when `verack` + is received, and the initiating peer should select `BIP434v1` + as soon as `feature BIP434v1` is received. + 7. In most cases, implementations should simply advertise incompatible + features in order from most recent to oldest, on the basis that + the only reason to make incompatible updates is because there are + significant improvements. Exceptions to that may occur when two + incompatible features are both receiving active development, or + when an implementation has only partially implemented the latest + spec, and the older spec is better supported (and thus should be + listed first, as the preferred protocol to adopt). + +This approach may be appropriate when making substantial changes to a +deployed protocol and backwards compatibility is desirable on a short-term +basis, or when there is disagreement amongst implementations or users +as to which approach is most desirable. + +## Considerations + +The advantage this approach has over bumping the protocol version +number when introducing new P2P messages or data structures, is that no +coordination is required (that is, there is no longer a question whether +version "n+1" belongs to Alice's new feature, or Bob's new feature), +and there is no implication that supporting each new feature means all +prior features are also supported. + +The advantage this approach has over defining new messages for each +feature is that the `featureid` can be much longer (at up to 80 +bytes) than a message type id (which are limited to 12 bytes). With a +[BIP 324][BIP324] one-byte `message_type`, the overhead compared to that +approach is also kept small. + +This approach is largely equivalent to adding a [payload to the `verack` +message][verack-payload] (eg, a vector of `featureid`, `featuredata` +pairs). It was chosen because: + + * it retains compatibility with any implementations that expect `verack` + to have no payload; + * it allows peers to process each feature request individually, rather than + having to first load the configuration information for all features into + memory at once (in order to validate the message's checksum), and then + deal with each feature's configuration; + * limiting the maximum message payload size you accept (eg to 4MB) + does not limit the number of features you can accept; and + * we have experience with negotiating features with individual messages, + but no experience with doing so via `verack` payload. + +A mild disadvantage compared to using a `verack` payload is that this +approach allows the possibility of interactive feature negotiation prior +to `verack`. However interactive feature negotiation is always possible +simply by having the initiating peer disconnect and reconnect after +discovering the listening peer's supported features. + +This specification attempts to maximise compatibility with implementations +that prefer to fully validate each message received: + + * `feature` messages, even for unknown features, must always be fully + parseable into a `featureid` and `featuredata` + * Ignoring unknown messages prior to `verack` is only a recommendation, + not a requirement, so compliant implementations may disconnect on an + unknown message that cannot be validated. + * Sending unknown messages after `verack` is explicitly forbidden, + in so far as that is possible. + +## Backward compatibility + +Clients specifying a version number prior to `70017` remain fully +compatible with this change. + +Clients specifying a version number of `70017` or higher that do not +implement this BIP remain fully compatible provided they do not disconnect +peers upon receiving unexpected messages received between `version` and +`verack`. + +## Acknowledgements + +Much of the logic here, and much of the text in the motivation section, +is based on Suhas Daftuar's 2020 post on [Generalizing feature +negotiation][suhas-draft]. + +## Copyright + +This BIP is licensed under the 2-clause BSD license. + +[BIP130]: https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki +[BIP133]: https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki +[BIP152]: https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki +[BIP155]: https://github.com/bitcoin/bips/blob/master/bip-0155.mediawiki +[BIP339]: https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki +[BIP35]: https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki +[BIP324]: https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki +[verack-payload]: https://gnusha.org/pi/bitcoindev/B514142F-382B-4D49-B68D-0115ECBD1D79@voskuil.org/ +[PR#20564]: https://github.com/bitcoin/bitcoin/pull/20564 +[PR#9720]: https://github.com/bitcoin/bitcoin/pull/9720 +[PR#19723]: https://github.com/bitcoin/bitcoin/pull/19723 +[btcd#1812]: https://github.com/btcsuite/btcd/pull/1812 +[btcd#1661]: https://github.com/btcsuite/btcd/issues/1661 +[permless-extensible]: https://github.com/bitcoin/bitcoin/pull/20564#issuecomment-738456560 +[0.1-extensibility]: https://github.com/benjiqq/bitcoinArchive/blob/master/bitcoin0.1/src/main.cpp#L2035-L2039 +[suhas-draft]: https://gnusha.org/pi/bitcoindev/CAFp6fsE=HPFUMFhyuZkroBO_QJ-dUWNJqCPg9=fMJ3Jqnu1hnw@mail.gmail.com/