dart_libp2p_pubsub
A comprehensive libp2p pubsub implementation for Dart, featuring GossipSub v1.2 (with v1.1, v1.0 and FloodSub peers), FloodSub, and RandomSub protocols with message validation, peer scoring, and tracing support.
Features
π Multiple PubSub Protocols
- GossipSub v1.2 - Mesh-based routing with peer scoring, IHAVE/IWANT gossip and IDONTWANT, interoperable with go-libp2p-pubsub
- 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: ^3.0.0
dart_libp2p: ">=1.0.0 <5.0.0"
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 follows go-libp2p-pubsub and is off by default. Give the router score parameters and thresholds to turn it on:
final router = GossipSubRouter(
scoreParams: PeerScoreParams(topics: {
'chat': TopicScoreParams(
topicWeight: 1,
invalidMessageDeliveriesWeight: -10,
invalidMessageDeliveriesDecay: scoreParameterDecay(const Duration(hours: 1)),
),
}),
scoreThresholds: const PeerScoreThresholds(
gossipThreshold: -10, publishThreshold: -50, graylistThreshold: -80),
);
See Configuration.
Documentation
π Comprehensive Guides
- Network Setup - Getting your libp2p network running
- GossipSub Usage - How to use GossipSub effectively
- GossipSub Deep Dive - Advanced GossipSub concepts
- Testing - Testing strategies and examples
- Configuration - Tuning parameters for your use case
- Best Practices - Production deployment guidelines
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: open an issue or a pull request.
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.
Related Projects
- dart_libp2p - Core libp2p implementation for Dart
- dart_libp2p_kad_dht - Kademlia DHT implementation
Support
- π Documentation
- π Issue Tracker
- π¬ Discussions