dart_libp2p_pubsub

A comprehensive libp2p pubsub implementation for Dart, featuring GossipSub v1.1, FloodSub, and RandomSub protocols with message validation, peer scoring, and tracing support.

Pub Version Dart CI License

Features

πŸš€ Multiple PubSub Protocols

  • GossipSub v1.1 - Production-ready, efficient pubsub protocol with mesh-based routing
  • FloodSub - Simple flooding protocol for development and testing
  • RandomSub - Randomized message propagation for research

πŸ”’ Security & Validation

  • Message validation with custom validators
  • Peer scoring system for network health
  • Cryptographic message signing and verification

πŸ“Š Monitoring & Debugging

  • Comprehensive event tracing
  • JSON and Protocol Buffer trace formats
  • Built-in logging and metrics

⚑ Performance

  • Efficient message caching with MCache
  • Optimized RPC queue management
  • Configurable mesh parameters for different use cases

Quick Start

Installation

Add to your pubspec.yaml:

dependencies:
  dart_libp2p_pubsub: ^1.4.2
  dart_libp2p: ^0.5.2

Basic Usage

import 'package:dart_libp2p_pubsub/dart_libp2p_pubsub.dart';
import 'package:dart_libp2p/core/host/host.dart';

// Create a libp2p host
final host = await createLibp2pHost();

// Set up GossipSub router
final router = GossipSubRouter();
// Published messages are signed with the host's own private key; no key
// needs to be passed.
final pubsub = PubSub(host, router);

// Start the pubsub system
await pubsub.start();

// Subscribe to a topic
const topic = '/my-app/chat';
final subscription = pubsub.subscribe(topic);

// Listen for messages
subscription.stream.listen((message) {
  print('Received: ${String.fromCharCodes(message.data)}');
});

// Publish a message
final messageData = Uint8List.fromList('Hello, World!'.codeUnits);
await pubsub.publish(topic, messageData);

Examples

Chat Application

Run a simple peer-to-peer chat:

# Terminal 1
dart example/chat.dart

# Terminal 2 (connect to the first node)
dart example/chat.dart /ip4/127.0.0.1/tcp/4001/p2p/QmPeerId...

Message Validation

A node forwards and delivers a message only when validation accepts it. Register a validator per topic (the model of go-libp2p-pubsub's RegisterTopicValidator). It can be async:

pubsub.registerTopicValidator('/chat/1.0.0', (PeerId receivedFrom, PubSubMessage msg) async {
  if (msg.data.length > 1000) return ValidationResult.reject; // invalid: drop and penalise the sender
  if (!await isRelevant(msg)) return ValidationResult.ignore; // drop without a penalty
  return ValidationResult.accept; // forward and deliver
}, timeout: Duration(seconds: 2));

Duplicates are dropped before validation, so a validator runs once per message. Validation has a per-run timeout (default 5 s, gives ignore) and a global limit of concurrent validations (default 8192). The older registerMessageValidator((topic, message) => bool) still works for all topics: false rejects. See Validating Messages.

Peer Scoring

Peer scoring is on by default. A peer that delivers a message that validation rejects gets a penalty of invalidMessageDeliveriesWeight * counter^2 on the topic (default weight -1.0; the counter decays to zero in about 1 hour). Tune it for your application:

final scoreParams = PeerScoreParams(
  defaultTopicParams: TopicScoreParams(
    invalidMessageDeliveriesWeight: -10.0,
    invalidMessageDeliveriesDecay: 0.9987, // per 1 s decayInterval
  ),
);

final pubsub = PubSub(host, router, scoreParams: scoreParams);

See Configuration.

Documentation

πŸ“š Comprehensive Guides

Architecture

The library is organized into several key components:

lib/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ core/           # Core pubsub functionality
β”‚   β”‚   β”œβ”€β”€ pubsub.dart      # Main PubSub class
β”‚   β”‚   β”œβ”€β”€ message.dart     # Message handling
β”‚   β”‚   β”œβ”€β”€ subscription.dart # Topic subscriptions
β”‚   β”‚   └── validation.dart  # Message validation
β”‚   β”œβ”€β”€ gossipsub/      # GossipSub v1.1 implementation
β”‚   β”‚   β”œβ”€β”€ gossipsub.dart   # Main router
β”‚   β”‚   β”œβ”€β”€ mcache.dart      # Message cache
β”‚   β”‚   └── score.dart       # Peer scoring
β”‚   β”œβ”€β”€ floodsub/       # FloodSub protocol
β”‚   β”œβ”€β”€ randomsub/      # RandomSub protocol
β”‚   └── tracing/        # Event tracing

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/stephanfeb/dart_libp2p_pubsub.git
cd dart_libp2p_pubsub

# Install dependencies
dart pub get

# Run tests
dart test

# Generate protobuf files
dart run build_runner build

A fresh clone builds against the published packages. To develop against local checkouts of dart_libp2p, dart_libp2p_kad_dht or dart-udx, create a pubspec_overrides.yaml (git-ignored) next to pubspec.yaml:

dependency_overrides:
  dart_libp2p:
    path: ../dart-libp2p
  dart_libp2p_kad_dht:
    path: ../dart-libp2p-kad-dht
  dart_udx:
    path: ../dart-udx

The Go interop test in test/interop builds the go-libp2p peer from a dart_libp2p checkout (GO_PEER_DIR, or ../dart-libp2p/interop/go-peer by default) and needs Go.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Libraries

dart_libp2p_pubsub