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

Deprecate peer-info and consolidate peers' information on PeerStore #589

Closed
vasco-santos opened this issue Mar 19, 2020 · 2 comments
Closed
Labels
exp/expert Having worked on the specific codebase is important kind/enhancement A net-new feature or improvement to an existing feature status/ready Ready to be worked

Comments

@vasco-santos
Copy link
Member

vasco-santos commented Mar 19, 2020

As part of the PeerStore improvements epic, we intend to deprecate peer-info and consolidate all peer's information on the PeerStore.

Background

On libp2p@0.27 we introduced the PeerStore on the js-libp2p codebase replacing the peer-book module. The PeerStore is responsible for managing known peers, as well as their addresses and metadata.

The initial version of this PeerStore is similar to the previous peer-book. It maps peer identifier strings to their peer-info object and has the common operations of a store, such as put, get, has, remove and replace.

Problem

Taking into account that peers' information might vary as the time passes and network operations are performed, we introduced two events in the initial version of the PeerStore: change:protocols and change:multiaddrs, but some other should be added in the future.

Since we currently rely on a PeerInfo instance stored in the PeerStore and a PeerInfo instance, we are prone to some data inconsistencies. For example, if a peer discovery protocol discovers a peer, it will create a PeerInfo with that peer and its discovered multiaddr and add it to the PeerStore. In the case that we already know the peer (other multiaddr or not, and possibly some protocols), we currently need to destruct the old information and merge it to the new one. This also creates complexity on finding the changes in multiaddr / protocols / ...

Therefore, peer-info adds an extra layer of complexity without benefits, both in the PeerStore store and on moving data around libp2p subsystems. In addition, it is better to move around only the needed data, instead of creating unnecessary instances.

PeerInfo usage

Module Details PR
libp2p .create() libp2p/js-libp2p#610
ipfs used to access id, or to access data from PeerStore TODO
libp2p-kad-dht peer-discovery / dht.findPeer/dht.findProvs return PeerInfo libp2p/js-libp2p-kad-dht#180 /libp2p/js-libp2p-kad-dht#181
libp2p-bootstrap interface-peer-discovery js-libp2p-bootstrap#103
libp2p-mdns interface-peer-discovery libp2p/js-libp2p-mdns#90
libp2p-webrtc-star interface-peer-discovery libp2p/js-libp2p-webrtc-star#213
libp2p-pubsub-discovery interface-peer-discovery libp2p/js-libp2p-pubsub-peer-discovery#5
discv5 interface-peer-discovery ChainSafe/discv5#51
libp2p-gossipsub usage for getting id, protocols for fallback to floodsub ChainSafe/gossipsub-js#70
libp2p-floodsub usage for getting id libp2p/js-libp2p-floodsub#102
libp2p-pubsub usage for getting id, protocol is added to info, but can move to internal peer abstraction libp2p/js-libp2p-pubsub#41
libp2p-delegated-content-routing .findProvs libp2p/js-libp2p-delegated-content-routing#34
libp2p-delegated-peer-routing .findPeer libp2p/js-libp2p-delegated-peer-routing#25
libp2p-interfaces peer-discovery / topology / content-routing and peer-routing libp2p/js-libp2p-interfaces#41 /libp2p/js-libp2p-interfaces#42 / libp2p/js-libp2p-interfaces#43
libp2p-daemon-client dht api libp2p/js-libp2p-daemon-client#25
libp2p-daemon some logic achievable via libp2p.* libp2p/js-libp2p-daemon#38

Solution design

While most usages of PeerInfo are easily removed, some will need to break APIs or to receive more parameters to be able to work without the PeerInfo.

interface-peer-discovery

Currently, the peer discovery protocols emit a peer event with the peerInfo as follows discovery.on('peer', (peerInfo) => {}). We currently rely on peerInfo because we need both the peerId and the discovered multiaddr.

We have 2 possible solutions for this:

  1. We can emit an event with an object as follows: discovery.emit('peer', { peerId, []multiaddrs }), while the interface should validate that both properties are provided.

  2. We can provide the peerStore to peer-discovery protocols and they would interact with it directly.

Since peerStore will be divided into different components (AddressBook, KeyBook, ProtoBook , peerMetadataStore?), I think that js-libp2p should be responsible for handling the events and update what it needs, instead of delegating the responsibility for other subsystems (consequently less logic and needed code changes)

To consider: future discovery mechanisms, like peer-exchange might also provide known protocols?

interface-topology

A libp2p toplogy has a peers map, which maps peer identifiers to their peerInfo. They rely on the peerInfo for checking the protocols they support.

We can simplify the Topology by having an array of peers important for the topology and provide access to the PeerStore data so that the topology can identify the current known protocols of a peer.

pubsub internal peer

We currently have an internal peer instance on pubsub. We rely on this instance for managing the stream with peers, subscribed topics and other relevant information. This peer also has an info propery with the PeerInfo of the peer. This is only used for checking the protocols available (particularly useful for fallback to floodsub on gossipsub)!

In this situation, we can just have a property for protocols on the internal peer instance and rely on the peerId instead. We have access for it on the incomingStream function.

content-routing / peer-routing APIs

We should uniform this like the ipfs api and get rid of peer-info. This is a similar approach to the interface-peer-discovery solution proposed.

libp2p

  • libp2p.create() accepts a previously created PeerInfo.

This is particularly useful for listening on a previously specified set of multiaddr. This should be part of the discussion around improving config, or js-libp2p will need to improve its API around transport management

  • libp2p.contentRouting, libp2p.peerRouting

Should be the same as above

  • Events

Should use peer-id instead of peer-info and the users can gather the same information from the exposed peerStore.

Review order

  • libp2p-interfaces PRs
  • peer-discovery PRs
  • pubsub PRs
  • content-routing and peer-routing PRs
@vasco-santos vasco-santos changed the title (WIP) Deprecate peer-info and consolidate peers' information on PeerStore Deprecate peer-info and consolidate peers' information on PeerStore Mar 19, 2020
@vasco-santos
Copy link
Member Author

cc @jacobheun

I did a list of all the cases where peer-info is currently used and wrote my thoughts on how to solve all of those usages. Let me know what you think

@vasco-santos vasco-santos added exp/expert Having worked on the specific codebase is important kind/enhancement A net-new feature or improvement to an existing feature status/ready Ready to be worked labels Mar 25, 2020
@jacobheun
Copy link
Contributor

Released in 0.28

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
exp/expert Having worked on the specific codebase is important kind/enhancement A net-new feature or improvement to an existing feature status/ready Ready to be worked
Projects
None yet
Development

No branches or pull requests

2 participants