-
Notifications
You must be signed in to change notification settings - Fork 296
Gossipsub: Partial Message Extension #685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
MarcoPolo
wants to merge
9
commits into
master
Choose a base branch
from
marco/partial-messages
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+204
−2
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
865d3aa
Partial Messages Extension
MarcoPolo 50f9c11
Remove PartialIDONTWANT
MarcoPolo 3f134d2
gossipsub: add explicit request to use partial messages for a given t…
MarcoPolo 8e42e17
Simplify the fields and remove message nesting.
MarcoPolo a4cb3c2
relax the requirement on the SubOpts partial field.
MarcoPolo 9177ea3
Update code Gossipsub partial extension codepoint
MarcoPolo d847d6c
mark off todos
MarcoPolo 442f51a
minor formatting
MarcoPolo ae6b268
Add supportsPartial field to subopts
MarcoPolo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,180 @@ | ||||||
| # Partial Messages Extension | ||||||
|
|
||||||
| | Lifecycle Stage | Maturity | Status | Latest Revision | | ||||||
| | --------------- | ------------- | ------ | --------------- | | ||||||
| | 1A | Working Draft | Active | r0, 2025-06-23 | | ||||||
|
|
||||||
| Authors: [@marcopolo, @cskiraly] | ||||||
|
|
||||||
| Interest Group: TODO | ||||||
|
|
||||||
| [@marcopolo]: https://github.com/marcopolo | ||||||
| [@cskiraly]: https://github.com/cskiraly | ||||||
|
|
||||||
| 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 | ||||||
|
|
||||||
| Partial Messages Extensions allow users to transmit only a small part of a | ||||||
| message rather than a full message. This is especially useful in cases where | ||||||
| there is a large messages and a peer is missing only a small part of the | ||||||
| message. | ||||||
|
|
||||||
| ## Terms and Definitions | ||||||
|
|
||||||
| **Full Message**: A Gossipsub Message. | ||||||
|
|
||||||
| **Message Part**: The smallest verifiable part of a message. | ||||||
|
|
||||||
| **Partial Message**: A group of one or more message parts. | ||||||
|
|
||||||
| **Group ID**: An identifier to some Full Message. This must not depend on | ||||||
| knowing the full message, so it can not simply be a hash of the full message. | ||||||
|
|
||||||
| ## Motivation | ||||||
|
|
||||||
| The main motivation for this extension is optimizing Ethereum's Data | ||||||
| Availability (DA) protocol. In Ethereum's upcoming fork, Fusaka, custodied data | ||||||
| is laid out in a matrix per block, where the rows represent user data (called | ||||||
| blobs), and the columns represent a slice across all blobs included in the block | ||||||
| (each blob slice in the column is called a cell). These columns are propagated | ||||||
| with Gossipsub. At the time of writing it is common for a node to already have | ||||||
| all the blobs from its mempool, but in cases where it doesn't (~38%[1]) have | ||||||
| _all_ of the blobs it almost always has _most_ of the blobs (today, it almost | ||||||
| always has all but one [1]). More details of how this integrates with Ethereum | ||||||
| can be found at the [consensus-specs | ||||||
| repo](https://github.com/ethereum/consensus-specs/pull/4558) | ||||||
|
|
||||||
| This extension would allow nodes to only request the column message part | ||||||
| belonging to the missing blob. Reducing the network resource usage | ||||||
| significantly. As an example, if there are 32 blob cells in a column and the | ||||||
| node has all but one cell, this would result in a transfer of 2KiB rather than | ||||||
| 64KiB per column. and since nodes custody at least 8 columns, the total savings | ||||||
| per slot is around 500KiB. | ||||||
|
|
||||||
| Later, partial messages could enable further optimizations: | ||||||
|
|
||||||
| - If cells can be validated individually, as in the case of DAS, partial | ||||||
| messages could also be forwarded, allowing us to reduce the store-and-forward | ||||||
| delay [2]. | ||||||
| - Finally, in the FullDAS construct, where both row and column topics are | ||||||
| defined, partial messages allow cross-forwarding cells between these topics | ||||||
| [2]. | ||||||
|
|
||||||
| ## Advantage of Partial Messages over smaller Gossipsub Messages | ||||||
|
|
||||||
| Partial Messages within a group imply some structure and correlation. Thus, | ||||||
| multiple partial messages can be referenced succinctly. For example, parts can | ||||||
| be referenced by bitmaps, ranges, or a bloom filter. | ||||||
|
|
||||||
| The structure of partial messages in a group, as well as how partial messages | ||||||
| are referenced is application defined. | ||||||
|
|
||||||
| If, in some application, a group only ever contained a single partial message, | ||||||
| then partial messages would be the same as smaller messages. | ||||||
|
|
||||||
| ## Protocol Messages | ||||||
|
|
||||||
| The following section specifies the semantics of each new protocol message. | ||||||
|
|
||||||
| ### partialMessage | ||||||
|
|
||||||
| The `partialMessage` field encodes one or more parts of the full message. The | ||||||
| encoding is application defined. | ||||||
|
|
||||||
| ### partsMetadata | ||||||
|
|
||||||
| The `partsMetadata` field encodes the parts a peer has and wants. The encoding | ||||||
| is application defined. An unset value carries no information besides that the | ||||||
| peer did not send a value. | ||||||
|
|
||||||
| Upon receiving a `partsMetadata` a node SHOULD respond with only parts the peer | ||||||
| wants. | ||||||
|
|
||||||
| A later `partsMetadata` replaces a prior one. | ||||||
|
|
||||||
| `partsMetadata` can be used during heartbeat gossip to inform non-mesh topic | ||||||
| peers about parts this node has. | ||||||
|
|
||||||
| Implementations are free to select when to send an update to their peers based | ||||||
| on signaling bandwidth tradeoff considerations. | ||||||
|
|
||||||
| ### Changes to `SubOpts` and interaction with the existing Gossipsub mesh. | ||||||
|
|
||||||
| The `SubOpts` message is how a peer subscribes to a topic. | ||||||
|
|
||||||
| Partial Messages uses the same mesh as normal Gossipsub messages. It is a | ||||||
| replacement to "full" messages. A node requests a peer to send partial messages | ||||||
| for a specific topic by setting the `requestsPartial` field in the `SubOpts` | ||||||
| message to true. A node signals support for sending partial messages on a given | ||||||
| topic by setting the `supportsPartial` field in `SubOpts` to true. A node can | ||||||
| support sending partial messages without wanting to receive them. | ||||||
|
|
||||||
| If a node requests partial messages, it MUST support partial messages. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| A node uses a peer's `supportsPartial` setting to know if it can send a partial | ||||||
| message request to a peer. It uses its `requestsPartial` setting to know whether | ||||||
| to send send the peer a full message or a partial message. | ||||||
|
|
||||||
| If a peer supports partial messages on a topic but did not request them, a node | ||||||
| MUST omit the `partialMessage` field of the `PartialMessagesExtension` message. | ||||||
|
|
||||||
| If a node does not support the partial message extension, it MUST ignore the | ||||||
| `requestPartial` and `supportsPartial` fields. This is the default behavior of | ||||||
| protobuf parsers. | ||||||
|
|
||||||
| The `requestPartial` and `supportsPartial` fields value MUST be ignored when a | ||||||
| peer sends an unsubscribe message `SubOpts.subscribe=false`. | ||||||
|
|
||||||
| #### Behavior table | ||||||
|
|
||||||
| The following table describes the expected behavior of receiver of a `SubOpts` | ||||||
| message for a given topic. | ||||||
|
|
||||||
| | SubOpts.requestsPartial | behavior of receiver that supports partial messages for the topic | | ||||||
| | ------------------------ | ------------------------------------------------------------------------------------------------- | | ||||||
| | true | The receiver SHOULD send partial messages (data and metadata) to this peer. | | ||||||
| | false | receiver MUST NOT send partial message data to this peer. The receiver SHOULD send full messages. | | ||||||
|
|
||||||
| | SubOpts.requestsPartial | behavior of receiver that does not support partial messages for the topic | | ||||||
| | ------------------------ | ------------------------------------------------------------------------- | | ||||||
| | \* | The receiver SHOULD send full messages. | | ||||||
|
|
||||||
| | SubOpts.supportsPartial | behavior of receiver that requested partial messages for the topic | | ||||||
| | ------------------------ | ---------------------------------------------------------------------------------------------------------------- | | ||||||
| | true | The receiver expects the peer to respond to partial message requests, and receive `partsMetadata` from the peer. | | ||||||
| | false | The receiver expects full messages. | | ||||||
|
|
||||||
| | SubOpts.supportsPartial | behavior of receiver that did not request partial messages for the topic | | ||||||
| | ------------------------ | ------------------------------------------------------------------------ | | ||||||
| | \* | The receiver expects full messages | | ||||||
|
|
||||||
| ## Application Interface | ||||||
|
|
||||||
| This specific interface is not intended to be normative to implementations, it | ||||||
| is only an example of one possible API. | ||||||
|
|
||||||
| Message contents are application defined, thus splitting a message must be | ||||||
| application defined. Applications should provide a Partial Message type that | ||||||
| supports the following operations: | ||||||
|
|
||||||
| 1. `.GroupID() -> GroupID: bytes` | ||||||
| 2. `.PartialMessageBytes(partsMetadata: bytes) -> Result<(EncodedPartialMessage: bytes, newPartsMetadata: bytes), Error>` | ||||||
| 1. The method should return an encoded partial message with just the parts the | ||||||
| peer requested. | ||||||
| 2. The returned `newPartsMetadata` can be used to track parts that could not | ||||||
| be fulfilled. This allows the GossipSub library to avoid sending duplicate | ||||||
| parts to the same peer. | ||||||
| 3. `.PartsMetadata() -> bytes` | ||||||
|
|
||||||
| Gossipsub in turn provides a `.PublishPartial(PartialMessage)` method. | ||||||
|
|
||||||
| ## Protobuf | ||||||
|
|
||||||
| Refer to the protobuf registry at `./extensions/extensions.proto` | ||||||
|
|
||||||
| [1]: https://ethresear.ch/t/is-data-available-in-the-el-mempool/22329 | ||||||
| [2]: https://ethresear.ch/t/fulldas-towards-massive-scalability-with-32mb-blocks-and-beyond/19529#possible-extensions-13 | ||||||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.