diff --git a/package.json b/package.json index c29728de..f669bfa6 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "protocol-buffers": "^3.2.1", "pull-length-prefixed": "^1.3.0", "pull-stream": "^3.6.0", + "safe-buffer": "^5.1.1", "varint": "^5.0.0", "xor-distance": "^1.0.0" }, @@ -67,17 +68,9 @@ "datastore-level": "^0.4.2", "dirty-chai": "^2.0.1", "interface-connection": "^0.3.2", - "left-pad": "^1.1.3", - "libp2p": "^0.10.1", - "libp2p-mdns": "^0.7.1", "libp2p-multiplex": "^0.4.4", - "libp2p-railing": "^0.5.2", - "libp2p-secio": "^0.6.8", - "libp2p-spdy": "^0.10.6", - "libp2p-swarm": "^0.29.2", + "libp2p-swarm": "^0.30.0", "libp2p-tcp": "^0.10.1", - "libp2p-webrtc-star": "^0.11.0", - "libp2p-websockets": "^0.10.0", "lodash": "^4.17.4", "lodash.random": "^3.2.0", "lodash.range": "^3.2.0", @@ -90,4 +83,4 @@ "Friedel Ziegelmayer ", "Pedro Teixeira " ] -} \ No newline at end of file +} diff --git a/src/index.js b/src/index.js index 80cd0054..53483641 100644 --- a/src/index.js +++ b/src/index.js @@ -18,6 +18,7 @@ const errors = require('./errors') const privateApi = require('./private') const Providers = require('./providers') const Message = require('./message') +const assert = require('assert') /** * A DHT implementation modeled after Kademlia with Coral and S/Kademlia modifications. @@ -28,70 +29,74 @@ class KadDHT { /** * Create a new KadDHT. * - * @param {Libp2p} libp2p - * @param {number} [kBucketSize=20] - * @param {Datastore} [datastore=MemoryDatastore] + * @param {swarm} Swarm + * @param {options} {kBucketSize=20, datastore=MemoryDatastore} */ - constructor (libp2p, kBucketSize, datastore) { + constructor (swarm, options) { + assert(swarm, 'libp2p-kad-dht requires a instance of swarmt a') + options = options || {} + /** - * Local reference to libp2p. + * Local reference to libp2p-swarm. * - * @type {Libp2p} + * @type {Swarm} */ - this.libp2p = libp2p + this.swarm = swarm /** * k-bucket size, defaults to 20. * * @type {number} */ - this.kBucketSize = kBucketSize || 20 + this.kBucketSize = options.kBucketSize || 20 /** - * Number of closest peers to return on kBucket search + * Number of closest peers to return on kBucket search, default 6 * * @type {number} */ - this.ncp = 6 + this.ncp = options.ncp || 6 /** * The routing table. * * @type {RoutingTable} */ - this.routingTable = new RoutingTable(this.self.id, this.kBucketSize) + this.routingTable = new RoutingTable(this.peerInfo.id, this.kBucketSize) /** * Reference to the datastore, uses an in-memory store if none given. * * @type {Datastore} */ - this.datastore = datastore || new MemoryStore() + this.datastore = options.datastore || new MemoryStore() /** * Provider management * * @type {Providers} */ - this.providers = new Providers(this.datastore, this.self.id) - - this.validators = { - pk: libp2pRecord.validator.validators.pk - } + this.providers = new Providers(this.datastore, this.peerInfo.id) - this.selectors = { - pk: libp2pRecord.selection.selectors.pk - } + this.validators = { pk: libp2pRecord.validator.validators.pk } + this.selectors = { pk: libp2pRecord.selection.selectors.pk } - this.network = new Network(this, this.libp2p) + this.network = new Network(this) - this._log = utils.logger(this.self.id) + this._log = utils.logger(this.peerInfo.id) // Inject private apis so we don't clutter up this file const pa = privateApi(this) - Object.keys(pa).forEach((name) => { - this[name] = pa[name] - }) + Object.keys(pa).forEach((name) => { this[name] = pa[name] }) + } + + /** + * Is this DHT running. + * + * @type {bool} + */ + get isStarted () { + return this._running } /** @@ -118,29 +123,17 @@ class KadDHT { this.network.stop(callback) } - /** - * Alias to the peerbook from libp2p - */ - get peerBook () { - return this.libp2p.peerBook - } - - /** - * Is this DHT running. - * - * @type {bool} - */ - get isRunning () { - return this._running - } - /** * Local peer (yourself) * * @type {PeerInfo} */ - get self () { - return this.libp2p.peerInfo + get peerInfo () { + return this.swarm._peerInfo + } + + get peerBook () { + return this.swarm._peerBook } /** @@ -205,7 +198,7 @@ class KadDHT { } waterfall([ - (cb) => utils.createPutRecord(key, value, this.self.id, sign, cb), + (cb) => utils.createPutRecord(key, value, this.peerInfo.id, sign, cb), (rec, cb) => waterfall([ (cb) => this._putLocal(key, rec, cb), (cb) => this.getClosestPeers(key, cb), @@ -266,7 +259,7 @@ class KadDHT { if (err == null) { vals.push({ val: localRec.value, - from: this.self.id + from: this.peerInfo.id }) } @@ -342,7 +335,7 @@ class KadDHT { // local check let info if (this.peerBook.has(peer)) { - info = this.libp2p.peerBook.get(peer) + info = this.peerBook.get(peer) if (info && info.id.pubKey) { this._log('getPublicKey: found local copy') @@ -355,7 +348,7 @@ class KadDHT { this._getPublicKeyFromNode(peer, (err, pk) => { if (!err) { info.id = new PeerId(peer.id, null, pk) - this.libp2p.peerBook.put(info) + this.peerBook.put(info) return callback(null, pk) } @@ -369,7 +362,7 @@ class KadDHT { const pk = crypto.unmarshalPublicKey(value) info.id = new PeerId(peer, null, pk) - this.libp2p.peerBook.put(info) + this.peerBook.put(info) callback(null, pk) }) @@ -389,7 +382,7 @@ class KadDHT { this._log('provide: %s', key.toBaseEncodedString()) waterfall([ - (cb) => this.providers.addProvider(key, this.self.id, cb), + (cb) => this.providers.addProvider(key, this.peerInfo.id, cb), (cb) => this.getClosestPeers(key.buffer, cb), (peers, cb) => { const msg = new Message(Message.TYPES.ADD_PROVIDER, key.buffer, 0) diff --git a/src/network.js b/src/network.js index 6af6b4c8..2e989501 100644 --- a/src/network.js +++ b/src/network.js @@ -17,17 +17,15 @@ class Network { /** * Create a new network. * - * @param {DHT} dht - * @param {Libp2p} libp2p + * @param {KadDHT} self */ - constructor (dht, libp2p) { - this.dht = dht - this.libp2p = libp2p + constructor (self) { + this.dht = self this.readMessageTimeout = c.READ_MESSAGE_TIMEOUT - this._log = utils.logger(this.dht.self.id, 'net') + this._log = utils.logger(this.dht.peerInfo.id, 'net') this._rpc = rpc(this.dht) this._onPeerConnected = this._onPeerConnected.bind(this) - this._online = false + this._running = false } /** @@ -43,17 +41,18 @@ class Network { return cb(new Error('Network is already running')) } - if (!this.dht.isRunning || !this.dht.libp2p.isStarted()) { + // TODO add a way to check if swarm has started or not + if (!this.dht.isStarted) { return cb(new Error('Can not start network')) } - this._online = true + this._running = true // handle incoming connections - this.libp2p.swarm.handle(c.PROTOCOL_DHT, this._rpc) + this.dht.swarm.handle(c.PROTOCOL_DHT, this._rpc) // handle new connections - this.libp2p.on('peer:connect', this._onPeerConnected) + this.dht.swarm.on('peer-mux-established', this._onPeerConnected) cb() } @@ -67,13 +66,13 @@ class Network { stop (callback) { const cb = (err) => setImmediate(() => callback(err)) - if (!this.isOnline) { + if (!this.dht.isStarted && !this.isStarted) { return cb(new Error('Network is already stopped')) } - this._online = false - this.libp2p.removeListener('peer:connect', this._onPeerConnected) + this._running = false + this.dht.swarm.removeListener('peer-mux-established', this._onPeerConnected) - this.libp2p.swarm.unhandle(c.PROTOCOL_DHT) + this.dht.swarm.unhandle(c.PROTOCOL_DHT) cb() } @@ -82,8 +81,8 @@ class Network { * * @type {bool} */ - get isOnline () { - return this._online + get isStarted () { + return this._running } /** @@ -92,7 +91,8 @@ class Network { * @type {bool} */ get isConnected () { - return this.dht.libp2p.isStarted() && this.dht.isRunning && this.isOnline + // TODO add a way to check if swarm has started or not + return this.dht.isStarted && this.isStarted } /** @@ -107,7 +107,7 @@ class Network { return this._log.error('Network is offline') } - this.libp2p.dial(peer, c.PROTOCOL_DHT, (err, conn) => { + this.dht.swarm.dial(peer, c.PROTOCOL_DHT, (err, conn) => { if (err) { return this._log('%s does not support protocol: %s', peer.id.toB58String(), c.PROTOCOL_DHT) } @@ -140,7 +140,7 @@ class Network { } this._log('sending to: %s', to.toB58String()) - this.dht.libp2p.dial(to, c.PROTOCOL_DHT, (err, conn) => { + this.dht.swarm.dial(to, c.PROTOCOL_DHT, (err, conn) => { if (err) { return callback(err) } @@ -159,12 +159,12 @@ class Network { */ sendMessage (to, msg, callback) { if (!this.isConnected) { - return callback(new Error('Network is offline')) + return setImmediate(() => callback(new Error('Network is offline'))) } this._log('sending to: %s', to.toB58String()) - this.dht.libp2p.dial(to, c.PROTOCOL_DHT, (err, conn) => { + this.dht.swarm.dial(to, c.PROTOCOL_DHT, (err, conn) => { if (err) { return callback(err) } diff --git a/src/private.js b/src/private.js index 768fb7f1..0c99a971 100644 --- a/src/private.js +++ b/src/private.js @@ -128,7 +128,7 @@ module.exports = (dht) => ({ // 5. check validity // 5. if: we are the author, all good - if (record.author.isEqual(dht.self.id)) { + if (record.author.isEqual(dht.peerInfo.id)) { return callback(null, record) } @@ -226,7 +226,7 @@ module.exports = (dht) => ({ * @private */ _isSelf (other) { - return other && dht.self.id.id.equals(other.id) + return other && dht.peerInfo.id.id.equals(other.id) }, /** * Ask peer `peer` if they know where the peer with id `target` is. @@ -308,7 +308,7 @@ module.exports = (dht) => ({ // Send out correction record waterfall([ - (cb) => utils.createPutRecord(key, best, dht.self.id, true, cb), + (cb) => utils.createPutRecord(key, best, dht.peerInfo.id, true, cb), (fixupRec, cb) => each(vals, (v, cb) => { // no need to do anything if (v.val.equals(best)) { @@ -523,7 +523,7 @@ module.exports = (dht) => ({ (cb) => dht._findProvidersSingle(peer, key, cb), (msg, cb) => { const provs = msg.providerPeers - dht._log('(%s) found %s provider entries', dht.self.id.toB58String(), provs.length) + dht._log('(%s) found %s provider entries', dht.peerInfo.id.toB58String(), provs.length) provs.forEach((prov) => { out.push(dht.peerBook.put(prov)) diff --git a/src/query.js b/src/query.js index 0c6003b8..0d784f9a 100644 --- a/src/query.js +++ b/src/query.js @@ -25,7 +25,7 @@ class Query { this.key = key this.query = query this.concurrency = c.ALPHA - this._log = utils.logger(this.dht.self.id, 'query:' + key.toString()) + this._log = utils.logger(this.dht.peerInfo.id, 'query:' + key.toString()) } /** diff --git a/src/rpc/handlers/add-provider.js b/src/rpc/handlers/add-provider.js index b14bdd90..62ef8fbd 100644 --- a/src/rpc/handlers/add-provider.js +++ b/src/rpc/handlers/add-provider.js @@ -5,7 +5,7 @@ const CID = require('cids') const utils = require('../../utils') module.exports = (dht) => { - const log = utils.logger(dht.self.id, 'rpc:add-provider') + const log = utils.logger(dht.peerInfo.id, 'rpc:add-provider') /** * Process `AddProvider` DHT messages. * diff --git a/src/rpc/handlers/find-node.js b/src/rpc/handlers/find-node.js index db460962..a0829a37 100644 --- a/src/rpc/handlers/find-node.js +++ b/src/rpc/handlers/find-node.js @@ -4,9 +4,10 @@ const waterfall = require('async/waterfall') const Message = require('../../message') const utils = require('../../utils') +const Buffer = require('safe-buffer').Buffer module.exports = (dht) => { - const log = utils.logger(dht.self.id, 'rpc:find-node') + const log = utils.logger(dht.peerInfo.id, 'rpc:find-node') /** * Process `FindNode` DHT messages. @@ -21,14 +22,14 @@ module.exports = (dht) => { waterfall([ (cb) => { - if (msg.key.equals(dht.self.id.id)) { - return cb(null, [dht.self]) + if (msg.key.equals(dht.peerInfo.id.id)) { + return cb(null, [dht.peerInfo]) } dht._betterPeersToQuery(msg, peer, cb) }, (closer, cb) => { - const response = new Message(msg.type, new Buffer(0), msg.clusterLevel) + const response = new Message(msg.type, Buffer.alloc(0), msg.clusterLevel) if (closer.length > 0) { response.closerPeers = closer diff --git a/src/rpc/handlers/get-providers.js b/src/rpc/handlers/get-providers.js index 15419890..fbb590f7 100644 --- a/src/rpc/handlers/get-providers.js +++ b/src/rpc/handlers/get-providers.js @@ -8,7 +8,7 @@ const Message = require('../../message') const utils = require('../../utils') module.exports = (dht) => { - const log = utils.logger(dht.self.id, 'rpc:get-providers') + const log = utils.logger(dht.peerInfo.id, 'rpc:get-providers') /** * Process `GetProviders` DHT messages. @@ -56,7 +56,7 @@ module.exports = (dht) => { }) if (has) { - providers.push(dht.self) + providers.push(dht.peerInfo) } const response = new Message(msg.type, msg.key, msg.clusterLevel) diff --git a/src/rpc/handlers/get-value.js b/src/rpc/handlers/get-value.js index ce9f7127..e4e5e355 100644 --- a/src/rpc/handlers/get-value.js +++ b/src/rpc/handlers/get-value.js @@ -7,7 +7,7 @@ const Message = require('../../message') const utils = require('../../utils') module.exports = (dht) => { - const log = utils.logger(dht.self.id, 'rpc:get-value') + const log = utils.logger(dht.peerInfo.id, 'rpc:get-value') /** * Process `GetValue` DHT messages. @@ -34,14 +34,14 @@ module.exports = (dht) => { let info if (dht._isSelf(id)) { - info = dht.self + info = dht.peerInfo } else if (dht.peerBook.has(id)) { info = dht.peerBook.get(id) } if (info && info.id.pubKey) { log('returning found public key') - response.record = new Record(key, info.id.pubKey.bytes, dht.self.id) + response.record = new Record(key, info.id.pubKey.bytes, dht.peerInfo.id) return callback(null, response) } } diff --git a/src/rpc/handlers/ping.js b/src/rpc/handlers/ping.js index 831b26f2..a3430393 100644 --- a/src/rpc/handlers/ping.js +++ b/src/rpc/handlers/ping.js @@ -3,7 +3,7 @@ const utils = require('../../utils') module.exports = (dht) => { - const log = utils.logger(dht.self.id, 'rpc:ping') + const log = utils.logger(dht.peerInfo.id, 'rpc:ping') /** * Process `Ping` DHT messages. diff --git a/src/rpc/handlers/put-value.js b/src/rpc/handlers/put-value.js index 559cc397..e339f758 100644 --- a/src/rpc/handlers/put-value.js +++ b/src/rpc/handlers/put-value.js @@ -3,7 +3,7 @@ const utils = require('../../utils') module.exports = (dht) => { - const log = utils.logger(dht.self.id, 'rpc:put-value') + const log = utils.logger(dht.peerInfo.id, 'rpc:put-value') /** * Process `PutValue` DHT messages. diff --git a/src/rpc/index.js b/src/rpc/index.js index 3b845457..a7359e1d 100644 --- a/src/rpc/index.js +++ b/src/rpc/index.js @@ -9,7 +9,7 @@ const utils = require('../utils') const c = require('../constants') module.exports = (dht) => { - const log = utils.logger(dht.self.id, 'rpc') + const log = utils.logger(dht.peerInfo.id, 'rpc') const getMessageHandler = handlers(dht) /** diff --git a/test/browser-bundle.js b/test/browser-bundle.js deleted file mode 100644 index 1db93dea..00000000 --- a/test/browser-bundle.js +++ /dev/null @@ -1,67 +0,0 @@ -'use strict' - -const WS = require('libp2p-websockets') -const WebRTCStar = require('libp2p-webrtc-star') -const spdy = require('libp2p-spdy') -const multiplex = require('libp2p-multiplex') -const secio = require('libp2p-secio') -const Railing = require('libp2p-railing') -const libp2p = require('libp2p') - -function mapMuxers (list) { - return list.map((pref) => { - if (typeof pref !== 'string') { - return pref - } - switch (pref.trim().toLowerCase()) { - case 'spdy': - return spdy - case 'multiplex': - return multiplex - default: - throw new Error(pref + ' muxer not available') - } - }) -} - -function getMuxers (options) { - if (options) { - return mapMuxers(options) - } else { - return [multiplex, spdy] - } -} - -class Node extends libp2p { - constructor (peerInfo, peerBook, options) { - options = options || {} - const webRTCStar = new WebRTCStar() - - const modules = { - transport: [ - new WS(), - webRTCStar - ], - connection: { - muxer: getMuxers(options.muxer), - crypto: [ - secio - ] - }, - discovery: [] - } - - if (options.webRTCStar) { - modules.discovery.push(webRTCStar.discovery) - } - - if (options.bootstrap) { - const r = new Railing(options.bootstrap) - modules.discovery.push(r) - } - - super(modules, peerInfo, peerBook, options) - } -} - -module.exports = Node diff --git a/test/browser.js b/test/browser.js deleted file mode 100644 index ccacec30..00000000 --- a/test/browser.js +++ /dev/null @@ -1 +0,0 @@ -'use strict' diff --git a/test/index.spec.js b/test/kad-dht.spec.js similarity index 71% rename from test/index.spec.js rename to test/kad-dht.spec.js index bdec72f4..42c1d0d4 100644 --- a/test/index.spec.js +++ b/test/kad-dht.spec.js @@ -11,23 +11,26 @@ const timeout = require('async/timeout') const retry = require('async/retry') const each = require('async/each') const waterfall = require('async/waterfall') -const Record = require('libp2p-record').Record -const Libp2p = require('./nodejs-bundle') const random = require('lodash.random') const Buffer = require('safe-buffer').Buffer const _ = require('lodash') +const Record = require('libp2p-record').Record +const PeerBook = require('peer-book') +const Swarm = require('libp2p-swarm') +const TCP = require('libp2p-tcp') +const Multiplex = require('libp2p-multiplex') const KadDHT = require('../src') -const utils = require('../src/utils') +const kadUtils = require('../src/utils') const c = require('../src/constants') -const util = require('./util') -const makePeers = util.makePeers -const setupDHT = util.setupDHT -const makeValues = util.makeValues +const utils = require('./utils') +const makePeers = utils.makePeers +const setupDHT = utils.setupDHT +const makeValues = utils.makeValues -describe('DHT', () => { - let infos +describe('KadDHT', () => { + let peerInfos let values before((done) => { @@ -36,21 +39,24 @@ describe('DHT', () => { (cb) => makeValues(20, cb) ], (err, res) => { expect(err).to.not.exist() - infos = res[0] + peerInfos = res[0] values = res[1] done() }) }) // Give the nodes some time to finish request - afterEach((done) => setTimeout(() => util.teardown(done), 100)) + afterEach((done) => setTimeout(() => utils.teardown(done), 100)) it('create', () => { - const libp2p = new Libp2p(infos[0]) - const dht = new KadDHT(libp2p, 5) - - expect(dht).to.have.property('self').eql(infos[0]) - expect(dht).to.have.property('libp2p').eql(libp2p) + const swarm = new Swarm(peerInfos[0], new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() + const dht = new KadDHT(swarm, { kBucketSize: 5 }) + + expect(dht).to.have.property('peerInfo').eql(peerInfos[0]) + expect(dht).to.have.property('swarm').eql(swarm) expect(dht).to.have.property('kBucketSize', 5) expect(dht).to.have.property('routingTable') }) @@ -171,14 +177,14 @@ describe('DHT', () => { const dhtA = dhts[0] const dhtB = dhts[1] - const peerA = dhtA.self - const peerB = dhtB.self + const peerA = dhtA.peerInfo + const peerB = dhtB.peerInfo dhtA.peerBook.put(peerB) dhtB.peerBook.put(peerA) parallel([ - (cb) => dhtA.libp2p.dial(peerB.id, cb), - (cb) => dhtB.libp2p.dial(peerA.id, cb) + (cb) => dhtA.swarm.dial(peerB.id, cb), + (cb) => dhtB.swarm.dial(peerA.id, cb) ], done) }) }) @@ -190,7 +196,7 @@ describe('DHT', () => { const guy = dhts[0] const others = dhts.slice(1) - const val = new Buffer('foobar') + const val = Buffer.from('foobar') series([ (cb) => times(20, (i, cb) => { @@ -202,7 +208,7 @@ describe('DHT', () => { (cb) => times(20, (i, cb) => { connect(guy, others[i], cb) }, cb), - (cb) => utils.convertBuffer(val, (err, rtval) => { + (cb) => kadUtils.convertBuffer(val, (err, rtval) => { expect(err).to.not.exist() const rtablePeers = guy.routingTable.closestPeers(rtval, c.ALPHA) expect(rtablePeers).to.have.length(3) @@ -217,20 +223,19 @@ describe('DHT', () => { series([ (cb) => guy.getClosestPeers(val, cb), - (cb) => utils.sortClosestPeers(ids.slice(1), rtval, cb) + (cb) => kadUtils.sortClosestPeers(ids.slice(1), rtval, cb) ], (err, res) => { expect(err).to.not.exist() const out = res[0] const actualClosest = res[1] - expect( - out.filter((p) => !rtableSet[p.toB58String()]) - ).to.not.be.empty() + expect(out.filter((p) => !rtableSet[p.toB58String()])) + .to.not.be.empty() expect(out).to.have.length(20) const exp = actualClosest.slice(0, 20) - utils.sortClosestPeers(out, rtval, (err, got) => { + kadUtils.sortClosestPeers(out, rtval, (err, got) => { expect(err).to.not.exist() expect(countDiffPeers(exp, got)).to.eql(0) @@ -264,10 +269,10 @@ describe('DHT', () => { it('already known', (done) => { setupDHTs(2, (err, dhts, addrs, ids) => { expect(err).to.not.exist() - dhts[0].peerBook.put(dhts[1].self) + dhts[0].peerBook.put(dhts[1].peerInfo) dhts[0].getPublicKey(ids[1], (err, key) => { expect(err).to.not.exist() - expect(key).to.be.eql(dhts[1].self.id.pubKey) + expect(key).to.be.eql(dhts[1].peerInfo.id.pubKey) done() }) }) @@ -288,7 +293,7 @@ describe('DHT', () => { }, (key, cb) => { expect( - key.equals(dhts[1].self.id.pubKey) + key.equals(dhts[1].peerInfo.id.pubKey) ).to.eql( true ) @@ -300,50 +305,63 @@ describe('DHT', () => { }) it('_nearestPeersToQuery', (done) => { - const libp2p = new Libp2p(infos[0]) - const dht = new KadDHT(libp2p) + const swarm = new Swarm(peerInfos[0], new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() + const dht = new KadDHT(swarm) - dht.peerBook.put(infos[1]) + dht.peerBook.put(peerInfos[1]) series([ - (cb) => dht._add(infos[1], cb), + (cb) => dht._add(peerInfos[1], cb), (cb) => dht._nearestPeersToQuery({key: 'hello'}, cb) ], (err, res) => { expect(err).to.not.exist() - expect(res[1]).to.be.eql([infos[1]]) + expect(res[1]).to.be.eql([peerInfos[1]]) done() }) }) it('_betterPeersToQuery', (done) => { - const libp2p = new Libp2p(infos[0]) - const dht = new KadDHT(libp2p) + const swarm = new Swarm(peerInfos[0], new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() + const dht = new KadDHT(swarm) - dht.peerBook.put(infos[1]) - dht.peerBook.put(infos[2]) + dht.peerBook.put(peerInfos[1]) + dht.peerBook.put(peerInfos[2]) series([ - (cb) => dht._add(infos[1], cb), - (cb) => dht._add(infos[2], cb), - (cb) => dht._betterPeersToQuery({key: 'hello'}, infos[1], cb) + (cb) => dht._add(peerInfos[1], cb), + (cb) => dht._add(peerInfos[2], cb), + (cb) => dht._betterPeersToQuery({key: 'hello'}, peerInfos[1], cb) ], (err, res) => { expect(err).to.not.exist() - expect(res[2]).to.be.eql([infos[2]]) + expect(res[2]).to.be.eql([peerInfos[2]]) done() }) }) describe('_verifyRecordLocally', () => { it('invalid record (missing public key)', (done) => { - const libp2p = new Libp2p(infos[0]) - const dht = new KadDHT(libp2p) + const swarm = new Swarm(peerInfos[0], new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() + const dht = new KadDHT(swarm) // Not putting the peer info into the peerbook - // dht.peerBook.put(infos[1]) + // dht.peerBook.put(peerInfos[1]) - const record = new Record(new Buffer('hello'), new Buffer('world'), infos[1].id) + const record = new Record( + Buffer.from('hello'), + Buffer.from('world'), + peerInfos[1].id + ) waterfall([ - (cb) => record.serializeSigned(infos[1].id.privKey, cb), + (cb) => record.serializeSigned(peerInfos[1].id.privKey, cb), (enc, cb) => dht._verifyRecordLocally(Record.deserialize(enc), (err) => { expect(err).to.match(/Missing public key/) cb() @@ -352,26 +370,40 @@ describe('DHT', () => { }) it('valid record - signed', (done) => { - const libp2p = new Libp2p(infos[0]) - const dht = new KadDHT(libp2p) + const swarm = new Swarm(peerInfos[0], new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() + const dht = new KadDHT(swarm) - dht.peerBook.put(infos[1]) + dht.peerBook.put(peerInfos[1]) - const record = new Record(new Buffer('hello'), new Buffer('world'), infos[1].id) + const record = new Record( + Buffer.from('hello'), + Buffer.from('world'), + peerInfos[1].id + ) waterfall([ - (cb) => record.serializeSigned(infos[1].id.privKey, cb), + (cb) => record.serializeSigned(peerInfos[1].id.privKey, cb), (enc, cb) => dht._verifyRecordLocally(Record.deserialize(enc), cb) ], done) }) it('valid record - not signed', (done) => { - const libp2p = new Libp2p(infos[0]) - const dht = new KadDHT(libp2p) + const swarm = new Swarm(peerInfos[0], new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() + const dht = new KadDHT(swarm) - dht.peerBook.put(infos[1]) + dht.peerBook.put(peerInfos[1]) - const record = new Record(new Buffer('hello'), new Buffer('world'), infos[1].id) + const record = new Record( + Buffer.from('hello'), + Buffer.from('world'), + peerInfos[1].id + ) waterfall([ (cb) => cb(null, record.serialize()), @@ -386,21 +418,21 @@ function setupDHTs (n, callback) { if (err) { return callback(err) } - callback(null, dhts, dhts.map((d) => d.self.multiaddrs.toArray()[0]), dhts.map((d) => d.self.id)) + callback(null, dhts, dhts.map((d) => d.peerInfo.multiaddrs.toArray()[0]), dhts.map((d) => d.peerInfo.id)) }) } // connect two dhts function connectNoSync (a, b, callback) { - const target = _.cloneDeep(b.self) + const target = _.cloneDeep(b.peerInfo) target.id._pubKey = target.id.pubKey target.id._privKey = null - a.libp2p.dial(target, callback) + a.swarm.dial(target, callback) } function find (a, b, cb) { retry({ times: 50, interval: 100 }, (cb) => { - a.routingTable.find(b.self.id, (err, match) => { + a.routingTable.find(b.peerInfo.id, (err, match) => { if (err) { return cb(err) } @@ -409,11 +441,8 @@ function find (a, b, cb) { } try { - expect( - a.peerBook.get(b.self).multiaddrs.toArray()[0].toString() - ).to.eql( - b.self.multiaddrs.toArray()[0].toString() - ) + expect(a.peerBook.get(b.peerInfo).multiaddrs.toArray()[0].toString()) + .to.eql(b.peerInfo.multiaddrs.toArray()[0].toString()) } catch (err) { return cb(err) } @@ -441,10 +470,7 @@ function bootstrap (dhts) { function waitForWellFormedTables (dhts, minPeers, avgPeers, maxTimeout, callback) { timeout((cb) => { - retry({ - times: 50, - interval: 200 - }, (cb) => { + retry({ times: 50, interval: 200 }, (cb) => { let totalPeers = 0 const ready = dhts.map((dht) => { diff --git a/test/limited-peer-list.spec.js b/test/limited-peer-list.spec.js index 2f642f19..f5019862 100644 --- a/test/limited-peer-list.spec.js +++ b/test/limited-peer-list.spec.js @@ -7,7 +7,7 @@ const expect = chai.expect const LimitedPeerList = require('../src/limited-peer-list') -const makePeers = require('./util').makePeers +const makePeers = require('./utils').makePeers describe('LimitedPeerList', () => { let peers diff --git a/test/network.spec.js b/test/network.spec.js index b4fb2b82..2a6e50d5 100644 --- a/test/network.spec.js +++ b/test/network.spec.js @@ -4,36 +4,40 @@ const chai = require('chai') chai.use(require('dirty-chai')) const expect = chai.expect -const Libp2p = require('./nodejs-bundle') const Connection = require('interface-connection').Connection const pull = require('pull-stream') const lp = require('pull-length-prefixed') const series = require('async/series') const Buffer = require('safe-buffer').Buffer +const PeerBook = require('peer-book') +const Swarm = require('libp2p-swarm') +const TCP = require('libp2p-tcp') +const Multiplex = require('libp2p-multiplex') -const DHT = require('../src') +const KadDHT = require('../src') const Message = require('../src/message') -const makePeers = require('./util').makePeers +const makePeers = require('./utils').makePeers describe('Network', () => { - let libp2p - let network let dht - let infos + let peerInfos before((done) => { - makePeers(3, (err, peers) => { + makePeers(3, (err, result) => { if (err) { return done(err) } - infos = peers - libp2p = new Libp2p(infos[0]) - dht = new DHT(libp2p) - network = dht.network + peerInfos = result + const swarm = new Swarm(peerInfos[0], new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() + dht = new KadDHT(swarm) + series([ - (cb) => libp2p.start(cb), + (cb) => swarm.listen(cb), (cb) => dht.start(cb) ], done) }) @@ -41,7 +45,7 @@ describe('Network', () => { after((done) => series([ (cb) => dht.stop(cb), - (cb) => libp2p.stop(cb) + (cb) => dht.swarm.close(cb) ], done)) describe('sendRequest', () => { @@ -56,7 +60,7 @@ describe('Network', () => { const msg = new Message(Message.TYPES.PING, Buffer.from('hello'), 0) // mock it - libp2p.dial = (peer, protocol, callback) => { + dht.swarm.dial = (peer, protocol, callback) => { expect(protocol).to.eql('/ipfs/kad/1.0.0') const msg = new Message(Message.TYPES.FIND_NODE, Buffer.from('world'), 0) @@ -78,7 +82,7 @@ describe('Network', () => { callback(null, conn) } - network.sendRequest(infos[0].id, msg, (err, response) => { + dht.network.sendRequest(peerInfos[0].id, msg, (err, response) => { expect(err).to.not.exist() expect(response.type).to.eql(Message.TYPES.FIND_NODE) @@ -97,7 +101,7 @@ describe('Network', () => { const msg = new Message(Message.TYPES.PING, Buffer.from('hello'), 0) // mock it - libp2p.dial = (peer, protocol, callback) => { + dht.swarm.dial = (peer, protocol, callback) => { expect(protocol).to.eql('/ipfs/kad/1.0.0') const rawConn = { // hanging @@ -115,9 +119,9 @@ describe('Network', () => { callback(null, conn) } - network.readMessageTimeout = 100 + dht.network.readMessageTimeout = 100 - network.sendRequest(infos[0].id, msg, (err, response) => { + dht.network.sendRequest(peerInfos[0].id, msg, (err, response) => { expect(err).to.exist() expect(err.message).to.match(/timed out/) diff --git a/test/nodejs-bundle.js b/test/nodejs-bundle.js deleted file mode 100644 index 620efe6b..00000000 --- a/test/nodejs-bundle.js +++ /dev/null @@ -1,80 +0,0 @@ -'use strict' - -const TCP = require('libp2p-tcp') -const MulticastDNS = require('libp2p-mdns') -const WS = require('libp2p-websockets') -const Railing = require('libp2p-railing') -const spdy = require('libp2p-spdy') -const KadDHT = require('..') -const multiplex = require('libp2p-multiplex') -const secio = require('libp2p-secio') -const libp2p = require('libp2p') - -function mapMuxers (list) { - return list.map((pref) => { - if (typeof pref !== 'string') { - return pref - } - switch (pref.trim().toLowerCase()) { - case 'spdy': return spdy - case 'multiplex': return multiplex - default: - throw new Error(pref + ' muxer not available') - } - }) -} - -function getMuxers (muxers) { - const muxerPrefs = process.env.LIBP2P_MUXER - if (muxerPrefs && !muxers) { - return mapMuxers(muxerPrefs.split(',')) - } else if (muxers) { - return mapMuxers(muxers) - } else { - return [multiplex, spdy] - } -} - -class Node extends libp2p { - constructor (peerInfo, peerBook, options) { - options = options || {} - - const modules = { - transport: [ - new TCP(), - new WS() - ], - connection: { - muxer: getMuxers(options.muxer), - crypto: [ secio ] - }, - discovery: [] - } - - if (options.dht) { - modules.DHT = KadDHT - } - - if (options.mdns) { - const mdns = new MulticastDNS(peerInfo, 'ipfs.local') - modules.discovery.push(mdns) - } - - if (options.bootstrap) { - const r = new Railing(options.bootstrap) - modules.discovery.push(r) - } - - if (options.modules && options.modules.transport) { - options.modules.transport.forEach((t) => modules.transport.push(t)) - } - - if (options.modules && options.modules.discovery) { - options.modules.discovery.forEach((d) => modules.discovery.push(d)) - } - - super(modules, peerInfo, peerBook, options) - } -} - -module.exports = Node diff --git a/test/peer-list.spec.js b/test/peer-list.spec.js index ddd4cad2..77708dcd 100644 --- a/test/peer-list.spec.js +++ b/test/peer-list.spec.js @@ -7,7 +7,7 @@ const expect = chai.expect const PeerList = require('../src/peer-list') -const makePeers = require('./util').makePeers +const makePeers = require('./utils').makePeers describe('PeerList', () => { let peers diff --git a/test/providers.spec.js b/test/providers.spec.js index bd8e37af..6614141a 100644 --- a/test/providers.spec.js +++ b/test/providers.spec.js @@ -17,10 +17,11 @@ const range = require('lodash.range') const LevelStore = require('datastore-level') const path = require('path') const os = require('os') +const Buffer = require('safe-buffer').Buffer const Providers = require('../src/providers') -const util = require('./util') +const util = require('./utils') describe('Providers', () => { let infos @@ -61,9 +62,7 @@ describe('Providers', () => { waterfall([ (cb) => map( range(100), - (i, cb) => { - multihashing(new Buffer(`hello ${i}`), 'sha2-256', cb) - }, + (i, cb) => multihashing(Buffer.from(`hello ${i}`), 'sha2-256', cb), cb ), (hashes, cb) => { diff --git a/test/query.spec.js b/test/query.spec.js index 2567a2c4..c0fa526c 100644 --- a/test/query.spec.js +++ b/test/query.spec.js @@ -4,59 +4,62 @@ const chai = require('chai') chai.use(require('dirty-chai')) const expect = chai.expect -const Libp2p = require('./nodejs-bundle') const Buffer = require('safe-buffer').Buffer +const PeerBook = require('peer-book') +const Swarm = require('libp2p-swarm') +const TCP = require('libp2p-tcp') +const Multiplex = require('libp2p-multiplex') const DHT = require('../src') const Query = require('../src/query') -const makePeers = require('./util').makePeers +const makePeers = require('./utils').makePeers describe('Query', () => { - let infos - let libp2p + let peerInfos let dht before((done) => { - makePeers(3, (err, peers) => { + makePeers(3, (err, result) => { if (err) { return done(err) } - infos = peers - libp2p = new Libp2p(infos[0]) - dht = new DHT(libp2p) + peerInfos = result + const swarm = new Swarm(peerInfos[0], new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() + dht = new DHT(swarm) done() }) }) it('simple run', (done) => { - const peer = infos[0] + const peer = peerInfos[0] // mock this so we can dial non existing peers - libp2p.dial = (peer, callback) => { - callback() - } + dht.swarm.dial = (peer, callback) => callback() let i = 0 const query = (p, cb) => { if (i++ === 1) { - expect(p.id).to.eql(infos[2].id.id) + expect(p.id).to.eql(peerInfos[2].id.id) return cb(null, { value: Buffer.from('cool'), success: true }) } - expect(p.id).to.eql(infos[1].id.id) + expect(p.id).to.eql(peerInfos[1].id.id) cb(null, { - closerPeers: [infos[2]] + closerPeers: [peerInfos[2]] }) } const q = new Query(dht, peer.id.id, query) - q.run([infos[1].id], (err, res) => { + q.run([peerInfos[1].id], (err, res) => { expect(err).to.not.exist() expect(res.value).to.eql(Buffer.from('cool')) expect(res.success).to.eql(true) @@ -66,19 +69,15 @@ describe('Query', () => { }) it('returns an error if all queries error', (done) => { - const peer = infos[0] + const peer = peerInfos[0] // mock this so we can dial non existing peers - libp2p.dial = (peer, callback) => { - callback() - } + dht.swarm.dial = (peer, callback) => callback() - const query = (p, cb) => { - cb(new Error('fail')) - } + const query = (p, cb) => cb(new Error('fail')) const q = new Query(dht, peer.id.id, query) - q.run([infos[1].id], (err, res) => { + q.run([peerInfos[1].id], (err, res) => { expect(err).to.exist() expect(err.message).to.eql('fail') done() @@ -86,21 +85,19 @@ describe('Query', () => { }) it('only closerPeers', (done) => { - const peer = infos[0] + const peer = peerInfos[0] // mock this so we can dial non existing peers - libp2p.dial = (peer, callback) => { - callback() - } + dht.swarm.dial = (peer, callback) => callback() const query = (p, cb) => { cb(null, { - closerPeers: [infos[2]] + closerPeers: [peerInfos[2]] }) } const q = new Query(dht, peer.id.id, query) - q.run([infos[1].id], (err, res) => { + q.run([peerInfos[1].id], (err, res) => { expect(err).to.not.exist() expect(res.finalSet.size).to.eql(2) done() diff --git a/test/rpc/handlers/add-provider.spec.js b/test/rpc/handlers/add-provider.spec.js index 082623e8..0360a46e 100644 --- a/test/rpc/handlers/add-provider.spec.js +++ b/test/rpc/handlers/add-provider.spec.js @@ -8,12 +8,13 @@ const expect = chai.expect const parallel = require('async/parallel') const waterfall = require('async/waterfall') const _ = require('lodash') +const Buffer = require('safe-buffer').Buffer const Message = require('../../../src/message') const handler = require('../../../src/rpc/handlers/add-provider') -const util = require('../../util') +const util = require('../../utils') describe('rpc - handlers - AddProvider', () => { let peers @@ -46,13 +47,13 @@ describe('rpc - handlers - AddProvider', () => { describe('invalid messages', () => { const tests = [{ - message: new Message(Message.TYPES.ADD_PROVIDER, new Buffer(0), 0), + message: new Message(Message.TYPES.ADD_PROVIDER, Buffer.alloc(0), 0), error: /Missing key/ }, { - message: new Message(Message.TYPES.ADD_PROVIDER, new Buffer(0), 0), + message: new Message(Message.TYPES.ADD_PROVIDER, Buffer.alloc(0), 0), error: /Missing key/ }, { - message: new Message(Message.TYPES.ADD_PROVIDER, new Buffer('hello world'), 0), + message: new Message(Message.TYPES.ADD_PROVIDER, Buffer.from('hello world'), 0), error: /Invalid CID/ }] diff --git a/test/rpc/handlers/find-node.spec.js b/test/rpc/handlers/find-node.spec.js index aecaa395..16448dda 100644 --- a/test/rpc/handlers/find-node.spec.js +++ b/test/rpc/handlers/find-node.spec.js @@ -5,10 +5,11 @@ const chai = require('chai') chai.use(require('dirty-chai')) const expect = chai.expect const waterfall = require('async/waterfall') +const Buffer = require('safe-buffer').Buffer const Message = require('../../../src/message') const handler = require('../../../src/rpc/handlers/find-node') -const util = require('../../util') +const util = require('../../utils') const T = Message.TYPES.FIND_NODE @@ -35,20 +36,20 @@ describe('rpc - handlers - FindNode', () => { }) it('returns self, if asked for self', (done) => { - const msg = new Message(T, dht.self.id.id, 0) + const msg = new Message(T, dht.peerInfo.id.id, 0) handler(dht)(peers[1], msg, (err, response) => { expect(err).to.not.exist() expect(response.closerPeers).to.have.length(1) const peer = response.closerPeers[0] - expect(peer.id.id).to.be.eql(dht.self.id.id) + expect(peer.id.id).to.be.eql(dht.peerInfo.id.id) done() }) }) it('returns closer peers', (done) => { - const msg = new Message(T, new Buffer('hello'), 0) + const msg = new Message(T, Buffer.from('hello'), 0) const other = peers[1] waterfall([ @@ -71,7 +72,7 @@ describe('rpc - handlers - FindNode', () => { }) it('handles no peers found', (done) => { - const msg = new Message(T, new Buffer('hello'), 0) + const msg = new Message(T, Buffer.from('hello'), 0) handler(dht)(peers[2], msg, (err, response) => { expect(err).to.not.exist() diff --git a/test/rpc/handlers/get-providers.spec.js b/test/rpc/handlers/get-providers.spec.js index 768e9ef6..89805383 100644 --- a/test/rpc/handlers/get-providers.spec.js +++ b/test/rpc/handlers/get-providers.spec.js @@ -6,11 +6,12 @@ chai.use(require('dirty-chai')) const expect = chai.expect const parallel = require('async/parallel') const waterfall = require('async/waterfall') +const Buffer = require('safe-buffer').Buffer const Message = require('../../../src/message') const utils = require('../../../src/utils') const handler = require('../../../src/rpc/handlers/get-providers') -const util = require('../../util') +const util = require('../../utils') const T = Message.TYPES.GET_PROVIDERS @@ -42,7 +43,7 @@ describe('rpc - handlers - GetProviders', () => { }) it('errors with an invalid key ', (done) => { - const msg = new Message(T, new Buffer('hello'), 0) + const msg = new Message(T, Buffer.from('hello'), 0) handler(dht)(peers[0], msg, (err, response) => { expect(err).to.match(/Invalid CID/) @@ -65,9 +66,8 @@ describe('rpc - handlers - GetProviders', () => { expect(response.key).to.be.eql(v.cid.buffer) expect(response.providerPeers).to.have.length(1) - expect( - response.providerPeers[0].id.toB58String() - ).to.be.eql(dht.self.id.toB58String()) + expect(response.providerPeers[0].id.toB58String()) + .to.eql(dht.peerInfo.id.toB58String()) done() }) @@ -89,14 +89,12 @@ describe('rpc - handlers - GetProviders', () => { expect(response.key).to.be.eql(v.cid.buffer) expect(response.providerPeers).to.have.length(1) - expect( - response.providerPeers[0].id.toB58String() - ).to.be.eql(prov.toB58String()) + expect(response.providerPeers[0].id.toB58String()) + .to.eql(prov.toB58String()) expect(response.closerPeers).to.have.length(1) - expect( - response.closerPeers[0].id.toB58String() - ).to.be.eql(closer.id.toB58String()) + expect(response.closerPeers[0].id.toB58String()) + .to.eql(closer.id.toB58String()) done() }) }) diff --git a/test/rpc/handlers/get-value.spec.js b/test/rpc/handlers/get-value.spec.js index 49718e4a..bfc61737 100644 --- a/test/rpc/handlers/get-value.spec.js +++ b/test/rpc/handlers/get-value.spec.js @@ -5,11 +5,11 @@ const chai = require('chai') chai.use(require('dirty-chai')) const expect = chai.expect const waterfall = require('async/waterfall') - +const Buffer = require('safe-buffer').Buffer const Message = require('../../../src/message') const handler = require('../../../src/rpc/handlers/get-value') const utils = require('../../../src/utils') -const util = require('../../util') +const util = require('../../utils') const T = Message.TYPES.GET_VALUE @@ -36,7 +36,7 @@ describe('rpc - handlers - GetValue', () => { }) it('errors when missing key', (done) => { - const msg = new Message(T, new Buffer(0), 0) + const msg = new Message(T, Buffer.alloc(0), 0) handler(dht)(peers[0], msg, (err, response) => { expect(err).to.match(/Invalid key/) @@ -46,8 +46,8 @@ describe('rpc - handlers - GetValue', () => { }) it('responds with a local value', (done) => { - const key = new Buffer('hello') - const value = new Buffer('world') + const key = Buffer.from('hello') + const value = Buffer.from('world') const msg = new Message(T, key, 0) waterfall([ @@ -63,7 +63,7 @@ describe('rpc - handlers - GetValue', () => { }) it('responds with closerPeers returned from the dht', (done) => { - const key = new Buffer('hello') + const key = Buffer.from('hello') const msg = new Message(T, key, 0) const other = peers[1] @@ -82,7 +82,7 @@ describe('rpc - handlers - GetValue', () => { describe('public key', () => { it('self', (done) => { - const key = utils.keyForPublicKey(dht.self.id) + const key = utils.keyForPublicKey(dht.peerInfo.id) const msg = new Message(T, key, 0) @@ -92,7 +92,7 @@ describe('rpc - handlers - GetValue', () => { expect(err).to.not.exist() expect(response.record).to.exist() expect(response.record.value).to.eql( - dht.self.id.pubKey.bytes + dht.peerInfo.id.pubKey.bytes ) done() }) diff --git a/test/rpc/handlers/ping.spec.js b/test/rpc/handlers/ping.spec.js index bf49f311..b1558583 100644 --- a/test/rpc/handlers/ping.spec.js +++ b/test/rpc/handlers/ping.spec.js @@ -4,11 +4,11 @@ const chai = require('chai') chai.use(require('dirty-chai')) const expect = chai.expect - +const Buffer = require('safe-buffer').Buffer const Message = require('../../../src/message') const handler = require('../../../src/rpc/handlers/ping') -const util = require('../../util') +const util = require('../../utils') const T = Message.TYPES.PING @@ -35,7 +35,7 @@ describe('rpc - handlers - Ping', () => { }) it('replies with the same message', (done) => { - const msg = new Message(T, new Buffer('hello'), 5) + const msg = new Message(T, Buffer.from('hello'), 5) handler(dht)(peers[0], msg, (err, response) => { expect(err).to.not.exist() diff --git a/test/rpc/handlers/put-value.spec.js b/test/rpc/handlers/put-value.spec.js index 13856e7e..84c67c5f 100644 --- a/test/rpc/handlers/put-value.spec.js +++ b/test/rpc/handlers/put-value.spec.js @@ -6,12 +6,13 @@ const chai = require('chai') chai.use(require('dirty-chai')) const expect = chai.expect const Record = require('libp2p-record').Record +const Buffer = require('safe-buffer').Buffer const Message = require('../../../src/message') const handler = require('../../../src/rpc/handlers/put-value') const utils = require('../../../src/utils') -const util = require('../../util') +const util = require('../../utils') const T = Message.TYPES.PUT_VALUE @@ -38,7 +39,7 @@ describe('rpc - handlers - PutValue', () => { }) it('errors on missing record', (done) => { - const msg = new Message(T, new Buffer('hello'), 5) + const msg = new Message(T, Buffer.from('hello'), 5) handler(dht)(peers[0], msg, (err, response) => { expect(err).to.match(/Empty record/) done() @@ -46,20 +47,24 @@ describe('rpc - handlers - PutValue', () => { }) it('stores the record in the datastore', (done) => { - const msg = new Message(T, new Buffer('hello'), 5) - const record = new Record(new Buffer('hello'), new Buffer('world'), peers[0].id) + const msg = new Message(T, Buffer.from('hello'), 5) + const record = new Record( + Buffer.from('hello'), + Buffer.from('world'), + peers[0].id + ) msg.record = record handler(dht)(peers[1], msg, (err, response) => { expect(err).to.not.exist() expect(response).to.be.eql(msg) - const key = utils.bufferToKey(new Buffer('hello')) + const key = utils.bufferToKey(Buffer.from('hello')) dht.datastore.get(key, (err, res) => { expect(err).to.not.exist() const rec = Record.deserialize(res) - expect(rec).to.have.property('key').eql(new Buffer('hello')) + expect(rec).to.have.property('key').eql(Buffer.from('hello')) // make sure some time has passed setTimeout(() => { diff --git a/test/rpc/index.spec.js b/test/rpc/index.spec.js index 5426d979..8e60d69b 100644 --- a/test/rpc/index.spec.js +++ b/test/rpc/index.spec.js @@ -7,16 +7,19 @@ const expect = chai.expect const pull = require('pull-stream') const lp = require('pull-length-prefixed') const Connection = require('interface-connection').Connection -const Libp2p = require('./../nodejs-bundle') +const PeerBook = require('peer-book') +const Swarm = require('libp2p-swarm') +const TCP = require('libp2p-tcp') +const Multiplex = require('libp2p-multiplex') const Message = require('../../src/message') -const Dht = require('../../src') +const KadDHT = require('../../src') const rpc = require('../../src/rpc') -const makePeers = require('../util').makePeers +const makePeers = require('../utils').makePeers describe('rpc', () => { - let infos + let peerInfos before((done) => { makePeers(2, (err, peers) => { @@ -24,20 +27,24 @@ describe('rpc', () => { return done(err) } - infos = peers + peerInfos = peers done() }) }) describe('protocolHandler', () => { it('calls back with the response', (done) => { - const libp2p = new Libp2p(infos[0]) - const dht = new Dht(libp2p) - dht.peerBook.put(infos[1]) + const swarm = new Swarm(peerInfos[0], new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() + const dht = new KadDHT(swarm, { kBucketSize: 5 }) + + dht.peerBook.put(peerInfos[1]) const msg = new Message(Message.TYPES.GET_VALUE, Buffer.from('hello'), 5) - const conn = makeConnection(msg, infos[1], (err, res) => { + const conn = makeConnection(msg, peerInfos[1], (err, res) => { expect(err).to.not.exist() expect(res).to.have.length(1) const msg = Message.deserialize(res[0]) diff --git a/test/utils.spec.js b/test/utils.spec.js index 272a3081..98369013 100644 --- a/test/utils.spec.js +++ b/test/utils.spec.js @@ -10,12 +10,12 @@ const distance = require('xor-distance') const waterfall = require('async/waterfall') const utils = require('../src/utils') -const makePeers = require('./util').makePeers +const makePeers = require('./utils').makePeers describe('utils', () => { describe('bufferToKey', () => { it('returns the base32 encoded key of the buffer', () => { - const buf = new Buffer('hello world') + const buf = Buffer.from('hello world') const key = utils.bufferToKey(buf) @@ -30,16 +30,13 @@ describe('utils', () => { describe('convertBuffer', () => { it('returns the sha2-256 hash of the buffer', (done) => { - const buf = new Buffer('hello world') + const buf = Buffer.from('hello world') utils.convertBuffer(buf, (err, digest) => { expect(err).to.not.exist() - expect( - digest - ).to.be.eql( - new Buffer('b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9', 'hex') - ) + expect(digest) + .to.eql(Buffer.from('b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9', 'hex')) done() }) }) @@ -55,7 +52,7 @@ describe('utils', () => { ] const ids = rawIds.map((raw) => { - return new PeerId(new Buffer(raw)) + return new PeerId(Buffer.from(raw)) }) const input = [ @@ -85,12 +82,12 @@ describe('utils', () => { describe('xorCompare', () => { it('sorts two distances', () => { - const target = new Buffer('11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a90') + const target = Buffer.from('11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a90') const a = { - distance: distance(new Buffer('11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a95'), target) + distance: distance(Buffer.from('11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a95'), target) } const b = { - distance: distance(new Buffer('11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a96'), target) + distance: distance(Buffer.from('11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a96'), target) } expect(utils.xorCompare(a, b)).to.eql(-1) @@ -104,12 +101,8 @@ describe('utils', () => { makePeers(1, (err, peers) => { expect(err).to.not.exist() - expect( - utils.keyForPublicKey(peers[0].id) - ).to.be.eql(Buffer.concat([ - new Buffer('/pk/'), - peers[0].id.id - ])) + expect(utils.keyForPublicKey(peers[0].id)) + .to.eql(Buffer.concat([Buffer.from('/pk/'), peers[0].id.id])) done() }) }) @@ -122,14 +115,9 @@ describe('utils', () => { peers.forEach((p, i) => { const id = p.id - expect( - utils.isPublicKeyKey(utils.keyForPublicKey(id)) - ).to.eql(true) - expect( - utils.fromPublicKeyKey(utils.keyForPublicKey(id)).id - ).to.eql( - id.id - ) + expect(utils.isPublicKeyKey(utils.keyForPublicKey(id))).to.eql(true) + expect(utils.fromPublicKeyKey(utils.keyForPublicKey(id)).id) + .to.eql(id.id) }) done() }) diff --git a/test/util.js b/test/utils/index.js similarity index 69% rename from test/util.js rename to test/utils/index.js index f428c58e..b0f46e97 100644 --- a/test/util.js +++ b/test/utils/index.js @@ -3,23 +3,23 @@ const times = require('async/times') const each = require('async/each') const series = require('async/series') -const PeerId = require('peer-id') -const PeerInfo = require('peer-info') -const leftPad = require('left-pad') const setImmediate = require('async/setImmediate') -const MemoryDatastore = require('interface-datastore').MemoryDatastore -const Libp2p = require('./nodejs-bundle') const multihashing = require('multihashing-async') -const crypto = require('libp2p-crypto') -const CID = require('cids') const waterfall = require('async/waterfall') +const CID = require('cids') +const PeerId = require('peer-id') +const PeerInfo = require('peer-info') +const PeerBook = require('peer-book') +const crypto = require('libp2p-crypto') +const Swarm = require('libp2p-swarm') +const TCP = require('libp2p-tcp') +const Multiplex = require('libp2p-multiplex') -const KadDHT = require('../src') +const KadDHT = require('../../src') +// Creates multiple PeerInfos exports.makePeers = (n, callback) => { - times(n, (i, cb) => { - PeerId.create({bits: 1024}, cb) - }, (err, ids) => { + times(n, (i, cb) => PeerId.create({bits: 1024}, cb), (err, ids) => { if (err) { return callback(err) } @@ -27,8 +27,8 @@ exports.makePeers = (n, callback) => { }) } +// TODO break this setupDHT to be a self contained thing. let nodes = [] -let i = 0 exports.setupDHT = (callback) => { exports.makePeers(1, (err, peers) => { @@ -37,10 +37,14 @@ exports.setupDHT = (callback) => { } const p = peers[0] - p.multiaddrs.add(`ip4/127.0.0.1/tcp/9${leftPad(i++, 3, 0)}`) + p.multiaddrs.add('/ip4/0.0.0.0/tcp/0') + + const swarm = new Swarm(p, new PeerBook()) + swarm.transport.add('tcp', new TCP()) + swarm.connection.addStreamMuxer(Multiplex) + swarm.connection.reuse() - const libp2p = new Libp2p(p, undefined, { mdns: false }) - const dht = new KadDHT(libp2p, 20, new MemoryDatastore()) + const dht = new KadDHT(swarm) dht.validators.v = { func (key, publicKey, callback) { @@ -52,7 +56,7 @@ exports.setupDHT = (callback) => { dht.selectors.v = (k, records) => 0 series([ - (cb) => libp2p.start(cb), + (cb) => swarm.listen(cb), (cb) => dht.start(cb) ], (err) => { if (err) { @@ -68,12 +72,10 @@ exports.teardown = (callback) => { each(nodes, (n, cb) => { series([ (cb) => n.stop(cb), - (cb) => n.libp2p.stop(cb) + (cb) => n.swarm.close(cb) ], cb) }, (err) => { - // ignoring error, just shut it down nodes = [] - i = 0 callback(err) }) }