From f6577f01017eff263fc6bab6c2f5eda69139ec8a Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 27 Sep 2018 16:11:08 +0100 Subject: [PATCH] chore: add option for allowing to disable random walk --- package.json | 3 +- src/index.js | 22 ++++++++++++-- test/kad-dht.spec.js | 66 +++++++++++++++++++++++++++++++++++++++++- test/utils/test-dht.js | 18 +++++++++--- 4 files changed, 100 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 67b79113..2adc2d39 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,8 @@ "lodash": "^4.17.10", "lodash.random": "^3.2.0", "lodash.range": "^3.2.0", - "peer-book": "~0.8.0" + "peer-book": "~0.8.0", + "sinon": "^6.3.4" }, "contributors": [ "Blake Byrnes ", diff --git a/src/index.js b/src/index.js index 476d3385..3b868d6a 100644 --- a/src/index.js +++ b/src/index.js @@ -30,8 +30,11 @@ class KadDHT { /** * Create a new KadDHT. * - * @param {Switch} sw - * @param {object} options // {kBucketSize=20, datastore=MemoryDatastore} + * @param {Switch} sw libp2p-switch instance + * @param {object} options DHT options + * @param {number} options.kBucketSize k-bucket size (default 20) + * @param {Datastore} options.datastore datastore (default MemoryDatastore) + * @param {boolean} options.enabledDiscovery enable dht discovery (default true) */ constructor (sw, options) { assert(sw, 'libp2p-kad-dht requires a instance of Switch') @@ -96,6 +99,11 @@ class KadDHT { * @type {RandomWalk} */ this.randomWalk = new RandomWalk(this) + + /** + * Random walk state, default true + */ + this.randomWalkEnabled = !options.hasOwnProperty('enabledDiscovery') ? true : Boolean(options.enabledDiscovery) } /** @@ -115,7 +123,15 @@ class KadDHT { */ start (callback) { this._running = true - this.network.start(callback) + this.network.start((err) => { + if (err) { + return callback(err) + } + + // Start random walk if enabled + this.randomWalkEnabled && this.randomWalk.start() + callback() + }) } /** diff --git a/test/kad-dht.spec.js b/test/kad-dht.spec.js index 15bc3c12..52ff654d 100644 --- a/test/kad-dht.spec.js +++ b/test/kad-dht.spec.js @@ -4,6 +4,7 @@ const chai = require('chai') chai.use(require('dirty-chai')) const expect = chai.expect +const sinon = require('sinon') const series = require('async/series') const times = require('async/times') const parallel = require('async/parallel') @@ -135,6 +136,68 @@ describe('KadDHT', () => { expect(dht).to.have.property('routingTable') }) + it('should be able to start and stop', function (done) { + const sw = new Switch(peerInfos[0], new PeerBook()) + sw.transport.add('tcp', new TCP()) + sw.connection.addStreamMuxer(Mplex) + sw.connection.reuse() + const dht = new KadDHT(sw) + + sinon.spy(dht.network, 'start') + sinon.spy(dht.randomWalk, 'start') + + sinon.spy(dht.network, 'stop') + sinon.spy(dht.randomWalk, 'stop') + + series([ + (cb) => dht.start(cb), + (cb) => { + expect(dht.network.start.calledOnce).to.equal(true) + expect(dht.randomWalk.start.calledOnce).to.equal(true) + + cb() + }, + (cb) => dht.stop(cb) + ], (err) => { + expect(err).to.not.exist() + expect(dht.network.stop.calledOnce).to.equal(true) + expect(dht.randomWalk.stop.calledOnce).to.equal(true) + + done() + }) + }) + + it('should be able to start with random-walk disabled', function (done) { + const sw = new Switch(peerInfos[0], new PeerBook()) + sw.transport.add('tcp', new TCP()) + sw.connection.addStreamMuxer(Mplex) + sw.connection.reuse() + const dht = new KadDHT(sw, { enabledDiscovery: false }) + + sinon.spy(dht.network, 'start') + sinon.spy(dht.randomWalk, 'start') + + sinon.spy(dht.network, 'stop') + sinon.spy(dht.randomWalk, 'stop') + + series([ + (cb) => dht.start(cb), + (cb) => { + expect(dht.network.start.calledOnce).to.equal(true) + expect(dht.randomWalk.start.calledOnce).to.equal(false) + + cb() + }, + (cb) => dht.stop(cb) + ], (err) => { + expect(err).to.not.exist() + expect(dht.network.stop.calledOnce).to.equal(true) + expect(dht.randomWalk.stop.calledOnce).to.equal(true) // Should be always disabled, as it can be started using the instance + + done() + }) + }) + it('put - get', function (done) { this.timeout(10 * 1000) const tdht = new TestDHT() @@ -206,7 +269,8 @@ describe('KadDHT', () => { const nDHTs = 20 const tdht = new TestDHT() - tdht.spawn(nDHTs, (err, dhts) => { + // random walk disabled for a manual usage + tdht.spawn(nDHTs, { enabledDiscovery: false }, (err, dhts) => { expect(err).to.not.exist() series([ diff --git a/test/utils/test-dht.js b/test/utils/test-dht.js index 5351008b..7c5fd42d 100644 --- a/test/utils/test-dht.js +++ b/test/utils/test-dht.js @@ -18,14 +18,24 @@ class TestDHT { this.nodes = [] } - spawn (n, callback) { - times(n, (i, cb) => this._spawnOne(cb), (err, dhts) => { + spawn (n, options, callback) { + if (typeof options === 'function') { + callback = options + options = {} + } + + times(n, (i, cb) => this._spawnOne(options, cb), (err, dhts) => { if (err) { return callback(err) } callback(null, dhts) }) } - _spawnOne (callback) { + _spawnOne (options, callback) { + if (typeof options === 'function') { + callback = options + options = {} + } + createPeerInfo(1, (err, peers) => { if (err) { return callback(err) } @@ -37,7 +47,7 @@ class TestDHT { sw.connection.addStreamMuxer(Mplex) sw.connection.reuse() - const dht = new KadDHT(sw) + const dht = new KadDHT(sw, options) dht.validators.v = { func (key, publicKey, callback) {