libp2p 0.37.3 → 0.38.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/README.md +1 -2
- package/dist/src/address-manager/index.d.ts +2 -2
- package/dist/src/address-manager/index.d.ts.map +1 -1
- package/dist/src/circuit/auto-relay.d.ts +4 -4
- package/dist/src/circuit/auto-relay.d.ts.map +1 -1
- package/dist/src/circuit/circuit/hop.d.ts +7 -5
- package/dist/src/circuit/circuit/hop.d.ts.map +1 -1
- package/dist/src/circuit/circuit/hop.js +8 -4
- package/dist/src/circuit/circuit/hop.js.map +1 -1
- package/dist/src/circuit/circuit/stop.d.ts +6 -4
- package/dist/src/circuit/circuit/stop.d.ts.map +1 -1
- package/dist/src/circuit/circuit/stop.js +4 -2
- package/dist/src/circuit/circuit/stop.js.map +1 -1
- package/dist/src/circuit/circuit/stream-handler.d.ts +3 -2
- package/dist/src/circuit/circuit/stream-handler.d.ts.map +1 -1
- package/dist/src/circuit/circuit/stream-handler.js +2 -2
- package/dist/src/circuit/circuit/stream-handler.js.map +1 -1
- package/dist/src/circuit/index.d.ts +4 -12
- package/dist/src/circuit/index.d.ts.map +1 -1
- package/dist/src/circuit/index.js.map +1 -1
- package/dist/src/circuit/listener.d.ts +3 -3
- package/dist/src/circuit/listener.d.ts.map +1 -1
- package/dist/src/circuit/pb/index.d.ts +5 -4
- package/dist/src/circuit/pb/index.d.ts.map +1 -1
- package/dist/src/circuit/pb/index.js +107 -11
- package/dist/src/circuit/pb/index.js.map +1 -1
- package/dist/src/circuit/transport.d.ts +8 -5
- package/dist/src/circuit/transport.d.ts.map +1 -1
- package/dist/src/circuit/transport.js +81 -59
- package/dist/src/circuit/transport.js.map +1 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +27 -4
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts.map +1 -1
- package/dist/src/connection-manager/dialer/auto-dialer.d.ts +2 -2
- package/dist/src/connection-manager/dialer/auto-dialer.d.ts.map +1 -1
- package/dist/src/connection-manager/dialer/auto-dialer.js +6 -0
- package/dist/src/connection-manager/dialer/auto-dialer.js.map +1 -1
- package/dist/src/connection-manager/dialer/dial-request.d.ts +1 -1
- package/dist/src/connection-manager/dialer/dial-request.d.ts.map +1 -1
- package/dist/src/connection-manager/dialer/index.d.ts +9 -9
- package/dist/src/connection-manager/dialer/index.d.ts.map +1 -1
- package/dist/src/connection-manager/dialer/index.js +11 -11
- package/dist/src/connection-manager/dialer/index.js.map +1 -1
- package/dist/src/connection-manager/index.d.ts +20 -16
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/connection-manager/index.js +185 -65
- package/dist/src/connection-manager/index.js.map +1 -1
- package/dist/src/constants.d.ts +4 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +4 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/content-routing/index.d.ts +4 -4
- package/dist/src/content-routing/index.d.ts.map +1 -1
- package/dist/src/content-routing/utils.d.ts +2 -2
- package/dist/src/content-routing/utils.d.ts.map +1 -1
- package/dist/src/dht/dht-content-routing.d.ts +3 -3
- package/dist/src/dht/dht-content-routing.d.ts.map +1 -1
- package/dist/src/dht/dht-peer-routing.d.ts +5 -5
- package/dist/src/dht/dht-peer-routing.d.ts.map +1 -1
- package/dist/src/dht/dummy-dht.d.ts +3 -3
- package/dist/src/dht/dummy-dht.d.ts.map +1 -1
- package/dist/src/dht/dummy-dht.js +1 -1
- package/dist/src/dht/dummy-dht.js.map +1 -1
- package/dist/src/errors.d.ts +4 -1
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +3 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/fetch/index.d.ts +11 -4
- package/dist/src/fetch/index.d.ts.map +1 -1
- package/dist/src/fetch/index.js +82 -41
- package/dist/src/fetch/index.js.map +1 -1
- package/dist/src/fetch/pb/proto.d.ts +4 -3
- package/dist/src/fetch/pb/proto.d.ts.map +1 -1
- package/dist/src/fetch/pb/proto.js +88 -8
- package/dist/src/fetch/pb/proto.js.map +1 -1
- package/dist/src/get-peer.d.ts +2 -2
- package/dist/src/get-peer.d.ts.map +1 -1
- package/dist/src/get-peer.js +1 -1
- package/dist/src/get-peer.js.map +1 -1
- package/dist/src/identify/index.d.ts +8 -8
- package/dist/src/identify/index.d.ts.map +1 -1
- package/dist/src/identify/index.js +49 -34
- package/dist/src/identify/index.js.map +1 -1
- package/dist/src/identify/pb/message.d.ts +2 -1
- package/dist/src/identify/pb/message.d.ts.map +1 -1
- package/dist/src/identify/pb/message.js +94 -10
- package/dist/src/identify/pb/message.js.map +1 -1
- package/dist/src/index.d.ts +18 -17
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/insecure/index.d.ts +2 -2
- package/dist/src/insecure/index.d.ts.map +1 -1
- package/dist/src/insecure/index.js +8 -4
- package/dist/src/insecure/index.js.map +1 -1
- package/dist/src/insecure/pb/proto.d.ts +4 -3
- package/dist/src/insecure/pb/proto.d.ts.map +1 -1
- package/dist/src/insecure/pb/proto.js +89 -9
- package/dist/src/insecure/pb/proto.js.map +1 -1
- package/dist/src/keychain/index.d.ts +2 -2
- package/dist/src/keychain/index.d.ts.map +1 -1
- package/dist/src/libp2p.d.ts +14 -14
- package/dist/src/libp2p.d.ts.map +1 -1
- package/dist/src/libp2p.js +17 -17
- package/dist/src/libp2p.js.map +1 -1
- package/dist/src/metrics/index.d.ts +4 -5
- package/dist/src/metrics/index.d.ts.map +1 -1
- package/dist/src/metrics/index.js +9 -6
- package/dist/src/metrics/index.js.map +1 -1
- package/dist/src/metrics/moving-average.d.ts +1 -1
- package/dist/src/metrics/moving-average.d.ts.map +1 -1
- package/dist/src/metrics/stats.d.ts +1 -1
- package/dist/src/metrics/stats.d.ts.map +1 -1
- package/dist/src/nat-manager.d.ts +1 -1
- package/dist/src/nat-manager.d.ts.map +1 -1
- package/dist/src/peer-record-updater.d.ts +1 -1
- package/dist/src/peer-record-updater.d.ts.map +1 -1
- package/dist/src/peer-routing.d.ts +4 -4
- package/dist/src/peer-routing.d.ts.map +1 -1
- package/dist/src/ping/index.d.ts +10 -3
- package/dist/src/ping/index.d.ts.map +1 -1
- package/dist/src/ping/index.js +32 -9
- package/dist/src/ping/index.js.map +1 -1
- package/dist/src/pnet/index.d.ts +1 -2
- package/dist/src/pnet/index.d.ts.map +1 -1
- package/dist/src/pnet/index.js +2 -1
- package/dist/src/pnet/index.js.map +1 -1
- package/dist/src/pubsub/dummy-pubsub.d.ts +2 -2
- package/dist/src/pubsub/dummy-pubsub.d.ts.map +1 -1
- package/dist/src/registrar.d.ts +10 -8
- package/dist/src/registrar.d.ts.map +1 -1
- package/dist/src/registrar.js +63 -44
- package/dist/src/registrar.js.map +1 -1
- package/dist/src/transport-manager.d.ts +3 -3
- package/dist/src/transport-manager.d.ts.map +1 -1
- package/dist/src/upgrader.d.ts +12 -6
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +183 -82
- package/dist/src/upgrader.js.map +1 -1
- package/dist/src/version.d.ts.map +1 -1
- package/dist/src/version.js.map +1 -1
- package/package.json +66 -42
- package/src/address-manager/index.ts +2 -2
- package/src/circuit/README.md +2 -2
- package/src/circuit/auto-relay.ts +4 -4
- package/src/circuit/circuit/hop.ts +20 -11
- package/src/circuit/circuit/stop.ts +10 -5
- package/src/circuit/circuit/stream-handler.ts +6 -5
- package/src/circuit/index.ts +4 -13
- package/src/circuit/listener.ts +3 -3
- package/src/circuit/pb/index.ts +133 -15
- package/src/circuit/transport.ts +92 -63
- package/src/config.ts +27 -4
- package/src/connection-manager/auto-dialler.ts +1 -1
- package/src/connection-manager/dialer/auto-dialer.ts +8 -2
- package/src/connection-manager/dialer/dial-request.ts +1 -1
- package/src/connection-manager/dialer/index.ts +15 -15
- package/src/connection-manager/index.ts +239 -82
- package/src/constants.ts +5 -0
- package/src/content-routing/index.ts +2 -2
- package/src/content-routing/utils.ts +2 -2
- package/src/dht/dht-content-routing.ts +2 -2
- package/src/dht/dht-peer-routing.ts +3 -3
- package/src/dht/dummy-dht.ts +3 -3
- package/src/errors.ts +4 -1
- package/src/fetch/index.ts +120 -53
- package/src/fetch/pb/proto.ts +109 -11
- package/src/get-peer.ts +3 -3
- package/src/identify/index.ts +64 -47
- package/src/identify/pb/message.ts +111 -11
- package/src/index.ts +18 -17
- package/src/insecure/index.ts +11 -6
- package/src/insecure/pb/proto.ts +111 -12
- package/src/keychain/index.ts +2 -2
- package/src/libp2p.ts +34 -29
- package/src/metrics/index.ts +13 -12
- package/src/metrics/moving-average.ts +1 -1
- package/src/metrics/stats.ts +1 -1
- package/src/nat-manager.ts +1 -1
- package/src/peer-record-updater.ts +1 -1
- package/src/peer-routing.ts +4 -4
- package/src/ping/index.ts +48 -15
- package/src/pnet/index.ts +3 -2
- package/src/pubsub/dummy-pubsub.ts +2 -2
- package/src/registrar.ts +79 -55
- package/src/transport-manager.ts +3 -3
- package/src/upgrader.ts +223 -93
- package/src/version.ts +1 -2
|
@@ -7,17 +7,19 @@ import retimer from 'retimer'
|
|
|
7
7
|
import type { AbortOptions } from '@libp2p/interfaces'
|
|
8
8
|
import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
|
|
9
9
|
import type { Startable } from '@libp2p/interfaces/startable'
|
|
10
|
-
import { trackedMap } from '@libp2p/tracked-map'
|
|
11
10
|
import { codes } from '../errors.js'
|
|
12
|
-
import { isPeerId, PeerId } from '@libp2p/
|
|
11
|
+
import { isPeerId, PeerId } from '@libp2p/interface-peer-id'
|
|
13
12
|
import { setMaxListeners } from 'events'
|
|
14
|
-
import type { Connection } from '@libp2p/
|
|
15
|
-
import type { ConnectionManager } from '@libp2p/
|
|
16
|
-
import { Components, Initializable } from '@libp2p/
|
|
17
|
-
import * as STATUS from '@libp2p/
|
|
13
|
+
import type { Connection } from '@libp2p/interface-connection'
|
|
14
|
+
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
|
|
15
|
+
import { Components, Initializable } from '@libp2p/components'
|
|
16
|
+
import * as STATUS from '@libp2p/interface-connection/status'
|
|
18
17
|
import { Dialer } from './dialer/index.js'
|
|
19
|
-
import type { AddressSorter } from '@libp2p/
|
|
18
|
+
import type { AddressSorter } from '@libp2p/interface-peer-store'
|
|
20
19
|
import type { Resolver } from '@multiformats/multiaddr'
|
|
20
|
+
import { PeerMap } from '@libp2p/peer-collections'
|
|
21
|
+
import { TimeoutController } from 'timeout-abort-controller'
|
|
22
|
+
import { KEEP_ALIVE } from '@libp2p/interface-peer-store/tags'
|
|
21
23
|
|
|
22
24
|
const log = logger('libp2p:connection-manager')
|
|
23
25
|
|
|
@@ -30,13 +32,12 @@ const defaultOptions: Partial<ConnectionManagerInit> = {
|
|
|
30
32
|
maxEventLoopDelay: Infinity,
|
|
31
33
|
pollInterval: 2000,
|
|
32
34
|
autoDialInterval: 10000,
|
|
33
|
-
movingAverageInterval: 60000
|
|
34
|
-
defaultPeerValue: 0.5
|
|
35
|
+
movingAverageInterval: 60000
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
const METRICS_SYSTEM = 'libp2p'
|
|
37
39
|
const METRICS_COMPONENT = 'connection-manager'
|
|
38
|
-
const
|
|
39
|
-
const METRICS_PEER_VALUES = 'peer-values'
|
|
40
|
+
const STARTUP_RECONNECT_TIMEOUT = 60000
|
|
40
41
|
|
|
41
42
|
export interface ConnectionManagerInit {
|
|
42
43
|
/**
|
|
@@ -79,11 +80,6 @@ export interface ConnectionManagerInit {
|
|
|
79
80
|
*/
|
|
80
81
|
movingAverageInterval?: number
|
|
81
82
|
|
|
82
|
-
/**
|
|
83
|
-
* The value of the peer
|
|
84
|
-
*/
|
|
85
|
-
defaultPeerValue?: number
|
|
86
|
-
|
|
87
83
|
/**
|
|
88
84
|
* If true, try to connect to all discovered peers up to the connection manager limit
|
|
89
85
|
*/
|
|
@@ -111,10 +107,17 @@ export interface ConnectionManagerInit {
|
|
|
111
107
|
maxAddrsToDial?: number
|
|
112
108
|
|
|
113
109
|
/**
|
|
114
|
-
* How long a dial attempt is allowed to take
|
|
110
|
+
* How long a dial attempt is allowed to take, including DNS resolution
|
|
111
|
+
* of the multiaddr, opening a socket and upgrading it to a Connection.
|
|
115
112
|
*/
|
|
116
113
|
dialTimeout?: number
|
|
117
114
|
|
|
115
|
+
/**
|
|
116
|
+
* When a new inbound connection is opened, the upgrade process (e.g. protect,
|
|
117
|
+
* encrypt, multiplex etc) must complete within this number of ms.
|
|
118
|
+
*/
|
|
119
|
+
inboundUpgradeTimeout: number
|
|
120
|
+
|
|
118
121
|
/**
|
|
119
122
|
* Number of max concurrent dials per peer
|
|
120
123
|
*/
|
|
@@ -124,6 +127,12 @@ export interface ConnectionManagerInit {
|
|
|
124
127
|
* Multiaddr resolvers to use when dialing
|
|
125
128
|
*/
|
|
126
129
|
resolvers?: Record<string, Resolver>
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* On startup we try to dial any peer that has previously been
|
|
133
|
+
* tagged with KEEP_ALIVE up to this timeout in ms. (default: 60000)
|
|
134
|
+
*/
|
|
135
|
+
startupReconnectTimeout?: number
|
|
127
136
|
}
|
|
128
137
|
|
|
129
138
|
export interface ConnectionManagerEvents {
|
|
@@ -138,11 +147,13 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
138
147
|
public readonly dialer: Dialer
|
|
139
148
|
private components = new Components()
|
|
140
149
|
private readonly opts: Required<ConnectionManagerInit>
|
|
141
|
-
private readonly peerValues: Map<string, number>
|
|
142
150
|
private readonly connections: Map<string, Connection[]>
|
|
143
151
|
private started: boolean
|
|
144
152
|
private timer?: ReturnType<retimer>
|
|
145
153
|
private readonly latencyMonitor: LatencyMonitor
|
|
154
|
+
private readonly startupReconnectTimeout: number
|
|
155
|
+
private connectOnStartupController?: TimeoutController
|
|
156
|
+
private readonly dialTimeout: number
|
|
146
157
|
|
|
147
158
|
constructor (init: ConnectionManagerInit) {
|
|
148
159
|
super()
|
|
@@ -155,25 +166,10 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
155
166
|
|
|
156
167
|
log('options: %o', this.opts)
|
|
157
168
|
|
|
158
|
-
/**
|
|
159
|
-
* Map of peer identifiers to their peer value for pruning connections.
|
|
160
|
-
*
|
|
161
|
-
* @type {Map<string, number>}
|
|
162
|
-
*/
|
|
163
|
-
this.peerValues = trackedMap({
|
|
164
|
-
component: METRICS_COMPONENT,
|
|
165
|
-
metric: METRICS_PEER_VALUES,
|
|
166
|
-
metrics: this.components.getMetrics()
|
|
167
|
-
})
|
|
168
|
-
|
|
169
169
|
/**
|
|
170
170
|
* Map of connections per peer
|
|
171
171
|
*/
|
|
172
|
-
this.connections =
|
|
173
|
-
component: METRICS_COMPONENT,
|
|
174
|
-
metric: METRICS_PEER_CONNECTIONS,
|
|
175
|
-
metrics: this.components.getMetrics()
|
|
176
|
-
})
|
|
172
|
+
this.connections = new Map()
|
|
177
173
|
|
|
178
174
|
this.started = false
|
|
179
175
|
this._checkMetrics = this._checkMetrics.bind(this)
|
|
@@ -192,12 +188,103 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
192
188
|
|
|
193
189
|
this.onConnect = this.onConnect.bind(this)
|
|
194
190
|
this.onDisconnect = this.onDisconnect.bind(this)
|
|
191
|
+
|
|
192
|
+
this.startupReconnectTimeout = init.startupReconnectTimeout ?? STARTUP_RECONNECT_TIMEOUT
|
|
193
|
+
this.dialTimeout = init.dialTimeout ?? 30000
|
|
195
194
|
}
|
|
196
195
|
|
|
197
196
|
init (components: Components): void {
|
|
198
197
|
this.components = components
|
|
199
198
|
|
|
200
199
|
this.dialer.init(components)
|
|
200
|
+
|
|
201
|
+
// track inbound/outbound connections
|
|
202
|
+
this.components.getMetrics()?.updateComponentMetric({
|
|
203
|
+
system: METRICS_SYSTEM,
|
|
204
|
+
component: METRICS_COMPONENT,
|
|
205
|
+
metric: 'connections',
|
|
206
|
+
label: 'direction',
|
|
207
|
+
value: () => {
|
|
208
|
+
const metric = {
|
|
209
|
+
inbound: 0,
|
|
210
|
+
outbound: 0
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
for (const conns of this.connections.values()) {
|
|
214
|
+
for (const conn of conns) {
|
|
215
|
+
if (conn.stat.direction === 'inbound') {
|
|
216
|
+
metric.inbound++
|
|
217
|
+
} else {
|
|
218
|
+
metric.outbound++
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return metric
|
|
224
|
+
}
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
// track total number of streams per protocol
|
|
228
|
+
this.components.getMetrics()?.updateComponentMetric({
|
|
229
|
+
system: METRICS_SYSTEM,
|
|
230
|
+
component: METRICS_COMPONENT,
|
|
231
|
+
metric: 'protocol-streams-total',
|
|
232
|
+
label: 'protocol',
|
|
233
|
+
value: () => {
|
|
234
|
+
const metric: Record<string, number> = {}
|
|
235
|
+
|
|
236
|
+
for (const conns of this.connections.values()) {
|
|
237
|
+
for (const conn of conns) {
|
|
238
|
+
for (const stream of conn.streams) {
|
|
239
|
+
const key = `${stream.stat.direction} ${stream.stat.protocol ?? 'unnegotiated'}`
|
|
240
|
+
|
|
241
|
+
metric[key] = (metric[key] ?? 0) + 1
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return metric
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
// track 90th percentile of streams per protocol
|
|
251
|
+
this.components.getMetrics()?.updateComponentMetric({
|
|
252
|
+
system: METRICS_SYSTEM,
|
|
253
|
+
component: METRICS_COMPONENT,
|
|
254
|
+
metric: 'protocol-streams-per-connection-90th-percentile',
|
|
255
|
+
label: 'protocol',
|
|
256
|
+
value: () => {
|
|
257
|
+
const allStreams: Record<string, number[]> = {}
|
|
258
|
+
|
|
259
|
+
for (const conns of this.connections.values()) {
|
|
260
|
+
for (const conn of conns) {
|
|
261
|
+
const streams: Record<string, number> = {}
|
|
262
|
+
|
|
263
|
+
for (const stream of conn.streams) {
|
|
264
|
+
const key = `${stream.stat.direction} ${stream.stat.protocol ?? 'unnegotiated'}`
|
|
265
|
+
|
|
266
|
+
streams[key] = (streams[key] ?? 0) + 1
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
for (const [protocol, count] of Object.entries(streams)) {
|
|
270
|
+
allStreams[protocol] = allStreams[protocol] ?? []
|
|
271
|
+
allStreams[protocol].push(count)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const metric: Record<string, number> = {}
|
|
277
|
+
|
|
278
|
+
for (let [protocol, counts] of Object.entries(allStreams)) {
|
|
279
|
+
counts = counts.sort((a, b) => a - b)
|
|
280
|
+
|
|
281
|
+
const index = Math.floor(counts.length * 0.9)
|
|
282
|
+
metric[protocol] = counts[index]
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return metric
|
|
286
|
+
}
|
|
287
|
+
})
|
|
201
288
|
}
|
|
202
289
|
|
|
203
290
|
isStarted () {
|
|
@@ -226,9 +313,51 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
226
313
|
async afterStart () {
|
|
227
314
|
this.components.getUpgrader().addEventListener('connection', this.onConnect)
|
|
228
315
|
this.components.getUpgrader().addEventListener('connectionEnd', this.onDisconnect)
|
|
316
|
+
|
|
317
|
+
// re-connect to any peers with the KEEP_ALIVE tag
|
|
318
|
+
void Promise.resolve()
|
|
319
|
+
.then(async () => {
|
|
320
|
+
const keepAlivePeers: PeerId[] = []
|
|
321
|
+
|
|
322
|
+
for (const peer of await this.components.getPeerStore().all()) {
|
|
323
|
+
const tags = await this.components.getPeerStore().getTags(peer.id)
|
|
324
|
+
const hasKeepAlive = tags.filter(tag => tag.name === KEEP_ALIVE).length > 0
|
|
325
|
+
|
|
326
|
+
if (hasKeepAlive) {
|
|
327
|
+
keepAlivePeers.push(peer.id)
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
this.connectOnStartupController?.clear()
|
|
332
|
+
this.connectOnStartupController = new TimeoutController(this.startupReconnectTimeout)
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
// fails on node < 15.4
|
|
336
|
+
setMaxListeners?.(Infinity, this.connectOnStartupController.signal)
|
|
337
|
+
} catch {}
|
|
338
|
+
|
|
339
|
+
await Promise.all(
|
|
340
|
+
keepAlivePeers.map(async peer => {
|
|
341
|
+
await this.openConnection(peer, {
|
|
342
|
+
signal: this.connectOnStartupController?.signal
|
|
343
|
+
})
|
|
344
|
+
.catch(err => {
|
|
345
|
+
log.error(err)
|
|
346
|
+
})
|
|
347
|
+
})
|
|
348
|
+
)
|
|
349
|
+
})
|
|
350
|
+
.catch(err => {
|
|
351
|
+
log.error(err)
|
|
352
|
+
})
|
|
353
|
+
.finally(() => {
|
|
354
|
+
this.connectOnStartupController?.clear()
|
|
355
|
+
})
|
|
229
356
|
}
|
|
230
357
|
|
|
231
358
|
async beforeStop () {
|
|
359
|
+
// if we are still dialing KEEP_ALIVE peers, abort those dials
|
|
360
|
+
this.connectOnStartupController?.abort()
|
|
232
361
|
this.components.getUpgrader().removeEventListener('connection', this.onConnect)
|
|
233
362
|
this.components.getUpgrader().removeEventListener('connectionEnd', this.onDisconnect)
|
|
234
363
|
}
|
|
@@ -271,18 +400,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
271
400
|
this.connections.clear()
|
|
272
401
|
}
|
|
273
402
|
|
|
274
|
-
/**
|
|
275
|
-
* Sets the value of the given peer. Peers with lower values
|
|
276
|
-
* will be disconnected first.
|
|
277
|
-
*/
|
|
278
|
-
setPeerValue (peerId: PeerId, value: number) {
|
|
279
|
-
if (value < 0 || value > 1) {
|
|
280
|
-
throw new Error('value should be a number between 0 and 1')
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
this.peerValues.set(peerId.toString(), value)
|
|
284
|
-
}
|
|
285
|
-
|
|
286
403
|
/**
|
|
287
404
|
* Checks the libp2p metrics to determine if any values have exceeded
|
|
288
405
|
* the configured maximums.
|
|
@@ -340,10 +457,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
340
457
|
await this.components.getPeerStore().keyBook.set(peerId, peerId.publicKey)
|
|
341
458
|
}
|
|
342
459
|
|
|
343
|
-
if (!this.peerValues.has(peerIdStr)) {
|
|
344
|
-
this.peerValues.set(peerIdStr, this.opts.defaultPeerValue)
|
|
345
|
-
}
|
|
346
|
-
|
|
347
460
|
const numConnections = this.getConnections().length
|
|
348
461
|
const toPrune = numConnections - this.opts.maxConnections
|
|
349
462
|
|
|
@@ -370,7 +483,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
370
483
|
this.connections.set(peerId, storedConn)
|
|
371
484
|
} else if (storedConn != null) {
|
|
372
485
|
this.connections.delete(peerId)
|
|
373
|
-
this.peerValues.delete(connection.remotePeer.toString())
|
|
374
486
|
this.dispatchEvent(new CustomEvent<Connection>('peer:disconnect', { detail: connection }))
|
|
375
487
|
|
|
376
488
|
this.components.getMetrics()?.onPeerDisconnected(connection.remotePeer)
|
|
@@ -391,7 +503,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
391
503
|
return conns
|
|
392
504
|
}
|
|
393
505
|
|
|
394
|
-
async openConnection (peerId: PeerId, options
|
|
506
|
+
async openConnection (peerId: PeerId, options: AbortOptions = {}): Promise<Connection> {
|
|
395
507
|
log('dial to %p', peerId)
|
|
396
508
|
const existingConnections = this.getConnections(peerId)
|
|
397
509
|
|
|
@@ -401,30 +513,48 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
401
513
|
return existingConnections[0]
|
|
402
514
|
}
|
|
403
515
|
|
|
404
|
-
|
|
405
|
-
|
|
516
|
+
let timeoutController: TimeoutController | undefined
|
|
517
|
+
|
|
518
|
+
if (options?.signal == null) {
|
|
519
|
+
timeoutController = new TimeoutController(this.dialTimeout)
|
|
520
|
+
options.signal = timeoutController.signal
|
|
406
521
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
522
|
+
try {
|
|
523
|
+
// fails on node < 15.4
|
|
524
|
+
setMaxListeners?.(Infinity, timeoutController.signal)
|
|
525
|
+
} catch {}
|
|
410
526
|
}
|
|
411
527
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
let trackedConnection = false
|
|
528
|
+
try {
|
|
529
|
+
const connection = await this.dialer.dial(peerId, options)
|
|
530
|
+
let peerConnections = this.connections.get(peerId.toString())
|
|
416
531
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
532
|
+
if (peerConnections == null) {
|
|
533
|
+
peerConnections = []
|
|
534
|
+
this.connections.set(peerId.toString(), peerConnections)
|
|
420
535
|
}
|
|
421
|
-
}
|
|
422
536
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
537
|
+
// we get notified of connections via the Upgrader emitting "connection"
|
|
538
|
+
// events, double check we aren't already tracking this connection before
|
|
539
|
+
// storing it
|
|
540
|
+
let trackedConnection = false
|
|
541
|
+
|
|
542
|
+
for (const conn of peerConnections) {
|
|
543
|
+
if (conn.id === connection.id) {
|
|
544
|
+
trackedConnection = true
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (!trackedConnection) {
|
|
549
|
+
peerConnections.push(connection)
|
|
550
|
+
}
|
|
426
551
|
|
|
427
|
-
|
|
552
|
+
return connection
|
|
553
|
+
} finally {
|
|
554
|
+
if (timeoutController != null) {
|
|
555
|
+
timeoutController.clear()
|
|
556
|
+
}
|
|
557
|
+
}
|
|
428
558
|
}
|
|
429
559
|
|
|
430
560
|
async closeConnections (peerId: PeerId): Promise<void> {
|
|
@@ -475,7 +605,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
475
605
|
const limit = this.opts[name]
|
|
476
606
|
log.trace('checking limit of %s. current value: %d of %d', name, value, limit)
|
|
477
607
|
if (value > limit) {
|
|
478
|
-
log('%s: limit exceeded: %p, %d, pruning %d connection(s)', this.components.getPeerId(), name, value, toPrune)
|
|
608
|
+
log('%s: limit exceeded: %p, %d/%d, pruning %d connection(s)', this.components.getPeerId(), name, value, limit, toPrune)
|
|
479
609
|
await this._maybePruneConnections(toPrune)
|
|
480
610
|
}
|
|
481
611
|
}
|
|
@@ -491,22 +621,49 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
|
|
|
491
621
|
return
|
|
492
622
|
}
|
|
493
623
|
|
|
494
|
-
const peerValues =
|
|
495
|
-
log.trace('sorted peer values: %j', peerValues)
|
|
624
|
+
const peerValues = new PeerMap<number>()
|
|
496
625
|
|
|
497
|
-
|
|
626
|
+
// work out peer values
|
|
627
|
+
for (const connection of connections) {
|
|
628
|
+
const remotePeer = connection.remotePeer
|
|
498
629
|
|
|
499
|
-
|
|
500
|
-
|
|
630
|
+
if (peerValues.has(remotePeer)) {
|
|
631
|
+
continue
|
|
632
|
+
}
|
|
501
633
|
|
|
502
|
-
|
|
503
|
-
if (connection.remotePeer.toString() === peerId) {
|
|
504
|
-
toClose.push(connection)
|
|
505
|
-
}
|
|
634
|
+
const tags = await this.components.getPeerStore().getTags(remotePeer)
|
|
506
635
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
636
|
+
// sum all tag values
|
|
637
|
+
peerValues.set(remotePeer, tags.reduce((acc, curr) => {
|
|
638
|
+
return acc + curr.value
|
|
639
|
+
}, 0))
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// sort by value, lowest to highest
|
|
643
|
+
const sortedConnections = connections.sort((a, b) => {
|
|
644
|
+
const peerAValue = peerValues.get(a.remotePeer) ?? 0
|
|
645
|
+
const peerBValue = peerValues.get(b.remotePeer) ?? 0
|
|
646
|
+
|
|
647
|
+
if (peerAValue > peerBValue) {
|
|
648
|
+
return 1
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (peerAValue < peerBValue) {
|
|
652
|
+
return -1
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
return 0
|
|
656
|
+
})
|
|
657
|
+
|
|
658
|
+
// close some connections
|
|
659
|
+
const toClose = []
|
|
660
|
+
|
|
661
|
+
for (const connection of sortedConnections) {
|
|
662
|
+
log('too many connections open - closing a connection to %p', connection.remotePeer)
|
|
663
|
+
toClose.push(connection)
|
|
664
|
+
|
|
665
|
+
if (toClose.length === toPrune) {
|
|
666
|
+
break
|
|
510
667
|
}
|
|
511
668
|
}
|
|
512
669
|
|
package/src/constants.ts
CHANGED
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
import drain from 'it-drain'
|
|
9
9
|
import merge from 'it-merge'
|
|
10
10
|
import { pipe } from 'it-pipe'
|
|
11
|
-
import type { ContentRouting } from '@libp2p/
|
|
11
|
+
import type { ContentRouting } from '@libp2p/interface-content-routing'
|
|
12
12
|
import type { AbortOptions } from '@libp2p/interfaces'
|
|
13
13
|
import type { Startable } from '@libp2p/interfaces/startable'
|
|
14
14
|
import type { CID } from 'multiformats/cid'
|
|
15
|
-
import type { Components } from '@libp2p/
|
|
15
|
+
import type { Components } from '@libp2p/components'
|
|
16
16
|
|
|
17
17
|
export interface CompoundContentRoutingInit {
|
|
18
18
|
routers: ContentRouting[]
|
|
@@ -2,8 +2,8 @@ import errCode from 'err-code'
|
|
|
2
2
|
import filter from 'it-filter'
|
|
3
3
|
import map from 'it-map'
|
|
4
4
|
import type { Source } from 'it-stream-types'
|
|
5
|
-
import type { PeerInfo } from '@libp2p/
|
|
6
|
-
import type { PeerStore } from '@libp2p/
|
|
5
|
+
import type { PeerInfo } from '@libp2p/interface-peer-info'
|
|
6
|
+
import type { PeerStore } from '@libp2p/interface-peer-store'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Store the multiaddrs from every peer in the passed peer store
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import drain from 'it-drain'
|
|
2
2
|
import errCode from 'err-code'
|
|
3
|
-
import type { DHT } from '@libp2p/
|
|
4
|
-
import type { ContentRouting } from '@libp2p/
|
|
3
|
+
import type { DHT } from '@libp2p/interface-dht'
|
|
4
|
+
import type { ContentRouting } from '@libp2p/interface-content-routing'
|
|
5
5
|
import type { CID } from 'multiformats/cid'
|
|
6
6
|
import type { AbortOptions } from '@libp2p/interfaces'
|
|
7
7
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import errCode from 'err-code'
|
|
2
2
|
import { messages, codes } from '../errors.js'
|
|
3
|
-
import type { PeerRouting } from '@libp2p/
|
|
4
|
-
import type { DHT } from '@libp2p/
|
|
5
|
-
import type { PeerId } from '@libp2p/
|
|
3
|
+
import type { PeerRouting } from '@libp2p/interface-peer-routing'
|
|
4
|
+
import type { DHT } from '@libp2p/interface-dht'
|
|
5
|
+
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
6
6
|
import type { AbortOptions } from '@libp2p/interfaces'
|
|
7
7
|
|
|
8
8
|
/**
|
package/src/dht/dummy-dht.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { DualDHT, QueryEvent, SingleDHT } from '@libp2p/
|
|
2
|
-
import type { PeerDiscoveryEvents } from '@libp2p/
|
|
1
|
+
import type { DualDHT, QueryEvent, SingleDHT } from '@libp2p/interface-dht'
|
|
2
|
+
import type { PeerDiscoveryEvents } from '@libp2p/interface-peer-discovery'
|
|
3
3
|
import errCode from 'err-code'
|
|
4
4
|
import { messages, codes } from '../errors.js'
|
|
5
5
|
import { EventEmitter } from '@libp2p/interfaces/events'
|
|
6
|
-
import { symbol } from '@libp2p/
|
|
6
|
+
import { symbol } from '@libp2p/interface-peer-discovery'
|
|
7
7
|
|
|
8
8
|
export class DummyDHT extends EventEmitter<PeerDiscoveryEvents> implements DualDHT {
|
|
9
9
|
get [symbol] (): true {
|
package/src/errors.ts
CHANGED
|
@@ -70,5 +70,8 @@ export enum codes {
|
|
|
70
70
|
ERR_NOT_IMPLEMENTED = 'ERR_NOT_IMPLEMENTED',
|
|
71
71
|
ERR_WRONG_PING_ACK = 'ERR_WRONG_PING_ACK',
|
|
72
72
|
ERR_INVALID_RECORD = 'ERR_INVALID_RECORD',
|
|
73
|
-
ERR_ALREADY_SUCCEEDED = 'ERR_ALREADY_SUCCEEDED'
|
|
73
|
+
ERR_ALREADY_SUCCEEDED = 'ERR_ALREADY_SUCCEEDED',
|
|
74
|
+
ERR_NO_HANDLER_FOR_PROTOCOL = 'ERR_NO_HANDLER_FOR_PROTOCOL',
|
|
75
|
+
ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS = 'ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS',
|
|
76
|
+
ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS = 'ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS'
|
|
74
77
|
}
|