libp2p 0.40.0 → 0.41.0-19e96cc

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.
Files changed (101) hide show
  1. package/README.md +26 -6
  2. package/dist/index.min.js +50 -0
  3. package/dist/src/address-manager/index.d.ts.map +1 -1
  4. package/dist/src/address-manager/index.js +1 -1
  5. package/dist/src/address-manager/index.js.map +1 -1
  6. package/dist/src/config.d.ts.map +1 -1
  7. package/dist/src/config.js +0 -11
  8. package/dist/src/config.js.map +1 -1
  9. package/dist/src/connection/index.d.ts +83 -0
  10. package/dist/src/connection/index.d.ts.map +1 -0
  11. package/dist/src/connection/index.js +96 -0
  12. package/dist/src/connection/index.js.map +1 -0
  13. package/dist/src/connection-manager/dialer/index.d.ts +13 -14
  14. package/dist/src/connection-manager/dialer/index.d.ts.map +1 -1
  15. package/dist/src/connection-manager/dialer/index.js +82 -62
  16. package/dist/src/connection-manager/dialer/index.js.map +1 -1
  17. package/dist/src/connection-manager/index.d.ts +7 -115
  18. package/dist/src/connection-manager/index.d.ts.map +1 -1
  19. package/dist/src/connection-manager/index.js +21 -57
  20. package/dist/src/connection-manager/index.js.map +1 -1
  21. package/dist/src/fetch/index.d.ts +14 -0
  22. package/dist/src/fetch/index.d.ts.map +1 -1
  23. package/dist/src/fetch/index.js +29 -3
  24. package/dist/src/fetch/index.js.map +1 -1
  25. package/dist/src/get-peer.d.ts +2 -2
  26. package/dist/src/get-peer.d.ts.map +1 -1
  27. package/dist/src/get-peer.js +2 -5
  28. package/dist/src/get-peer.js.map +1 -1
  29. package/dist/src/index.d.ts +192 -77
  30. package/dist/src/index.d.ts.map +1 -1
  31. package/dist/src/index.js +41 -1
  32. package/dist/src/index.js.map +1 -1
  33. package/dist/src/insecure/index.d.ts +23 -0
  34. package/dist/src/insecure/index.d.ts.map +1 -1
  35. package/dist/src/insecure/index.js +23 -0
  36. package/dist/src/insecure/index.js.map +1 -1
  37. package/dist/src/keychain/index.d.ts +1 -1
  38. package/dist/src/keychain/index.d.ts.map +1 -1
  39. package/dist/src/libp2p.d.ts +3 -3
  40. package/dist/src/libp2p.d.ts.map +1 -1
  41. package/dist/src/libp2p.js +2 -3
  42. package/dist/src/libp2p.js.map +1 -1
  43. package/dist/src/nat-manager.d.ts.map +1 -1
  44. package/dist/src/nat-manager.js +5 -1
  45. package/dist/src/nat-manager.js.map +1 -1
  46. package/dist/src/pnet/index.d.ts +23 -0
  47. package/dist/src/pnet/index.d.ts.map +1 -1
  48. package/dist/src/pnet/index.js +23 -0
  49. package/dist/src/pnet/index.js.map +1 -1
  50. package/dist/src/pnet/key-generator.d.ts +3 -2
  51. package/dist/src/pnet/key-generator.d.ts.map +1 -1
  52. package/dist/src/pnet/key-generator.js +7 -10
  53. package/dist/src/pnet/key-generator.js.map +1 -1
  54. package/dist/src/registrar.d.ts +5 -0
  55. package/dist/src/registrar.d.ts.map +1 -1
  56. package/dist/src/registrar.js +25 -0
  57. package/dist/src/registrar.js.map +1 -1
  58. package/dist/src/transport-manager.d.ts.map +1 -1
  59. package/dist/src/transport-manager.js +1 -2
  60. package/dist/src/transport-manager.js.map +1 -1
  61. package/dist/src/upgrader.d.ts +1 -1
  62. package/dist/src/upgrader.d.ts.map +1 -1
  63. package/dist/src/upgrader.js +46 -59
  64. package/dist/src/upgrader.js.map +1 -1
  65. package/package.json +15 -14
  66. package/src/address-manager/index.ts +3 -2
  67. package/src/circuit/README.md +6 -6
  68. package/src/config.ts +0 -11
  69. package/src/connection/index.ts +171 -0
  70. package/src/connection-manager/dialer/index.ts +100 -75
  71. package/src/connection-manager/index.ts +29 -192
  72. package/src/fetch/README.md +7 -2
  73. package/src/fetch/index.ts +30 -3
  74. package/src/get-peer.ts +3 -7
  75. package/src/index.ts +224 -83
  76. package/src/insecure/index.ts +24 -0
  77. package/src/keychain/index.ts +1 -1
  78. package/src/libp2p.ts +5 -6
  79. package/src/nat-manager.ts +6 -1
  80. package/src/pnet/README.md +31 -29
  81. package/src/pnet/index.ts +24 -0
  82. package/src/pnet/key-generator.ts +7 -12
  83. package/src/registrar.ts +29 -2
  84. package/src/transport-manager.ts +1 -2
  85. package/src/upgrader.ts +51 -64
  86. package/src/version.ts +1 -1
  87. package/dist/src/metrics/index.d.ts +0 -93
  88. package/dist/src/metrics/index.d.ts.map +0 -1
  89. package/dist/src/metrics/index.js +0 -234
  90. package/dist/src/metrics/index.js.map +0 -1
  91. package/dist/src/metrics/moving-average.d.ts +0 -14
  92. package/dist/src/metrics/moving-average.d.ts.map +0 -1
  93. package/dist/src/metrics/moving-average.js +0 -40
  94. package/dist/src/metrics/moving-average.js.map +0 -1
  95. package/dist/src/metrics/stats.d.ts +0 -87
  96. package/dist/src/metrics/stats.d.ts.map +0 -1
  97. package/dist/src/metrics/stats.js +0 -183
  98. package/dist/src/metrics/stats.js.map +0 -1
  99. package/src/metrics/index.ts +0 -311
  100. package/src/metrics/moving-average.ts +0 -53
  101. package/src/metrics/stats.ts +0 -238
@@ -1,12 +1,7 @@
1
1
  import { logger } from '@libp2p/logger'
2
- import all from 'it-all'
3
- import filter from 'it-filter'
4
- import { pipe } from 'it-pipe'
5
2
  import errCode from 'err-code'
6
- import type { Multiaddr, Resolver } from '@multiformats/multiaddr'
7
- import { multiaddr, resolvers } from '@multiformats/multiaddr'
3
+ import { isMultiaddr, Multiaddr, Resolver, multiaddr, resolvers } from '@multiformats/multiaddr'
8
4
  import { TimeoutController } from 'timeout-abort-controller'
9
- import { AbortError } from '@libp2p/interfaces/errors'
10
5
  import { anySignal } from 'any-signal'
11
6
  import { setMaxListeners } from 'events'
12
7
  import { DialAction, DialRequest } from './dial-request.js'
@@ -22,21 +17,15 @@ import {
22
17
  import type { Connection, ConnectionGater } from '@libp2p/interface-connection'
23
18
  import type { AbortOptions } from '@libp2p/interfaces'
24
19
  import type { Startable } from '@libp2p/interfaces/startable'
25
- import type { PeerId } from '@libp2p/interface-peer-id'
20
+ import { isPeerId, PeerId } from '@libp2p/interface-peer-id'
26
21
  import { getPeer } from '../../get-peer.js'
27
- import sort from 'it-sort'
28
- import map from 'it-map'
29
22
  import type { AddressSorter, PeerStore } from '@libp2p/interface-peer-store'
30
- import type { ComponentMetricsTracker, Metrics } from '@libp2p/interface-metrics'
23
+ import type { Metrics } from '@libp2p/interface-metrics'
31
24
  import type { Dialer } from '@libp2p/interface-connection-manager'
32
25
  import type { TransportManager } from '@libp2p/interface-transport'
33
26
 
34
27
  const log = logger('libp2p:dialer')
35
28
 
36
- const METRICS_COMPONENT = 'dialler'
37
- const METRICS_PENDING_DIALS = 'pending-dials'
38
- const METRICS_PENDING_DIAL_TARGETS = 'pending-dial-targets'
39
-
40
29
  export interface DialTarget {
41
30
  id: string
42
31
  addrs: Multiaddr[]
@@ -84,7 +73,6 @@ export interface DialerInit {
84
73
  * Multiaddr resolvers to use when dialing
85
74
  */
86
75
  resolvers?: Record<string, Resolver>
87
- metrics?: ComponentMetricsTracker
88
76
  }
89
77
 
90
78
  export interface DefaultDialerComponents {
@@ -103,7 +91,7 @@ export class DefaultDialer implements Startable, Dialer {
103
91
  private readonly maxDialsPerPeer: number
104
92
  public tokens: number[]
105
93
  public pendingDials: Map<string, PendingDial>
106
- public pendingDialTargets: Map<string, PendingDialTarget>
94
+ public pendingDialTargets: Map<string, AbortController>
107
95
  private started: boolean
108
96
 
109
97
  constructor (components: DefaultDialerComponents, init: DialerInit = {}) {
@@ -115,13 +103,11 @@ export class DefaultDialer implements Startable, Dialer {
115
103
  this.tokens = [...new Array(init.maxParallelDials ?? MAX_PARALLEL_DIALS)].map((_, index) => index)
116
104
  this.components = components
117
105
  this.pendingDials = trackedMap({
118
- component: METRICS_COMPONENT,
119
- metric: METRICS_PENDING_DIALS,
120
- metrics: init.metrics
106
+ name: 'libp2p_dialler_pending_dials',
107
+ metrics: components.metrics
121
108
  })
122
109
  this.pendingDialTargets = trackedMap({
123
- component: METRICS_COMPONENT,
124
- metric: METRICS_PENDING_DIAL_TARGETS,
110
+ name: 'libp2p_dialler_pending_dial_targets',
125
111
  metrics: components.metrics
126
112
  })
127
113
 
@@ -154,7 +140,7 @@ export class DefaultDialer implements Startable, Dialer {
154
140
  this.pendingDials.clear()
155
141
 
156
142
  for (const pendingTarget of this.pendingDialTargets.values()) {
157
- pendingTarget.reject(new AbortError('Dialer was destroyed'))
143
+ pendingTarget.abort()
158
144
  }
159
145
  this.pendingDialTargets.clear()
160
146
  }
@@ -164,8 +150,8 @@ export class DefaultDialer implements Startable, Dialer {
164
150
  * The dial to the first address that is successfully able to upgrade a connection
165
151
  * will be used.
166
152
  */
167
- async dial (peer: PeerId | Multiaddr, options: AbortOptions = {}): Promise<Connection> {
168
- const { id, multiaddrs } = getPeer(peer)
153
+ async dial (peerIdOrMultiaddr: PeerId | Multiaddr, options: AbortOptions = {}): Promise<Connection> {
154
+ const { id, multiaddrs } = getPeer(peerIdOrMultiaddr)
169
155
 
170
156
  if (this.components.peerId.equals(id)) {
171
157
  throw errCode(new Error('Tried to dial self'), codes.ERR_DIALED_SELF)
@@ -184,13 +170,35 @@ export class DefaultDialer implements Startable, Dialer {
184
170
 
185
171
  log('creating dial target for %p', id)
186
172
 
187
- const dialTarget = await this._createCancellableDialTarget(id, options)
173
+ // resolving multiaddrs can involve dns lookups so allow them to be aborted
174
+ const controller = new AbortController()
175
+ const controllerId = randomId()
176
+ this.pendingDialTargets.set(controllerId, controller)
177
+ let signal = controller.signal
178
+
179
+ // merge with the passed signal, if any
180
+ if (options.signal != null) {
181
+ signal = anySignal([signal, options.signal])
182
+ }
183
+
184
+ let dialTarget: DialTarget
185
+
186
+ try {
187
+ dialTarget = await this._createDialTarget(peerIdOrMultiaddr, {
188
+ ...options,
189
+ signal
190
+ })
191
+ } finally {
192
+ // done resolving the multiaddrs so remove the abort controller
193
+ this.pendingDialTargets.delete(controllerId)
194
+ }
188
195
 
189
196
  if (dialTarget.addrs.length === 0) {
190
197
  throw errCode(new Error('The dial request has no valid addresses'), codes.ERR_NO_VALID_ADDRESSES)
191
198
  }
192
199
 
193
- const pendingDial = this.pendingDials.get(dialTarget.id) ?? this._createPendingDial(dialTarget, options)
200
+ // try to join an in-flight dial for this peer if one is available
201
+ const pendingDial = this.pendingDials.get(dialTarget.id.toString()) ?? this._createPendingDial(dialTarget, options)
194
202
 
195
203
  try {
196
204
  const connection = await pendingDial.promise
@@ -209,74 +217,77 @@ export class DefaultDialer implements Startable, Dialer {
209
217
  }
210
218
  }
211
219
 
212
- /**
213
- * Connects to a given `peer` by dialing all of its known addresses.
214
- * The dial to the first address that is successfully able to upgrade a connection
215
- * will be used.
216
- */
217
- async _createCancellableDialTarget (peer: PeerId, options: AbortOptions): Promise<DialTarget> {
218
- // Make dial target promise cancellable
219
- const id = `${(parseInt(String(Math.random() * 1e9), 10)).toString()}${Date.now()}`
220
- const cancellablePromise = new Promise<DialTarget>((resolve, reject) => {
221
- this.pendingDialTargets.set(id, { resolve, reject })
222
- })
223
-
224
- try {
225
- const dialTarget = await Promise.race([
226
- this._createDialTarget(peer, options),
227
- cancellablePromise
228
- ])
229
-
230
- return dialTarget
231
- } finally {
232
- this.pendingDialTargets.delete(id)
233
- }
234
- }
235
-
236
220
  /**
237
221
  * Creates a DialTarget. The DialTarget is used to create and track
238
222
  * the DialRequest to a given peer.
239
- * If a multiaddr is received it should be the first address attempted.
223
+ *
224
+ * If a multiaddr is received it should be the only address attempted.
225
+ *
240
226
  * Multiaddrs not supported by the available transports will be filtered out.
241
227
  */
242
- async _createDialTarget (peer: PeerId, options: AbortOptions): Promise<DialTarget> {
228
+ async _createDialTarget (peerIdOrMultiaddr: PeerId | Multiaddr, options: AbortOptions): Promise<DialTarget> {
243
229
  const _resolve = this._resolve.bind(this)
244
230
 
245
- const addrs = await pipe(
246
- await this.components.peerStore.addressBook.get(peer),
247
- (source) => filter(source, async (address) => {
248
- return !(await this.components.connectionGater.denyDialMultiaddr(peer, address.multiaddr))
249
- }),
250
- // Sort addresses so, for example, we try certified public address first
251
- (source) => sort(source, this.addressSorter),
252
- async function * resolve (source) {
253
- for await (const a of source) {
254
- yield * await _resolve(a.multiaddr, options)
255
- }
256
- },
231
+ let addrs = isMultiaddr(peerIdOrMultiaddr) ? [peerIdOrMultiaddr] : await this._loadAddresses(peerIdOrMultiaddr)
232
+
233
+ addrs = (await Promise.all(
234
+ addrs.map(async (ma) => await _resolve(ma, options))
235
+ ))
236
+ .flat()
257
237
  // Multiaddrs not supported by the available transports will be filtered out.
258
- (source) => filter(source, (ma) => Boolean(this.components.transportManager.transportForMultiaddr(ma))),
259
- (source) => map(source, (ma) => {
260
- if (peer.toString() === ma.getPeerId()) {
261
- return ma
262
- }
238
+ .filter(ma => Boolean(this.components.transportManager.transportForMultiaddr(ma)))
263
239
 
264
- return ma.encapsulate(`/p2p/${peer.toString()}`)
265
- }),
266
- async (source) => await all(source)
267
- )
240
+ // deduplicate addresses
241
+ addrs = [...new Set(addrs)]
268
242
 
269
243
  if (addrs.length > this.maxAddrsToDial) {
270
- await this.components.peerStore.delete(peer)
271
244
  throw errCode(new Error('dial with more addresses than allowed'), codes.ERR_TOO_MANY_ADDRESSES)
272
245
  }
273
246
 
247
+ const peerId = isPeerId(peerIdOrMultiaddr) ? peerIdOrMultiaddr : undefined
248
+
249
+ if (peerId != null) {
250
+ const peerIdMultiaddr = `/p2p/${peerId.toString()}`
251
+ addrs = addrs.map(addr => {
252
+ const addressPeerId = addr.getPeerId()
253
+
254
+ if (addressPeerId == null || !peerId.equals(addressPeerId)) {
255
+ return addr.encapsulate(peerIdMultiaddr)
256
+ }
257
+
258
+ return addr
259
+ })
260
+ }
261
+
274
262
  return {
275
- id: peer.toString(),
263
+ id: peerId == null ? randomId() : peerId.toString(),
276
264
  addrs
277
265
  }
278
266
  }
279
267
 
268
+ /**
269
+ * Loads a list of addresses from the peer store for the passed peer id
270
+ */
271
+ async _loadAddresses (peer: PeerId): Promise<Multiaddr[]> {
272
+ const addresses = await this.components.peerStore.addressBook.get(peer)
273
+
274
+ return (await Promise.all(
275
+ addresses.map(async address => {
276
+ const deny = await this.components.connectionGater.denyDialMultiaddr(peer, address.multiaddr)
277
+
278
+ if (deny) {
279
+ return false
280
+ }
281
+
282
+ return address
283
+ })
284
+ ))
285
+ .filter(isTruthy)
286
+ // Sort addresses so, for example, we try certified public address first
287
+ .sort(this.addressSorter)
288
+ .map(address => address.multiaddr)
289
+ }
290
+
280
291
  /**
281
292
  * Creates a PendingDial that wraps the underlying DialRequest
282
293
  */
@@ -388,3 +399,17 @@ export class DefaultDialer implements Startable, Dialer {
388
399
  }
389
400
  }
390
401
  }
402
+
403
+ /**
404
+ * Type safe version of `list.filter(Boolean)`
405
+ */
406
+ function isTruthy <T> (e: T | false | null | undefined): e is T {
407
+ return Boolean(e)
408
+ }
409
+
410
+ /**
411
+ * Returns a random string
412
+ */
413
+ function randomId (): string {
414
+ return `${(parseInt(String(Math.random() * 1e9), 10)).toString()}${Date.now()}`
415
+ }
@@ -2,8 +2,6 @@ import { logger } from '@libp2p/logger'
2
2
  import errCode from 'err-code'
3
3
  import mergeOptions from 'merge-options'
4
4
  import { LatencyMonitor, SummaryObject } from './latency-monitor.js'
5
- // @ts-expect-error retimer does not have types
6
- import retimer from 'retimer'
7
5
  import type { AbortOptions } from '@libp2p/interfaces'
8
6
  import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
9
7
  import type { Startable } from '@libp2p/interfaces/startable'
@@ -11,162 +9,33 @@ import { codes } from '../errors.js'
11
9
  import { isPeerId, PeerId } from '@libp2p/interface-peer-id'
12
10
  import { setMaxListeners } from 'events'
13
11
  import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection'
14
- import type { ConnectionManager, Dialer } from '@libp2p/interface-connection-manager'
12
+ import type { ConnectionManager, ConnectionManagerEvents, Dialer } from '@libp2p/interface-connection-manager'
15
13
  import * as STATUS from '@libp2p/interface-connection/status'
16
- import type { AddressSorter, PeerStore } from '@libp2p/interface-peer-store'
17
- import { multiaddr, Multiaddr, Resolver } from '@multiformats/multiaddr'
14
+ import type { PeerStore } from '@libp2p/interface-peer-store'
15
+ import { isMultiaddr, multiaddr, Multiaddr } from '@multiformats/multiaddr'
18
16
  import { PeerMap } from '@libp2p/peer-collections'
19
17
  import { TimeoutController } from 'timeout-abort-controller'
20
18
  import { KEEP_ALIVE } from '@libp2p/interface-peer-store/tags'
21
19
  import { RateLimiterMemory } from 'rate-limiter-flexible'
22
20
  import type { Metrics } from '@libp2p/interface-metrics'
23
21
  import type { Upgrader } from '@libp2p/interface-transport'
22
+ import { getPeer } from '../get-peer.js'
23
+ import type { ConnectionManagerConfig } from '../index.js'
24
24
 
25
25
  const log = logger('libp2p:connection-manager')
26
26
 
27
- const defaultOptions: Partial<ConnectionManagerInit> = {
27
+ const defaultOptions: Partial<ConnectionManagerConfig> = {
28
28
  maxConnections: Infinity,
29
29
  minConnections: 0,
30
- maxData: Infinity,
31
- maxSentData: Infinity,
32
- maxReceivedData: Infinity,
33
30
  maxEventLoopDelay: Infinity,
34
31
  pollInterval: 2000,
35
32
  autoDialInterval: 10000,
36
- movingAverageInterval: 60000,
37
33
  inboundConnectionThreshold: 5,
38
34
  maxIncomingPendingConnections: 10
39
35
  }
40
36
 
41
- const METRICS_SYSTEM = 'libp2p'
42
- const METRICS_COMPONENT = 'connection-manager'
43
37
  const STARTUP_RECONNECT_TIMEOUT = 60000
44
38
 
45
- export interface ConnectionManagerInit {
46
- /**
47
- * The maximum number of connections to keep open
48
- */
49
- maxConnections: number
50
-
51
- /**
52
- * The minimum number of connections to keep open
53
- */
54
- minConnections: number
55
-
56
- /**
57
- * The max data (in and out), per average interval to allow
58
- */
59
- maxData?: number
60
-
61
- /**
62
- * The max outgoing data, per average interval to allow
63
- */
64
- maxSentData?: number
65
-
66
- /**
67
- * The max incoming data, per average interval to allow
68
- */
69
- maxReceivedData?: number
70
-
71
- /**
72
- * The upper limit the event loop can take to run
73
- */
74
- maxEventLoopDelay?: number
75
-
76
- /**
77
- * How often, in milliseconds, metrics and latency should be checked
78
- */
79
- pollInterval?: number
80
-
81
- /**
82
- * How often, in milliseconds, to compute averages
83
- */
84
- movingAverageInterval?: number
85
-
86
- /**
87
- * If true, try to connect to all discovered peers up to the connection manager limit
88
- */
89
- autoDial?: boolean
90
-
91
- /**
92
- * How long to wait between attempting to keep our number of concurrent connections
93
- * above minConnections
94
- */
95
- autoDialInterval: number
96
-
97
- /**
98
- * Sort the known addresses of a peer before trying to dial
99
- */
100
- addressSorter?: AddressSorter
101
-
102
- /**
103
- * Number of max concurrent dials
104
- */
105
- maxParallelDials?: number
106
-
107
- /**
108
- * Number of max addresses to dial for a given peer
109
- */
110
- maxAddrsToDial?: number
111
-
112
- /**
113
- * How long a dial attempt is allowed to take, including DNS resolution
114
- * of the multiaddr, opening a socket and upgrading it to a Connection.
115
- */
116
- dialTimeout?: number
117
-
118
- /**
119
- * When a new inbound connection is opened, the upgrade process (e.g. protect,
120
- * encrypt, multiplex etc) must complete within this number of ms.
121
- */
122
- inboundUpgradeTimeout: number
123
-
124
- /**
125
- * Number of max concurrent dials per peer
126
- */
127
- maxDialsPerPeer?: number
128
-
129
- /**
130
- * Multiaddr resolvers to use when dialing
131
- */
132
- resolvers?: Record<string, Resolver>
133
-
134
- /**
135
- * On startup we try to dial any peer that has previously been
136
- * tagged with KEEP_ALIVE up to this timeout in ms. (default: 60000)
137
- */
138
- startupReconnectTimeout?: number
139
-
140
- /**
141
- * A list of multiaddrs that will always be allowed (except if they are in the
142
- * deny list) to open connections to this node even if we've reached maxConnections
143
- */
144
- allow?: string[]
145
-
146
- /**
147
- * A list of multiaddrs that will never be allowed to open connections to
148
- * this node under any circumstances
149
- */
150
- deny?: string[]
151
-
152
- /**
153
- * If more than this many connections are opened per second by a single
154
- * host, reject subsequent connections
155
- */
156
- inboundConnectionThreshold?: number
157
-
158
- /**
159
- * The maximum number of parallel incoming connections allowed that have yet to
160
- * complete the connection upgrade - e.g. choosing connection encryption, muxer, etc
161
- */
162
- maxIncomingPendingConnections?: number
163
- }
164
-
165
- export interface ConnectionManagerEvents {
166
- 'peer:connect': CustomEvent<PeerId>
167
- 'peer:disconnect': CustomEvent<PeerId>
168
- }
169
-
170
39
  export interface DefaultConnectionManagerComponents {
171
40
  peerId: PeerId
172
41
  metrics?: Metrics
@@ -175,15 +44,16 @@ export interface DefaultConnectionManagerComponents {
175
44
  dialer: Dialer
176
45
  }
177
46
 
47
+ export type ConnectionManagerInit = Required<ConnectionManagerConfig>
48
+
178
49
  /**
179
50
  * Responsible for managing known connections.
180
51
  */
181
52
  export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEvents> implements ConnectionManager, Startable {
182
53
  private readonly components: DefaultConnectionManagerComponents
183
- private readonly opts: Required<ConnectionManagerInit>
54
+ private readonly opts: ConnectionManagerInit
184
55
  private readonly connections: Map<string, Connection[]>
185
56
  private started: boolean
186
- private timer?: ReturnType<retimer>
187
57
  private readonly latencyMonitor: LatencyMonitor
188
58
  private readonly startupReconnectTimeout: number
189
59
  private connectOnStartupController?: TimeoutController
@@ -193,7 +63,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
193
63
  private readonly inboundConnectionRateLimiter: RateLimiterMemory
194
64
  private incomingPendingConnections: number
195
65
 
196
- constructor (components: DefaultConnectionManagerComponents, init: ConnectionManagerInit) {
66
+ constructor (components: DefaultConnectionManagerComponents, init: ConnectionManagerConfig) {
197
67
  super()
198
68
 
199
69
  this.opts = mergeOptions.call({ ignoreUndefined: true }, defaultOptions, init)
@@ -212,7 +82,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
212
82
  this.connections = new Map()
213
83
 
214
84
  this.started = false
215
- this._checkMetrics = this._checkMetrics.bind(this)
216
85
 
217
86
  this.latencyMonitor = new LatencyMonitor({
218
87
  latencyCheckIntervalMs: init.pollInterval,
@@ -250,17 +119,9 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
250
119
  * only event loop and connection limits will be monitored.
251
120
  */
252
121
  async start () {
253
- if (this.components.metrics != null) {
254
- this.timer = this.timer ?? retimer(this._checkMetrics, this.opts.pollInterval)
255
- }
256
-
257
122
  // track inbound/outbound connections
258
- this.components.metrics?.updateComponentMetric({
259
- system: METRICS_SYSTEM,
260
- component: METRICS_COMPONENT,
261
- metric: 'connections',
262
- label: 'direction',
263
- value: () => {
123
+ this.components.metrics?.registerMetricGroup('libp2p_connection_manager_connections', {
124
+ calculate: () => {
264
125
  const metric = {
265
126
  inbound: 0,
266
127
  outbound: 0
@@ -281,12 +142,9 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
281
142
  })
282
143
 
283
144
  // track total number of streams per protocol
284
- this.components.metrics?.updateComponentMetric({
285
- system: METRICS_SYSTEM,
286
- component: METRICS_COMPONENT,
287
- metric: 'protocol-streams-total',
145
+ this.components.metrics?.registerMetricGroup('libp2p_protocol_streams_total', {
288
146
  label: 'protocol',
289
- value: () => {
147
+ calculate: () => {
290
148
  const metric: Record<string, number> = {}
291
149
 
292
150
  for (const conns of this.connections.values()) {
@@ -304,12 +162,9 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
304
162
  })
305
163
 
306
164
  // track 90th percentile of streams per protocol
307
- this.components.metrics?.updateComponentMetric({
308
- system: METRICS_SYSTEM,
309
- component: METRICS_COMPONENT,
310
- metric: 'protocol-streams-per-connection-90th-percentile',
165
+ this.components.metrics?.registerMetricGroup('libp2p_connection_manager_protocol_streams_per_connection_90th_percentile', {
311
166
  label: 'protocol',
312
- value: () => {
167
+ calculate: () => {
313
168
  const allStreams: Record<string, number[]> = {}
314
169
 
315
170
  for (const conns of this.connections.values()) {
@@ -407,8 +262,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
407
262
  * Stops the Connection Manager
408
263
  */
409
264
  async stop () {
410
- this.timer?.clear()
411
-
412
265
  this.latencyMonitor.removeEventListener('data', this._onLatencyMeasure)
413
266
  this.latencyMonitor.stop()
414
267
 
@@ -440,31 +293,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
440
293
  this.connections.clear()
441
294
  }
442
295
 
443
- /**
444
- * Checks the libp2p metrics to determine if any values have exceeded
445
- * the configured maximums.
446
- *
447
- * @private
448
- */
449
- async _checkMetrics () {
450
- const metrics = this.components.metrics
451
-
452
- if (metrics != null) {
453
- try {
454
- const movingAverages = metrics.getGlobal().getMovingAverages()
455
- const received = movingAverages.dataReceived[this.opts.movingAverageInterval].movingAverage
456
- await this._checkMaxLimit('maxReceivedData', received)
457
- const sent = movingAverages.dataSent[this.opts.movingAverageInterval].movingAverage
458
- await this._checkMaxLimit('maxSentData', sent)
459
- const total = received + sent
460
- await this._checkMaxLimit('maxData', total)
461
- log.trace('metrics update', total)
462
- } finally {
463
- this.timer = retimer(this._checkMetrics, this.opts.pollInterval)
464
- }
465
- }
466
- }
467
-
468
296
  onConnect (evt: CustomEvent<Connection>) {
469
297
  void this._onConnect(evt).catch(err => {
470
298
  log.error(err)
@@ -524,8 +352,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
524
352
  } else if (storedConn != null) {
525
353
  this.connections.delete(peerId)
526
354
  this.dispatchEvent(new CustomEvent<Connection>('peer:disconnect', { detail: connection }))
527
-
528
- this.components.metrics?.onPeerDisconnected(connection.remotePeer)
529
355
  }
530
356
  }
531
357
 
@@ -543,7 +369,18 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
543
369
  return conns
544
370
  }
545
371
 
546
- async openConnection (peerId: PeerId, options: AbortOptions = {}): Promise<Connection> {
372
+ async openConnection (peerIdOrMultiaddr: PeerId | Multiaddr, options: AbortOptions = {}): Promise<Connection> {
373
+ let peerId: PeerId
374
+
375
+ if (isPeerId(peerIdOrMultiaddr)) {
376
+ peerId = peerIdOrMultiaddr
377
+ } else if (isMultiaddr(peerIdOrMultiaddr)) {
378
+ const info = getPeer(peerIdOrMultiaddr)
379
+ peerId = info.id
380
+ } else {
381
+ throw errCode(new TypeError('Can only open connections to PeerIds or Multiaddrs'), codes.ERR_INVALID_PARAMETERS)
382
+ }
383
+
547
384
  log('dial to %p', peerId)
548
385
  const existingConnections = this.getConnections(peerId)
549
386
 
@@ -566,7 +403,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
566
403
  }
567
404
 
568
405
  try {
569
- const connection = await this.components.dialer.dial(peerId, options)
406
+ const connection = await this.components.dialer.dial(peerIdOrMultiaddr, options)
570
407
  let peerConnections = this.connections.get(peerId.toString())
571
408
 
572
409
  if (peerConnections == null) {
@@ -1,8 +1,13 @@
1
- libp2p-fetch JavaScript Implementation
1
+ libp2p-fetch JavaScript Implementation <!-- omit in toc -->
2
2
  =====================================
3
3
 
4
4
  > Libp2p fetch protocol JavaScript implementation
5
5
 
6
+ ## Table of contents <!-- omit in toc -->
7
+
8
+ - [Overview](#overview)
9
+ - [Usage](#usage)
10
+
6
11
  ## Overview
7
12
 
8
13
  An implementation of the Fetch protocol as described here: https://github.com/libp2p/specs/tree/master/fetch
@@ -27,7 +32,7 @@ async function my_subsystem_key_lookup(key) {
27
32
  }
28
33
 
29
34
  // Enable this peer to respond to fetch requests for keys that begin with '/my_subsystem_key_prefix/'
30
- const libp2p = Libp2p.create(...)
35
+ const libp2p = createLibp2p()
31
36
  libp2p.fetchService.registerLookupFunction('/my_subsystem_key_prefix/', my_subsystem_key_lookup)
32
37
 
33
38
  const key = '/my_subsystem_key_prefix/{...}'