Skip to content

3.0.0

Latest

Choose a tag to compare

@stephanfeb stephanfeb released this 08 Oct 00:33
· 4 commits to main since this release

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 and publish(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 for JsonEventTracer). Tools that read the old formats need updating.

  • GossipSubRouter negotiates /meshsub/1.3.0 with 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. PbEventTracer prefixes each event with its length as a varint, where it wrote 4 bytes. JsonEventTracer writes one JSON object per line with the fields named as in trace.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 peerID to the remote peer, and no event had a timestamp. Routers now send events through the new PubSub.traceEvent, which stamps them.

  • RECV_RPC events 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() and dispose() 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's Topic.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's WithPeerOutboundQueueSize (default 32).

Discovery

  • Topic discovery works, as go-libp2p-pubsub's WithDiscovery. PubSub(discovery: ...) takes a dart_libp2p Discovery service. 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). discoveryOptions are passed to the service. Before, the discovery helper was not connected to PubSub.
  • Topics are advertised under Go's namespace, floodsub:<topic>, so Dart and Go nodes find each other. The helper used gossipsub_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's WithReadiness.
  • Breaking for custom routers: Router has a new method, enoughPeers(topic, suggested), as Go's EnoughPeers. 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.validateMessage takes onReject, 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, as WithSeenMessagesStrategy.
  • Removed lib/src/util/backoff.dart, which nothing used and was not exported.

GossipSub v1.3

  • GossipSubRouter speaks /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 a TestExtension message.
  • The protobuf gains ControlMessage.extensions, ControlExtensions and RPC.testExtension, encoded as Go encodes them.
  • PubSubProtocol.onFirstRpc lets 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.