libp2p 0.43.4 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.min.js +30 -30
- package/dist/src/autonat/index.d.ts +1 -2
- package/dist/src/autonat/index.d.ts.map +1 -1
- package/dist/src/autonat/index.js +4 -6
- package/dist/src/autonat/index.js.map +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.d.ts +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
- package/dist/src/circuit-relay/utils.d.ts.map +1 -1
- package/dist/src/circuit-relay/utils.js +3 -1
- package/dist/src/circuit-relay/utils.js.map +1 -1
- package/dist/src/components.d.ts +1 -6
- package/dist/src/components.d.ts.map +1 -1
- package/dist/src/components.js +0 -10
- package/dist/src/components.js.map +1 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +0 -9
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection-manager/auto-dial.d.ts +36 -0
- package/dist/src/connection-manager/auto-dial.d.ts.map +1 -0
- package/dist/src/connection-manager/auto-dial.js +122 -0
- package/dist/src/connection-manager/auto-dial.js.map +1 -0
- package/dist/src/connection-manager/connection-pruner.d.ts +28 -0
- package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -0
- package/dist/src/connection-manager/connection-pruner.js +96 -0
- package/dist/src/connection-manager/connection-pruner.js.map +1 -0
- package/dist/src/connection-manager/constants.d.ts +49 -0
- package/dist/src/connection-manager/constants.d.ts.map +1 -0
- package/dist/src/connection-manager/constants.js +49 -0
- package/dist/src/connection-manager/constants.js.map +1 -0
- package/dist/src/connection-manager/dial-queue.d.ts +77 -0
- package/dist/src/connection-manager/dial-queue.d.ts.map +1 -0
- package/dist/src/connection-manager/dial-queue.js +366 -0
- package/dist/src/connection-manager/dial-queue.js.map +1 -0
- package/dist/src/connection-manager/index.d.ts +65 -69
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/connection-manager/index.js +116 -234
- package/dist/src/connection-manager/index.js.map +1 -1
- package/dist/src/connection-manager/utils.d.ts +9 -0
- package/dist/src/connection-manager/utils.d.ts.map +1 -0
- package/dist/src/connection-manager/utils.js +66 -0
- package/dist/src/connection-manager/utils.js.map +1 -0
- package/dist/src/fetch/index.js +3 -3
- package/dist/src/fetch/index.js.map +1 -1
- package/dist/src/identify/index.js +5 -5
- package/dist/src/identify/index.js.map +1 -1
- package/dist/src/insecure/index.d.ts.map +1 -1
- package/dist/src/insecure/index.js +3 -1
- package/dist/src/insecure/index.js.map +1 -1
- package/dist/src/libp2p.d.ts +10 -2
- package/dist/src/libp2p.d.ts.map +1 -1
- package/dist/src/libp2p.js +7 -13
- package/dist/src/libp2p.js.map +1 -1
- package/dist/src/upgrader.d.ts +1 -1
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +2 -1
- package/dist/src/upgrader.js.map +1 -1
- package/dist/typedoc-urls.json +1 -1
- package/package.json +18 -18
- package/src/autonat/index.ts +6 -9
- package/src/circuit-relay/transport/reservation-store.ts +1 -1
- package/src/circuit-relay/utils.ts +3 -1
- package/src/components.ts +1 -17
- package/src/config.ts +0 -9
- package/src/connection-manager/auto-dial.ts +171 -0
- package/src/connection-manager/connection-pruner.ts +137 -0
- package/src/connection-manager/constants.ts +60 -0
- package/src/connection-manager/dial-queue.ts +504 -0
- package/src/connection-manager/index.ts +190 -323
- package/src/connection-manager/utils.ts +76 -0
- package/src/fetch/index.ts +4 -4
- package/src/identify/index.ts +5 -5
- package/src/insecure/index.ts +5 -1
- package/src/libp2p.ts +17 -15
- package/src/upgrader.ts +3 -2
- package/src/version.ts +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts +0 -42
- package/dist/src/connection-manager/auto-dialler.d.ts.map +0 -1
- package/dist/src/connection-manager/auto-dialler.js +0 -105
- package/dist/src/connection-manager/auto-dialler.js.map +0 -1
- package/dist/src/connection-manager/dialer/dial-request.d.ts +0 -27
- package/dist/src/connection-manager/dialer/dial-request.d.ts.map +0 -1
- package/dist/src/connection-manager/dialer/dial-request.js +0 -114
- package/dist/src/connection-manager/dialer/dial-request.js.map +0 -1
- package/dist/src/connection-manager/dialer/index.d.ts +0 -121
- package/dist/src/connection-manager/dialer/index.d.ts.map +0 -1
- package/dist/src/connection-manager/dialer/index.js +0 -324
- package/dist/src/connection-manager/dialer/index.js.map +0 -1
- package/dist/src/connection-manager/latency-monitor.d.ts +0 -120
- package/dist/src/connection-manager/latency-monitor.d.ts.map +0 -1
- package/dist/src/connection-manager/latency-monitor.js +0 -220
- package/dist/src/connection-manager/latency-monitor.js.map +0 -1
- package/dist/src/connection-manager/visibility-change-emitter.d.ts +0 -66
- package/dist/src/connection-manager/visibility-change-emitter.d.ts.map +0 -1
- package/dist/src/connection-manager/visibility-change-emitter.js +0 -118
- package/dist/src/connection-manager/visibility-change-emitter.js.map +0 -1
- package/dist/src/constants.d.ts +0 -27
- package/dist/src/constants.d.ts.map +0 -1
- package/dist/src/constants.js +0 -31
- package/dist/src/constants.js.map +0 -1
- package/src/connection-manager/auto-dialler.ts +0 -158
- package/src/connection-manager/dialer/dial-request.ts +0 -144
- package/src/connection-manager/dialer/index.ts +0 -461
- package/src/connection-manager/latency-monitor.ts +0 -319
- package/src/connection-manager/visibility-change-emitter.ts +0 -135
- package/src/constants.ts +0 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libp2p",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p#readme",
|
|
@@ -102,10 +102,10 @@
|
|
|
102
102
|
"@achingbrain/nat-port-mapper": "^1.0.3",
|
|
103
103
|
"@libp2p/crypto": "^1.0.4",
|
|
104
104
|
"@libp2p/interface-address-manager": "^2.0.0",
|
|
105
|
-
"@libp2p/interface-connection": "^
|
|
105
|
+
"@libp2p/interface-connection": "^4.0.0",
|
|
106
106
|
"@libp2p/interface-connection-encrypter": "^3.0.1",
|
|
107
|
-
"@libp2p/interface-connection-gater": "^
|
|
108
|
-
"@libp2p/interface-connection-manager": "^
|
|
107
|
+
"@libp2p/interface-connection-gater": "^2.0.1",
|
|
108
|
+
"@libp2p/interface-connection-manager": "^2.1.0",
|
|
109
109
|
"@libp2p/interface-content-routing": "^2.0.0",
|
|
110
110
|
"@libp2p/interface-dht": "^2.0.0",
|
|
111
111
|
"@libp2p/interface-keychain": "^2.0.4",
|
|
@@ -136,21 +136,21 @@
|
|
|
136
136
|
"@multiformats/mafmt": "^12.0.0",
|
|
137
137
|
"@multiformats/multiaddr": "^12.0.0",
|
|
138
138
|
"abortable-iterator": "^4.0.2",
|
|
139
|
-
"any-signal": "^
|
|
139
|
+
"any-signal": "^4.1.1",
|
|
140
140
|
"datastore-core": "^9.0.0",
|
|
141
141
|
"interface-datastore": "^8.0.0",
|
|
142
|
-
"it-all": "^
|
|
143
|
-
"it-drain": "^
|
|
144
|
-
"it-filter": "^
|
|
145
|
-
"it-first": "^
|
|
146
|
-
"it-parallel": "^3.0.0",
|
|
142
|
+
"it-all": "^3.0.1",
|
|
143
|
+
"it-drain": "^3.0.1",
|
|
144
|
+
"it-filter": "^3.0.1",
|
|
145
|
+
"it-first": "^3.0.1",
|
|
147
146
|
"it-handshake": "^4.1.2",
|
|
148
|
-
"it-length-prefixed": "^
|
|
149
|
-
"it-map": "^
|
|
150
|
-
"it-merge": "^
|
|
147
|
+
"it-length-prefixed": "^9.0.0",
|
|
148
|
+
"it-map": "^3.0.2",
|
|
149
|
+
"it-merge": "^3.0.0",
|
|
151
150
|
"it-pair": "^2.0.2",
|
|
151
|
+
"it-parallel": "^3.0.0",
|
|
152
152
|
"it-pb-stream": "^3.2.0",
|
|
153
|
-
"it-pipe": "^
|
|
153
|
+
"it-pipe": "^3.0.1",
|
|
154
154
|
"it-stream-types": "^1.0.4",
|
|
155
155
|
"merge-options": "^3.0.4",
|
|
156
156
|
"multiformats": "^11.0.0",
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
"devDependencies": {
|
|
173
173
|
"@chainsafe/libp2p-gossipsub": "^6.2.0",
|
|
174
174
|
"@chainsafe/libp2p-noise": "^11.0.0",
|
|
175
|
-
"@chainsafe/libp2p-yamux": "^3.0.
|
|
175
|
+
"@chainsafe/libp2p-yamux": "^3.0.8",
|
|
176
176
|
"@libp2p/bootstrap": "^6.0.0",
|
|
177
177
|
"@libp2p/daemon-client": "^5.0.0",
|
|
178
178
|
"@libp2p/daemon-server": "^4.1.0",
|
|
@@ -182,9 +182,9 @@
|
|
|
182
182
|
"@libp2p/interface-connection-encrypter-compliance-tests": "^4.0.0",
|
|
183
183
|
"@libp2p/interface-mocks": "^9.0.0",
|
|
184
184
|
"@libp2p/interop": "^7.0.0",
|
|
185
|
-
"@libp2p/kad-dht": "^8.0.
|
|
185
|
+
"@libp2p/kad-dht": "^8.0.7",
|
|
186
186
|
"@libp2p/mdns": "^7.0.0",
|
|
187
|
-
"@libp2p/mplex": "^7.
|
|
187
|
+
"@libp2p/mplex": "^7.1.6",
|
|
188
188
|
"@libp2p/pubsub": "^6.0.0",
|
|
189
189
|
"@libp2p/tcp": "^6.0.0",
|
|
190
190
|
"@libp2p/websockets": "^5.0.0",
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
"execa": "^7.0.0",
|
|
198
198
|
"go-libp2p": "^1.0.1",
|
|
199
199
|
"it-pushable": "^3.0.0",
|
|
200
|
-
"it-to-buffer": "^
|
|
200
|
+
"it-to-buffer": "^4.0.1",
|
|
201
201
|
"npm-run-all": "^4.1.5",
|
|
202
202
|
"p-event": "^5.0.1",
|
|
203
203
|
"p-times": "^4.0.0",
|
package/src/autonat/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AddressManager } from '@libp2p/interface-address-manager'
|
|
2
2
|
import type { Connection } from '@libp2p/interface-connection'
|
|
3
|
-
import type { ConnectionManager
|
|
3
|
+
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
|
|
4
4
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
5
5
|
import type { PeerInfo } from '@libp2p/interface-peer-info'
|
|
6
6
|
import type { PeerRouting } from '@libp2p/interface-peer-routing'
|
|
@@ -74,7 +74,6 @@ export interface DefaultAutonatComponents {
|
|
|
74
74
|
registrar: Registrar
|
|
75
75
|
addressManager: AddressManager
|
|
76
76
|
transportManager: TransportManager
|
|
77
|
-
dialer: Dialer
|
|
78
77
|
peerId: PeerId
|
|
79
78
|
connectionManager: ConnectionManager
|
|
80
79
|
peerRouting: PeerRouting
|
|
@@ -151,7 +150,7 @@ export class AutonatService implements Startable {
|
|
|
151
150
|
|
|
152
151
|
await pipe(
|
|
153
152
|
source,
|
|
154
|
-
lp.decode(),
|
|
153
|
+
(source) => lp.decode(source),
|
|
155
154
|
async function * (stream) {
|
|
156
155
|
const buf = await first(stream)
|
|
157
156
|
|
|
@@ -319,9 +318,7 @@ export class AutonatService implements Startable {
|
|
|
319
318
|
lastMultiaddr = multiaddr
|
|
320
319
|
|
|
321
320
|
try {
|
|
322
|
-
|
|
323
|
-
// multiaddr for the peer
|
|
324
|
-
connection = await self.components.dialer.dial(multiaddr, {
|
|
321
|
+
connection = await self.components.connectionManager.openConnection(multiaddr, {
|
|
325
322
|
signal: controller.signal
|
|
326
323
|
})
|
|
327
324
|
|
|
@@ -360,7 +357,7 @@ export class AutonatService implements Startable {
|
|
|
360
357
|
}
|
|
361
358
|
})
|
|
362
359
|
},
|
|
363
|
-
lp.encode(),
|
|
360
|
+
(source) => lp.encode(source),
|
|
364
361
|
// pipe to the stream, not the abortable source other wise we
|
|
365
362
|
// can't tell the remote when a dial timed out..
|
|
366
363
|
data.stream
|
|
@@ -449,9 +446,9 @@ export class AutonatService implements Startable {
|
|
|
449
446
|
|
|
450
447
|
const buf = await pipe(
|
|
451
448
|
[request],
|
|
452
|
-
lp.encode(),
|
|
449
|
+
(source) => lp.encode(source),
|
|
453
450
|
source,
|
|
454
|
-
lp.decode(),
|
|
451
|
+
(source) => lp.decode(source),
|
|
455
452
|
async (stream) => await first(stream)
|
|
456
453
|
)
|
|
457
454
|
if (buf == null) {
|
|
@@ -10,7 +10,7 @@ import type { Reservation } from '../pb/index.js'
|
|
|
10
10
|
import { HopMessage, Status } from '../pb/index.js'
|
|
11
11
|
import { getExpirationMilliseconds } from '../utils.js'
|
|
12
12
|
import type { TransportManager } from '@libp2p/interface-transport'
|
|
13
|
-
import type { Startable } from '@libp2p/interfaces/
|
|
13
|
+
import type { Startable } from '@libp2p/interfaces/startable'
|
|
14
14
|
import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
|
|
15
15
|
import type { PeerStore } from '@libp2p/interface-peer-store'
|
|
16
16
|
import { multiaddr } from '@multiformats/multiaddr'
|
|
@@ -7,7 +7,7 @@ import { logger } from '@libp2p/logger'
|
|
|
7
7
|
import type { Stream } from '@libp2p/interface-connection'
|
|
8
8
|
import { DEFAULT_DATA_LIMIT, DEFAULT_DURATION_LIMIT } from './constants.js'
|
|
9
9
|
import { abortableSource } from 'abortable-iterator'
|
|
10
|
-
import anySignal from 'any-signal'
|
|
10
|
+
import { anySignal } from 'any-signal'
|
|
11
11
|
|
|
12
12
|
const log = logger('libp2p:circuit-relay:utils')
|
|
13
13
|
|
|
@@ -69,6 +69,7 @@ const doRelay = (src: Stream, dst: Stream, abortSignal: AbortSignal, limit: Requ
|
|
|
69
69
|
srcDstFinished = true
|
|
70
70
|
|
|
71
71
|
if (dstSrcFinished) {
|
|
72
|
+
signal.clear()
|
|
72
73
|
clearTimeout(timeout)
|
|
73
74
|
}
|
|
74
75
|
})
|
|
@@ -86,6 +87,7 @@ const doRelay = (src: Stream, dst: Stream, abortSignal: AbortSignal, limit: Requ
|
|
|
86
87
|
dstSrcFinished = true
|
|
87
88
|
|
|
88
89
|
if (srcDstFinished) {
|
|
90
|
+
signal.clear()
|
|
89
91
|
clearTimeout(timeout)
|
|
90
92
|
}
|
|
91
93
|
})
|
package/src/components.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { TransportManager, Upgrader } from '@libp2p/interface-transport'
|
|
|
12
12
|
import type { Datastore } from 'interface-datastore'
|
|
13
13
|
import type { PubSub } from '@libp2p/interface-pubsub'
|
|
14
14
|
import type { DualDHT } from '@libp2p/interface-dht'
|
|
15
|
-
import type { ConnectionManager
|
|
15
|
+
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
|
|
16
16
|
import type { ConnectionGater } from '@libp2p/interface-connection-gater'
|
|
17
17
|
|
|
18
18
|
export interface Components {
|
|
@@ -28,7 +28,6 @@ export interface Components {
|
|
|
28
28
|
peerRouting: PeerRouting
|
|
29
29
|
datastore: Datastore
|
|
30
30
|
connectionProtector?: ConnectionProtector
|
|
31
|
-
dialer: Dialer
|
|
32
31
|
metrics?: Metrics
|
|
33
32
|
dht?: DualDHT
|
|
34
33
|
pubsub?: PubSub
|
|
@@ -50,7 +49,6 @@ export interface ComponentsInit {
|
|
|
50
49
|
connectionProtector?: ConnectionProtector
|
|
51
50
|
dht?: DualDHT
|
|
52
51
|
pubsub?: PubSub
|
|
53
|
-
dialer?: Dialer
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
export class DefaultComponents implements Components, Startable {
|
|
@@ -69,7 +67,6 @@ export class DefaultComponents implements Components, Startable {
|
|
|
69
67
|
private _connectionProtector?: ConnectionProtector
|
|
70
68
|
private _dht?: DualDHT
|
|
71
69
|
private _pubsub?: PubSub
|
|
72
|
-
private _dialer?: Dialer
|
|
73
70
|
private _started = false
|
|
74
71
|
|
|
75
72
|
constructor (init: ComponentsInit = {}) {
|
|
@@ -88,7 +85,6 @@ export class DefaultComponents implements Components, Startable {
|
|
|
88
85
|
this._connectionProtector = init.connectionProtector
|
|
89
86
|
this._dht = init.dht
|
|
90
87
|
this._pubsub = init.pubsub
|
|
91
|
-
this._dialer = init.dialer
|
|
92
88
|
}
|
|
93
89
|
|
|
94
90
|
isStarted (): boolean {
|
|
@@ -295,18 +291,6 @@ export class DefaultComponents implements Components, Startable {
|
|
|
295
291
|
this._connectionProtector = connectionProtector
|
|
296
292
|
}
|
|
297
293
|
|
|
298
|
-
get dialer (): Dialer {
|
|
299
|
-
if (this._dialer == null) {
|
|
300
|
-
throw new CodeError('dialer not set', 'ERR_SERVICE_MISSING')
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return this._dialer
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
set dialer (dialer: Dialer) {
|
|
307
|
-
this._dialer = dialer
|
|
308
|
-
}
|
|
309
|
-
|
|
310
294
|
get metrics (): Metrics | undefined {
|
|
311
295
|
return this._metrics
|
|
312
296
|
}
|
package/src/config.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import mergeOptions from 'merge-options'
|
|
2
2
|
import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
|
3
|
-
import * as Constants from './constants.js'
|
|
4
3
|
import { AGENT_VERSION } from './identify/consts.js'
|
|
5
4
|
import { publicAddressesFirst } from '@libp2p/utils/address-sort'
|
|
6
5
|
import { FaultTolerance } from '@libp2p/interface-transport'
|
|
@@ -19,19 +18,11 @@ const DefaultConfig: Partial<Libp2pInit> = {
|
|
|
19
18
|
announceFilter: (multiaddrs: Multiaddr[]) => multiaddrs
|
|
20
19
|
},
|
|
21
20
|
connectionManager: {
|
|
22
|
-
maxConnections: 300,
|
|
23
|
-
minConnections: 50,
|
|
24
|
-
autoDialInterval: 10000,
|
|
25
|
-
maxParallelDials: Constants.MAX_PARALLEL_DIALS,
|
|
26
|
-
maxDialsPerPeer: Constants.MAX_PER_PEER_DIALS,
|
|
27
|
-
dialTimeout: Constants.DIAL_TIMEOUT,
|
|
28
|
-
inboundUpgradeTimeout: Constants.INBOUND_UPGRADE_TIMEOUT,
|
|
29
21
|
resolvers: {
|
|
30
22
|
dnsaddr: dnsaddrResolver
|
|
31
23
|
},
|
|
32
24
|
addressSorter: publicAddressesFirst
|
|
33
25
|
},
|
|
34
|
-
connectionGater: {},
|
|
35
26
|
transportManager: {
|
|
36
27
|
faultTolerance: FaultTolerance.FATAL_ALL
|
|
37
28
|
},
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { logger } from '@libp2p/logger'
|
|
2
|
+
import type { PeerStore } from '@libp2p/interface-peer-store'
|
|
3
|
+
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
|
|
4
|
+
import { PeerMap } from '@libp2p/peer-collections'
|
|
5
|
+
import PQueue from 'p-queue'
|
|
6
|
+
import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_INTERVAL, AUTO_DIAL_PRIORITY, MIN_CONNECTIONS } from './constants.js'
|
|
7
|
+
import type { Startable } from '@libp2p/interfaces/startable'
|
|
8
|
+
|
|
9
|
+
const log = logger('libp2p:connection-manager:auto-dial')
|
|
10
|
+
|
|
11
|
+
interface AutoDialInit {
|
|
12
|
+
minConnections?: number
|
|
13
|
+
autoDialConcurrency?: number
|
|
14
|
+
autoDialPriority?: number
|
|
15
|
+
autoDialInterval?: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface AutoDialComponents {
|
|
19
|
+
connectionManager: ConnectionManager
|
|
20
|
+
peerStore: PeerStore
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const defaultOptions = {
|
|
24
|
+
minConnections: MIN_CONNECTIONS,
|
|
25
|
+
autoDialConcurrency: AUTO_DIAL_CONCURRENCY,
|
|
26
|
+
autoDialPriority: AUTO_DIAL_PRIORITY,
|
|
27
|
+
autoDialInterval: AUTO_DIAL_INTERVAL
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class AutoDial implements Startable {
|
|
31
|
+
private readonly connectionManager: ConnectionManager
|
|
32
|
+
private readonly peerStore: PeerStore
|
|
33
|
+
private readonly queue: PQueue
|
|
34
|
+
private readonly minConnections: number
|
|
35
|
+
private readonly autoDialPriority: number
|
|
36
|
+
private readonly autoDialIntervalMs: number
|
|
37
|
+
private autoDialInterval?: ReturnType<typeof setInterval>
|
|
38
|
+
private started: boolean
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Proactively tries to connect to known peers stored in the PeerStore.
|
|
42
|
+
* It will keep the number of connections below the upper limit and sort
|
|
43
|
+
* the peers to connect based on whether we know their keys and protocols.
|
|
44
|
+
*/
|
|
45
|
+
constructor (components: AutoDialComponents, init: AutoDialInit) {
|
|
46
|
+
this.connectionManager = components.connectionManager
|
|
47
|
+
this.peerStore = components.peerStore
|
|
48
|
+
this.minConnections = init.minConnections ?? defaultOptions.minConnections
|
|
49
|
+
this.autoDialPriority = init.autoDialPriority ?? defaultOptions.autoDialPriority
|
|
50
|
+
this.autoDialIntervalMs = init.autoDialInterval ?? defaultOptions.autoDialInterval
|
|
51
|
+
this.started = false
|
|
52
|
+
this.queue = new PQueue({
|
|
53
|
+
concurrency: init.autoDialConcurrency ?? defaultOptions.autoDialConcurrency
|
|
54
|
+
})
|
|
55
|
+
this.queue.addListener('error', (err) => {
|
|
56
|
+
log.error('error during auto-dial', err)
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
isStarted (): boolean {
|
|
61
|
+
return this.started
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
start (): void {
|
|
65
|
+
this.autoDialInterval = setInterval(() => {
|
|
66
|
+
this.autoDial()
|
|
67
|
+
.catch(err => {
|
|
68
|
+
log.error('error while autodialing', err)
|
|
69
|
+
})
|
|
70
|
+
}, this.autoDialIntervalMs)
|
|
71
|
+
this.started = true
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
afterStart (): void {
|
|
75
|
+
this.autoDial()
|
|
76
|
+
.catch(err => {
|
|
77
|
+
log.error('error while autodialing', err)
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
stop (): void {
|
|
82
|
+
// clear the queue
|
|
83
|
+
this.queue.clear()
|
|
84
|
+
clearInterval(this.autoDialInterval)
|
|
85
|
+
this.started = false
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async autoDial (): Promise<void> {
|
|
89
|
+
const numConnections = this.connectionManager.getConnections().length
|
|
90
|
+
|
|
91
|
+
// Already has enough connections
|
|
92
|
+
if (numConnections >= this.minConnections) {
|
|
93
|
+
log('have enough connections %d/%d', numConnections, this.minConnections)
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
log('not enough connections %d/%d - will dial peers to increase the number of connections', numConnections, this.minConnections)
|
|
98
|
+
|
|
99
|
+
// Sort peers on whether we know protocols or public keys for them
|
|
100
|
+
let peers = await this.peerStore.all()
|
|
101
|
+
|
|
102
|
+
log('loaded %d peers from the peer store', peers.length)
|
|
103
|
+
|
|
104
|
+
// Remove some peers
|
|
105
|
+
peers = peers.filter((peer) => {
|
|
106
|
+
// Remove peers without addresses
|
|
107
|
+
if (peer.addresses.length === 0) {
|
|
108
|
+
return false
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return true
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
// shuffle the peers
|
|
115
|
+
peers = peers.sort(() => Math.random() > 0.5 ? 1 : -1)
|
|
116
|
+
|
|
117
|
+
// Sort shuffled peers by tag value
|
|
118
|
+
const peerValues = new PeerMap<number>()
|
|
119
|
+
for (const peer of peers) {
|
|
120
|
+
if (peerValues.has(peer.id)) {
|
|
121
|
+
continue
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const tags = await this.peerStore.getTags(peer.id)
|
|
125
|
+
|
|
126
|
+
// sum all tag values
|
|
127
|
+
peerValues.set(peer.id, (tags ?? []).reduce((acc, curr) => {
|
|
128
|
+
return acc + curr.value
|
|
129
|
+
}, 0))
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// sort by value, highest to lowest
|
|
133
|
+
const sortedPeers = peers.sort((a, b) => {
|
|
134
|
+
const peerAValue = peerValues.get(a.id) ?? 0
|
|
135
|
+
const peerBValue = peerValues.get(b.id) ?? 0
|
|
136
|
+
|
|
137
|
+
if (peerAValue > peerBValue) {
|
|
138
|
+
return -1
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (peerAValue < peerBValue) {
|
|
142
|
+
return 1
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return 0
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
log('selected %d peers to dial', sortedPeers.length)
|
|
149
|
+
|
|
150
|
+
for (const peer of sortedPeers) {
|
|
151
|
+
this.queue.add(async () => {
|
|
152
|
+
const numConnections = this.connectionManager.getConnections().length
|
|
153
|
+
|
|
154
|
+
// Check to see if we still need to auto dial
|
|
155
|
+
if (numConnections >= this.minConnections) {
|
|
156
|
+
log('got enough connections now %d/%d', numConnections, this.minConnections)
|
|
157
|
+
this.queue.clear()
|
|
158
|
+
return
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
log('connecting to a peerStore stored peer %p', peer.id)
|
|
162
|
+
await this.connectionManager.openConnection(peer.id, {
|
|
163
|
+
// @ts-expect-error needs adding to the ConnectionManager interface
|
|
164
|
+
priority: this.autoDialPriority
|
|
165
|
+
})
|
|
166
|
+
}).catch(err => {
|
|
167
|
+
log.error('could not connect to peerStore stored peer', err)
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { logger } from '@libp2p/logger'
|
|
2
|
+
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
|
|
3
|
+
import type { PeerStore } from '@libp2p/interface-peer-store'
|
|
4
|
+
import { PeerMap } from '@libp2p/peer-collections'
|
|
5
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
6
|
+
import { MAX_CONNECTIONS } from './constants.js'
|
|
7
|
+
import { CustomEvent } from '@libp2p/interfaces/events'
|
|
8
|
+
|
|
9
|
+
const log = logger('libp2p:connection-manager:connection-pruner')
|
|
10
|
+
|
|
11
|
+
interface ConnectionPrunerInit {
|
|
12
|
+
maxConnections?: number
|
|
13
|
+
allow?: Multiaddr[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ConnectionPrunerComponents {
|
|
17
|
+
connectionManager: ConnectionManager
|
|
18
|
+
peerStore: PeerStore
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const defaultOptions = {
|
|
22
|
+
maxConnections: MAX_CONNECTIONS,
|
|
23
|
+
allow: []
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* If we go over the max connections limit, choose some connections to close
|
|
28
|
+
*/
|
|
29
|
+
export class ConnectionPruner {
|
|
30
|
+
private readonly maxConnections: number
|
|
31
|
+
private readonly connectionManager: ConnectionManager
|
|
32
|
+
private readonly peerStore: PeerStore
|
|
33
|
+
private readonly allow: Multiaddr[]
|
|
34
|
+
|
|
35
|
+
constructor (components: ConnectionPrunerComponents, init: ConnectionPrunerInit = {}) {
|
|
36
|
+
this.maxConnections = init.maxConnections ?? defaultOptions.maxConnections
|
|
37
|
+
this.allow = init.allow ?? defaultOptions.allow
|
|
38
|
+
this.connectionManager = components.connectionManager
|
|
39
|
+
this.peerStore = components.peerStore
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* If we have more connections than our maximum, select some excess connections
|
|
44
|
+
* to prune based on peer value
|
|
45
|
+
*/
|
|
46
|
+
async maybePruneConnections (): Promise<void> {
|
|
47
|
+
const connections = this.connectionManager.getConnections()
|
|
48
|
+
const numConnections = connections.length
|
|
49
|
+
const toPrune = Math.max(numConnections - this.maxConnections, 0)
|
|
50
|
+
|
|
51
|
+
log.trace('checking max connections limit %d/%d', numConnections, this.maxConnections)
|
|
52
|
+
if (numConnections <= this.maxConnections) {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
log('max connections limit exceeded %d/%d, pruning %d connection(s)', numConnections, this.maxConnections, toPrune)
|
|
57
|
+
const peerValues = new PeerMap<number>()
|
|
58
|
+
|
|
59
|
+
// work out peer values
|
|
60
|
+
for (const connection of connections) {
|
|
61
|
+
const remotePeer = connection.remotePeer
|
|
62
|
+
|
|
63
|
+
if (peerValues.has(remotePeer)) {
|
|
64
|
+
continue
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const tags = await this.peerStore.getTags(remotePeer)
|
|
68
|
+
|
|
69
|
+
// sum all tag values
|
|
70
|
+
peerValues.set(remotePeer, tags.reduce((acc, curr) => {
|
|
71
|
+
return acc + curr.value
|
|
72
|
+
}, 0))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// sort by value, lowest to highest
|
|
76
|
+
const sortedConnections = connections.sort((a, b) => {
|
|
77
|
+
const peerAValue = peerValues.get(a.remotePeer) ?? 0
|
|
78
|
+
const peerBValue = peerValues.get(b.remotePeer) ?? 0
|
|
79
|
+
|
|
80
|
+
if (peerAValue > peerBValue) {
|
|
81
|
+
return 1
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (peerAValue < peerBValue) {
|
|
85
|
+
return -1
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// if the peers have an equal tag value then we want to close short-lived connections first
|
|
89
|
+
const connectionALifespan = a.stat.timeline.open
|
|
90
|
+
const connectionBLifespan = b.stat.timeline.open
|
|
91
|
+
|
|
92
|
+
if (connectionALifespan < connectionBLifespan) {
|
|
93
|
+
return 1
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (connectionALifespan > connectionBLifespan) {
|
|
97
|
+
return -1
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return 0
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
// close some connections
|
|
104
|
+
const toClose = []
|
|
105
|
+
|
|
106
|
+
for (const connection of sortedConnections) {
|
|
107
|
+
log('too many connections open - closing a connection to %p', connection.remotePeer)
|
|
108
|
+
// check allow list
|
|
109
|
+
const connectionInAllowList = this.allow.some((ma) => {
|
|
110
|
+
return connection.remoteAddr.toString().startsWith(ma.toString())
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
// Connections in the allow list should be excluded from pruning
|
|
114
|
+
if (!connectionInAllowList) {
|
|
115
|
+
toClose.push(connection)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (toClose.length === toPrune) {
|
|
119
|
+
break
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// close connections
|
|
124
|
+
await Promise.all(
|
|
125
|
+
toClose.map(async connection => {
|
|
126
|
+
try {
|
|
127
|
+
await connection.close()
|
|
128
|
+
} catch (err) {
|
|
129
|
+
log.error(err)
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
// despatch prune event
|
|
135
|
+
this.connectionManager.dispatchEvent(new CustomEvent('peer:prune', { detail: toClose.map(conn => conn.remotePeer) }))
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#dialTimeout
|
|
4
|
+
*/
|
|
5
|
+
export const DIAL_TIMEOUT = 30e3
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#inboundUpgradeTimeout
|
|
9
|
+
*/
|
|
10
|
+
export const INBOUND_UPGRADE_TIMEOUT = 30e3
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#maxParallelDials
|
|
14
|
+
*/
|
|
15
|
+
export const MAX_PARALLEL_DIALS = 100
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#maxPeerAddrsToDial
|
|
19
|
+
*/
|
|
20
|
+
export const MAX_PEER_ADDRS_TO_DIAL = 25
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#maxParallelDialsPerPeer
|
|
24
|
+
*/
|
|
25
|
+
export const MAX_PARALLEL_DIALS_PER_PEER = 10
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#minConnections
|
|
29
|
+
*/
|
|
30
|
+
export const MIN_CONNECTIONS = 50
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#maxConnections
|
|
34
|
+
*/
|
|
35
|
+
export const MAX_CONNECTIONS = 300
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#autoDialInterval
|
|
39
|
+
*/
|
|
40
|
+
export const AUTO_DIAL_INTERVAL = 5000
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#autoDialConcurrency
|
|
44
|
+
*/
|
|
45
|
+
export const AUTO_DIAL_CONCURRENCY = 25
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#autoDialPriority
|
|
49
|
+
*/
|
|
50
|
+
export const AUTO_DIAL_PRIORITY = 0
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#inboundConnectionThreshold
|
|
54
|
+
*/
|
|
55
|
+
export const INBOUND_CONNECTION_THRESHOLD = 5
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#maxIncomingPendingConnections
|
|
59
|
+
*/
|
|
60
|
+
export const MAX_INCOMING_PENDING_CONNECTIONS = 10
|