Awesome
@libp2p/example-discovery-mechanisms <!-- omit in toc -->
How to configure peer discovery mechanisms
Table of contents <!-- omit in toc -->
- 1. Find peers on the Amino DHT
- 2. Using MulticastDNS to find other peers on the same network
- 3. Pubsub based Peer Discovery
- 4. Where to find other Peer Discovery Mechanisms
- Need help?
- License
- Contribution
With this system, a libp2p node can both have a set of nodes to always connect on boot (bootstraper nodes), discover nodes through locality (e.g connected in the same LAN) or through serendipity (random walks on a DHT).
These mechanisms save configuration and enable a node to operate without any explicit dials, it will just work. Once new peers are discovered, their known data is stored in the peer's PeerStore.
1. Find peers on the Amino DHT
The IPFS DHT, "Amino" is a network of peers that all speak a variation of the Kademlia protocol.
Kademlia works on the principal of "closeness" - this is not geographic or latency based, instead:
- Given two nodes A and B, and some target data
- Calculate the hash of the PeerID of each node, and the hash of the target data
- XOR each PeerID hash together with the data hash
- We can say that A is closer than B if the numeric result of the XOR calculation is lower
When your node connects to the DHT, the first thing it will do is run a "self-query". During this query it asks connected peers for the peers they know that are closer to your node's PeerID. It will repeat this query until it finds the 20 closest nodes on the network.
During this query, every peer it traverses through is a peer discovery!
To run the demo, take a look a 1-dht.js. In this demo we use the @libp2p/bootstrap
module to connect to a list of bootstrap peers - these peers allow us to make our "self-query".
Once peers are discovered, they will be dialed due to libp2p's auto-dialer which attempts to increase the number of connections a node has..
From running 1-dht.js, you should see the following:
> node 1-dht.js
Discovered: QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
Discovered: QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN
Discovered: QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb
Discovered: QmZa1sAxajnQjVM8WjWXoMbmPd7NsWhfKsPkErzpm9wGkp
Discovered: QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa
Discovered: QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt
Connection established to: QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb
Discovered: 12D3KooWNUHA7Upmvcfk4GUz5orpQKrnbTFDofsNL95rUX7g2nzX
Discovered: 12D3KooWGJvA6di2KL2YezPVNdUp6fuC2ZbdngNBGvwhgKPcQYf2
Discovered: 12D3KooWK8bRNVA5bWVpixTVSAP6oLkXTsVBo5Et91S846wpK6xW
Discovered: 12D3KooWMn8cJNsPMAw9jif9CHzom7so3usSHRdkQsPfcS9x9Prt
Discovered: Qmeau5xZPEciw3Kw8FFsufkkjWoBYjNoxxNcLx93rABY56
Discovered: 12D3KooWHgohc8QPpJXRW8mEm1vgvnh6AQKU1bwSRuLEMYMvPahA
Discovered: 12D3KooWMBbpduEtVHbKTiBcjLQpV2Tj3QRJD3zGFKctFuAhkgMd
... lots more output
2. Using MulticastDNS to find other peers on the same network
mDNS is a mechanism for device and peer discovery on the local network.
For this example, we need @libp2p/mdns
, go ahead and npm install
it. You can find the complete solution at 2-mdns.js.
Update your libp2p configuration to include MulticastDNS.
import { createLibp2p } from 'libp2p'
import { mdns } from '@libp2p/mdns'
import { tcp } from '@libp2p/tcp'
import { yamux } from '@chainsafe/libp2p-yamux'
import { noise } from '@chainsafe/libp2p-noise'
const createNode = () => {
return createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
transports: [
tcp()
],
streamMuxers: [
yamux(),
],
connectionEncrypters: [
noise()
],
peerDiscovery: [
mdns({
interval: 20e3
})
]
})
}
To observe it working, spawn two nodes.
const [node1, node2] = await Promise.all([
createNode(),
createNode()
])
node1.addEventListener('peer:discovery', (evt) => console.log('Discovered:', evt.detail.id.toString()))
node2.addEventListener('peer:discovery', (evt) => console.log('Discovered:', evt.detail.id.toString()))
If you run this example, you will see the other peers being discovered.
> node 2.js
Discovered: QmSSbQpuKrxkoXHm1v4Pi35hPN5hUHMZoBoawEs2Nhvi8m
Discovered: QmRcXXhtG8vTqwVBRonKWtV4ovDoC1Fe56WYtcrw694eiJ
3. Pubsub based Peer Discovery
For this example, we need @libp2p/pubsub-peer-discovery
, go ahead and npm install
it. It is a module that has the local node subscribe to a known pub/sub topic and to broadcast it's peer info on the topic periodically.
Pub/sub based peer discovery is useful for deployments where other mechanisms may not be suitable - for example in browsers which do not support transports which make up the majority of nodes on the DHT (e.g. TCP or QUIC).
You can find the complete solution at 3-pubsub.js.
In the example we create three nodes. The first is used to bootstrap the network. The second and third dial the bootstrapper, then discover each other via the pub/sub peer discovery topic.
4. Where to find other Peer Discovery Mechanisms
There are plenty more Peer Discovery Mechanisms out there, you can:
- Any DHT will offer you a discovery capability. You can simple random-walk the routing tables to find other peers to connect to. For example @libp2p/kad-dht can be used for peer discovery. An example of how to configure it to enable random walks can be found here.
- You can create your own Discovery service, a registry, a list, a radio beacon, you name it!
Need help?
- Read the js-libp2p documentation
- Check out the js-libp2p API docs
- Check out the general libp2p documentation for tips, how-tos and more
- Read the libp2p specs
- Ask a question on the js-libp2p discussion board
License
Licensed under either of
- Apache 2.0, (LICENSE-APACHE / http://www.apache.org/licenses/LICENSE-2.0)
- MIT (LICENSE-MIT / http://opensource.org/licenses/MIT)
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.