diff --git a/src/content-routing.js b/src/content-routing.js new file mode 100644 index 00000000..559541ed --- /dev/null +++ b/src/content-routing.js @@ -0,0 +1,20 @@ +'use strict' + +module.exports = (node) => { + return { + findProviders: (key, timeout, callback) => { + if (!node._dht) { + return callback(new Error('DHT is not available')) + } + + node._dht.findProviders(key, timeout, callback) + }, + provide: (key, callback) => { + if (!node._dht) { + return callback(new Error('DHT is not available')) + } + + node._dht.provide(key, callback) + } + } +} diff --git a/src/dht.js b/src/dht.js new file mode 100644 index 00000000..504db7a6 --- /dev/null +++ b/src/dht.js @@ -0,0 +1,27 @@ +'use strict' + +module.exports = (node) => { + return { + put: (key, value, callback) => { + if (!node._dht) { + return callback(new Error('DHT is not available')) + } + + node._dht.put(key, value, callback) + }, + get: (key, callback) => { + if (!node._dht) { + return callback(new Error('DHT is not available')) + } + + node._dht.get(key, callback) + }, + getMany (key, nVals, callback) { + if (!node._dht) { + return callback(new Error('DHT is not available')) + } + + node._dht.getMany(key, nVals, callback) + } + } +} diff --git a/src/get-peer-info.js b/src/get-peer-info.js new file mode 100644 index 00000000..25d74e72 --- /dev/null +++ b/src/get-peer-info.js @@ -0,0 +1,48 @@ +'use strict' + +const PeerId = require('peer-id') +const PeerInfo = require('peer-info') +const multiaddr = require('multiaddr') + +module.exports = (node) => { + /* + * Helper method to check the data type of peer and convert it to PeerInfo + */ + return function (peer, callback) { + let p + // PeerInfo + if (PeerInfo.isPeerInfo(peer)) { + p = peer + // Multiaddr instance or Multiaddr String + } else if (multiaddr.isMultiaddr(peer) || typeof peer === 'string') { + if (typeof peer === 'string') { + peer = multiaddr(peer) + } + + const peerIdB58Str = peer.getPeerId() + if (!peerIdB58Str) { + throw new Error(`peer multiaddr instance or string must include peerId`) + } + + try { + p = node.peerBook.get(peerIdB58Str) + } catch (err) { + p = new PeerInfo(PeerId.createFromB58String(peerIdB58Str)) + } + p.multiaddrs.add(peer) + + // PeerId + } else if (PeerId.isPeerId(peer)) { + const peerIdB58Str = peer.toB58String() + try { + p = node.peerBook.get(peerIdB58Str) + } catch (err) { + return node.peerRouting.findPeer(peer, callback) + } + } else { + return setImmediate(() => callback(new Error('peer type not recognized'))) + } + + setImmediate(() => callback(null, p)) + } +} diff --git a/src/index.js b/src/index.js index 2093fe4a..b6663ae7 100644 --- a/src/index.js +++ b/src/index.js @@ -7,12 +7,14 @@ const setImmediate = require('async/setImmediate') const each = require('async/each') const series = require('async/series') -const Ping = require('libp2p-ping') -const Switch = require('libp2p-switch') -const PeerId = require('peer-id') -const PeerInfo = require('peer-info') const PeerBook = require('peer-book') -const multiaddr = require('multiaddr') +const Switch = require('libp2p-switch') +const Ping = require('libp2p-ping') + +const peerRouting = require('./peer-routing') +const contentRouting = require('./content-routing') +const dht = require('./dht') +const getPeerInfo = require('./get-peer-info') exports = module.exports @@ -76,9 +78,6 @@ class Node extends EventEmitter { }) } - // Mount default protocols - Ping.mount(this.switch) - // dht provided components (peerRouting, contentRouting, dht) if (_modules.DHT) { this._dht = new this.modules.DHT(this.switch, { @@ -87,56 +86,14 @@ class Node extends EventEmitter { }) } - this.peerRouting = { - findPeer: (id, callback) => { - if (!this._dht) { - return callback(new Error('DHT is not available')) - } + this.peerRouting = peerRouting(this) + this.contentRouting = contentRouting(this) + this.dht = dht(this) - this._dht.findPeer(id, callback) - } - } + this._getPeerInfo = getPeerInfo(this) - 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')) - } - - this._dht.getMany(key, nVals, callback) - } - } + // Mount default protocols + Ping.mount(this.switch) } /* @@ -252,18 +209,22 @@ class Node extends EventEmitter { return this._isStarted } - ping (peer, callback) { + dial (peer, callback) { assert(this.isStarted(), NOT_STARTED_ERROR_MESSAGE) - this._getPeerInfo(peer, (err, peerInfo) => { - if (err) { - return callback(err) - } - callback(null, new Ping(this.switch, peerInfo)) + this._getPeerInfo(peer, (err, peerInfo) => { + if (err) { return callback(err) } + + this.switch.dial(peerInfo, (err, conn) => { + if (err) { return callback(err) } + + this.peerBook.put(peerInfo) + callback(null, conn) + }) }) } - dial (peer, protocol, callback) { + dialProtocol (peer, protocol, callback) { assert(this.isStarted(), NOT_STARTED_ERROR_MESSAGE) if (typeof protocol === 'function') { @@ -272,14 +233,10 @@ class Node extends EventEmitter { } this._getPeerInfo(peer, (err, peerInfo) => { - if (err) { - return callback(err) - } + if (err) { return callback(err) } this.switch.dial(peerInfo, protocol, (err, conn) => { - if (err) { - return callback(err) - } + if (err) { return callback(err) } this.peerBook.put(peerInfo) callback(null, conn) }) @@ -290,14 +247,21 @@ class Node extends EventEmitter { assert(this.isStarted(), NOT_STARTED_ERROR_MESSAGE) this._getPeerInfo(peer, (err, peerInfo) => { - if (err) { - return callback(err) - } + if (err) { return callback(err) } this.switch.hangUp(peerInfo, callback) }) } + ping (peer, callback) { + assert(this.isStarted(), NOT_STARTED_ERROR_MESSAGE) + this._getPeerInfo(peer, (err, peerInfo) => { + if (err) { return callback(err) } + + callback(null, new Ping(this.switch, peerInfo)) + }) + } + handle (protocol, handlerFunc, matchFunc) { this.switch.handle(protocol, handlerFunc, matchFunc) } @@ -305,47 +269,6 @@ class Node extends EventEmitter { unhandle (protocol) { this.switch.unhandle(protocol) } - - /* - * Helper method to check the data type of peer and convert it to PeerInfo - */ - _getPeerInfo (peer, callback) { - let p - // PeerInfo - if (PeerInfo.isPeerInfo(peer)) { - p = peer - // Multiaddr instance or Multiaddr String - } else if (multiaddr.isMultiaddr(peer) || typeof peer === 'string') { - if (typeof peer === 'string') { - peer = multiaddr(peer) - } - - const peerIdB58Str = peer.getPeerId() - if (!peerIdB58Str) { - throw new Error(`peer multiaddr instance or string must include peerId`) - } - - try { - p = this.peerBook.get(peerIdB58Str) - } catch (err) { - p = new PeerInfo(PeerId.createFromB58String(peerIdB58Str)) - } - p.multiaddrs.add(peer) - - // PeerId - } else if (PeerId.isPeerId(peer)) { - const peerIdB58Str = peer.toB58String() - try { - p = this.peerBook.get(peerIdB58Str) - } catch (err) { - return this.peerRouting.findPeer(peer, callback) - } - } else { - return setImmediate(() => callback(new Error('peer type not recognized'))) - } - - setImmediate(() => callback(null, p)) - } } module.exports = Node diff --git a/src/peer-routing.js b/src/peer-routing.js new file mode 100644 index 00000000..3a48d075 --- /dev/null +++ b/src/peer-routing.js @@ -0,0 +1,13 @@ +'use strict' + +module.exports = (node) => { + return { + findPeer: (id, callback) => { + if (!node._dht) { + return callback(new Error('DHT is not available')) + } + + node._dht.findPeer(id, callback) + } + } +}