Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed the topology directly in the NetworkBehaviour #854

Closed
tomaka opened this issue Jan 15, 2019 · 2 comments
Closed

Embed the topology directly in the NetworkBehaviour #854

tomaka opened this issue Jan 15, 2019 · 2 comments

Comments

@tomaka
Copy link
Member

tomaka commented Jan 15, 2019

cc #785

Right now libp2p assumes one single network, and therefore one single topology.
In practice, though, we probably want to support multiple overlay networks, potentially on top of one another.

In these situations, having one single Topology plugged into the Swarm is not necessarily an ideal solution.

Instead I suggest that:

  • Some implementations of NetworkBehaviour hold a topology (example: KademliaDiscovery, Brahms, Mdns).
  • When asked to dial a peer, the swarm retrieves the dialing addresses by calling a method on NetworkBehaviour. Multiple behaviours can be plugged together by joining the results.
  • The user can create complex layouts by "plugging" the multiple behaviours together manually.
  • Floodsub would get passed a list of destinations every time we send a message (cc Should the nodes floodsub sends messages to be better defined? #713).

For example, a user can:

  • Have a HashMap<NetworkId, KademliaDiscovery>, where each KademliaDiscovery holds a partial random view of its network.
  • The KademliaDiscovery generates events that indicate when this view is updated.
  • When they receive such an event, the user calls a method on the corresponding Gossipsub (for example) in a HashMap<NetworkId, Gossipsub>.
  • Gossipsub handles building an overlay network of top of the view of the KademliaDiscovery.

The drawback is that the user now has to do things a bit more manually. For example when identify generates events containing the listening addresses of a node we're connected to, the user has to transmit this information to the KademliaDiscovery.

This solution would work around #785 by removing the problem altogether.

@tomaka
Copy link
Member Author

tomaka commented Jan 17, 2019

Have a HashMap<NetworkId, KademliaDiscovery>, where each KademliaDiscovery holds a partial random view of its network.

Note that this is probably not the brightest idea. Right now you can't have multiple handlers of the same protocol simultaneously, otherwise only the first handler will receive all the substreams.
Even if that problem is solved, when we receive an incoming connection we would have to dispatch it to the right KademliaDiscovery.

I don't think it is a good idea in general for rust-libp2p to try support multiple separate networks.

The protocols handlers managed by network behaviours automatically apply to all connections, but in practice can be either used or unused.

@tomaka
Copy link
Member Author

tomaka commented Jan 21, 2019

More precise potential changes:

  • Mdns would report discovered nodes through events. It would also optionally try to maintain connections with all the discovered nodes, and would therefore store the list of discovered nodes.
  • Brahms would store a changing partial view of the network, and would report changes to this view through events.
  • Kademlia would store the k-buckets, and would report changes to the k-buckets through events.
  • When identify reports an external listened address, the user has to manually call a method on Kademlia.
  • When Brahms or Kademlia receive a node connection event, they add the new node to their view.
  • Gossipsub (and similar) would get methods add_node_to_partial_view and remove_node_from_partial_view that the user must call whenever mDNS/Brahms/Kademlia reports something. Gossipsub maintains this list, and automatically builds the overlay network on top of that.
  • Floodsub would get similar methods.
  • When the swarm fails to connect to an address, it notifies the behaviours, which can then flush the bad address.
  • When the swarm wants to reach an address, it calls a to-be-added method on the NetworkBehaviour trait.

For Substrate (which is our real-world test-case for changes in libp2p): assuming that the way Substrate is similar to gossipsub, the topology.rs file would be part of the "gossipsub-like" behaviour.

After this change, the user would have to perform more actions manually. However we ideally also would like to provide some combinations of behaviours in libp2p.

On a more theoretical level:

  • We would still have only one single network, but each behaviour would hold a partial view of this network, potentially but not necessarily overlapping with the view of the other behaviours.
  • Instead of having one topology that is concerned with respecting all the protocols, which is very difficult for the user to implement, the logic of the topology would be split between the behaviours.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant