Skip to content

Support Gossipsub partial messages - #210

Open
flcl42 wants to merge 6 commits into
gossipsub-v13-extensionsfrom
gossipsub-v13-partial-messages
Open

Support Gossipsub partial messages#210
flcl42 wants to merge 6 commits into
gossipsub-v13-extensionsfrom
gossipsub-v13-partial-messages

Conversation

@flcl42

@flcl42 flcl42 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • provide an opt-in application API for the Gossipsub v1.3 Partial Messages extension
  • advertise capabilities only on v1.3 streams and honor each peer's subscription flags
  • forward application-defined partial payloads without retaining peer-initiated state
  • replace eligible IHAVE gossip with application callbacks for partial-message recipients

Validation

  • Pubsub protocol unit tests

@flcl42
flcl42 requested a review from rubo as a code owner August 24, 2026 08:59
@flcl42
flcl42 requested a lite review from Copilot August 24, 2026 08:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds opt-in support for the Gossipsub v1.3 Partial Messages extension to the Pubsub router, exposing a topic-level application API to send/receive partial payloads and integrating capability advertisement and per-peer gating into subscription handling and gossip flow.

Changes:

  • Introduces IPartialMessagesTopic + PartialMessage/PartialMessagesTopicOptions and wires partial-message delivery through Topic/PubsubRouter.
  • Adds router support for advertising/processing the Partial Messages extension (including per-topic subscription flags and a new OnPartialGossip callback path).
  • Adds unit tests covering opt-in requirements and basic advertisement/gating behavior.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/libp2p/Libp2p.Protocols.Pubsub/Topic.cs Implements IPartialMessagesTopic, wires partial-message events, adds publish/send APIs for partial payloads.
src/libp2p/Libp2p.Protocols.Pubsub/PubSubSettings.cs Adds EnablePartialMessages opt-in setting.
src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.Topics.cs Adds GetPartialMessagesTopic, subscription capability flags, and partial publish/send routing APIs.
src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.Rpc.cs Parses incoming partial-message extension payloads and tracks per-peer partial subscription flags.
src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.cs Adds extension advertisement and heartbeat logic to swap some IHAVE gossip for OnPartialGossip callbacks.
src/libp2p/Libp2p.Protocols.Pubsub/PartialMessage.cs Adds PartialMessage and PartialMessagesTopicOptions public API types.
src/libp2p/Libp2p.Protocols.Pubsub/IPartialMessagesTopic.cs Adds the public partial-messages topic interface.
src/libp2p/Libp2p.Protocols.Pubsub.Tests/PartialMessagesTests.cs Adds unit tests for opt-in, advertisement, and per-peer gating.
Suppressed comments (1)

src/libp2p/Libp2p.Protocols.Pubsub/Topic.cs:82

  • Topic.Unsubscribe() currently calls router.Unsubscribe() only when IsSubscribed is false, which prevents unsubscribing when the topic is actually subscribed and can cause subscription state to get stuck.
    public void Unsubscribe()
    {
        if (!IsSubscribed) router.Unsubscribe(topicName);
    }

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.Topics.cs
Comment thread src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.cs Outdated
Comment thread src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.Rpc.cs
Comment thread src/libp2p/Libp2p.Protocols.Pubsub/PartialMessage.cs Outdated
@flcl42
flcl42 force-pushed the gossipsub-v13-partial-messages branch from 273d3ac to c03196f Compare August 24, 2026 09:21
@flcl42
flcl42 requested a lite review from Copilot August 24, 2026 09:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Suppressed comments (3)

src/libp2p/Libp2p.Protocols.Pubsub/Topic.cs:82

  • Topic.Unsubscribe() currently calls router.Unsubscribe(topicName) only when the topic is not subscribed, which makes Unsubscribe a no-op for subscribed topics (and can trigger an unnecessary unsubscribe call when already unsubscribed). Flip the condition so subscribed topics are actually unsubscribed.
    public void Unsubscribe()
    {
        if (!IsSubscribed) router.Unsubscribe(topicName);
    }

src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.Topics.cs:64

  • CreateSubscription() sets RequestsPartial/SupportsSendingPartial whenever partial messages are enabled and the local Topic has flags, but the resulting SubOpts are sent to all peers (including non-v1.3 streams) via OutboundConnection() and AnnounceSubscription(). This contradicts the PR description constraint to advertise capabilities only on v1.3 streams. Consider constructing per-peer subscription updates so these fields are only populated when sending over Gossipsub v1.3 (SupportsExtensions), otherwise leave them unset/false.
    private Rpc.Types.SubOpts CreateSubscription(string topicId, bool subscribe)
    {
        Rpc.Types.SubOpts subscription = new() { Subscribe = subscribe, Topicid = topicId };
        if (subscribe && _settings.EnablePartialMessages && topicState.TryGetValue(topicId, out Topic? topic))
        {
            subscription.RequestsPartial = topic.RequestsPartialMessages;
            subscription.SupportsSendingPartial = topic.SupportsSendingPartialMessages;
        }

src/libp2p/Libp2p.Protocols.Pubsub/PartialMessage.cs:42

  • PartialMessagesTopicOptions uses the name SupportSendingPartialMessages, while other related APIs use SupportsSendingPartialMessages (plural) (e.g., IPartialMessagesTopic.SupportsSendingPartialMessages). This inconsistency makes the public API harder to discover and can lead to confusion. Consider renaming the option to SupportsSendingPartialMessages while the API is still new.
    /// <summary>
    /// Signals that this topic can send partial data and receive parts metadata.
    /// </summary>
    public bool SupportSendingPartialMessages { get; init; }

Comment thread src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.Rpc.cs Outdated
Comment thread src/libp2p/Libp2p.Protocols.Pubsub.Tests/PartialMessagesTests.cs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

src/libp2p/Libp2p.Protocols.Pubsub/Topic.cs:82

  • Topic.Unsubscribe() calls router.Unsubscribe() when IsSubscribed is false. This is inverted logic and can trigger KeyNotFoundException in PubsubRouter.Unsubscribe(topicId) (it indexes fPeers[topicId]) when called on an already-unsubscribed topic.
    public void Unsubscribe()
    {
        if (!IsSubscribed) router.Unsubscribe(topicName);
    }

src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.Rpc.cs:254

  • Partial-messages subscription flags are not being honored as sent by the peer: SupportsSendingPartialMessages is stored as (RequestsPartial || SupportsSendingPartial). This causes the router to treat a peer that only set RequestsPartial as also supporting the metadata flow, and may send PartsMetadata contrary to the peer's advertised capability.
                if (_settings.EnablePartialMessages && state.SupportsPartialMessagesExtension)
                {
                    bool requestsPartialMessages = sub.RequestsPartial;
                    state.UpdatePartialMessagesSubscription(
                        sub.Topicid,
                        requestsPartialMessages,
                        sub.SupportsSendingPartial);
                }

Comment thread src/libp2p/Libp2p.Protocols.Pubsub/PubsubRouter.cs Outdated
@flcl42
flcl42 force-pushed the gossipsub-v13-partial-messages branch from 6c14089 to f1fa49d Compare August 24, 2026 10:33
@flcl42
flcl42 requested a lite review from Copilot August 24, 2026 10:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

src/libp2p/Libp2p.Protocols.Pubsub/Topic.cs:37

  • OnRouterPartialMessage forwards partial payloads even when the topic is not subscribed and even when the topic was never configured for partial messages. This makes partial-message delivery inconsistent with OnRouterMessage and undermines the intended opt-in behavior (topics created via GetTopic can still receive partial messages if the event is hooked via an interface cast). Gate partial-message delivery on IsSubscribed and on the topic having partial-message capabilities enabled.
    private void OnRouterPartialMessage(string topicName, PeerId peerId, PartialMessage message)
    {
        if (this.topicName != topicName)
        {
            return;
        }

Comment thread src/libp2p/Libp2p.Protocols.Pubsub/Topic.cs Outdated
@flcl42
flcl42 force-pushed the gossipsub-v13-partial-messages branch from f1fa49d to c9a37f8 Compare August 24, 2026 10:44
@flcl42
flcl42 force-pushed the gossipsub-v13-partial-messages branch from 36a5fe2 to 63c375a Compare August 24, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants