Repository navigation
This release closes the remaining gaps with go-libp2p-pubsub v0.15.0 found by the 2.0.0 review: GossipSub v1.3, topic discovery, Go's trace formats, the peer gater and the seen-message cache. It also adds two options applications asked for: setting a topic's score parameters at runtime, and the outbound queue size.
Upgrading from 2.x
-
Custom routers must implement
Router.enoughPeers(topic, suggested), which discovery andpublish(ready:)use. The built-in routers implement it. This is the only breaking API change. -
Trace files change format to Go's (varint framing for
PbEventTracer, Go's JSON forJsonEventTracer). Tools that read the old formats need updating. -
GossipSubRouternegotiates/meshsub/1.3.0with peers that speak it (including Go v0.15.0 nodes). Older peers still negotiate 1.2.0 or lower. -
Messages for topics the node does not subscribe to are now dropped, as in Go. A node that relied on validating or forwarding them must subscribe to the topic.
-
The tracers write go-libp2p-pubsub's formats, so Go's trace tools can read their files.
PbEventTracerprefixes each event with its length as a varint, where it wrote 4 bytes.JsonEventTracerwrites one JSON object per line with the fields named as intrace.proto, bytes in base64, and the type and timestamp as numbers, where it wrote field numbers as keys. -
Every event carries the local peer ID and a timestamp (nanoseconds since the Unix epoch), as in Go. The router used to set
peerIDto the remote peer, and no event had a timestamp. Routers now send events through the newPubSub.traceEvent, which stamps them. -
RECV_RPCevents carry the summary of the RPC (meta), and the RPC summaries list the subscriptions, as in Go. -
Tracing after
dispose()no longer throws: the event is dropped.stop()anddispose()can be called again.
Added for applications
GossipSubRouter.setTopicScoreParams(topic, params)sets or changes a topic's score parameters after the router is created, as go-libp2p-pubsub'sTopic.SetScoreParams: a topic created later can use the built-in penalties (such as P4 for invalid messages). Lowering the delivery caps caps the peers' counters, as in Go.PeerScore.topicScoreParams(topic)reads them. The scorer is now created with the router rather than when it is attached.PubSub(peerOutboundQueueSize: n)sets the number of RPCs queued per peer before more are dropped, as go-libp2p-pubsub'sWithPeerOutboundQueueSize(default 32).
Discovery
- Topic discovery works, as go-libp2p-pubsub's
WithDiscovery.PubSub(discovery: ...)takes a dart_libp2pDiscoveryservice. PubSub advertises each subscribed topic, every second looks up the peers of the subscribed topics that the router has not enough peers on, and dials them through a backoff connector (discoveryConnector, default Go's).discoveryOptionsare passed to the service. Before, the discovery helper was not connected toPubSub. - Topics are advertised under Go's namespace,
floodsub:<topic>, so Dart and Go nodes find each other. The helper usedgossipsub_topic:<topic>. publish(topic, data, ready: minTopicSize(n), readyTimeout: ...)waits until the router has enough peers on the topic before publishing, looking them up while it waits, as Go'sWithReadiness.- Breaking for custom routers:
Routerhas a new method,enoughPeers(topic, suggested), as Go'sEnoughPeers. The built-in routers implement it with Go's rules. - Removed
PubSubDiscovery's old API (addDiscoveryListener,discoverTopic,DEFAULT_GENERAL_PUBSUB_SERVICE_TAG,TOPIC_DISCOVERY_PREFIX). The class was not exported.
Messages
- Messages for topics the node does not subscribe to are ignored, before validation, as in go-libp2p-pubsub. They used to be validated, scored, cached and forwarded, which cost validation work on topics the node had no interest in.
Peer gater
- Added go-libp2p-pubsub's peer gater (
WithPeerGater):GossipSubRouter(peerGaterParams: PeerGaterParams()). When validation is throttled, it handles only the control messages of peers whose messages are mostly not delivered, at random. Off by default, as in Go. PubSub.validateMessagetakesonReject, called with the reason a message was dropped.- Removed
lib/src/core/peer_gater.dart, a connection gater that nothing used and was not exported.
Seen messages
- The seen-message cache has no size limit, as in go-libp2p-pubsub. It held at most 2^17 IDs and evicted the oldest beyond that, so under a high message rate a message could be validated and forwarded again within
seenMessagesTTL. - The cache uses a monotonic clock, so a change to the system clock no longer expires IDs early or keeps them too long.
seenMessagesStrategy(GossipSubParams,FloodSubRouter,RandomSubRouter) chooses Go's first-seen (default) or last-seen expiry, asWithSeenMessagesStrategy.- Removed
lib/src/util/backoff.dart, which nothing used and was not exported.
GossipSub v1.3
GossipSubRouterspeaks/meshsub/1.3.0(gossipSubIDv13), first, as go-libp2p-pubsub v0.15.0, and negotiates it with Go nodes. With a v1.3 peer, each side announces its extensions in its first RPC; a peer that announces them again gets a behaviour penalty of 10, as in Go. v1.3 peers get IDONTWANT and PX as v1.2 peers.- The experimental test extension, as Go's
WithTestExtension:GossipSubRouter(testExtension: TestExtensionConfig(...)). Unlike Go, the callback runs only for RPCs that carry aTestExtensionmessage. - The protobuf gains
ControlMessage.extensions,ControlExtensionsandRPC.testExtension, encoded as Go encodes them. PubSubProtocol.onFirstRpclets a router rewrite the first RPC on each new stream.
Tests
- Peer Exchange is tested on a real network: peers pruned by a bootstrapper with PX connect to each other, build a mesh and exchange messages. The test stores the signed peer records in the bootstrapper's address book itself, as dart_libp2p 4.0.1's identify does not.
Known limitations
- The PRUNEs we send rarely carry signed peer records: dart_libp2p 4.0.1's identify checks the records of remote peers but does not store them.