From 7b326cc5250d31253a393bd827ff5bc6732f306c Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 18 Dec 2019 02:37:36 +0000 Subject: [PATCH] refactor: examples/peer-and-content-routing (#500) * refactor: examples-peer-and-content-routing * chore: address review * chore: review suggestions Co-Authored-By: Jacob Heun --- examples/peer-and-content-routing/1.js | 96 +++++++----------- examples/peer-and-content-routing/2.js | 104 ++++++++------------ examples/peer-and-content-routing/README.md | 79 +++++++-------- 3 files changed, 110 insertions(+), 169 deletions(-) diff --git a/examples/peer-and-content-routing/1.js b/examples/peer-and-content-routing/1.js index 605ec307a5..405a8a35aa 100644 --- a/examples/peer-and-content-routing/1.js +++ b/examples/peer-and-content-routing/1.js @@ -1,77 +1,55 @@ /* eslint-disable no-console */ 'use strict' -const libp2p = require('../../') +const Libp2p = require('../../') const TCP = require('libp2p-tcp') const Mplex = require('libp2p-mplex') const SECIO = require('libp2p-secio') const PeerInfo = require('peer-info') const KadDHT = require('libp2p-kad-dht') -const defaultsDeep = require('@nodeutils/defaults-deep') -const waterfall = require('async/waterfall') -const parallel = require('async/parallel') -class MyBundle extends libp2p { - constructor (_options) { - const defaults = { - modules: { - transport: [ TCP ], - streamMuxer: [ Mplex ], - connEncryption: [ SECIO ], - // we add the DHT module that will enable Peer and Content Routing - dht: KadDHT - }, - config: { - dht: { - enabled: true, - kBucketSize: 20 - } +const delay = require('delay') + +const createNode = async () => { + const peerInfo = await PeerInfo.create() + peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0') + + const node = await Libp2p.create({ + peerInfo, + modules: { + transport: [TCP], + streamMuxer: [Mplex], + connEncryption: [SECIO], + dht: KadDHT + }, + config: { + dht: { + enabled: true } } + }) - super(defaultsDeep(_options, defaults)) - } -} - -function createNode (callback) { - let node - - waterfall([ - (cb) => PeerInfo.create(cb), - (peerInfo, cb) => { - peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0') - node = new MyBundle({ - peerInfo - }) - node.start(cb) - } - ], (err) => callback(err, node)) + await node.start() + return node } -parallel([ - (cb) => createNode(cb), - (cb) => createNode(cb), - (cb) => createNode(cb) -], (err, nodes) => { - if (err) { throw err } +;(async () => { + const [node1, node2, node3] = await Promise.all([ + createNode(), + createNode(), + createNode() + ]) - const node1 = nodes[0] - const node2 = nodes[1] - const node3 = nodes[2] + await Promise.all([ + node1.dial(node2.peerInfo), + node2.dial(node3.peerInfo) + ]) - parallel([ - (cb) => node1.dial(node2.peerInfo, cb), - (cb) => node2.dial(node3.peerInfo, cb), - // Set up of the cons might take time - (cb) => setTimeout(cb, 300) - ], (err) => { - if (err) { throw err } + // The DHT routing tables need a moment to populate + await delay(100) - node1.peerRouting.findPeer(node3.peerInfo.id, (err, peer) => { - if (err) { throw err } + const peer = await node1.peerRouting.findPeer(node3.peerInfo.id) - console.log('Found it, multiaddrs are:') - peer.multiaddrs.forEach((ma) => console.log(ma.toString())) - }) - }) -}) + console.log('Found it, multiaddrs are:') + peer.multiaddrs.forEach((ma) => console.log(ma.toString())) +})(); diff --git a/examples/peer-and-content-routing/2.js b/examples/peer-and-content-routing/2.js index 78b187c5d3..b6346803e2 100644 --- a/examples/peer-and-content-routing/2.js +++ b/examples/peer-and-content-routing/2.js @@ -1,85 +1,61 @@ /* eslint-disable no-console */ 'use strict' -const libp2p = require('../../') +const Libp2p = require('../../') const TCP = require('libp2p-tcp') const Mplex = require('libp2p-mplex') const SECIO = require('libp2p-secio') const PeerInfo = require('peer-info') const CID = require('cids') const KadDHT = require('libp2p-kad-dht') -const defaultsDeep = require('@nodeutils/defaults-deep') -const waterfall = require('async/waterfall') -const parallel = require('async/parallel') -class MyBundle extends libp2p { - constructor (_options) { - const defaults = { - modules: { - transport: [ TCP ], - streamMuxer: [ Mplex ], - connEncryption: [ SECIO ], - // we add the DHT module that will enable Peer and Content Routing - dht: KadDHT - }, - config: { - dht: { - enabled: true, - kBucketSize: 20 - } +const all = require('it-all') +const delay = require('delay') + +const createNode = async () => { + const peerInfo = await PeerInfo.create() + peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0') + + const node = await Libp2p.create({ + peerInfo, + modules: { + transport: [TCP], + streamMuxer: [Mplex], + connEncryption: [SECIO], + dht: KadDHT + }, + config: { + dht: { + enabled: true } } + }) - super(defaultsDeep(_options, defaults)) - } + await node.start() + return node } -function createNode (callback) { - let node - - waterfall([ - (cb) => PeerInfo.create(cb), - (peerInfo, cb) => { - peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0') - node = new MyBundle({ - peerInfo - }) - node.start(cb) - } - ], (err) => callback(err, node)) -} +;(async () => { + const [node1, node2, node3] = await Promise.all([ + createNode(), + createNode(), + createNode() + ]) -parallel([ - (cb) => createNode(cb), - (cb) => createNode(cb), - (cb) => createNode(cb) -], (err, nodes) => { - if (err) { throw err } + await Promise.all([ + node1.dial(node2.peerInfo), + node2.dial(node3.peerInfo) + ]) - const node1 = nodes[0] - const node2 = nodes[1] - const node3 = nodes[2] + const cid = new CID('QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL') + await node1.contentRouting.provide(cid) - parallel([ - (cb) => node1.dial(node2.peerInfo, cb), - (cb) => node2.dial(node3.peerInfo, cb), - // Set up of the cons might take time - (cb) => setTimeout(cb, 300) - ], (err) => { - if (err) { throw err } + console.log('Node %s is providing %s', node1.peerInfo.id.toB58String(), cid.toBaseEncodedString()) - const cid = new CID('QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL') + // wait for propagation + await delay(300) - node1.contentRouting.provide(cid, (err) => { - if (err) { throw err } + const providers = await all(node3.contentRouting.findProviders(cid, { timeout: 3000 })) - console.log('Node %s is providing %s', node1.peerInfo.id.toB58String(), cid.toBaseEncodedString()) - - node3.contentRouting.findProviders(cid, 5000, (err, providers) => { - if (err) { throw err } - - console.log('Found provider:', providers[0].id.toB58String()) - }) - }) - }) -}) + console.log('Found provider:', providers[0].id.toB58String()) +})(); diff --git a/examples/peer-and-content-routing/README.md b/examples/peer-and-content-routing/README.md index e00903efd7..7c7653f3a0 100644 --- a/examples/peer-and-content-routing/README.md +++ b/examples/peer-and-content-routing/README.md @@ -10,31 +10,27 @@ Content Routing is the category of modules that offer a way to find where conten This example builds on top of the [Protocol and Stream Muxing](../protocol-and-stream-muxing). We need to install `libp2p-kad-dht`, go ahead and `npm install libp2p-kad-dht`. If you want to see the final version, open [1.js](./1.js). -First, let's update our bundle to support Peer Routing and Content Routing. +First, let's update our config to support Peer Routing and Content Routing. ```JavaScript -class MyBundle extends libp2p { - constructor (_options) { - const defaults = { - modules: { - transport: [ TCP ], - streamMuxer: [ Mplex ], - connEncryption: [ SECIO ], - // we add the DHT module that will enable Peer and Content Routing - dht: KadDHT - }, - config: { - dht: { - // dht must be enabled - enabled: true, - kBucketSize: 20 - } - } +const Libp2p = require('libp2p') +const KadDHT = require('libp2p-kad-dht') + +const node = await Libp2p.create({ + modules: { + transport: [ TCP ], + streamMuxer: [ Mplex ], + connEncryption: [ SECIO ], + // we add the DHT module that will enable Peer and Content Routing + dht: KadDHT + }, + config: { + dht: { + // dht must be enabled + enabled: true } - - super(defaultsDeep(_options, defaults)) } -} +}) ``` Once that is done, we can use the createNode function we developed in the previous example to create 3 nodes. Connect node 1 to node 2 and node 2 to node 3. We will use node 2 as a way to find the whereabouts of node 3 @@ -44,22 +40,18 @@ const node1 = nodes[0] const node2 = nodes[1] const node3 = nodes[2] -parallel([ - (cb) => node1.dial(node2.peerInfo, cb), - (cb) => node2.dial(node3.peerInfo, cb), - // Set up of the cons might take time - (cb) => setTimeout(cb, 100) -], (err) => { - if (err) { throw err } - - // - node1.peerRouting.findPeer(node3.peerInfo.id, (err, peer) => { - if (err) { throw err } - - console.log('Found it, multiaddrs are:') - peer.multiaddrs.forEach((ma) => console.log(ma.toString())) - }) -}) +await Promise.all([ + node1.dial(node2.peerInfo), + node2.dial(node3.peerInfo) +]) + +// Set up of the cons might take time +await delay(100) + +const peer = await node1.peerRouting.findPeer(node3.peerInfo.id) + +console.log('Found it, multiaddrs are:') +peer.multiaddrs.forEach((ma) => console.log(ma.toString())) ``` You should see the output being something like: @@ -82,17 +74,12 @@ You can find this example completed in [2.js](./2.js), however as you will see i Instead of calling `peerRouting.findPeer`, we will use `contentRouting.provide` and `contentRouting.findProviders`. ```JavaScript -node1.contentRouting.provide(cid, (err) => { - if (err) { throw err } +await node1.contentRouting.provide(cid) +console.log('Node %s is providing %s', node1.peerInfo.id.toB58String(), cid.toBaseEncodedString()) - console.log('Node %s is providing %s', node1.peerInfo.id.toB58String(), cid.toBaseEncodedString()) +const provs = await all(node3.contentRouting.findProviders(cid, { timeout: 5000 })) - node3.contentRouting.findProviders(cid, 5000, (err, providers) => { - if (err) { throw err } - - console.log('Found provider:', providers[0].id.toB58String()) - }) -}) +console.log('Found provider:', providers[0].id.toB58String()) ``` The output of your program should look like: