go-libp2p-pubsub icon indicating copy to clipboard operation
go-libp2p-pubsub copied to clipboard

Subscribe and Relay should be separate operations.

Open Stebalien opened this issue 8 years ago • 13 comments

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).

Stebalien avatar Jul 15 '17 02:07 Stebalien

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.

film42 avatar Sep 01 '17 18:09 film42

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.

vyzo avatar Feb 22 '18 15:02 vyzo

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:

  1. Relayer: Receive & forward a message to fanout[T] even if it hasn't subscribed to T AND the message does NOT originate from T
  2. Subscriber: Receive a message of type T without having to forward it to mesh[T] or gossip to randomD(gossip[T] - mesh[T])
  3. 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.

aarshkshah1992 avatar Oct 03 '19 13:10 aarshkshah1992

I'd like confirmation from @Stebalien or @vyzo, but my understanding is that the situation is more like:

Currently (for a given topic T)

  1. Publisher(T):
    • Sends messages I publish about T to the network (in floodsub to all connections and in gossipsub to my fanout[T] peers)
  2. 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()

You can be a Publisher, a Subscriber or Both.

With Separate Relaying option

  1. Publisher(T): The same
  2. 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()
  3. 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 avatar Oct 03 '19 17:10 aschmahmann

@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 ?

  1. 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.

aarshkshah1992 avatar Oct 06 '19 10:10 aarshkshah1992

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)

aschmahmann avatar Oct 08 '19 16:10 aschmahmann

@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?

aschmahmann avatar Oct 08 '19 16:10 aschmahmann

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 avatar Oct 08 '19 16:10 vyzo

@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 ?

aarshkshah1992 avatar Oct 08 '19 16:10 aarshkshah1992

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.

aschmahmann avatar Oct 08 '19 17:10 aschmahmann

Subscribers should be relays, we don't want leeches.

vyzo avatar Oct 08 '19 17:10 vyzo

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.

aschmahmann avatar Oct 08 '19 17:10 aschmahmann

@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.

raulk avatar Oct 11 '19 14:10 raulk