Nethermind.Libp2p.Protocols.Pubsub 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Nethermind.Libp2p.Protocols.Pubsub --version 1.0.0
                    
NuGet\Install-Package Nethermind.Libp2p.Protocols.Pubsub -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nethermind.Libp2p.Protocols.Pubsub" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nethermind.Libp2p.Protocols.Pubsub" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Nethermind.Libp2p.Protocols.Pubsub" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Nethermind.Libp2p.Protocols.Pubsub --version 1.0.0
                    
#r "nuget: Nethermind.Libp2p.Protocols.Pubsub, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Nethermind.Libp2p.Protocols.Pubsub@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Nethermind.Libp2p.Protocols.Pubsub&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Nethermind.Libp2p.Protocols.Pubsub&version=1.0.0
                    
Install as a Cake Tool

Pubsub protocol set

This package implements the libp2p pubsub protocol family. It includes floodsub and gossipsub protocol handlers and provides a shared PubsubRouter for topic operations.

See the libp2p pubsub spec for protocol details.

Setup

Enable pubsub on the standard stack with WithPubsub():

using Microsoft.Extensions.DependencyInjection;
using System.Text;
using Nethermind.Libp2p;
using Nethermind.Libp2p.Core;
using Nethermind.Libp2p.Protocols.Pubsub;

ServiceProvider provider = new ServiceCollection()
    .AddLibp2p(builder => builder.WithPubsub())
    .BuildServiceProvider();

ILocalPeer peer = provider.GetRequiredService<IPeerFactory>().Create();
await peer.StartListenAsync();

PubsubRouter router = provider.GetRequiredService<PubsubRouter>();
await router.StartAsync(peer);

StartAsync connects the router to the local peer and starts heartbeat and reconnect loops. Call it once for the peer that owns the router.

Subscribing to a topic

GetTopic returns an ITopic and subscribes by default:

ITopic chat = router.GetTopic("chat");

chat.OnMessage += (peerId, bytes) =>
{
    string text = Encoding.UTF8.GetString(bytes);
    Console.WriteLine($"{peerId}: {text}");
};

The peerId argument is the connected peer that delivered the RPC message to the local router. It is not necessarily the original pubsub message author when messages are forwarded through the mesh. If your application needs author identity, include it in the published payload and validate it at the application layer.

To create a topic handle without subscribing immediately, pass subscribe: false and call Subscribe() later:

ITopic alerts = router.GetTopic("alerts", subscribe: false);
alerts.Subscribe();

Publishing

Publish raw bytes or protobuf messages:

chat.Publish(Encoding.UTF8.GetBytes("hello from dotnet-libp2p"));

// Any Google.Protobuf.IMessage can also be published.
// chat.Publish(myProtobufMessage);

Publishing does not create peers by itself. The router sends messages to connected pubsub peers and uses PeerStore.OnNewPeer to dial newly discovered peers that advertise pubsub support.

Validating received messages

VerifyMessage runs after libp2p signature verification and before the message is delivered, forwarded, or placed in the message cache. Its callback takes the connected peer that sent the RPC and the message. Applications using the older message-only callback must add the peer argument. Return Accepted to deliver and forward, Rejected to record an invalid delivery, Ignored to suppress without a penalty, or Throttled to drop without caching the message ID. Do not mutate the message in the callback.

For asynchronous checks, assign one OnDeferredMessage callback before configuring VerifyMessage to return Deferred, especially when the router is already running. The callback receives the same message instance outside the router lock. Complete it with CompleteValidation(message, verdict) before the timeout; a false return means the message is no longer pending, expired, or changed after authentication. A deferred message is not delivered or forwarded while pending.

router.OnDeferredMessage = async (sourcePeer, message) =>
{
    bool valid = await ValidateAsync(sourcePeer, message);
    router.CompleteValidation(message, valid ? MessageValidity.Accepted : MessageValidity.Rejected);
};
router.VerifyMessage = (sourcePeer, message) => NeedsAsyncCheck(message)
    ? MessageValidity.Deferred
    : MessageValidity.Accepted;

Configure MaxPendingValidationMessages, MaxPendingValidationBytes, and PendingValidationTimeout in PubsubSettings to bound deferred work. PendingValidationCount reports the current unexpired count. If the store is full, the callback is absent, or the timeout is invalid, the router drops the deferred message without scoring its source because these are local capacity or configuration conditions. Expired entries are removed when the router next processes a message or queries the count; application validation work is not cancelled on expiry or disposal. An invalid signature is rejected before VerifyMessage and does not reserve its message ID, so replaying the same invalid message repeats signature verification.

Connecting pubsub peers

Use one of the discovery mechanisms to populate PeerStore, or add known peer addresses manually:

using Multiformats.Address;
using Nethermind.Libp2p.Core.Discovery;

PeerStore peerStore = provider.GetRequiredService<PeerStore>();
peerStore.Discover([
    Multiaddress.Decode("/ip4/127.0.0.1/tcp/4001/p2p/12D3KooW...")
]);

When a new peer is discovered, PubsubRouter dials it and negotiates the best supported pubsub protocol from the remote peer's identified protocols. Gossipsub v1.3 is preferred, then gossipsub v1.2, gossipsub v1.1, gossipsub v1.0, and floodsub.

Unsubscribing

chat.Unsubscribe();
router.UnsubscribeAll();

Unsubscribing announces the topic leave to connected pubsub peers and prunes the local mesh for that topic.

Stopping the router

The router stops when the token passed to StartAsync is cancelled or when the router is disposed. Disposal cancels its heartbeat and reconnect loops and the dials it started, closes the pubsub streams it serves and stops reacting to new PeerStore peers. It does not dispose the PeerStore or the local peer.

await router.DisposeAsync(); // waits for the owned background work to finish

A router resolved from the service provider is disposed together with the provider, so dispose it yourself only when you created it with new. Dispose() stops the same work without waiting for it. A disposed router cannot be started again.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Nethermind.Libp2p.Protocols.Pubsub:

Package Downloads
Nethermind.Libp2p

A libp2p implementation for .NET

Nethermind.Libp2p.Protocols.PubsubPeerDiscovery

A libp2p implementation for .NET

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 54 10/2/2026
1.0.0 207 10/1/2026
1.0.0-preview.51 4,690 11/11/2025
1.0.0-preview.50 162 11/7/2025
1.0.0-preview.49 211 11/6/2025
1.0.0-preview.45 1,719,523 5/13/2025
1.0.0-preview.44 1,148 5/9/2025
1.0.0-preview.43 207 5/9/2025
1.0.0-preview.37 190 2/18/2025
1.0.0-preview.36 46,047 2/10/2025
1.0.0-preview.35 191 2/10/2025
1.0.0-preview.34 50,404 10/24/2024
1.0.0-preview.33 11,589 9/11/2024
1.0.0-preview.32 217 9/9/2024
1.0.0-preview.30 158 9/6/2024
1.0.0-preview.29 210 10/3/2023
1.0.0-preview.6 2,784 6/25/2024
1.0.0-preview.5 314 6/21/2024
1.0.0-preview.4 158 2/29/2024
1.0.0-preview.3 207 10/18/2023
Loading failed