go-libp2p-pubsub
go-libp2p-pubsub copied to clipboard
Subscribe and Relay should be separate operations.
Not all subscribers will want to relay (bandwidth reasons) and not all relays will want to subscribe (they may just want to forward values without looking at them).
I'm new to ipfs and libp2p, but I was thinking this could set this at the subscription level. For a not great example:
// Subscribe and relay by default.
pubsub.Subscribe("topic1")
// maybe implemented as:
td := pb.TopicDescriptor{Name: "topic1", Relay: true, Subscriber: true}
pubsub.SubscribeByTopicDescriptor(&td)
// Relay without reading messages.
pubsub.Relay("topic1")
// maybe implemented as:
td := pb.TopicDescriptor{Name: "topic1", Relay: true, Subscriber: false}
pubsub.SubscribeByTopicDescriptor(&td)
// Subscribe without relaying messages.
td := pb.TopicDescriptor{Name: "topic1", Relay: false, Subscriber: true}
pubsub.SubscribeByTopicDescriptor(&td)
I'm sure there's a better way to do this because having different flags makes things a bit cumbersome.
But, if you then had a wild card topic "*" you could become a dedicated relay or sink.
I think it will be a great feature to decouple subscription from routing, especially with gossipsub. We can use it to offer pubsub services in the core network, without spawning new goroutines and channels for them.
We can add two methods to the pubsub interface to this effect:
Join(topic string)
Leave(topic string)
I will work on it after gossipsub, pr as it maps nicely to the new router Join/Leave methods it adds.
Hey @aschmahmann @vyzo
Thanks for the beautifully written gossipsub spec.
Now, I understand that a peer publishes a message with topic T to peers in fanout[T] ONLY if it is NOT subscribed to T AND the message originates from itself. Even in this case, it is acting as a 'relayer' of the message even though it is not a 'subscriber' of T.
If my understand is correct, this issue is to enable a peer to choose one of three modes:
- Relayer: Receive & forward a message to
fanout[T]even if it hasn't subscribed toTAND the message does NOT originate fromT - Subscriber: Receive a message of type
Twithout having to forward it tomesh[T]or gossip torandomD(gossip[T] - mesh[T]) - Dual: The current implementation
This applies to floodsub as well ofcourse. We will forward to floodsub[T] only if we are in mode 1) or 3).
Please let me know if I'm sounding stupid. I'll come up with a design/notes once we've fleshed this out.
I'd like confirmation from @Stebalien or @vyzo, but my understanding is that the situation is more like:
Currently (for a given topic T)
- Publisher(T):
- Sends messages I publish about
Tto the network (in floodsub to all connections and in gossipsub to myfanout[T]peers)
- Sends messages I publish about
- Subscriber(T):
- Tells peers that I want them to send me messages about
T. - Propagates received messages to peers (in floodsub all peers, in gossipsub mesh peers)
- I can view the messages in the order I receive them via
Subscription.Next()
- Tells peers that I want them to send me messages about
You can be a Publisher, a Subscriber or Both.
With Separate Relaying option
- Publisher(T): The same
- Subscriber(T):
- Tells peers that I want them to send me messages about
T. - I can view the messages in the order I receive them viaSubscription.Next() - Relayer(T):
- Tells peers that I want them to send me messages about
T. - Propagates received messages to peers (in floodsub all peers, in gossipsub mesh peers)
You should be able to be any combination of these three.
@aschmahmann Pinged @vyzo on IRC about this & he agrees with our comments here.
You should be able to be any combination of these three
A peer will ALWAYS be a publisher though ?
Subscriber(T):
- Tells peers that I want them to send me messages about
T.- I can view the messages in the order I receive them via `Subscription.Next()
We will still enable the gossip we send with every heartbeat on such peers, right ?
- Relayer(T):
- Tells peers that I want them to send me messages about
T.- Propagates received messages to peers (in floodsub all peers, in gossipsub mesh peers)
Makes sense.
A peer will ALWAYS be a publisher though ?
Yes, our current use of "Publisher" is really the ability to publish. Since we don't setup anything special to do publishing peers can always publish (assuming the validator allows them to).
We will still enable the gossip we send with every heartbeat on such peers, right ?
I think so, the gossip is really a delayed repeated rebroadcasting of messages that we Published (and it only does so for a few heartbeats anyway)
@Stebalien @vyzo Do we need any protocol extensions to support this capability? My concern is that Gossipsub is limited to a mesh size of D_max and with this PR it's possible that many of the mesh members will not be rebroadcasting messages which changes the network dynamics.
Does there need to be a "Subscribe without Relay" option at the protocol level that we deal with?
Nothing special is needed -- the routers already implement the Relay operation, while the subscription is handled by the core of pubsub.
This is pretty simple to do, nothing needs to change in the wire or protocols.
All we have to do is add a new Relay operation (or maybe a better name, more common to pubsub literature, Join) to the pubsub interface.
Subscribe is Join + create a subscription object.
@vyzo If a publisher's mesh is mostly full of 'Subscribe Only' peers, wont it be at the mercy of the gossip/heartbeats on those peers for it's messages to propagate through the network ?
The main problem is that if a message isn't rebroadcasted by a group of 'encircling' peers to their mesh/es, the ONLY way for other 'outer' peers in the network to get it is via gossip.
Please correct me if I'm wrong. Also, please can you assign the issue to me ?
Subscribe is Join + create a subscription object.
If Relay = Join and Subscribe = Join + subscription object then this is not what was proposed in the issue.
Not all subscribers will want to relay (bandwidth reasons) and not all relays will want to subscribe (they may just want to forward values without looking at them).
@vyzo your approach helps for "not all relays will want to subscribe", but does nothing for "Not all subscribers will want to relay". Are you proposing we shouldn't bother caring about the second case at this time?
It is for that second approach of "Not all subscribers will want to relay" that I'm concerned we might need to modify the protobuf.
Subscribers should be relays, we don't want leeches.
Subscribers should be relays, we don't want leeches.
Does that mean the only purpose of this change is to save a few bytes of memory per topic on the message buffer for relay-only nodes?
Of course, that's potentially a lot of memory if we're talking about large infrastructure nodes, but it certainly limits the scope of the issue.
@magik6k wanted this a few days ago as well.
I agree with @vyzo. For p2p pubsub to work collaboratively and fairly, peers subscribed to a topic MUST participate in the dissemination of that topic. Nodes wanting to participate voluntarily in the dissemination of a topic (without being interested in its messages), should also be able to do so.