From d1c1b8028f3854be8e731f8e1ea3c344ff04c288 Mon Sep 17 00:00:00 2001 From: chad Date: Tue, 21 Feb 2023 22:28:24 -0500 Subject: [PATCH 1/3] feat: Allow for alternative connection manager (#1581) --- src/index.ts | 6 ++++++ src/libp2p.ts | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index db2a467ee9..7c454cd6dd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -41,6 +41,7 @@ import type { KeyChainInit } from '@libp2p/keychain' import type { NatManagerInit } from './nat-manager.js' import type { AddressManagerInit } from './address-manager/index.js' import type { PeerRoutingInit } from './peer-routing.js' +import type { ConnectionManager } from '@libp2p/interface-connection-manager' import type { ConnectionManagerInit } from './connection-manager/index.js' /** @@ -149,6 +150,11 @@ export interface Libp2pInit { * A ConnectionProtector can be used to create a secure overlay on top of the network using pre-shared keys */ connectionProtector?: (components: Components) => ConnectionProtector + + /** + * Pass a custom ConnectionManager implementation to enable custom connection management + */ + customConnectionManager?: (components: Components) => ConnectionManager } /** diff --git a/src/libp2p.ts b/src/libp2p.ts index 819f6c3e53..457eeafba2 100644 --- a/src/libp2p.ts +++ b/src/libp2p.ts @@ -133,7 +133,8 @@ export class Libp2pNode extends EventEmitter implements Libp2p { this.components.dialer = new DefaultDialer(this.components, init.connectionManager) // Create the Connection Manager - this.connectionManager = this.components.connectionManager = new DefaultConnectionManager(this.components, init.connectionManager) + // if a connection manager is not provided, create a default one + this.connectionManager = (init.customConnectionManager != null) ? init.customConnectionManager(this.components) : this.components.connectionManager = new DefaultConnectionManager(this.components, init.connectionManager) // forward connection manager events this.components.connectionManager.addEventListener('peer:disconnect', (event) => { From 8aead1a5f3da0196dd51f2df0bd6f19518cde3b1 Mon Sep 17 00:00:00 2001 From: chad Date: Sat, 25 Feb 2023 13:31:58 -0500 Subject: [PATCH 2/3] refactor to seperate dialer and connection manager configs --- src/circuit/index.ts | 9 ++--- src/config.ts | 19 ++++++---- src/connection-manager/dialer/index.ts | 39 ++++++++++++++------ src/connection-manager/index.ts | 51 +++----------------------- src/index.ts | 10 ++++- src/libp2p.ts | 19 +++++----- 6 files changed, 65 insertions(+), 82 deletions(-) diff --git a/src/circuit/index.ts b/src/circuit/index.ts index a5870fbc71..c43f894014 100644 --- a/src/circuit/index.ts +++ b/src/circuit/index.ts @@ -23,6 +23,7 @@ export interface RelayConfig extends StreamHandlerOptions { advertise: RelayAdvertiseConfig hop: HopConfig autoRelay: AutoRelayConfig + addressSorter?: AddressSorter } export interface HopConfig { @@ -48,10 +49,6 @@ export interface AutoRelayConfig { maxListeners: number } -export interface RelayInit extends RelayConfig { - addressSorter?: AddressSorter -} - export interface RelayComponents { peerId: PeerId contentRouting: ContentRouting @@ -62,7 +59,7 @@ export interface RelayComponents { export class Relay implements Startable { private readonly components: RelayComponents - private readonly init: RelayInit + private readonly init: RelayConfig // @ts-expect-error this field isn't used anywhere? private readonly autoRelay?: AutoRelay private timeout?: any @@ -71,7 +68,7 @@ export class Relay implements Startable { /** * Creates an instance of Relay */ - constructor (components: RelayComponents, init: RelayInit) { + constructor (components: RelayComponents, init: RelayConfig) { this.components = components // Create autoRelay if enabled this.autoRelay = init.autoRelay?.enabled !== false diff --git a/src/config.ts b/src/config.ts index e856061c99..35b39547de 100644 --- a/src/config.ts +++ b/src/config.ts @@ -12,26 +12,29 @@ import errCode from 'err-code' import type { RecursivePartial } from '@libp2p/interfaces' import { isNode, isBrowser, isWebWorker, isElectronMain, isElectronRenderer, isReactNative } from 'wherearewe' -const DefaultConfig: Partial = { +export const DefaultConfig: Partial = { addresses: { listen: [], announce: [], noAnnounce: [], announceFilter: (multiaddrs: Multiaddr[]) => multiaddrs }, - connectionManager: { + connectionManagerConfig: { maxConnections: 300, minConnections: 50, + + resolvers: { + dnsaddr: dnsaddrResolver + } + }, + dialer: { + addressSorter: publicAddressesFirst, + inboundUpgradeTimeout: Constants.INBOUND_UPGRADE_TIMEOUT, autoDial: true, autoDialInterval: 10000, maxParallelDials: Constants.MAX_PARALLEL_DIALS, maxDialsPerPeer: Constants.MAX_PER_PEER_DIALS, - dialTimeout: Constants.DIAL_TIMEOUT, - inboundUpgradeTimeout: Constants.INBOUND_UPGRADE_TIMEOUT, - resolvers: { - dnsaddr: dnsaddrResolver - }, - addressSorter: publicAddressesFirst + dialTimeout: Constants.DIAL_TIMEOUT }, connectionGater: {}, transportManager: { diff --git a/src/connection-manager/dialer/index.ts b/src/connection-manager/dialer/index.ts index 4aa81e971d..58b7a02a4c 100644 --- a/src/connection-manager/dialer/index.ts +++ b/src/connection-manager/dialer/index.ts @@ -50,20 +50,37 @@ export interface DialerInit { addressSorter?: AddressSorter /** - * Number of max concurrent dials + * If true, try to connect to all discovered peers up to the connection manager limit */ - maxParallelDials?: number + autoDial?: boolean /** - * Number of max addresses to dial for a given peer + * How long to wait between attempting to keep our number of concurrent connections + * above minConnections */ - maxAddrsToDial?: number + autoDialInterval: number /** * How long a dial attempt is allowed to take */ dialTimeout?: number + /** + * When a new inbound connection is opened, the upgrade process (e.g. protect, + * encrypt, multiplex etc) must complete within this number of ms. + */ + inboundUpgradeTimeout: number + + /** + * Number of max concurrent dials + */ + maxParallelDials?: number + + /** + * Number of max addresses to dial for a given peer + */ + maxAddrsToDial?: number + /** * Number of max concurrent dials per peer */ @@ -94,13 +111,13 @@ export class DefaultDialer implements Startable, Dialer { public pendingDialTargets: Map private started: boolean - constructor (components: DefaultDialerComponents, init: DialerInit = {}) { + constructor (components: DefaultDialerComponents, dialerInit?: DialerInit) { this.started = false - this.addressSorter = init.addressSorter ?? publicAddressesFirst - this.maxAddrsToDial = init.maxAddrsToDial ?? MAX_ADDRS_TO_DIAL - this.timeout = init.dialTimeout ?? DIAL_TIMEOUT - this.maxDialsPerPeer = init.maxDialsPerPeer ?? MAX_PER_PEER_DIALS - this.tokens = [...new Array(init.maxParallelDials ?? MAX_PARALLEL_DIALS)].map((_, index) => index) + this.addressSorter = dialerInit?.addressSorter ?? publicAddressesFirst + this.maxAddrsToDial = dialerInit?.maxAddrsToDial ?? MAX_ADDRS_TO_DIAL + this.timeout = dialerInit?.dialTimeout ?? DIAL_TIMEOUT + this.maxDialsPerPeer = dialerInit?.maxDialsPerPeer ?? MAX_PER_PEER_DIALS + this.tokens = [...new Array(dialerInit?.maxParallelDials ?? MAX_PARALLEL_DIALS)].map((_, index) => index) this.components = components this.pendingDials = trackedMap({ name: 'libp2p_dialler_pending_dials', @@ -111,7 +128,7 @@ export class DefaultDialer implements Startable, Dialer { metrics: components.metrics }) - for (const [key, value] of Object.entries(init.resolvers ?? {})) { + for (const [key, value] of Object.entries(dialerInit?.resolvers ?? {})) { resolvers.set(key, value) } } diff --git a/src/connection-manager/index.ts b/src/connection-manager/index.ts index c22e59ec5b..8bb7be60ef 100644 --- a/src/connection-manager/index.ts +++ b/src/connection-manager/index.ts @@ -11,7 +11,7 @@ import { setMaxListeners } from 'events' import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection' import type { ConnectionManager, ConnectionManagerEvents, Dialer } from '@libp2p/interface-connection-manager' import * as STATUS from '@libp2p/interface-connection/status' -import type { AddressSorter, PeerStore } from '@libp2p/interface-peer-store' +import type { PeerStore } from '@libp2p/interface-peer-store' import { multiaddr, Multiaddr, Resolver } from '@multiformats/multiaddr' import { PeerMap } from '@libp2p/peer-collections' import { TimeoutController } from 'timeout-abort-controller' @@ -45,47 +45,9 @@ export interface ConnectionManagerConfig { pollInterval?: number /** - * If true, try to connect to all discovered peers up to the connection manager limit + * The abort signal to use for timeouts when opening connections to peers */ - autoDial?: boolean - - /** - * How long to wait between attempting to keep our number of concurrent connections - * above minConnections - */ - autoDialInterval: number - - /** - * Sort the known addresses of a peer before trying to dial - */ - addressSorter?: AddressSorter - - /** - * Number of max concurrent dials - */ - maxParallelDials?: number - - /** - * Number of max addresses to dial for a given peer - */ - maxAddrsToDial?: number - - /** - * How long a dial attempt is allowed to take, including DNS resolution - * of the multiaddr, opening a socket and upgrading it to a Connection. - */ - dialTimeout?: number - - /** - * When a new inbound connection is opened, the upgrade process (e.g. protect, - * encrypt, multiplex etc) must complete within this number of ms. - */ - inboundUpgradeTimeout: number - - /** - * Number of max concurrent dials per peer - */ - maxDialsPerPeer?: number + outgoingDialTimeout?: number /** * Multiaddr resolvers to use when dialing @@ -128,7 +90,6 @@ const defaultOptions: Partial = { minConnections: 0, maxEventLoopDelay: Infinity, pollInterval: 2000, - autoDialInterval: 10000, inboundConnectionThreshold: 5, maxIncomingPendingConnections: 10 } @@ -156,7 +117,7 @@ export class DefaultConnectionManager extends EventEmitter multiaddr(ma)) this.deny = (init.deny ?? []).map(ma => multiaddr(ma)) @@ -496,7 +457,7 @@ export class DefaultConnectionManager extends EventEmitter ConnectionManager + connectionManager?: (components: Components) => ConnectionManager } /** diff --git a/src/libp2p.ts b/src/libp2p.ts index 457eeafba2..cc207075a2 100644 --- a/src/libp2p.ts +++ b/src/libp2p.ts @@ -122,19 +122,19 @@ export class Libp2pNode extends EventEmitter implements Libp2p { this.components.connectionProtector = init.connectionProtector(components) } + // Create the Connection Manager + // if a connection manager is not provided, create a default one + this.connectionManager = (init.connectionManager != null) ? init.connectionManager(this.components) : this.components.connectionManager = new DefaultConnectionManager(this.components, init.connectionManagerConfig) + // Set up the Upgrader this.components.upgrader = new DefaultUpgrader(this.components, { connectionEncryption: (init.connectionEncryption ?? []).map(fn => this.configureComponent(fn(this.components))), muxers: (init.streamMuxers ?? []).map(fn => this.configureComponent(fn(this.components))), - inboundUpgradeTimeout: init.connectionManager.inboundUpgradeTimeout + inboundUpgradeTimeout: init.dialer.inboundUpgradeTimeout }) // Create the dialer - this.components.dialer = new DefaultDialer(this.components, init.connectionManager) - - // Create the Connection Manager - // if a connection manager is not provided, create a default one - this.connectionManager = (init.customConnectionManager != null) ? init.customConnectionManager(this.components) : this.components.connectionManager = new DefaultConnectionManager(this.components, init.connectionManager) + this.components.dialer = new DefaultDialer(this.components, init.dialer) // forward connection manager events this.components.connectionManager.addEventListener('peer:disconnect', (event) => { @@ -157,9 +157,9 @@ export class Libp2pNode extends EventEmitter implements Libp2p { this.configureComponent(new PeerRecordUpdater(this.components)) this.configureComponent(new AutoDialler(this.components, { - enabled: init.connectionManager.autoDial, - minConnections: init.connectionManager.minConnections, - autoDialInterval: init.connectionManager.autoDialInterval + enabled: init.dialer.autoDial, + minConnections: init.connectionManagerConfig.minConnections, + autoDialInterval: init.dialer.autoDialInterval })) // Create keychain @@ -231,7 +231,6 @@ export class Libp2pNode extends EventEmitter implements Libp2p { this.components.transportManager.add(this.configureComponent(new Circuit(this.components, init.relay))) this.configureComponent(new Relay(this.components, { - addressSorter: init.connectionManager.addressSorter, ...init.relay })) } From dbcece3b8504bc75ad41fe431e4df35800b06b95 Mon Sep 17 00:00:00 2001 From: chad Date: Sun, 26 Feb 2023 15:11:41 -0500 Subject: [PATCH 3/3] fix: refactored tests to instantiate default dialer (#1581) --- src/config.ts | 1 - src/connection-manager/dialer/index.ts | 4 +-- src/libp2p.ts | 2 +- test/connection-manager/index.node.ts | 43 +++++++++++++++++++------- test/dialing/direct.node.ts | 8 +++-- test/dialing/direct.spec.ts | 8 +++-- test/fetch/index.spec.ts | 10 ++++-- test/identify/index.spec.ts | 5 ++- test/identify/push.spec.ts | 5 ++- test/ping/index.spec.ts | 9 ++++-- test/registrar/registrar.spec.ts | 4 +-- 11 files changed, 67 insertions(+), 32 deletions(-) diff --git a/src/config.ts b/src/config.ts index 35b39547de..1b94d5004f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -22,7 +22,6 @@ export const DefaultConfig: Partial = { connectionManagerConfig: { maxConnections: 300, minConnections: 50, - resolvers: { dnsaddr: dnsaddrResolver } diff --git a/src/connection-manager/dialer/index.ts b/src/connection-manager/dialer/index.ts index 58b7a02a4c..e475636704 100644 --- a/src/connection-manager/dialer/index.ts +++ b/src/connection-manager/dialer/index.ts @@ -58,7 +58,7 @@ export interface DialerInit { * How long to wait between attempting to keep our number of concurrent connections * above minConnections */ - autoDialInterval: number + autoDialInterval?: number /** * How long a dial attempt is allowed to take @@ -69,7 +69,7 @@ export interface DialerInit { * When a new inbound connection is opened, the upgrade process (e.g. protect, * encrypt, multiplex etc) must complete within this number of ms. */ - inboundUpgradeTimeout: number + inboundUpgradeTimeout?: number /** * Number of max concurrent dials diff --git a/src/libp2p.ts b/src/libp2p.ts index cc207075a2..3450952250 100644 --- a/src/libp2p.ts +++ b/src/libp2p.ts @@ -130,7 +130,7 @@ export class Libp2pNode extends EventEmitter implements Libp2p { this.components.upgrader = new DefaultUpgrader(this.components, { connectionEncryption: (init.connectionEncryption ?? []).map(fn => this.configureComponent(fn(this.components))), muxers: (init.streamMuxers ?? []).map(fn => this.configureComponent(fn(this.components))), - inboundUpgradeTimeout: init.dialer.inboundUpgradeTimeout + inboundUpgradeTimeout: init.dialer.inboundUpgradeTimeout ?? 10000 }) // Create the dialer diff --git a/test/connection-manager/index.node.ts b/test/connection-manager/index.node.ts index 8de955eeb1..df2c739033 100644 --- a/test/connection-manager/index.node.ts +++ b/test/connection-manager/index.node.ts @@ -13,12 +13,13 @@ import { stubInterface } from 'sinon-ts' import type { KeyBook, PeerStore } from '@libp2p/interface-peer-store' import sinon from 'sinon' import pWaitFor from 'p-wait-for' -import type { Connection } from '@libp2p/interface-connection' +import type { Connection, ConnectionGater } from '@libp2p/interface-connection' import delay from 'delay' import type { Libp2pNode } from '../../src/libp2p.js' import { codes } from '../../src/errors.js' import { start } from '@libp2p/interfaces/startable' -import type { Dialer } from '@libp2p/interface-connection-manager' +import { DefaultDialer } from '../../src/connection-manager/dialer/index.js' +import type { TransportManager } from '@libp2p/interface-transport' describe('Connection Manager', () => { let libp2p: Libp2p @@ -49,18 +50,28 @@ describe('Connection Manager', () => { it('should filter connections on disconnect, removing the closed one', async () => { const upgrader = mockUpgrader() const peerStore = stubInterface() + const peerId = peerIds[0] peerStore.keyBook = stubInterface() + const dialer = new DefaultDialer({ + peerId, + peerStore, + transportManager: stubInterface(), + connectionGater: stubInterface() + }, + { + autoDialInterval: 1000, + inboundUpgradeTimeout: 1000 + }) + const connectionManager = new DefaultConnectionManager({ - peerId: peerIds[0], - dialer: stubInterface(), + peerId, + dialer, upgrader, peerStore }, { maxConnections: 1000, - minConnections: 50, - autoDialInterval: 1000, - inboundUpgradeTimeout: 1000 + minConnections: 5 }) await start(connectionManager) @@ -89,18 +100,28 @@ describe('Connection Manager', () => { it('should close connections on stop', async () => { const upgrader = mockUpgrader() const peerStore = stubInterface() + const peerId = peerIds[0] peerStore.keyBook = stubInterface() + const dialer = new DefaultDialer({ + peerId, + peerStore, + transportManager: stubInterface(), + connectionGater: stubInterface() + }, + { + autoDialInterval: 1000, + inboundUpgradeTimeout: 1000 + }) + const connectionManager = new DefaultConnectionManager({ peerId: peerIds[0], - dialer: stubInterface(), + dialer, upgrader, peerStore }, { maxConnections: 1000, - minConnections: 50, - autoDialInterval: 1000, - inboundUpgradeTimeout: 1000 + minConnections: 50 }) await start(connectionManager) diff --git a/test/dialing/direct.node.ts b/test/dialing/direct.node.ts index 86ff236db8..f947244050 100644 --- a/test/dialing/direct.node.ts +++ b/test/dialing/direct.node.ts @@ -78,12 +78,14 @@ describe('Dialing (direct, TCP)', () => { connectionGater: mockConnectionGater() }) localComponents.peerStore = new PersistentPeerStore(localComponents) - localComponents.connectionManager = new DefaultConnectionManager(localComponents, { - maxConnections: 100, - minConnections: 50, + localComponents.dialer = new DefaultDialer(localComponents, { autoDialInterval: 1000, inboundUpgradeTimeout: 1000 }) + localComponents.connectionManager = new DefaultConnectionManager(localComponents, { + maxConnections: 100, + minConnections: 50 + }) localTM = new DefaultTransportManager(localComponents) localTM.add(tcp()()) diff --git a/test/dialing/direct.spec.ts b/test/dialing/direct.spec.ts index 1084db1270..bb12647026 100644 --- a/test/dialing/direct.spec.ts +++ b/test/dialing/direct.spec.ts @@ -50,12 +50,14 @@ describe('Dialing (direct, WebSockets)', () => { localComponents.peerStore = new PersistentPeerStore(localComponents, { addressFilter: localComponents.connectionGater.filterMultiaddrForPeer }) - localComponents.connectionManager = new DefaultConnectionManager(localComponents, { - maxConnections: 100, - minConnections: 50, + localComponents.dialer = new DefaultDialer(localComponents, { autoDialInterval: 1000, inboundUpgradeTimeout: 1000 }) + localComponents.connectionManager = new DefaultConnectionManager(localComponents, { + maxConnections: 100, + minConnections: 50 + }) localTM = new DefaultTransportManager(localComponents) localTM.add(webSockets({ filter: filters.all })()) diff --git a/test/fetch/index.spec.ts b/test/fetch/index.spec.ts index 27a7e80db3..9c75c40b79 100644 --- a/test/fetch/index.spec.ts +++ b/test/fetch/index.spec.ts @@ -15,6 +15,7 @@ import { pipe } from 'it-pipe' import { PersistentPeerStore } from '@libp2p/peer-store' import { MemoryDatastore } from 'datastore-core' import { DefaultComponents } from '../../src/components.js' +import { DefaultDialer } from '../../src/connection-manager/dialer/index.js' const defaultInit: FetchServiceInit = { protocolPrefix: 'ipfs', @@ -33,12 +34,15 @@ async function createComponents (index: number) { datastore: new MemoryDatastore() }) components.peerStore = new PersistentPeerStore(components) - components.connectionManager = new DefaultConnectionManager(components, { - minConnections: 50, - maxConnections: 1000, + components.dialer = new DefaultDialer(components, { autoDialInterval: 1000, inboundUpgradeTimeout: 1000 }) + components.connectionManager = new DefaultConnectionManager(components, { + minConnections: 50, + maxConnections: 1000 + + }) return components } diff --git a/test/identify/index.spec.ts b/test/identify/index.spec.ts index 5a5f0b247e..4bb78815e2 100644 --- a/test/identify/index.spec.ts +++ b/test/identify/index.spec.ts @@ -29,6 +29,7 @@ import { TimeoutController } from 'timeout-abort-controller' import { CustomEvent } from '@libp2p/interfaces/events' import pDefer from 'p-defer' import { DefaultComponents } from '../../src/components.js' +import { DefaultDialer } from '../../src/connection-manager/dialer/index.js' const listenMaddrs = [multiaddr('/ip4/127.0.0.1/tcp/15002/ws')] @@ -59,7 +60,9 @@ async function createComponents (index: number) { components.peerStore = new PersistentPeerStore(components) components.connectionManager = new DefaultConnectionManager(components, { minConnections: 50, - maxConnections: 1000, + maxConnections: 1000 + }) + components.dialer = new DefaultDialer(components, { autoDialInterval: 1000, inboundUpgradeTimeout: 1000 }) diff --git a/test/identify/push.spec.ts b/test/identify/push.spec.ts index c6482aecce..e612e6ede4 100644 --- a/test/identify/push.spec.ts +++ b/test/identify/push.spec.ts @@ -26,6 +26,7 @@ import { start, stop } from '@libp2p/interfaces/startable' import { stubInterface } from 'sinon-ts' import type { Dialer } from '@libp2p/interface-connection-manager' import { DefaultComponents } from '../../src/components.js' +import { DefaultDialer } from '../../src/connection-manager/dialer/index.js' const listenMaddrs = [multiaddr('/ip4/127.0.0.1/tcp/15002/ws')] @@ -57,7 +58,9 @@ async function createComponents (index: number): Promise { components.peerStore = new PersistentPeerStore(components) components.connectionManager = new DefaultConnectionManager(components, { minConnections: 50, - maxConnections: 1000, + maxConnections: 1000 + }) + components.dialer = new DefaultDialer(components, { autoDialInterval: 1000, inboundUpgradeTimeout: 1000 }) diff --git a/test/ping/index.spec.ts b/test/ping/index.spec.ts index 4fedd39806..808be0b713 100644 --- a/test/ping/index.spec.ts +++ b/test/ping/index.spec.ts @@ -15,6 +15,7 @@ import { pipe } from 'it-pipe' import { PersistentPeerStore } from '@libp2p/peer-store' import { MemoryDatastore } from 'datastore-core' import { DefaultComponents } from '../../src/components.js' +import { DefaultDialer } from '../../src/connection-manager/dialer/index.js' const defaultInit: PingServiceInit = { protocolPrefix: 'ipfs', @@ -33,12 +34,14 @@ async function createComponents (index: number): Promise { datastore: new MemoryDatastore() }) components.peerStore = new PersistentPeerStore(components) - components.connectionManager = new DefaultConnectionManager(components, { - minConnections: 50, - maxConnections: 1000, + components.dialer = new DefaultDialer(components, { autoDialInterval: 1000, inboundUpgradeTimeout: 1000 }) + components.connectionManager = new DefaultConnectionManager(components, { + minConnections: 50, + maxConnections: 1000 + }) return components } diff --git a/test/registrar/registrar.spec.ts b/test/registrar/registrar.spec.ts index d9fac96a4f..09fe237a27 100644 --- a/test/registrar/registrar.spec.ts +++ b/test/registrar/registrar.spec.ts @@ -43,9 +43,7 @@ describe('registrar', () => { components.peerStore = new PersistentPeerStore(components) components.connectionManager = new DefaultConnectionManager(components, { minConnections: 50, - maxConnections: 1000, - autoDialInterval: 1000, - inboundUpgradeTimeout: 1000 + maxConnections: 1000 }) registrar = new DefaultRegistrar(components) })