From 767eac22ce282d8a6626dc31468f0ef0d0ff0662 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Mon, 23 Jun 2025 16:00:21 -0700 Subject: [PATCH 1/8] Gossipsub v1.3: Extensions control Message --- pubsub/gossipsub/gossipsub-v1.3.md | 137 +++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 pubsub/gossipsub/gossipsub-v1.3.md diff --git a/pubsub/gossipsub/gossipsub-v1.3.md b/pubsub/gossipsub/gossipsub-v1.3.md new file mode 100644 index 000000000..5a5032e8f --- /dev/null +++ b/pubsub/gossipsub/gossipsub-v1.3.md @@ -0,0 +1,137 @@ +# gossipsub v1.3: Extensions Control Message + +| Lifecycle Stage | Maturity | Status | Latest Revision | +| --------------- | ------------- | ------ | --------------- | +| 1A | Working Draft | Active | r0, 2025-06-23 | + +Authors: [@marcopolo] + +Interest Group: TODO + +[@marcopolo]: https://github.com/marcopolo + +See the [lifecycle document][lifecycle-spec] for context about the maturity level +and spec status. + +[lifecycle-spec]: https://github.com/libp2p/specs/blob/master/00-framework-01-spec-lifecycle.md + +## Overview + +This version specifies a way to for gossipsub peers to describe their +characteristics to each other without requiring a new protocol ID per extension. + +This spec MUST be updated upon introducing a new extension, either canonical or +experimental, to the network. + +## Motivation + +This version makes Gossipsub easier to extend by allowing applications to +selectively make use of the extensions it would benefit from. It removes the +need to make Gossipsub extensions follow a strict ordering. Finally, it allows +extensions to iterate independently from Gossipsub's versioning. + +## The Extensions Control Message + +If a peer supports any extension, the Extensions control message MUST be +included in the first message on the stream. An Extensions control message MUST +NOT be sent more than once. If a peer supports no extensions, it may omit +sending the Extensions control message. + +Extensions are not negotiated; they describe characteristics of the sending peer +that can be used by the receiving peer. However, a negotiation can be implied: +each peer uses the Extensions control message to advertise a set of supported +values. The specification of an extension describes how each peer combines the +two sets to define its behavior. + +Peers MUST ignore unknown extensions. + +Extensions that modify or replace core protocol functionality will be difficult +to combine with other extensions that modify or replace the same functionality +unless the behavior of the combination is explicitly defined. Such extensions +SHOULD define their interaction with previously defined extensions modifying the +same protocol components. + +## Protocol ID + +The Gossipsub version for this specification is `v1.3.0`. The protocol ID is +`/meshsub/1.3.0`. + +## Process to add a new extensions to this spec + +### Canonical Extensions + +A Canonical Extension is an extension that is well defined, has multiple +implementations, has shown to be useful in real networks, and has rough +consensus on becoming a canonical extension. The extension specification MUST be +defined in the `libp2p/specs` GitHub repo. After an extension meets the stated +criteria, this specification MUST be updated to include the extension in the +`ControlExtensions` protobuf with a link to the extension's specification doc in +a comment. The extension SHOULD use the next lowest available field number. + +Any new messages defined by the extension MUST be added to `RPC` message +definition in this spec. Extensions SHOULD minimize the number of new messages +they introduce here. Try to introduce a single new message, and use that message +as a container for more messages similar to the strategy used by the +ControlMessage in the RPC. + +All extension messages MUST be an `optional` field. + +### Experimental Extensions + +In contrast with a Canonical Extension, an Experimental Extension is still being +evaluated and iterated upon. Adding an experimental extension to this spec lets +others see what is being tried, and ensure there are no misinterpretations of +messages on the wire. A patch to this spec is not needed if experimenting with +an extension in a controlled environment. A patch to this spec is also not +needed if you are not using the `/meshsub/v1.3.0` protocol ID. + +If the extension is being tested on a live network, a PR MUST be created that +adds the extension to the `ControlExtensions` protobuf with a link to the +extension's specification. Experimental extensions MUST use a large field number +randomly generated to be at least 4 bytes long when varint encoded. The +extension author MUST ensure this field number does not conflict with any +existing field. + +New messages defined by this extension should follow the same guidelines as new +messages for canonical extensions. Field numbers MUST be randomly generated and +be at least 4 bytes long when varint encoded. + +Maintainers MUST check that the extension is well specified, in the experimental +range, and that the extension will be tested on a live network. If so, +maintainers SHOULD merge the change. + +## Protobuf + +```protobuf +syntax = "proto2"; + +message ControlExtensions { + // Initially empty. Future extensions will be added here along with a + // reference to their specification. + + // Experimental extensions must use field numbers larger than 0x200000 to be + // encoded with at least 4 bytes +} + +message ControlMessage { + repeated ControlIHave ihave = 1; + repeated ControlIWant iwant = 2; + repeated ControlGraft graft = 3; + repeated ControlPrune prune = 4; + repeated ControlIDontWant idontwant = 5; + optional ControlExtensions extensions = 6; +} + +message RPC { + repeated SubOpts subscriptions = 1; + repeated Message publish = 2; + optional ControlMessage control = 3; + + + // Canonical Extensions should register their messages here. + + // Experimental Extensions should register their messages here. They + // must use field numbers larger than 0x200000 to be encoded with at least 4 + // bytes +} +``` From c9c8b5a4dd804f312b4064d00478101ae361e743 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Thu, 3 Jul 2025 14:45:35 -0700 Subject: [PATCH 2/8] Add test extension for interop-testing --- .../extensions/experimental/test-extension.md | 37 +++++++++++++++++++ pubsub/gossipsub/gossipsub-v1.3.md | 3 ++ 2 files changed, 40 insertions(+) create mode 100644 pubsub/gossipsub/extensions/experimental/test-extension.md diff --git a/pubsub/gossipsub/extensions/experimental/test-extension.md b/pubsub/gossipsub/extensions/experimental/test-extension.md new file mode 100644 index 000000000..8fac86e16 --- /dev/null +++ b/pubsub/gossipsub/extensions/experimental/test-extension.md @@ -0,0 +1,37 @@ +# Test Extension + +| Lifecycle Stage | Maturity | Status | Latest Revision | +| --------------- | ------------- | ------ | --------------- | +| 1A | Working Draft | Active | r0, 2025-06-23 | + +Authors: [@marcopolo] + +Interest Group: @jxs + +[@marcopolo]: https://github.com/marcopolo +[@jxs]: https://github.com/jxs + +See the [lifecycle document][lifecycle-spec] for context about the maturity level +and spec status. + +[lifecycle-spec]: https://github.com/libp2p/specs/blob/master/00-framework-01-spec-lifecycle.md + +## Overview + +This introduces a minimal extension to Gossipsub. The only motivation is to +test the interoperability of Gossipsub Extensions Control Message across +implementations. One way for example, is to connect different implementations +together and assert that both peers send the TestExtension message. + +## The Protocol + +If both Peers support the Test Extension, each peer MUST send a TestExtension +Message. + +## Protobuf + +```protobuf +syntax = "proto2"; + +message TestExtension {} +``` diff --git a/pubsub/gossipsub/gossipsub-v1.3.md b/pubsub/gossipsub/gossipsub-v1.3.md index 5a5032e8f..18602572b 100644 --- a/pubsub/gossipsub/gossipsub-v1.3.md +++ b/pubsub/gossipsub/gossipsub-v1.3.md @@ -111,6 +111,8 @@ message ControlExtensions { // Experimental extensions must use field numbers larger than 0x200000 to be // encoded with at least 4 bytes + + optional TestExtension testExtension = 6492434; } message ControlMessage { @@ -133,5 +135,6 @@ message RPC { // Experimental Extensions should register their messages here. They // must use field numbers larger than 0x200000 to be encoded with at least 4 // bytes + optional bool testExtension = 6492434; } ``` From cf8237ada75e75f46e842024af9825289568de08 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 4 Jul 2025 12:22:04 -0700 Subject: [PATCH 3/8] fix typo --- pubsub/gossipsub/gossipsub-v1.3.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubsub/gossipsub/gossipsub-v1.3.md b/pubsub/gossipsub/gossipsub-v1.3.md index 18602572b..707d3ea63 100644 --- a/pubsub/gossipsub/gossipsub-v1.3.md +++ b/pubsub/gossipsub/gossipsub-v1.3.md @@ -112,7 +112,7 @@ message ControlExtensions { // Experimental extensions must use field numbers larger than 0x200000 to be // encoded with at least 4 bytes - optional TestExtension testExtension = 6492434; + optional bool testExtension = 6492434; } message ControlMessage { @@ -135,6 +135,6 @@ message RPC { // Experimental Extensions should register their messages here. They // must use field numbers larger than 0x200000 to be encoded with at least 4 // bytes - optional bool testExtension = 6492434; + optional TestExtension testExtension = 6492434; } ``` From e01116b014d0ee001451e9e23780f8d9f1fb5458 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 9 Jul 2025 16:19:49 -0700 Subject: [PATCH 4/8] Update interest group and lifecycle status --- pubsub/gossipsub/gossipsub-v1.3.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pubsub/gossipsub/gossipsub-v1.3.md b/pubsub/gossipsub/gossipsub-v1.3.md index 5a5032e8f..45db5188e 100644 --- a/pubsub/gossipsub/gossipsub-v1.3.md +++ b/pubsub/gossipsub/gossipsub-v1.3.md @@ -1,14 +1,18 @@ # gossipsub v1.3: Extensions Control Message -| Lifecycle Stage | Maturity | Status | Latest Revision | -| --------------- | ------------- | ------ | --------------- | -| 1A | Working Draft | Active | r0, 2025-06-23 | +| Lifecycle Stage | Maturity | Status | Latest Revision | +| --------------- | ------------------------ | ------ | --------------- | +| 3A | Candidate Recommendation | Active | r0, 2025-06-23 | Authors: [@marcopolo] -Interest Group: TODO +Interest Group: [@cortze], [@cskiraly], [@ppopth], [@jxs] [@marcopolo]: https://github.com/marcopolo +[@cortze]: https://github.com/cortze +[@cskiraly]: https://github.com/cskiraly +[@ppopth]: https://github.com/ppopth +[@jxs]: https://github.com/jxs See the [lifecycle document][lifecycle-spec] for context about the maturity level and spec status. From 7bb41166ff58f6c33fde622755d85c13ed8e48fa Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Thu, 10 Jul 2025 15:33:29 -0700 Subject: [PATCH 5/8] Expand interest group --- pubsub/gossipsub/gossipsub-v1.3.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pubsub/gossipsub/gossipsub-v1.3.md b/pubsub/gossipsub/gossipsub-v1.3.md index 45db5188e..237176979 100644 --- a/pubsub/gossipsub/gossipsub-v1.3.md +++ b/pubsub/gossipsub/gossipsub-v1.3.md @@ -6,13 +6,14 @@ Authors: [@marcopolo] -Interest Group: [@cortze], [@cskiraly], [@ppopth], [@jxs] +Interest Group: [@cortze], [@cskiraly], [@ppopth], [@jxs], [@raulk] [@marcopolo]: https://github.com/marcopolo [@cortze]: https://github.com/cortze [@cskiraly]: https://github.com/cskiraly [@ppopth]: https://github.com/ppopth [@jxs]: https://github.com/jxs +[@raulk]: https://github.com/raulk See the [lifecycle document][lifecycle-spec] for context about the maturity level and spec status. From 9d4be1f4cc239f0d5adae97c983661bfaf1e36eb Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Thu, 7 Aug 2025 14:29:45 -0700 Subject: [PATCH 6/8] Move extensions protobuf to a separate file --- pubsub/gossipsub/extensions/extensions.proto | 39 +++++++++++++ pubsub/gossipsub/gossipsub-v1.3.md | 60 +++++--------------- 2 files changed, 54 insertions(+), 45 deletions(-) create mode 100644 pubsub/gossipsub/extensions/extensions.proto diff --git a/pubsub/gossipsub/extensions/extensions.proto b/pubsub/gossipsub/extensions/extensions.proto new file mode 100644 index 000000000..41c3ae8a8 --- /dev/null +++ b/pubsub/gossipsub/extensions/extensions.proto @@ -0,0 +1,39 @@ +syntax = "proto2"; + +message ControlExtensions { + // Initially empty. Future canonical extensions will be added here along with + // a reference to their specification. + + // Experimental extensions must use field numbers larger than 0x200000 to be + // encoded with at least 4 bytes + + optional bool testExtension = 6492434; +} + +message ControlMessage { + repeated ControlIHave ihave = 1; + repeated ControlIWant iwant = 2; + repeated ControlGraft graft = 3; + repeated ControlPrune prune = 4; + repeated ControlIDontWant idontwant = 5; + optional ControlExtensions extensions = 6; +} + +message RPC { + message SubOpts { + optional bool subscribe = 1; // subscribe or unsubcribe + optional string topicid = 2; + } + + repeated SubOpts subscriptions = 1; + repeated Message publish = 2; + optional ControlMessage control = 3; + + // Canonical Extensions should register their messages here. + + // Experimental Extensions should register their messages here. They + // must use field numbers larger than 0x200000 to be encoded with at least 4 + // bytes + + optional TestExtension testExtension = 6492434; +} diff --git a/pubsub/gossipsub/gossipsub-v1.3.md b/pubsub/gossipsub/gossipsub-v1.3.md index 7ca6ea79c..a041afa18 100644 --- a/pubsub/gossipsub/gossipsub-v1.3.md +++ b/pubsub/gossipsub/gossipsub-v1.3.md @@ -69,26 +69,27 @@ A Canonical Extension is an extension that is well defined, has multiple implementations, has shown to be useful in real networks, and has rough consensus on becoming a canonical extension. The extension specification MUST be defined in the `libp2p/specs` GitHub repo. After an extension meets the stated -criteria, this specification MUST be updated to include the extension in the +criteria, `extensions.proto` MUST be updated to include the extension in the `ControlExtensions` protobuf with a link to the extension's specification doc in a comment. The extension SHOULD use the next lowest available field number. Any new messages defined by the extension MUST be added to `RPC` message -definition in this spec. Extensions SHOULD minimize the number of new messages -they introduce here. Try to introduce a single new message, and use that message -as a container for more messages similar to the strategy used by the -ControlMessage in the RPC. +definition in the `extensions.proto` protobuf. Extensions SHOULD minimize the +number of new messages they introduce here. Try to introduce a single new +message, and use that message as a container for more messages similar to the +strategy used by the ControlMessage in the RPC. All extension messages MUST be an `optional` field. ### Experimental Extensions In contrast with a Canonical Extension, an Experimental Extension is still being -evaluated and iterated upon. Adding an experimental extension to this spec lets -others see what is being tried, and ensure there are no misinterpretations of -messages on the wire. A patch to this spec is not needed if experimenting with -an extension in a controlled environment. A patch to this spec is also not -needed if you are not using the `/meshsub/v1.3.0` protocol ID. +evaluated and iterated upon. Adding an experimental extension to the +`extensions.proto` lets others see what is being tried, and ensure there are no +misinterpretations of messages on the wire. A patch to this `extensions.proto` +is not needed if experimenting with an extension in a controlled environment. A +patch to `extensions.proto` is also not needed if you are not using the +`/meshsub/v1.3.0` protocol ID. If the extension is being tested on a live network, a PR MUST be created that adds the extension to the `ControlExtensions` protobuf with a link to the @@ -107,39 +108,8 @@ maintainers SHOULD merge the change. ## Protobuf -```protobuf -syntax = "proto2"; +The `extensions.proto` file can be found at +(`./extensions/extensions.proto`)[./extensions/extensions.proto]. -message ControlExtensions { - // Initially empty. Future extensions will be added here along with a - // reference to their specification. - - // Experimental extensions must use field numbers larger than 0x200000 to be - // encoded with at least 4 bytes - - optional bool testExtension = 6492434; -} - -message ControlMessage { - repeated ControlIHave ihave = 1; - repeated ControlIWant iwant = 2; - repeated ControlGraft graft = 3; - repeated ControlPrune prune = 4; - repeated ControlIDontWant idontwant = 5; - optional ControlExtensions extensions = 6; -} - -message RPC { - repeated SubOpts subscriptions = 1; - repeated Message publish = 2; - optional ControlMessage control = 3; - - - // Canonical Extensions should register their messages here. - - // Experimental Extensions should register their messages here. They - // must use field numbers larger than 0x200000 to be encoded with at least 4 - // bytes - optional TestExtension testExtension = 6492434; -} -``` +Implementations MUST use the protobuf messages defined in the `extensions.proto` +file. From ca0420d5e9ee9f52fb1c3289ee750544f7195830 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Tue, 12 Aug 2025 12:01:43 -0700 Subject: [PATCH 7/8] Add divma to interest group --- pubsub/gossipsub/gossipsub-v1.3.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pubsub/gossipsub/gossipsub-v1.3.md b/pubsub/gossipsub/gossipsub-v1.3.md index a041afa18..aa1c4bce3 100644 --- a/pubsub/gossipsub/gossipsub-v1.3.md +++ b/pubsub/gossipsub/gossipsub-v1.3.md @@ -6,7 +6,7 @@ Authors: [@marcopolo] -Interest Group: [@cortze], [@cskiraly], [@ppopth], [@jxs], [@raulk] +Interest Group: [@cortze], [@cskiraly], [@ppopth], [@jxs], [@raulk], [@divagant-martian] [@marcopolo]: https://github.com/marcopolo [@cortze]: https://github.com/cortze @@ -14,6 +14,7 @@ Interest Group: [@cortze], [@cskiraly], [@ppopth], [@jxs], [@raulk] [@ppopth]: https://github.com/ppopth [@jxs]: https://github.com/jxs [@raulk]: https://github.com/raulk +[@divagant-martian]: https://github.com/divagant-martian See the [lifecycle document][lifecycle-spec] for context about the maturity level and spec status. From e539bd60bc16332dbf81566f726db95943de8894 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Tue, 12 Aug 2025 12:02:04 -0700 Subject: [PATCH 8/8] Reference extensions file registry --- pubsub/gossipsub/gossipsub-v1.3.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubsub/gossipsub/gossipsub-v1.3.md b/pubsub/gossipsub/gossipsub-v1.3.md index aa1c4bce3..db62c7b3f 100644 --- a/pubsub/gossipsub/gossipsub-v1.3.md +++ b/pubsub/gossipsub/gossipsub-v1.3.md @@ -26,8 +26,8 @@ and spec status. This version specifies a way to for gossipsub peers to describe their characteristics to each other without requiring a new protocol ID per extension. -This spec MUST be updated upon introducing a new extension, either canonical or -experimental, to the network. +The extensions.proto file registry MUST be updated upon introducing a new +extension, either canonical or experimental, to the network. ## Motivation