From f57c540e1b28001ddd34fbd586b0663fcf27f117 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 11 Nov 2020 09:24:53 +0100 Subject: [PATCH 1/3] feat: discover and connect to closest peers --- doc/API.md | 32 ++++ doc/CONFIGURATION.md | 7 +- package.json | 1 + src/config.js | 5 + src/index.js | 8 +- src/peer-routing.js | 137 ++++++++++++--- test/peer-routing/peer-routing.node.js | 233 ++++++++++++++++++++++++- 7 files changed, 395 insertions(+), 28 deletions(-) diff --git a/doc/API.md b/doc/API.md index 3fdcee727c..d907b7d851 100644 --- a/doc/API.md +++ b/doc/API.md @@ -20,6 +20,7 @@ * [`contentRouting.get`](#contentroutingget) * [`contentRouting.getMany`](#contentroutinggetmany) * [`peerRouting.findPeer`](#peerroutingfindpeer) + * [`peerRouting.getClosestPeers`](#peerroutinggetclosestpeers) * [`peerStore.addressBook.add`](#peerstoreaddressbookadd) * [`peerStore.addressBook.delete`](#peerstoreaddressbookdelete) * [`peerStore.addressBook.get`](#peerstoreaddressbookget) @@ -99,6 +100,7 @@ Creates an instance of Libp2p. | [options.keychain] | [`object`](./CONFIGURATION.md#setup-with-keychain) | keychain [configuration](./CONFIGURATION.md#setup-with-keychain) | | [options.metrics] | [`object`](./CONFIGURATION.md#configuring-metrics) | libp2p Metrics [configuration](./CONFIGURATION.md#configuring-metrics) | | [options.peerId] | [`PeerId`][peer-id] | peerId instance (it will be created if not provided) | +| [options.peerRouting] | [`object`](./CONFIGURATION.md#setup-with-content-and-peer-routing) | libp2p Peer routing service [configuration](./CONFIGURATION.md#setup-with-content-and-peer-routing) | | [options.peerStore] | [`object`](./CONFIGURATION.md#configuring-peerstore) | libp2p PeerStore [configuration](./CONFIGURATION.md#configuring-peerstore) | For Libp2p configurations and modules details read the [Configuration Document](./CONFIGURATION.md). @@ -675,6 +677,36 @@ Iterates over all peer routers in series to find the given peer. If the DHT is e const peer = await libp2p.peerRouting.findPeer(peerId, options) ``` +### peerRouting.getClosestPeers + +Iterates over all content routers in series to get the closest peers of the given key. +Once a content router succeeds, the iteration will stop. If the DHT is enabled, it will be queried first. + +`libp2p.peerRouting.getClosestPeers(cid, options)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| key | `Uint8Array` | A CID like key | +| options | `object` | operation options | +| options.timeout | `number` | How long the query can take (ms). | + +#### Returns + +| Type | Description | +|------|-------------| +| `AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }` | Async iterator for peer data | + +#### Example + +```js +// Iterate over the closest peers found for the given key +for await (const peer of libp2p.peerRouting.getClosestPeers(key)) { + console.log(peer.id, peer.multiaddrs) +} +``` + ### peerStore.addressBook.add Adds known `multiaddrs` of a given peer. If the peer is not known, it will be set with the provided multiaddrs. diff --git a/doc/CONFIGURATION.md b/doc/CONFIGURATION.md index cbee2e598c..aafbc2bc07 100644 --- a/doc/CONFIGURATION.md +++ b/doc/CONFIGURATION.md @@ -396,7 +396,12 @@ const node = await Libp2p.create({ new DelegatedPeerRouter() ], }, - peerId + peerId, + peerRouting: { // Peer routing service configuration + enabled: true, // Should find the closest peers. + interval: 300e3, // Interval for getting the new for closest peers + bootDelay: 10e3 // Delay for the initial query for closest peers + } }) ``` diff --git a/package.json b/package.json index 27c86bc14f..8812e4347c 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "chai-string": "^1.5.0", "delay": "^4.3.0", "interop-libp2p": "^0.3.0", + "into-stream": "^6.0.0", "ipfs-http-client": "^47.0.1", "it-concat": "^1.0.0", "it-pair": "^1.0.0", diff --git a/src/config.js b/src/config.js index 2337e249ae..993debab07 100644 --- a/src/config.js +++ b/src/config.js @@ -35,6 +35,11 @@ const DefaultConfig = { persistence: false, threshold: 5 }, + peerRouting: { + enabled: true, + interval: 300e3, + bootDelay: 10e3 + }, config: { dht: { enabled: false, diff --git a/src/index.js b/src/index.js index 56401c358b..f2376324dc 100644 --- a/src/index.js +++ b/src/index.js @@ -9,7 +9,7 @@ log.error = debug('libp2p:error') const errCode = require('err-code') const PeerId = require('peer-id') -const peerRouting = require('./peer-routing') +const PeerRouting = require('./peer-routing') const contentRouting = require('./content-routing') const getPeer = require('./get-peer') const { validate: validateConfig } = require('./config') @@ -192,7 +192,7 @@ class Libp2p extends EventEmitter { // Attach remaining APIs // peer and content routing will automatically get modules from _modules and _dht - this.peerRouting = peerRouting(this) + this.peerRouting = new PeerRouting(this) this.contentRouting = contentRouting(this) // Mount default protocols @@ -249,8 +249,8 @@ class Libp2p extends EventEmitter { try { this._isStarted = false - // Relay this.relay && this.relay.stop() + this.peerRouting.stop() for (const service of this._discovery.values()) { service.removeListener('peer', this._onDiscoveryPeer) @@ -495,6 +495,8 @@ class Libp2p extends EventEmitter { // Relay this.relay && this.relay.start() + + this.peerRouting.start() } /** diff --git a/src/peer-routing.js b/src/peer-routing.js index 7594f15d77..929f888450 100644 --- a/src/peer-routing.js +++ b/src/peer-routing.js @@ -1,40 +1,131 @@ 'use strict' const errCode = require('err-code') +const debug = require('debug') +const log = debug('libp2p:peer-routing') +log.error = debug('libp2p:peer-routing:error') + +const all = require('it-all') const pAny = require('p-any') -module.exports = (node) => { - const routers = node._modules.peerRouting || [] +/** + * Responsible for managing the usage of the available Peer Routing modules. + */ +class PeerRouting { + /** + * @class + * @param {Libp2p} libp2p + */ + constructor (libp2p) { + this._peerId = libp2p.peerId + this._peerStore = libp2p.peerStore + this._routers = libp2p._modules.peerRouting || [] + + // If we have the dht, make it first + if (libp2p._dht) { + this._routers.unshift(libp2p._dht) + } + + this._options = libp2p._options.peerRouting + } + + /** + * Start peer routing service. + */ + start () { + if (!this._routers.length || this._timeoutId || !this._options.enabled) { + return + } + + // Start doing queries after `this._options.delay` + this._timeoutId = setTimeout(() => { + // Start runner immediately + this._runPeriodically() + }, this._options.bootDelay) + } + + /** + * Run peridocally on every `this._options.interval` ms + * + * @private + */ + async _runPeriodically () { + // run until the walk has been stopped + while (this._timeoutId) { + try { + for await (const { id, multiaddrs } of this.getClosestPeers(this._peerId.id)) { + this._peerStore.addressBook.add(id, multiaddrs) + } + } catch (err) { + log.error(err) + } + // Each subsequent task should run on a `this._options.interval` ms interval + await new Promise(resolve => { + this._timeoutId = setTimeout(resolve, this._options.interval) + }) + } + } - // If we have the dht, make it first - if (node._dht) { - routers.unshift(node._dht) + /** + * Stop peer routing service. + */ + stop () { + clearTimeout(this._timeoutId) } - return { - /** - * Iterates over all peer routers in series to find the given peer. - * - * @param {string} id - The id of the peer to find - * @param {object} [options] - * @param {number} [options.timeout] - How long the query should run - * @returns {Promise<{ id: PeerId, multiaddrs: Multiaddr[] }>} - */ - findPeer: async (id, options) => { // eslint-disable-line require-await - if (!routers.length) { - throw errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE') + /** + * Iterates over all peer routers in series to find the given peer. + * + * @param {string} id - The id of the peer to find + * @param {object} [options] + * @param {number} [options.timeout] - How long the query should run + * @returns {Promise<{ id: PeerId, multiaddrs: Multiaddr[] }>} + */ + async findPeer (id, options) { // eslint-disable-line require-await + if (!this._routers.length) { + throw errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE') + } + + return pAny(this._routers.map(async (router) => { + const result = await router.findPeer(id, options) + + // If we don't have a result, we need to provide an error to keep trying + if (!result || Object.keys(result).length === 0) { + throw errCode(new Error('not found'), 'NOT_FOUND') } - return pAny(routers.map(async (router) => { - const result = await router.findPeer(id, options) + return result + })) + } + + /** + * Attempt to find the closest peers on the network to the given key. + * + * @param {Uint8Array} key - A CID like key + * @param {Object} [options] + * @param {number} [options.timeout=30e3] - How long the query can take. + * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} + */ + async * getClosestPeers (key, options = { timeout: 30e3 }) { + if (!this._routers.length) { + throw errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE') + } - // If we don't have a result, we need to provide an error to keep trying - if (!result || Object.keys(result).length === 0) { + const result = await pAny( + this._routers.map(async (router) => { + const peers = await all(router.getClosestPeers(key, options)) + + if (!peers || !peers.length) { throw errCode(new Error('not found'), 'NOT_FOUND') } + return peers + }) + ) - return result - })) + for (const peer of result) { + yield peer } } } + +module.exports = PeerRouting diff --git a/test/peer-routing/peer-routing.node.js b/test/peer-routing/peer-routing.node.js index cdce080c1e..06283aa07b 100644 --- a/test/peer-routing/peer-routing.node.js +++ b/test/peer-routing/peer-routing.node.js @@ -4,17 +4,22 @@ const { expect } = require('aegir/utils/chai') const nock = require('nock') const sinon = require('sinon') +const intoStream = require('into-stream') +const delay = require('delay') const pDefer = require('p-defer') +const pWaitFor = require('p-wait-for') const mergeOptions = require('merge-options') const ipfsHttpClient = require('ipfs-http-client') const DelegatedPeerRouter = require('libp2p-delegated-peer-routing') +const multiaddr = require('multiaddr') +const PeerId = require('peer-id') const peerUtils = require('../utils/creators/peer') const { baseOptions, routingOptions } = require('./utils') -describe('peer-routing', () => { +describe.only('peer-routing', () => { describe('no routers', () => { let node @@ -29,6 +34,16 @@ describe('peer-routing', () => { .to.eventually.be.rejected() .and.to.have.property('code', 'NO_ROUTERS_AVAILABLE') }) + + it('.getClosestPeers should return an error', async () => { + try { + for await (const _ of node.peerRouting.getClosestPeers('a cid')) { } // eslint-disable-line + throw new Error('.getClosestPeers should return an error') + } catch (err) { + expect(err).to.exist() + expect(err.code).to.equal('NO_ROUTERS_AVAILABLE') + } + }) }) describe('via dht router', () => { @@ -64,6 +79,19 @@ describe('peer-routing', () => { nodes[0].peerRouting.findPeer() return deferred.promise }) + + it('should use the nodes dht to get the closest peers', async () => { + const deferred = pDefer() + + sinon.stub(nodes[0]._dht, 'getClosestPeers').callsFake(function * () { + deferred.resolve() + yield + }) + + await nodes[0].peerRouting.getClosestPeers().next() + + return deferred.promise + }) }) describe('via delegate router', () => { @@ -110,6 +138,19 @@ describe('peer-routing', () => { return deferred.promise }) + it('should use the delegate router to get the closest peers', async () => { + const deferred = pDefer() + + sinon.stub(delegate, 'getClosestPeers').callsFake(function * () { + deferred.resolve() + yield + }) + + await node.peerRouting.getClosestPeers().next() + + return deferred.promise + }) + it('should be able to find a peer', async () => { const peerKey = 'QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL' const mockApi = nock('http://0.0.0.0:60197') @@ -154,6 +195,60 @@ describe('peer-routing', () => { expect(mockApi.isDone()).to.equal(true) }) + + it('should be able to get the closest peers', async () => { + const peerId = await PeerId.create({ keyType: 'ed25519' }) + + const closest1 = '12D3KooWLewYMMdGWAtuX852n4rgCWkK7EBn4CWbwwBzhsVoKxk3' + const closest2 = '12D3KooWDtoQbpKhtnWddfj72QmpFvvLDTsBLTFkjvgQm6cde2AK' + + const mockApi = nock('http://0.0.0.0:60197') + .post('/api/v0/dht/query') + .query(true) + .reply(200, + () => intoStream([ + `{"extra":"","id":"${closest1}","responses":[{"ID":"${closest1}","Addrs":["/ip4/127.0.0.1/tcp/63930","/ip4/127.0.0.1/tcp/63930"]}],"type":1}\n`, + `{"extra":"","id":"${closest2}","responses":[{"ID":"${closest2}","Addrs":["/ip4/127.0.0.1/tcp/63506","/ip4/127.0.0.1/tcp/63506"]}],"type":1}\n`, + `{"Extra":"","ID":"${closest2}","Responses":[],"Type":2}\n`, + `{"Extra":"","ID":"${closest1}","Responses":[],"Type":2}\n` + ]), + [ + 'Content-Type', 'application/json', + 'X-Chunked-Output', '1' + ]) + + const closestPeers = [] + for await (const peer of node.peerRouting.getClosestPeers(peerId.id, { timeout: 1000 })) { + closestPeers.push(peer) + } + + expect(closestPeers).to.have.length(2) + expect(closestPeers[0].id.toB58String()).to.equal(closest2) + expect(closestPeers[0].multiaddrs).to.have.lengthOf(2) + expect(closestPeers[1].id.toB58String()).to.equal(closest1) + expect(closestPeers[1].multiaddrs).to.have.lengthOf(2) + expect(mockApi.isDone()).to.equal(true) + }) + + it('should handle errors when getting the closest peers', async () => { + const peerId = await PeerId.create({ keyType: 'ed25519' }) + + const mockApi = nock('http://0.0.0.0:60197') + .post('/api/v0/dht/query') + .query(true) + .reply(502, 'Bad Gateway', [ + 'X-Chunked-Output', '1' + ]) + + try { + for await (const _ of node.peerRouting.getClosestPeers(peerId.id)) { } // eslint-disable-line + throw new Error('should handle errors when getting the closest peers') + } catch (err) { + expect(err).to.exist() + } + + expect(mockApi.isDone()).to.equal(true) + }) }) describe('via dht and delegate routers', () => { @@ -208,5 +303,141 @@ describe('peer-routing', () => { const peer = await node.peerRouting.findPeer('a peer id') expect(peer).to.eql(results) }) + + it('should only use the dht if it gets the closest peers', async () => { + const results = [true] + + sinon.stub(node._dht, 'getClosestPeers').callsFake(function * () { + yield results[0] + }) + + sinon.stub(delegate, 'getClosestPeers').callsFake(function * () { // eslint-disable-line require-yield + throw new Error('the delegate should not have been called') + }) + + const closest = [] + for await (const peer of node.peerRouting.getClosestPeers('a cid')) { + closest.push(peer) + } + + expect(closest).to.have.length.above(0) + expect(closest).to.eql(results) + }) + + it('should use the delegate if the dht fails to get the closest peer', async () => { + const results = [true] + + sinon.stub(node._dht, 'getClosestPeers').callsFake(function * () { }) + + sinon.stub(delegate, 'getClosestPeers').callsFake(function * () { + yield results[0] + }) + + const closest = [] + for await (const peer of node.peerRouting.getClosestPeers('a cid')) { + closest.push(peer) + } + + expect(closest).to.have.length.above(0) + expect(closest).to.eql(results) + }) + }) + + describe('peer routing service', () => { + let node + let peerIds + + before(async () => { + peerIds = await peerUtils.createPeerId({ number: 2}) + }) + + afterEach(() => { + sinon.restore() + + return node && node.stop() + }) + + it('should be enabled and start by default', async () => { + const results = [ + { id: peerIds[0], multiaddrs: [multiaddr('/ip4/30.0.0.1/tcp/2000')] }, + { id: peerIds[1], multiaddrs: [multiaddr('/ip4/32.0.0.1/tcp/2000')] } + ] + + ;[node] = await peerUtils.createPeer({ + config: mergeOptions(routingOptions, { + peerRouting: { + bootDelay: 100 + } + }), + started: false + }) + + sinon.spy(node.peerStore.addressBook, 'add') + sinon.stub(node._dht, 'getClosestPeers').callsFake(function* () { + yield results[0] + yield results[1] + }) + + await node.start() + + await pWaitFor(() => node._dht.getClosestPeers.callCount === 1) + await pWaitFor(() => node.peerStore.addressBook.add.callCount === results.length) + + const call0 = node.peerStore.addressBook.add.getCall(0) + expect(call0.args[0].equals(results[0].id)) + call0.args[1].forEach((m, index) => { + expect(m.equals(results[0].multiaddrs[index])) + }) + + const call1 = node.peerStore.addressBook.add.getCall(1) + expect(call1.args[0].equals(results[1].id)) + call0.args[1].forEach((m, index) => { + expect(m.equals(results[1].multiaddrs[index])) + }) + }) + + it('should support being disabled', async () => { + ;[node] = await peerUtils.createPeer({ + config: mergeOptions(routingOptions, { + peerRouting: { + bootDelay: 100, + enabled: false + } + }), + started: false + }) + + sinon.stub(node._dht, 'getClosestPeers').callsFake(function* () { + throw new Error('should not be called') + }) + + await node.start() + await delay(100) + + expect(node._dht.getClosestPeers.callCount === 0) + }) + + it('should start and run recurrently on interval', async () => { + ;[node] = await peerUtils.createPeer({ + config: mergeOptions(routingOptions, { + peerRouting: { + interval: 500, + bootDelay: 200 + } + }), + started: false + }) + + sinon.stub(node._dht, 'getClosestPeers').callsFake(function* () { + yield { id: peerIds[0], multiaddrs: [multiaddr('/ip4/30.0.0.1/tcp/2000')] } + }) + + await node.start() + + await delay(300) + expect(node._dht.getClosestPeers.callCount).to.eql(1) + await delay(500) + expect(node._dht.getClosestPeers.callCount).to.eql(2) + }) }) }) From 226efad3e5a29ca1e051ad26b8a1960522f197ef Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 11 Nov 2020 18:14:07 +0100 Subject: [PATCH 2/3] chore: use set-delayed-interval module --- package.json | 1 + src/peer-routing.js | 39 +++++++++++--------------- test/peer-routing/peer-routing.node.js | 15 +++++----- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 8812e4347c..3fde77caad 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "protons": "^2.0.0", "retimer": "^2.0.0", "sanitize-filename": "^1.6.3", + "set-delayed-interval": "vasco-santos/set-delayed-interval#feat/initial-implementation", "streaming-iterables": "^5.0.2", "timeout-abort-controller": "^1.1.1", "varint": "^5.0.0", diff --git a/src/peer-routing.js b/src/peer-routing.js index 929f888450..61caf41712 100644 --- a/src/peer-routing.js +++ b/src/peer-routing.js @@ -7,6 +7,10 @@ log.error = debug('libp2p:peer-routing:error') const all = require('it-all') const pAny = require('p-any') +const { + setDelayedInterval, + clearDelayedInterval +} = require('set-delayed-interval') /** * Responsible for managing the usage of the available Peer Routing modules. @@ -27,6 +31,8 @@ class PeerRouting { } this._options = libp2p._options.peerRouting + + this._findClosestPeersTask = this._findClosestPeersTask.bind(this) } /** @@ -37,32 +43,21 @@ class PeerRouting { return } - // Start doing queries after `this._options.delay` - this._timeoutId = setTimeout(() => { - // Start runner immediately - this._runPeriodically() - }, this._options.bootDelay) + this._timeoutId = setDelayedInterval( + this._findClosestPeersTask, this._options.interval, this._options.bootDelay + ) } /** - * Run peridocally on every `this._options.interval` ms - * - * @private + * Recurrent task to find closest peers and add their addresses to the Address Book. */ - async _runPeriodically () { - // run until the walk has been stopped - while (this._timeoutId) { - try { - for await (const { id, multiaddrs } of this.getClosestPeers(this._peerId.id)) { - this._peerStore.addressBook.add(id, multiaddrs) - } - } catch (err) { - log.error(err) + async _findClosestPeersTask () { + try { + for await (const { id, multiaddrs } of this.getClosestPeers(this._peerId.id)) { + this._peerStore.addressBook.add(id, multiaddrs) } - // Each subsequent task should run on a `this._options.interval` ms interval - await new Promise(resolve => { - this._timeoutId = setTimeout(resolve, this._options.interval) - }) + } catch (err) { + log.error(err) } } @@ -70,7 +65,7 @@ class PeerRouting { * Stop peer routing service. */ stop () { - clearTimeout(this._timeoutId) + clearDelayedInterval(this._timeoutId) } /** diff --git a/test/peer-routing/peer-routing.node.js b/test/peer-routing/peer-routing.node.js index 06283aa07b..01e88410a0 100644 --- a/test/peer-routing/peer-routing.node.js +++ b/test/peer-routing/peer-routing.node.js @@ -19,7 +19,7 @@ const PeerId = require('peer-id') const peerUtils = require('../utils/creators/peer') const { baseOptions, routingOptions } = require('./utils') -describe.only('peer-routing', () => { +describe('peer-routing', () => { describe('no routers', () => { let node @@ -348,7 +348,7 @@ describe.only('peer-routing', () => { let peerIds before(async () => { - peerIds = await peerUtils.createPeerId({ number: 2}) + peerIds = await peerUtils.createPeerId({ number: 2 }) }) afterEach(() => { @@ -373,7 +373,7 @@ describe.only('peer-routing', () => { }) sinon.spy(node.peerStore.addressBook, 'add') - sinon.stub(node._dht, 'getClosestPeers').callsFake(function* () { + sinon.stub(node._dht, 'getClosestPeers').callsFake(function * () { yield results[0] yield results[1] }) @@ -397,7 +397,7 @@ describe.only('peer-routing', () => { }) it('should support being disabled', async () => { - ;[node] = await peerUtils.createPeer({ + [node] = await peerUtils.createPeer({ config: mergeOptions(routingOptions, { peerRouting: { bootDelay: 100, @@ -407,7 +407,8 @@ describe.only('peer-routing', () => { started: false }) - sinon.stub(node._dht, 'getClosestPeers').callsFake(function* () { + sinon.stub(node._dht, 'getClosestPeers').callsFake(function * () { + yield throw new Error('should not be called') }) @@ -418,7 +419,7 @@ describe.only('peer-routing', () => { }) it('should start and run recurrently on interval', async () => { - ;[node] = await peerUtils.createPeer({ + [node] = await peerUtils.createPeer({ config: mergeOptions(routingOptions, { peerRouting: { interval: 500, @@ -428,7 +429,7 @@ describe.only('peer-routing', () => { started: false }) - sinon.stub(node._dht, 'getClosestPeers').callsFake(function* () { + sinon.stub(node._dht, 'getClosestPeers').callsFake(function * () { yield { id: peerIds[0], multiaddrs: [multiaddr('/ip4/30.0.0.1/tcp/2000')] } }) From d80e86e3cf9b5abf8626b7d016188d43670881ad Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Tue, 24 Nov 2020 16:55:39 +0100 Subject: [PATCH 3/3] chore: address review --- doc/CONFIGURATION.md | 10 ++++++---- package.json | 2 +- src/config.js | 8 +++++--- src/peer-routing.js | 6 +++--- test/peer-routing/peer-routing.node.js | 18 ++++++++++++------ 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/doc/CONFIGURATION.md b/doc/CONFIGURATION.md index aafbc2bc07..99ca2f6de8 100644 --- a/doc/CONFIGURATION.md +++ b/doc/CONFIGURATION.md @@ -397,10 +397,12 @@ const node = await Libp2p.create({ ], }, peerId, - peerRouting: { // Peer routing service configuration - enabled: true, // Should find the closest peers. - interval: 300e3, // Interval for getting the new for closest peers - bootDelay: 10e3 // Delay for the initial query for closest peers + peerRouting: { // Peer routing configuration + refreshManager: { // Refresh known and connected closest peers + enabled: true, // Should find the closest peers. + interval: 6e5, // Interval for getting the new for closest peers of 10min + bootDelay: 10e3 // Delay for the initial query for closest peers + } } }) ``` diff --git a/package.json b/package.json index 3fde77caad..445a37a189 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "protons": "^2.0.0", "retimer": "^2.0.0", "sanitize-filename": "^1.6.3", - "set-delayed-interval": "vasco-santos/set-delayed-interval#feat/initial-implementation", + "set-delayed-interval": "^1.0.0", "streaming-iterables": "^5.0.2", "timeout-abort-controller": "^1.1.1", "varint": "^5.0.0", diff --git a/src/config.js b/src/config.js index 993debab07..739afb1875 100644 --- a/src/config.js +++ b/src/config.js @@ -36,9 +36,11 @@ const DefaultConfig = { threshold: 5 }, peerRouting: { - enabled: true, - interval: 300e3, - bootDelay: 10e3 + refreshManager: { + enabled: true, + interval: 6e5, + bootDelay: 10e3 + } }, config: { dht: { diff --git a/src/peer-routing.js b/src/peer-routing.js index 61caf41712..e783c82f8b 100644 --- a/src/peer-routing.js +++ b/src/peer-routing.js @@ -30,7 +30,7 @@ class PeerRouting { this._routers.unshift(libp2p._dht) } - this._options = libp2p._options.peerRouting + this._refreshManagerOptions = libp2p._options.peerRouting.refreshManager this._findClosestPeersTask = this._findClosestPeersTask.bind(this) } @@ -39,12 +39,12 @@ class PeerRouting { * Start peer routing service. */ start () { - if (!this._routers.length || this._timeoutId || !this._options.enabled) { + if (!this._routers.length || this._timeoutId || !this._refreshManagerOptions.enabled) { return } this._timeoutId = setDelayedInterval( - this._findClosestPeersTask, this._options.interval, this._options.bootDelay + this._findClosestPeersTask, this._refreshManagerOptions.interval, this._refreshManagerOptions.bootDelay ) } diff --git a/test/peer-routing/peer-routing.node.js b/test/peer-routing/peer-routing.node.js index 01e88410a0..74cc6393e6 100644 --- a/test/peer-routing/peer-routing.node.js +++ b/test/peer-routing/peer-routing.node.js @@ -343,7 +343,7 @@ describe('peer-routing', () => { }) }) - describe('peer routing service', () => { + describe('peer routing refresh manager service', () => { let node let peerIds @@ -366,7 +366,9 @@ describe('peer-routing', () => { ;[node] = await peerUtils.createPeer({ config: mergeOptions(routingOptions, { peerRouting: { - bootDelay: 100 + refreshManager: { + bootDelay: 100 + } } }), started: false @@ -400,8 +402,10 @@ describe('peer-routing', () => { [node] = await peerUtils.createPeer({ config: mergeOptions(routingOptions, { peerRouting: { - bootDelay: 100, - enabled: false + refreshManager: { + bootDelay: 100, + enabled: false + } } }), started: false @@ -422,8 +426,10 @@ describe('peer-routing', () => { [node] = await peerUtils.createPeer({ config: mergeOptions(routingOptions, { peerRouting: { - interval: 500, - bootDelay: 200 + refreshManager: { + interval: 500, + bootDelay: 200 + } } }), started: false