js-libp2p-gossipsub
js-libp2p-gossipsub copied to clipboard
GossipSub with libp2p v2
Since the autodialer has been removed in libp2p v2, I have been unable to get peers to communicate over gossipsub (they discover each other, but do not dial or connect). What would the recommended best practice be to get peers to dial each other after discovery?
@julienmalard It really depends on your application. You should make your own auto-dialer / peer manager based on your needs. This may be as simple as listening to the appropriate event when peers are discovered, and dialing that peer, or it may include additional logic tailored to your app.
Thanks @wemeetagain . I can get connections working again by dialing on each "peer:discovery" event, but I suppose that this is probably inefficient. Is there a way of interacting with the GossipSub mesh and PX algorithms which, as I understand, do manage peer connections according to subscription status and peer behaviour (https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md)? Many thanks!
Also wondering this - any examples of a auto-dialer / peer manager?
The GossipSub PX algorithm means that when they are pruned, a node will dial other peers subscribed to the topic discovered through PX as part of pruning if those peers have a high enough score. This is all handled by this module.
If you dial arbitrary peers manually (including those discovered via peer:discovery events) there's a chance they will or would have low scores and may be attacking the network.
In general you want to subscribe to a set of topics you are interested in, bootstrap to a known good set of peers who are also subscribed to those topics (this would be application-specific), then let the GossipSub module do it's thing.
Thanks @achingbrain !
I just tried with a relay server and gossipsub peer discovery. Peers are discovered, but never connect to each other through the relay, even though they are all subscribed to the same gossipsub channel (in this case, the peer discovery channel). Manually connecting on discovery does, however, work. Do you know why this would be so? Is this expected behaviour, or a configuration bug? Many thanks!
Thank @achingbrain as always! Owe you a beer :)
So PX only happens on prune, so if the number of nodes in the network is less than Dhi(?) then prune/PX won't occur. Also if the peer supplying the PX has a score < acceptPXThreshold, it won't be accepted by the host and thus it won't autodial peers.
Thanks @dozyio . I see that the default value for acceptPXThreshold is 10. What is the default score for a new peer (such as a relay added to directPeers), and how could it be increased above 10?
At the same time, I'm still a bit confused regarding the role of the relay. If multiple peers connect to it and subscribe to a given topic (to which the relay is also subscribed), should gossipsub not automatically connect them to each other? Or is being connected to only one peer on a given topic considered "sufficient" by the algorithm?
I think I can see the issue with the initial peers not connecting with each other. I think its due to the libp2p peer store peerStore not propagating peers to the gossipsub peer store peers. A side effect of autodialing is that when connections are made, they are also added to registrar. Gossipsub uses the shared registrar to populate peers via the onPeerConnected event, which now isn't occurring.
~~Would exposing addPeer / removePeer as public methods be a suitable solution? That way pubsubPeerDiscovery or any other method could provide potential peers to gossipsub and let gossipsub handle the connections/scoring. Maybe addPeerWithScore?~~ Noticed addPeer requires a connection
That said, once the network is of large enough size (>Dhi), PX kicks in.
One thing I did notice is that although prune is called by bootstrapper/relay, it doesn't drop the connection - I'm guessing this is because the connection is initiated from libp2p and not by gossipsub - need a bit more investigation here / might be a config issue my side.
Also not sure on how to set the initial score of the bootstrapper/relay nodes so that PX is accepted without waiting for its score to improve.
@julienmalard Recommended settings for relay/bootstrappers here - https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#recommendations-for-network-operators. Seems to work well in my tests with nodes dialing each other
Also to set the bootstrapper score you can do something like
function applicationScore(p: string) {
if (p === bootstrapperPeerId) {
return 150
}
return 0
}
createLibp2p({
...
services: {
...
pubsub: gossipsub({
...
scoreParams: createPeerScoreParams({
appSpecificScore: applicationScore,
topics: {
["yourtopic"]: createTopicScoreParams({
topicWeight: 1
})
}
}),
scoreThresholds: {
...
acceptPXThreshold: 100,
}
}),
}
...
})
Thank you @dozyio ; I will try this. How should this be done in an application where not all topics are known ahead of time (e.g., with OrbitDB, which assigns a new random topic to every user-created database)?
@julienmalard It seems the Go implementation has the ability to relay https://github.com/libp2p/go-libp2p-pubsub/blob/master/topic.go#L186
@julienmalard with OrbitDB e.g. a relay could discover the unknown topics it should or want to subscribe either through identify or via received "subscription-changed" events which a relay always receives if a connected peer opens (and subscribes) to an orbitdb.
Subscribing to all /orbitdb topics might not be wanted. The relay could check the peerId of the pubsub message, if it is a peer which is in a white list. A message signature check is probably already handled by GossipSub.
@NiKrause Thanks; that's similar to what we've done here, though without an option to unsubscribe yet.