From d56ab687504e8b7d7024576b3b7c77473ce8142d Mon Sep 17 00:00:00 2001 From: Jacob Heun Date: Mon, 16 Dec 2019 16:02:04 +0100 Subject: [PATCH] fix: make dialer configurable docs: update configuration and api docs --- doc/API.md | 3 +++ doc/CONFIGURATION.md | 24 ++++++++++++++++++++++++ src/config.js | 6 ++++++ src/constants.js | 6 ------ src/index.js | 5 ++++- test/dialing/direct.spec.js | 25 +++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 7 deletions(-) diff --git a/doc/API.md b/doc/API.md index 651be03d00..8d904e07e0 100644 --- a/doc/API.md +++ b/doc/API.md @@ -46,7 +46,10 @@ Creates an instance of Libp2p. | options | `Object` | libp2p options | | options.modules | `Array` | libp2p modules to use | | [options.config] | `Object` | libp2p modules configuration and core configuration | +| [options.connectionManager] | `Object` | libp2p Connection Manager configuration | | [options.datastore] | `Object` | must implement [ipfs/interface-datastore](https://github.com/ipfs/interface-datastore) (in memory datastore will be used if not provided) | +| [options.dialer] | `Object` | libp2p Dialer configuration +| [options.metrics] | `Object` | libp2p Metrics configuration | [options.peerInfo] | [PeerInfo](https://github.com/libp2p/js-peer-info) | peerInfo instance (it will be created if not provided) | For Libp2p configurations and modules details read the [Configuration Document](./CONFIGURATION.md). diff --git a/doc/CONFIGURATION.md b/doc/CONFIGURATION.md index c0c55b1348..8df6512f19 100644 --- a/doc/CONFIGURATION.md +++ b/doc/CONFIGURATION.md @@ -20,6 +20,7 @@ - [Customizing DHT](#customizing-dht) - [Setup with Content and Peer Routing](#setup-with-content-and-peer-routing) - [Setup with Relay](#setup-with-relay) + - [Configuring Dialing](#configuring-dialing) - [Configuring Connection Manager](#configuring-connection-manager) - [Configuring Metrics](#configuring-metrics) - [Configuration examples](#configuration-examples) @@ -414,6 +415,29 @@ const node = await Libp2p.create({ }) ``` +#### Configuring Dialing + +Dialing in libp2p can be configured to limit the rate of dialing, and how long dials are allowed to take. The below configuration example shows the default values for the dialer. + +```js +const Libp2p = require('libp2p') +const TCP = require('libp2p-tcp') +const MPLEX = require('libp2p-mplex') +const SECIO = require('libp2p-secio') + +const node = await Libp2p.create({ + modules: { + transport: [TCP], + streamMuxer: [MPLEX], + connEncryption: [SECIO] + }, + dialer: { + maxParallelDials: 100, // How many multiaddrs we can dial in parallel + maxDialsPerPeer: 4, // How many multiaddrs we can dial per peer, in parallel + dialTimeout: 30e3 // 30 second dial timeout per peer + } +``` + #### Configuring Connection Manager The Connection Manager prunes Connections in libp2p whenever certain limits are exceeded. If Metrics are enabled, you can also configure the Connection Manager to monitor the bandwidth of libp2p and prune connections as needed. You can read more about what Connection Manager does at [./CONNECTION_MANAGER.md](./CONNECTION_MANAGER.md). The configuration values below show the defaults for Connection Manager. See [./CONNECTION_MANAGER.md](./CONNECTION_MANAGER.md#options) for a full description of the parameters. diff --git a/src/config.js b/src/config.js index 257ec65605..6d365c07f8 100644 --- a/src/config.js +++ b/src/config.js @@ -1,11 +1,17 @@ 'use strict' const mergeOptions = require('merge-options') +const Constants = require('./constants') const DefaultConfig = { connectionManager: { minPeers: 25 }, + dialer: { + maxParallelDials: Constants.MAX_PARALLEL_DIALS, + maxDialsPerPeer: Constants.MAX_PER_PEER_DIALS, + dialTimeout: Constants.DIAL_TIMEOUT + }, metrics: { enabled: false }, diff --git a/src/constants.js b/src/constants.js index a0d5cc7955..08ad156971 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,15 +1,9 @@ 'use strict' module.exports = { - DENY_TTL: 5 * 60 * 1e3, // How long before an errored peer can be dialed again - DENY_ATTEMPTS: 5, // Num of unsuccessful dials before a peer is permanently denied DIAL_TIMEOUT: 30e3, // How long in ms a dial attempt is allowed to take - MAX_COLD_CALLS: 50, // How many dials w/o protocols that can be queued MAX_PARALLEL_DIALS: 100, // Maximum allowed concurrent dials MAX_PER_PEER_DIALS: 4, // Allowed parallel dials per DialRequest - QUARTER_HOUR: 15 * 60e3, - PRIORITY_HIGH: 10, - PRIORITY_LOW: 20, METRICS: { computeThrottleMaxQueueSize: 1000, computeThrottleTimeout: 2000, diff --git a/src/index.js b/src/index.js index 3fc56692ac..36aaa6abbf 100644 --- a/src/index.js +++ b/src/index.js @@ -107,7 +107,10 @@ class Libp2p extends EventEmitter { this.dialer = new Dialer({ transportManager: this.transportManager, - peerStore: this.peerStore + peerStore: this.peerStore, + concurrency: this._options.dialer.maxParallelDials, + perPeerLimit: this._options.dialer.maxDialsPerPeer, + timeout: this._options.dialer.dialTimeout }) this._modules.transport.forEach((Transport) => { diff --git a/test/dialing/direct.spec.js b/test/dialing/direct.spec.js index e7cff9c979..b886b4b700 100644 --- a/test/dialing/direct.spec.js +++ b/test/dialing/direct.spec.js @@ -273,10 +273,35 @@ describe('Dialing (direct, WebSockets)', () => { }) expect(libp2p.dialer).to.exist() + expect(libp2p.dialer.concurrency).to.equal(Constants.MAX_PARALLEL_DIALS) + expect(libp2p.dialer.perPeerLimit).to.equal(Constants.MAX_PER_PEER_DIALS) + expect(libp2p.dialer.timeout).to.equal(Constants.DIAL_TIMEOUT) // Ensure the dialer also has the transport manager expect(libp2p.transportManager).to.equal(libp2p.dialer.transportManager) }) + it('should be able to override dialer options', async () => { + const config = { + peerInfo, + modules: { + transport: [Transport], + streamMuxer: [Muxer], + connEncryption: [Crypto] + }, + dialer: { + maxParallelDials: 10, + maxDialsPerPeer: 1, + dialTimeout: 1e3 // 30 second dial timeout per peer + } + } + libp2p = await Libp2p.create(config) + + expect(libp2p.dialer).to.exist() + expect(libp2p.dialer.concurrency).to.equal(config.dialer.maxParallelDials) + expect(libp2p.dialer.perPeerLimit).to.equal(config.dialer.maxDialsPerPeer) + expect(libp2p.dialer.timeout).to.equal(config.dialer.dialTimeout) + }) + it('should use the dialer for connecting', async () => { libp2p = new Libp2p({ peerInfo,