From cc431cd9318d98ff1ab81c8b373e40c40577d141 Mon Sep 17 00:00:00 2001 From: Friedel Ziegelmayer Date: Sat, 1 Apr 2017 19:24:13 +0200 Subject: [PATCH 1/8] feat: integrate dht --- src/index.js | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/index.js b/src/index.js index f120645281..50c0d50719 100644 --- a/src/index.js +++ b/src/index.js @@ -1,15 +1,20 @@ 'use strict' +const EventEmitter = require('events').EventEmitter +const assert = require('assert') + +const setImmediate = require('async/setImmediate') +const each = require('async/each') +const series = require('async/series') + +const Ping = require('libp2p-ping') +const DHT = require('libp2p-dht') const Swarm = require('libp2p-swarm') const PeerId = require('peer-id') const PeerInfo = require('peer-info') -const mafmt = require('mafmt') const PeerBook = require('peer-book') +const mafmt = require('mafmt') const multiaddr = require('multiaddr') -const EventEmitter = require('events').EventEmitter -const assert = require('assert') -const Ping = require('libp2p-ping') -const setImmediate = require('async/setImmediate') exports = module.exports @@ -73,9 +78,10 @@ class Node extends EventEmitter { // Mount default protocols Ping.mount(this.swarm) + this.dht = new DHT(this) + // Not fully implemented in js-libp2p yet this.routing = undefined - this.records = undefined } /* @@ -117,22 +123,29 @@ class Node extends EventEmitter { } }) - this.swarm.listen((err) => { + series([ + (cb) => this.swarm.listen(cb), + (cb) => { + if (this.modules.discovery) { + each(this.modules.discovery, (d, cb) => { + d.start(cb) + }, cb) + } + cb() + }, + (cb) => this.dht.start(cb) + ], (err) => { if (err) { return callback(err) } + if (ws) { - this.swarm.transport.add(ws.tag || ws.constructor.name, ws) + this.swarm.transport.add( + ws.tag || ws.constructor.name, ws + ) } this.isOnline = true - - if (this.modules.discovery) { - this.modules.discovery.forEach((discovery) => { - setImmediate(() => discovery.start(() => {})) - }) - } - callback() }) } From af528b79f23f31fa3aad159521aafee2830a5fe4 Mon Sep 17 00:00:00 2001 From: Friedel Ziegelmayer Date: Mon, 3 Apr 2017 22:31:42 -0400 Subject: [PATCH 2/8] better interfaces --- src/index.js | 100 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 16 deletions(-) diff --git a/src/index.js b/src/index.js index 50c0d50719..9f477af172 100644 --- a/src/index.js +++ b/src/index.js @@ -78,10 +78,60 @@ class Node extends EventEmitter { // Mount default protocols Ping.mount(this.swarm) - this.dht = new DHT(this) + if (this.options.dht) { + this._dht = new DHT(this) + } + + this.peerRouting = { + findPeer: (id, callback) => { + if (!this._dht) { + return callback(new Error('DHT is not available')) + } + + this._dht.findPeer(id, callback) + } + } + + this.contentRouting = { + findProviders: (key, timeout, callback) => { + if (!this._dht) { + return callback(new Error('DHT is not available')) + } + + this._dht.findProviders(key, timeout, callback) + }, + provide: (key, callback) => { + if (!this._dht) { + return callback(new Error('DHT is not available')) + } + + this._dht.provide(key, callback) + } + } + + this.dht = { + put: (key, value, callback) => { + if (!this._dht) { + return callback(new Error('DHT is not available')) + } + + this._dht.put(key, value, callback) + }, + get: (key, callback) => { + if (!this._dht) { + return callback(new Error('DHT is not available')) + } + + this._dht.get(key, callback) + }, + getMany (key, nvals, callback) { + if (!this._dht) { + return callback(new Error('DHT is not available')) + } - // Not fully implemented in js-libp2p yet - this.routing = undefined + this._dht.getMany(key, nvals, callback) + } + } } /* @@ -126,6 +176,14 @@ class Node extends EventEmitter { series([ (cb) => this.swarm.listen(cb), (cb) => { + if (ws) { + // always add dialing on websockets + this.swarm.transport.add( + ws.tag || ws.constructor.name, ws + ) + } + + // all transports need to be setup before discover starts if (this.modules.discovery) { each(this.modules.discovery, (d, cb) => { d.start(cb) @@ -133,18 +191,17 @@ class Node extends EventEmitter { } cb() }, - (cb) => this.dht.start(cb) + (cb) => { + if (this._dht) { + return this.dht.start(cb) + } + cb() + } ], (err) => { if (err) { return callback(err) } - if (ws) { - this.swarm.transport.add( - ws.tag || ws.constructor.name, ws - ) - } - this.isOnline = true callback() }) @@ -162,7 +219,15 @@ class Node extends EventEmitter { }) } - this.swarm.close(callback) + series([ + (cb) => { + if (this._dht) { + return this._dht.stop(cb) + } + cb() + }, + (cb) => this.swarm.close(cb) + ], callback) } isOn () { @@ -217,7 +282,7 @@ class Node extends EventEmitter { /* * Helper method to check the data type of peer and convert it to PeerInfo */ - _getPeerInfo (peer) { + _getPeerInfo (peer, callback) { let p if (PeerInfo.isPeerInfo(peer)) { p = peer @@ -234,14 +299,17 @@ class Node extends EventEmitter { try { p = this.peerBook.get(peerIdB58Str) } catch (err) { - // TODO this is where PeerRouting comes into place - throw new Error('No knowledge about: ' + peerIdB58Str) + this.peerRouting.findPeer(peer, callback) } } else { - throw new Error('peer type not recognized') + setImmediate(() => { + callback(new Error('peer type not recognized')) + }) } - return p + setImmediate(() => { + callback(null, p) + }) } } From 64ffdeacd6d9ff25a5c4d0800f17669b5e175ad1 Mon Sep 17 00:00:00 2001 From: David Dias Date: Tue, 4 Apr 2017 07:51:49 -0400 Subject: [PATCH 3/8] docs: add documentation for peerRouting, contentRouting, dht --- README.md | 35 +++++++++++++++++++++++- src/index.js | 77 ++++++++++++++++++++++------------------------------ 2 files changed, 66 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 8a162d1f26..bb9dcfd2d9 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ const WS = require('libp2p-websockets') const spdy = require('libp2p-spdy') const secio = require('libp2p-secio') const MulticastDNS = require('libp2p-mdns') +const DHT = require('libp2p-dht') class Node extends libp2p { constructor (peerInfo, peerBook, options) { @@ -95,7 +96,9 @@ class Node extends libp2p { }, discovery: [ new MulticastDNS(peerInfo, 'your-identifier') - ] + ], + // DHT is passed as its own enabling PeerRouting, ContentRouting and DHT itself components + dht: new DHT() } super(modules, peerInfo, peerBook, options) @@ -144,6 +147,36 @@ class Node extends libp2p { `callback` is a function with the following `function (err) {}` signature, where `err` is an Error in case stopping the node fails. +#### `libp2p.peerRouting.findPeer(id, callback)` + +> Looks up for multiaddrs of a peer in the DHT + +- `id`: instance of [PeerId][] + +#### `libp2p.contentRouting.findProviders(key, timeout, callback)` + +- `key`: +- `timeout`: Number miliseconds + +#### `libp2p.contentRouting.provide(key, timeout, callback)` + +- `key`: +- `timeout`: Number miliseconds + +#### `libp2p.dht.put(key, value, callback)` + +- `key`: +- `value`: + +#### `libp2p.dht.get(key, callback)` + +- `key`: + +#### `libp2p.dht.getMany(key, nVals, callback)` + +- `key`: +- `nVals`: Number + #### `libp2p.handle(protocol, handlerFunc [, matchFunc])` > Handle new protocol diff --git a/src/index.js b/src/index.js index 9f477af172..f6055ef29b 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,6 @@ const each = require('async/each') const series = require('async/series') const Ping = require('libp2p-ping') -const DHT = require('libp2p-dht') const Swarm = require('libp2p-swarm') const PeerId = require('peer-id') const PeerInfo = require('peer-info') @@ -31,27 +30,27 @@ class Node extends EventEmitter { this.peerBook = _peerBook || new PeerBook() this.isOnline = false - this.swarm = new Swarm(this.peerInfo, this.peerBook) + this._swarm = new Swarm(this.peerInfo, this.peerBook) // Attach stream multiplexers if (this.modules.connection.muxer) { let muxers = this.modules.connection.muxer muxers = Array.isArray(muxers) ? muxers : [muxers] muxers.forEach((muxer) => { - this.swarm.connection.addStreamMuxer(muxer) + this._swarm.connection.addStreamMuxer(muxer) }) // If muxer exists, we can use Identify - this.swarm.connection.reuse() + this._swarm.connection.reuse() // Received incommind dial and muxer upgrade happened, // reuse this muxed connection - this.swarm.on('peer-mux-established', (peerInfo) => { + this._swarm.on('peer-mux-established', (peerInfo) => { this.emit('peer:connect', peerInfo) this.peerBook.put(peerInfo) }) - this.swarm.on('peer-mux-closed', (peerInfo) => { + this._swarm.on('peer-mux-closed', (peerInfo) => { this.emit('peer:disconnect', peerInfo) }) } @@ -61,7 +60,7 @@ class Node extends EventEmitter { let cryptos = this.modules.connection.crypto cryptos = Array.isArray(cryptos) ? cryptos : [cryptos] cryptos.forEach((crypto) => { - this.swarm.connection.crypto(crypto.tag, crypto.encrypt) + this._swarm.connection.crypto(crypto.tag, crypto.encrypt) }) } @@ -76,17 +75,16 @@ class Node extends EventEmitter { } // Mount default protocols - Ping.mount(this.swarm) + Ping.mount(this._swarm) - if (this.options.dht) { - this._dht = new DHT(this) + // dht provided components (peerRouting, contentRouting, dht) + if (this.modules.dht) { + this._dht = this.modules.dht } this.peerRouting = { findPeer: (id, callback) => { - if (!this._dht) { - return callback(new Error('DHT is not available')) - } + assert(this._dht, 'DHT is not available') this._dht.findPeer(id, callback) } @@ -94,16 +92,12 @@ class Node extends EventEmitter { this.contentRouting = { findProviders: (key, timeout, callback) => { - if (!this._dht) { - return callback(new Error('DHT is not available')) - } + assert(this._dht, 'DHT is not available') this._dht.findProviders(key, timeout, callback) }, provide: (key, callback) => { - if (!this._dht) { - return callback(new Error('DHT is not available')) - } + assert(this._dht, 'DHT is not available') this._dht.provide(key, callback) } @@ -111,25 +105,19 @@ class Node extends EventEmitter { this.dht = { put: (key, value, callback) => { - if (!this._dht) { - return callback(new Error('DHT is not available')) - } + assert(this._dht, 'DHT is not available') this._dht.put(key, value, callback) }, get: (key, callback) => { - if (!this._dht) { - return callback(new Error('DHT is not available')) - } + assert(this._dht, 'DHT is not available') this._dht.get(key, callback) }, - getMany (key, nvals, callback) { - if (!this._dht) { - return callback(new Error('DHT is not available')) - } + getMany (key, nVals, callback) { + assert(this._dht, 'DHT is not available') - this._dht.getMany(key, nvals, callback) + this._dht.getMany(key, nVals, callback) } } } @@ -163,7 +151,7 @@ class Node extends EventEmitter { transports.forEach((transport) => { if (transport.filter(multiaddrs).length > 0) { - this.swarm.transport.add( + this._swarm.transport.add( transport.tag || transport.constructor.name, transport) } else if (transport.constructor && transport.constructor.name === 'WebSockets') { @@ -174,11 +162,11 @@ class Node extends EventEmitter { }) series([ - (cb) => this.swarm.listen(cb), + (cb) => this._swarm.listen(cb), (cb) => { if (ws) { // always add dialing on websockets - this.swarm.transport.add( + this._swarm.transport.add( ws.tag || ws.constructor.name, ws ) } @@ -226,7 +214,7 @@ class Node extends EventEmitter { } cb() }, - (cb) => this.swarm.close(cb) + (cb) => this._swarm.close(cb) ], callback) } @@ -237,7 +225,7 @@ class Node extends EventEmitter { ping (peer, callback) { assert(this.isOn(), OFFLINE_ERROR_MESSAGE) const peerInfo = this._getPeerInfo(peer) - callback(null, new Ping(this.swarm, peerInfo)) + callback(null, new Ping(this._swarm, peerInfo)) } dial (peer, protocol, callback) { @@ -255,7 +243,7 @@ class Node extends EventEmitter { return callback(err) } - this.swarm.dial(peerInfo, protocol, (err, conn) => { + this._swarm.dial(peerInfo, protocol, (err, conn) => { if (err) { return callback(err) } @@ -268,15 +256,15 @@ class Node extends EventEmitter { assert(this.isOn(), OFFLINE_ERROR_MESSAGE) const peerInfo = this._getPeerInfo(peer) - this.swarm.hangUp(peerInfo, callback) + this._swarm.hangUp(peerInfo, callback) } handle (protocol, handlerFunc, matchFunc) { - this.swarm.handle(protocol, handlerFunc, matchFunc) + this._swarm.handle(protocol, handlerFunc, matchFunc) } unhandle (protocol) { - this.swarm.unhandle(protocol) + this._swarm.unhandle(protocol) } /* @@ -284,8 +272,10 @@ class Node extends EventEmitter { */ _getPeerInfo (peer, callback) { let p + // PeerInfo if (PeerInfo.isPeerInfo(peer)) { p = peer + // Multiaddr instance (not string) } else if (multiaddr.isMultiaddr(peer)) { const peerIdB58Str = peer.getPeerId() try { @@ -294,6 +284,7 @@ class Node extends EventEmitter { p = new PeerInfo(PeerId.createFromB58String(peerIdB58Str)) } p.multiaddrs.add(peer) + // PeerId } else if (PeerId.isPeerId(peer)) { const peerIdB58Str = peer.toB58String() try { @@ -302,14 +293,10 @@ class Node extends EventEmitter { this.peerRouting.findPeer(peer, callback) } } else { - setImmediate(() => { - callback(new Error('peer type not recognized')) - }) + setImmediate(() => callback(new Error('peer type not recognized'))) } - setImmediate(() => { - callback(null, p) - }) + setImmediate(() => callback(null, p)) } } From 1826f094e92720078c6d9ea1446847cf263c130e Mon Sep 17 00:00:00 2001 From: David Dias Date: Tue, 4 Apr 2017 09:00:30 -0400 Subject: [PATCH 4/8] fix: take in passed datastore --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index f6055ef29b..468e2d7bea 100644 --- a/src/index.js +++ b/src/index.js @@ -79,7 +79,7 @@ class Node extends EventEmitter { // dht provided components (peerRouting, contentRouting, dht) if (this.modules.dht) { - this._dht = this.modules.dht + this._dht = new this.modules.DHT(this, 20, this.options.dht && this.options.dht.datastore) } this.peerRouting = { From 3d4999fc83ff9979d44f7a9ec2ce63e40df547d6 Mon Sep 17 00:00:00 2001 From: David Dias Date: Tue, 4 Apr 2017 09:42:20 -0400 Subject: [PATCH 5/8] fix: update usage of _getPeerInfo --- src/index.js | 87 ++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/src/index.js b/src/index.js index 468e2d7bea..11ad39c2e9 100644 --- a/src/index.js +++ b/src/index.js @@ -30,27 +30,27 @@ class Node extends EventEmitter { this.peerBook = _peerBook || new PeerBook() this.isOnline = false - this._swarm = new Swarm(this.peerInfo, this.peerBook) + this.swarm = new Swarm(this.peerInfo, this.peerBook) // Attach stream multiplexers if (this.modules.connection.muxer) { let muxers = this.modules.connection.muxer muxers = Array.isArray(muxers) ? muxers : [muxers] muxers.forEach((muxer) => { - this._swarm.connection.addStreamMuxer(muxer) + this.swarm.connection.addStreamMuxer(muxer) }) // If muxer exists, we can use Identify - this._swarm.connection.reuse() + this.swarm.connection.reuse() // Received incommind dial and muxer upgrade happened, // reuse this muxed connection - this._swarm.on('peer-mux-established', (peerInfo) => { + this.swarm.on('peer-mux-established', (peerInfo) => { this.emit('peer:connect', peerInfo) this.peerBook.put(peerInfo) }) - this._swarm.on('peer-mux-closed', (peerInfo) => { + this.swarm.on('peer-mux-closed', (peerInfo) => { this.emit('peer:disconnect', peerInfo) }) } @@ -60,7 +60,7 @@ class Node extends EventEmitter { let cryptos = this.modules.connection.crypto cryptos = Array.isArray(cryptos) ? cryptos : [cryptos] cryptos.forEach((crypto) => { - this._swarm.connection.crypto(crypto.tag, crypto.encrypt) + this.swarm.connection.crypto(crypto.tag, crypto.encrypt) }) } @@ -75,11 +75,11 @@ class Node extends EventEmitter { } // Mount default protocols - Ping.mount(this._swarm) + Ping.mount(this.swarm) // dht provided components (peerRouting, contentRouting, dht) - if (this.modules.dht) { - this._dht = new this.modules.DHT(this, 20, this.options.dht && this.options.dht.datastore) + if (_modules.DHT) { + this._dht = new this.modules.DHT(this, 20, _options.DHT && _options.DHT.datastore) } this.peerRouting = { @@ -151,7 +151,7 @@ class Node extends EventEmitter { transports.forEach((transport) => { if (transport.filter(multiaddrs).length > 0) { - this._swarm.transport.add( + this.swarm.transport.add( transport.tag || transport.constructor.name, transport) } else if (transport.constructor && transport.constructor.name === 'WebSockets') { @@ -162,37 +162,29 @@ class Node extends EventEmitter { }) series([ - (cb) => this._swarm.listen(cb), + (cb) => this.swarm.listen(cb), (cb) => { + // listeners on, libp2p is on + this.isOnline = true + if (ws) { // always add dialing on websockets - this._swarm.transport.add( - ws.tag || ws.constructor.name, ws - ) + this.swarm.transport.add(ws.tag || ws.constructor.name, ws) } // all transports need to be setup before discover starts if (this.modules.discovery) { - each(this.modules.discovery, (d, cb) => { - d.start(cb) - }, cb) + return each(this.modules.discovery, (d, cb) => d.start(cb), cb) } cb() }, (cb) => { if (this._dht) { - return this.dht.start(cb) + return this._dht.start(cb) } cb() } - ], (err) => { - if (err) { - return callback(err) - } - - this.isOnline = true - callback() - }) + ], callback) } /* @@ -214,7 +206,7 @@ class Node extends EventEmitter { } cb() }, - (cb) => this._swarm.close(cb) + (cb) => this.swarm.close(cb) ], callback) } @@ -224,8 +216,13 @@ class Node extends EventEmitter { ping (peer, callback) { assert(this.isOn(), OFFLINE_ERROR_MESSAGE) - const peerInfo = this._getPeerInfo(peer) - callback(null, new Ping(this._swarm, peerInfo)) + this._getPeerInfo(peer, (err, peerInfo) => { + if (err) { + return callback(err) + } + + callback(null, new Ping(this.swarm, peerInfo)) + }) } dial (peer, protocol, callback) { @@ -236,35 +233,39 @@ class Node extends EventEmitter { protocol = undefined } - let peerInfo - try { - peerInfo = this._getPeerInfo(peer) - } catch (err) { - return callback(err) - } - - this._swarm.dial(peerInfo, protocol, (err, conn) => { + this._getPeerInfo(peer, (err, peerInfo) => { if (err) { return callback(err) } - this.peerBook.put(peerInfo) - callback(null, conn) + + this.swarm.dial(peerInfo, protocol, (err, conn) => { + if (err) { + return callback(err) + } + this.peerBook.put(peerInfo) + callback(null, conn) + }) }) } hangUp (peer, callback) { assert(this.isOn(), OFFLINE_ERROR_MESSAGE) - const peerInfo = this._getPeerInfo(peer) - this._swarm.hangUp(peerInfo, callback) + this._getPeerInfo(peer, (err, peerInfo) => { + if (err) { + return callback(err) + } + + this.swarm.hangUp(peerInfo, callback) + }) } handle (protocol, handlerFunc, matchFunc) { - this._swarm.handle(protocol, handlerFunc, matchFunc) + this.swarm.handle(protocol, handlerFunc, matchFunc) } unhandle (protocol) { - this._swarm.unhandle(protocol) + this.swarm.unhandle(protocol) } /* From 4b0447b180d55565c4baf3a72c3d45f08f87d9ca Mon Sep 17 00:00:00 2001 From: David Dias Date: Wed, 5 Apr 2017 23:42:15 -0400 Subject: [PATCH 6/8] fix: getPeerInfo --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 11ad39c2e9..055f0b73da 100644 --- a/src/index.js +++ b/src/index.js @@ -291,10 +291,10 @@ class Node extends EventEmitter { try { p = this.peerBook.get(peerIdB58Str) } catch (err) { - this.peerRouting.findPeer(peer, callback) + return this.peerRouting.findPeer(peer, callback) } } else { - setImmediate(() => callback(new Error('peer type not recognized'))) + return setImmediate(() => callback(new Error('peer type not recognized'))) } setImmediate(() => callback(null, p)) From e846511482f0b378687395dfe3b51d8da0aff662 Mon Sep 17 00:00:00 2001 From: David Dias Date: Thu, 6 Apr 2017 14:37:16 -0400 Subject: [PATCH 7/8] docs: update docs --- README.md | 12 ++++++------ src/index.js | 4 +--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index bb9dcfd2d9..78208538a9 100644 --- a/README.md +++ b/README.md @@ -155,26 +155,26 @@ class Node extends libp2p { #### `libp2p.contentRouting.findProviders(key, timeout, callback)` -- `key`: +- `key`: Buffer - `timeout`: Number miliseconds #### `libp2p.contentRouting.provide(key, timeout, callback)` -- `key`: +- `key`: Buffer - `timeout`: Number miliseconds #### `libp2p.dht.put(key, value, callback)` -- `key`: -- `value`: +- `key`: Buffer +- `value`: Buffer #### `libp2p.dht.get(key, callback)` -- `key`: +- `key`: Buffer #### `libp2p.dht.getMany(key, nVals, callback)` -- `key`: +- `key`: Buffer - `nVals`: Number #### `libp2p.handle(protocol, handlerFunc [, matchFunc])` diff --git a/src/index.js b/src/index.js index 055f0b73da..fddef7883d 100644 --- a/src/index.js +++ b/src/index.js @@ -36,9 +36,7 @@ class Node extends EventEmitter { if (this.modules.connection.muxer) { let muxers = this.modules.connection.muxer muxers = Array.isArray(muxers) ? muxers : [muxers] - muxers.forEach((muxer) => { - this.swarm.connection.addStreamMuxer(muxer) - }) + muxers.forEach((muxer) => this.swarm.connection.addStreamMuxer(muxer)) // If muxer exists, we can use Identify this.swarm.connection.reuse() From 990cf61da1c5db7fd35e45510230ae22ca373f79 Mon Sep 17 00:00:00 2001 From: David Dias Date: Thu, 6 Apr 2017 15:44:53 -0400 Subject: [PATCH 8/8] moar --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 78208538a9..64e5806600 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ const WS = require('libp2p-websockets') const spdy = require('libp2p-spdy') const secio = require('libp2p-secio') const MulticastDNS = require('libp2p-mdns') -const DHT = require('libp2p-dht') +const DHT = require('libp2p-kad-dht') class Node extends libp2p { constructor (peerInfo, peerBook, options) { @@ -98,7 +98,7 @@ class Node extends libp2p { new MulticastDNS(peerInfo, 'your-identifier') ], // DHT is passed as its own enabling PeerRouting, ContentRouting and DHT itself components - dht: new DHT() + dht: DHT } super(modules, peerInfo, peerBook, options)