libp2p-kad-dht
Advanced tools
Comparing version 0.14.5 to 0.14.6
@@ -0,1 +1,16 @@ | ||
<a name="0.14.6"></a> | ||
## [0.14.6](https://github.com/libp2p/js-libp2p-kad-dht/compare/v0.14.5...v0.14.6) (2019-02-25) | ||
### Bug Fixes | ||
* specify # of peers for successful put ([#72](https://github.com/libp2p/js-libp2p-kad-dht/issues/72)) ([97e8e60](https://github.com/libp2p/js-libp2p-kad-dht/commit/97e8e60)) | ||
### Features | ||
* expose randomwalk parameters in config ([#77](https://github.com/libp2p/js-libp2p-kad-dht/issues/77)) ([dc5a67f](https://github.com/libp2p/js-libp2p-kad-dht/commit/dc5a67f)) | ||
<a name="0.14.5"></a> | ||
@@ -2,0 +17,0 @@ ## [0.14.5](https://github.com/libp2p/js-libp2p-kad-dht/compare/v0.14.4...v0.14.5) (2019-02-05) |
{ | ||
"name": "libp2p-kad-dht", | ||
"version": "0.14.5", | ||
"version": "0.14.6", | ||
"description": "JavaScript implementation of the Kad-DHT for libp2p", | ||
@@ -40,3 +40,4 @@ "leadMaintainer": "Vasco Santos <vasco.santos@moxy.studio>", | ||
"dependencies": { | ||
"async": "^2.6.1", | ||
"@nodeutils/defaults-deep": "^1.1.0", | ||
"async": "^2.6.2", | ||
"base32.js": "~0.1.0", | ||
@@ -52,7 +53,7 @@ "chai-checkmark": "^1.0.1", | ||
"libp2p-crypto": "~0.16.0", | ||
"libp2p-record": "~0.6.1", | ||
"libp2p-record": "~0.6.2", | ||
"multihashes": "~0.4.14", | ||
"multihashing-async": "~0.5.1", | ||
"peer-id": "~0.12.1", | ||
"peer-info": "~0.15.0", | ||
"multihashing-async": "~0.5.2", | ||
"peer-id": "~0.12.2", | ||
"peer-info": "~0.15.1", | ||
"priorityqueue": "~0.2.1", | ||
@@ -66,3 +67,3 @@ "protons": "^1.0.1", | ||
"devDependencies": { | ||
"aegir": "^18.0.2", | ||
"aegir": "^18.1.1", | ||
"chai": "^4.2.0", | ||
@@ -73,3 +74,3 @@ "datastore-level": "~0.10.0", | ||
"libp2p-mplex": "~0.8.4", | ||
"libp2p-switch": "~0.41.4", | ||
"libp2p-switch": "~0.41.5", | ||
"libp2p-tcp": "~0.13.0", | ||
@@ -79,4 +80,4 @@ "lodash": "^4.17.11", | ||
"lodash.range": "^3.2.0", | ||
"peer-book": "~0.9.0", | ||
"sinon": "^7.2.2" | ||
"peer-book": "~0.9.1", | ||
"sinon": "^7.2.4" | ||
}, | ||
@@ -93,2 +94,3 @@ "contributors": [ | ||
"Richard Schneider <makaretu@gmail.com>", | ||
"Thomas Eizinger <thomas@eizinger.io>", | ||
"Vasco Santos <vasco.santos@ua.pt>", | ||
@@ -95,0 +97,0 @@ "Vasco Santos <vasco.santos@moxy.studio>", |
@@ -39,1 +39,8 @@ 'use strict' | ||
exports.maxMessageSize = 2 << 22 // 4MB | ||
exports.defaultRandomWalk = { | ||
enabled: true, | ||
queriesPerPeriod: 1, | ||
interval: 5 * minute, | ||
timeout: 10 * second | ||
} |
@@ -8,2 +8,3 @@ 'use strict' | ||
const each = require('async/each') | ||
const filter = require('async/filter') | ||
const timeout = require('async/timeout') | ||
@@ -26,2 +27,3 @@ const PeerId = require('peer-id') | ||
const assert = require('assert') | ||
const defaultsDeep = require('@nodeutils/defaults-deep') | ||
@@ -35,2 +37,12 @@ /** | ||
/** | ||
* Random walk options | ||
* | ||
* @typedef {Object} randomWalkOptions | ||
* @property {boolean} enabled discovery enabled (default: true) | ||
* @property {number} queriesPerPeriod how many queries to run per period (default: 1) | ||
* @property {number} interval how often to run the the random-walk process, in milliseconds (default: 300000) | ||
* @property {number} timeout how long to wait for the the random-walk query to run, in milliseconds (default: 10000) | ||
*/ | ||
/** | ||
* Create a new KadDHT. | ||
@@ -42,5 +54,5 @@ * | ||
* @param {Datastore} options.datastore datastore (default MemoryDatastore) | ||
* @param {boolean} options.enabledDiscovery enable dht discovery (default true) | ||
* @param {object} options.validators validators object with namespace as keys and function(key, record, callback) | ||
* @param {object} options.selectors selectors object with namespace as keys and function(key, records) | ||
* @param {randomWalkOptions} options.randomWalk randomWalk options | ||
*/ | ||
@@ -53,2 +65,3 @@ constructor (sw, options) { | ||
options.selectors = options.selectors || {} | ||
options.randomWalk = defaultsDeep(options.randomWalk, c.defaultRandomWalk) | ||
@@ -125,3 +138,6 @@ /** | ||
*/ | ||
this.randomWalkEnabled = !options.hasOwnProperty('enabledDiscovery') ? true : Boolean(options.enabledDiscovery) | ||
this.randomWalkEnabled = Boolean(options.randomWalk.enabled) | ||
this.randomWalkQueriesPerPeriod = parseInt(options.randomWalk.queriesPerPeriod) | ||
this.randomWalkInterval = parseInt(options.randomWalk.interval) | ||
this.randomWalkTimeout = parseInt(options.randomWalk.timeout) | ||
} | ||
@@ -152,3 +168,3 @@ | ||
// Start random walk if enabled | ||
this.randomWalkEnabled && this.randomWalk.start() | ||
this.randomWalkEnabled && this.randomWalk.start(this.randomWalkQueriesPerPeriod, this.randomWalkInterval, this.randomWalkTimeout) | ||
callback() | ||
@@ -191,6 +207,16 @@ }) | ||
* @param {Buffer} value | ||
* @param {Object} options - get options | ||
* @param {number} options.minPeers - minimum peers that must be put to to consider this a successful operation | ||
* (default: closestPeers.length) | ||
* @param {function(Error)} callback | ||
* @returns {void} | ||
*/ | ||
put (key, value, callback) { | ||
put (key, value, options, callback) { | ||
if (typeof options === 'function') { | ||
callback = options | ||
options = {} | ||
} else { | ||
options = options || {} | ||
} | ||
this._log('PutValue %b', key) | ||
@@ -203,5 +229,27 @@ | ||
(cb) => this.getClosestPeers(key, cb), | ||
(peers, cb) => each(peers, (peer, cb) => { | ||
this._putValueToPeer(key, rec, peer, cb) | ||
}, cb) | ||
(peers, cb) => { | ||
// Ensure we have a default `minPeers` | ||
options.minPeers = options.minPeers || peers.length | ||
// filter out the successful puts | ||
filter(peers, (peer, cb) => { | ||
this._putValueToPeer(key, rec, peer, (err) => { | ||
if (err) { | ||
this._log.error('Failed to put to peer (%b): %s', peer.id, err) | ||
return cb(null, false) | ||
} | ||
cb(null, true) | ||
}) | ||
}, (err, results) => { | ||
if (err) return cb(err) | ||
// Did we put to enough peers? | ||
if (options.minPeers > results.length) { | ||
const error = errcode(new Error('Failed to put value to enough peers'), 'ERR_NOT_ENOUGH_PUT_PEERS') | ||
this._log.error(error) | ||
return cb(error) | ||
} | ||
cb() | ||
}) | ||
} | ||
], cb) | ||
@@ -208,0 +256,0 @@ ], callback) |
@@ -31,6 +31,3 @@ 'use strict' | ||
*/ | ||
start (queries, period, timeout) { | ||
if (queries == null) { queries = 1 } | ||
if (period == null) { period = 5 * c.minute } | ||
if (timeout == null) { timeout = 10 * c.second } | ||
start (queries = c.defaultRandomWalk.queriesPerPeriod, period = c.defaultRandomWalk.interval, timeout = c.defaultRandomWalk.timeout) { | ||
// Don't run twice | ||
@@ -37,0 +34,0 @@ if (this._running) { return } |
@@ -203,3 +203,3 @@ /* eslint-env mocha */ | ||
sw.connection.reuse() | ||
const dht = new KadDHT(sw, { enabledDiscovery: false }) | ||
const dht = new KadDHT(sw, { randomWalk: { enabled: false } }) | ||
@@ -310,2 +310,103 @@ sinon.spy(dht.network, 'start') | ||
it('put - should require a minimum number of peers to have successful puts', function (done) { | ||
this.timeout(10 * 1000) | ||
const tdht = new TestDHT() | ||
const errCode = 'ERR_NOT_AVAILABLE' | ||
const error = errcode(new Error('fake error'), errCode) | ||
tdht.spawn(4, (err, dhts) => { | ||
expect(err).to.not.exist() | ||
const dhtA = dhts[0] | ||
const dhtB = dhts[1] | ||
const dhtC = dhts[2] | ||
const dhtD = dhts[3] | ||
const stub = sinon.stub(dhtD, '_verifyRecordLocally').callsArgWithAsync(1, error) | ||
waterfall([ | ||
(cb) => connect(dhtA, dhtB, cb), | ||
(cb) => connect(dhtA, dhtC, cb), | ||
(cb) => connect(dhtA, dhtD, cb), | ||
(cb) => dhtA.put(Buffer.from('/v/hello'), Buffer.from('world'), { minPeers: 2 }, cb), | ||
(cb) => dhtB.get(Buffer.from('/v/hello'), { timeout: 1000 }, cb), | ||
(res, cb) => { | ||
expect(res).to.eql(Buffer.from('world')) | ||
cb() | ||
} | ||
], (err) => { | ||
expect(err).to.not.exist() | ||
stub.restore() | ||
tdht.teardown(done) | ||
}) | ||
}) | ||
}) | ||
it('put - should fail if not enough peers can be written to', function (done) { | ||
this.timeout(10 * 1000) | ||
const tdht = new TestDHT() | ||
const errCode = 'ERR_NOT_AVAILABLE' | ||
const error = errcode(new Error('fake error'), errCode) | ||
tdht.spawn(4, (err, dhts) => { | ||
expect(err).to.not.exist() | ||
const dhtA = dhts[0] | ||
const dhtB = dhts[1] | ||
const dhtC = dhts[2] | ||
const dhtD = dhts[3] | ||
const stub = sinon.stub(dhtD, '_verifyRecordLocally').callsArgWithAsync(1, error) | ||
const stub2 = sinon.stub(dhtC, '_verifyRecordLocally').callsArgWithAsync(1, error) | ||
waterfall([ | ||
(cb) => connect(dhtA, dhtB, cb), | ||
(cb) => connect(dhtA, dhtC, cb), | ||
(cb) => connect(dhtA, dhtD, cb), | ||
(cb) => dhtA.put(Buffer.from('/v/hello'), Buffer.from('world'), { minPeers: 2 }, cb), | ||
(cb) => dhtB.get(Buffer.from('/v/hello'), { timeout: 1000 }, cb), | ||
(res, cb) => { | ||
expect(res).to.eql(Buffer.from('world')) | ||
cb() | ||
} | ||
], (err) => { | ||
expect(err).to.exist() | ||
expect(err.code).to.eql('ERR_NOT_ENOUGH_PUT_PEERS') | ||
stub.restore() | ||
stub2.restore() | ||
tdht.teardown(done) | ||
}) | ||
}) | ||
}) | ||
it('put - should require all peers to be put to successfully if no minPeers specified', function (done) { | ||
this.timeout(10 * 1000) | ||
const tdht = new TestDHT() | ||
const errCode = 'ERR_NOT_AVAILABLE' | ||
const error = errcode(new Error('fake error'), errCode) | ||
tdht.spawn(3, (err, dhts) => { | ||
expect(err).to.not.exist() | ||
const dhtA = dhts[0] | ||
const dhtB = dhts[1] | ||
const dhtC = dhts[2] | ||
const stub = sinon.stub(dhtC, '_verifyRecordLocally').callsArgWithAsync(1, error) | ||
waterfall([ | ||
(cb) => connect(dhtA, dhtB, cb), | ||
(cb) => connect(dhtA, dhtC, cb), | ||
(cb) => dhtA.put(Buffer.from('/v/hello'), Buffer.from('world'), {}, cb), | ||
(cb) => dhtB.get(Buffer.from('/v/hello'), { timeout: 1000 }, cb), | ||
(res, cb) => { | ||
expect(res).to.eql(Buffer.from('world')) | ||
cb() | ||
} | ||
], (err) => { | ||
expect(err).to.exist() | ||
expect(err.code).to.eql('ERR_NOT_ENOUGH_PUT_PEERS') | ||
stub.restore() | ||
tdht.teardown(done) | ||
}) | ||
}) | ||
}) | ||
it('put - get using key with no prefix (no selector available)', function (done) { | ||
@@ -884,3 +985,3 @@ this.timeout(10 * 1000) | ||
dhts[0].getMany('/v/hello', 5, (err) => { | ||
dhts[0].getMany(Buffer.from('/v/hello'), 5, (err) => { | ||
expect(err).to.exist() | ||
@@ -887,0 +988,0 @@ expect(err.code).to.be.eql('ERR_NO_PEERS_IN_ROUTING_TABLE') |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
180999
5453
23
+ Added@nodeutils/defaults-deep@1.1.0(transitive)
Updatedasync@^2.6.2
Updatedlibp2p-record@~0.6.2
Updatedmultihashing-async@~0.5.2
Updatedpeer-id@~0.12.2
Updatedpeer-info@~0.15.1