-
Notifications
You must be signed in to change notification settings - Fork 504
Description
As part of the PeerStore improvements epic, we intend to deprecate peer-info and consolidate all peer's information on the PeerStore.
Background
On [email protected] 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:
-
We can emit an event with an object as follows:
discovery.emit('peer', { peerId, []multiaddrs }), while theinterfaceshould validate that both properties are provided. -
We can provide the
peerStoretopeer-discoveryprotocols 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 createdPeerInfo.
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-discoveryPRspubsubPRscontent-routingandpeer-routingPRs