libp2p 2.10.0 → 3.0.0-049bfa0fa

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 (121) hide show
  1. package/README.md +39 -37
  2. package/dist/index.min.js +14 -17
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/address-manager/dns-mappings.d.ts +1 -2
  5. package/dist/src/address-manager/dns-mappings.d.ts.map +1 -1
  6. package/dist/src/address-manager/dns-mappings.js +39 -43
  7. package/dist/src/address-manager/dns-mappings.js.map +1 -1
  8. package/dist/src/address-manager/index.d.ts.map +1 -1
  9. package/dist/src/address-manager/index.js +31 -14
  10. package/dist/src/address-manager/index.js.map +1 -1
  11. package/dist/src/address-manager/ip-mappings.d.ts +1 -0
  12. package/dist/src/address-manager/ip-mappings.d.ts.map +1 -1
  13. package/dist/src/address-manager/ip-mappings.js +51 -40
  14. package/dist/src/address-manager/ip-mappings.js.map +1 -1
  15. package/dist/src/address-manager/observed-addresses.d.ts.map +1 -1
  16. package/dist/src/address-manager/observed-addresses.js +1 -3
  17. package/dist/src/address-manager/observed-addresses.js.map +1 -1
  18. package/dist/src/address-manager/transport-addresses.d.ts.map +1 -1
  19. package/dist/src/address-manager/transport-addresses.js +6 -8
  20. package/dist/src/address-manager/transport-addresses.js.map +1 -1
  21. package/dist/src/config/connection-gater.browser.d.ts.map +1 -1
  22. package/dist/src/config/connection-gater.browser.js +8 -22
  23. package/dist/src/config/connection-gater.browser.js.map +1 -1
  24. package/dist/src/config/connection-gater.d.ts.map +1 -1
  25. package/dist/src/config/connection-gater.js +1 -12
  26. package/dist/src/config/connection-gater.js.map +1 -1
  27. package/dist/src/config.d.ts.map +1 -1
  28. package/dist/src/config.js +3 -22
  29. package/dist/src/config.js.map +1 -1
  30. package/dist/src/connection-manager/address-sorter.d.ts.map +1 -1
  31. package/dist/src/connection-manager/address-sorter.js +1 -2
  32. package/dist/src/connection-manager/address-sorter.js.map +1 -1
  33. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  34. package/dist/src/connection-manager/connection-pruner.js +7 -3
  35. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  36. package/dist/src/connection-manager/constants.defaults.d.ts +4 -0
  37. package/dist/src/connection-manager/constants.defaults.d.ts.map +1 -1
  38. package/dist/src/connection-manager/constants.defaults.js +4 -0
  39. package/dist/src/connection-manager/constants.defaults.js.map +1 -1
  40. package/dist/src/connection-manager/dial-queue.d.ts +2 -2
  41. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  42. package/dist/src/connection-manager/dial-queue.js +11 -23
  43. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  44. package/dist/src/connection-manager/index.d.ts +10 -18
  45. package/dist/src/connection-manager/index.d.ts.map +1 -1
  46. package/dist/src/connection-manager/index.js +44 -26
  47. package/dist/src/connection-manager/index.js.map +1 -1
  48. package/dist/src/connection-manager/reconnect-queue.js +1 -1
  49. package/dist/src/connection-manager/reconnect-queue.js.map +1 -1
  50. package/dist/src/connection-manager/utils.d.ts +31 -3
  51. package/dist/src/connection-manager/utils.d.ts.map +1 -1
  52. package/dist/src/connection-manager/utils.js +99 -18
  53. package/dist/src/connection-manager/utils.js.map +1 -1
  54. package/dist/src/connection-monitor.d.ts +1 -1
  55. package/dist/src/connection-monitor.d.ts.map +1 -1
  56. package/dist/src/connection-monitor.js +2 -3
  57. package/dist/src/connection-monitor.js.map +1 -1
  58. package/dist/src/connection.d.ts +14 -9
  59. package/dist/src/connection.d.ts.map +1 -1
  60. package/dist/src/connection.js +118 -139
  61. package/dist/src/connection.js.map +1 -1
  62. package/dist/src/get-peer.js +3 -3
  63. package/dist/src/get-peer.js.map +1 -1
  64. package/dist/src/index.d.ts +2 -2
  65. package/dist/src/index.js +2 -2
  66. package/dist/src/libp2p.d.ts +3 -1
  67. package/dist/src/libp2p.d.ts.map +1 -1
  68. package/dist/src/libp2p.js +13 -7
  69. package/dist/src/libp2p.js.map +1 -1
  70. package/dist/src/peer-routing.js +1 -1
  71. package/dist/src/peer-routing.js.map +1 -1
  72. package/dist/src/random-walk.d.ts.map +1 -1
  73. package/dist/src/random-walk.js +13 -3
  74. package/dist/src/random-walk.js.map +1 -1
  75. package/dist/src/registrar.d.ts +8 -4
  76. package/dist/src/registrar.d.ts.map +1 -1
  77. package/dist/src/registrar.js +66 -46
  78. package/dist/src/registrar.js.map +1 -1
  79. package/dist/src/transport-manager.js +15 -2
  80. package/dist/src/transport-manager.js.map +1 -1
  81. package/dist/src/upgrader.d.ts +26 -16
  82. package/dist/src/upgrader.d.ts.map +1 -1
  83. package/dist/src/upgrader.js +88 -122
  84. package/dist/src/upgrader.js.map +1 -1
  85. package/dist/src/utils.d.ts +3 -0
  86. package/dist/src/utils.d.ts.map +1 -0
  87. package/dist/src/utils.js +25 -0
  88. package/dist/src/utils.js.map +1 -0
  89. package/dist/src/version.d.ts +1 -1
  90. package/dist/src/version.d.ts.map +1 -1
  91. package/dist/src/version.js +1 -1
  92. package/dist/src/version.js.map +1 -1
  93. package/package.json +27 -30
  94. package/src/address-manager/dns-mappings.ts +50 -50
  95. package/src/address-manager/index.ts +37 -17
  96. package/src/address-manager/ip-mappings.ts +64 -44
  97. package/src/address-manager/observed-addresses.ts +1 -3
  98. package/src/address-manager/transport-addresses.ts +7 -9
  99. package/src/config/connection-gater.browser.ts +8 -24
  100. package/src/config/connection-gater.ts +1 -12
  101. package/src/config.ts +3 -25
  102. package/src/connection-manager/address-sorter.ts +1 -2
  103. package/src/connection-manager/connection-pruner.ts +8 -3
  104. package/src/connection-manager/constants.defaults.ts +5 -0
  105. package/src/connection-manager/dial-queue.ts +12 -27
  106. package/src/connection-manager/index.ts +60 -45
  107. package/src/connection-manager/reconnect-queue.ts +1 -1
  108. package/src/connection-manager/utils.ts +129 -21
  109. package/src/connection-monitor.ts +3 -4
  110. package/src/connection.ts +142 -179
  111. package/src/get-peer.ts +3 -3
  112. package/src/index.ts +2 -2
  113. package/src/libp2p.ts +16 -9
  114. package/src/peer-routing.ts +1 -1
  115. package/src/random-walk.ts +13 -3
  116. package/src/registrar.ts +87 -61
  117. package/src/transport-manager.ts +18 -2
  118. package/src/upgrader.ts +132 -149
  119. package/src/utils.ts +31 -0
  120. package/src/version.ts +1 -1
  121. package/dist/typedoc-urls.json +0 -24
package/src/registrar.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { InvalidParametersError } from '@libp2p/interface'
2
- import { mergeOptions } from '@libp2p/utils/merge-options'
3
- import { trackedMap } from '@libp2p/utils/tracked-map'
4
- import * as errorsJs from './errors.js'
5
- import type { IdentifyResult, Libp2pEvents, Logger, PeerUpdate, PeerId, PeerStore, Topology, StreamHandler, StreamHandlerRecord, StreamHandlerOptions, AbortOptions, Metrics } from '@libp2p/interface'
2
+ import { trackedMap } from '@libp2p/utils'
3
+ import { DuplicateProtocolHandlerError, UnhandledProtocolError } from './errors.js'
4
+ import type { IdentifyResult, Libp2pEvents, Logger, PeerUpdate, PeerId, PeerStore, Topology, StreamHandler, StreamHandlerRecord, StreamHandlerOptions, AbortOptions, Metrics, StreamMiddleware } from '@libp2p/interface'
6
5
  import type { Registrar as RegistrarInterface } from '@libp2p/interface-internal'
7
6
  import type { ComponentLogger } from '@libp2p/logger'
8
7
  import type { TypedEventTarget } from 'main-event'
@@ -26,10 +25,12 @@ export class Registrar implements RegistrarInterface {
26
25
  private readonly topologies: Map<string, Map<string, Topology>>
27
26
  private readonly handlers: Map<string, StreamHandlerRecord>
28
27
  private readonly components: RegistrarComponents
28
+ private readonly middleware: Map<string, StreamMiddleware[]>
29
29
 
30
30
  constructor (components: RegistrarComponents) {
31
31
  this.components = components
32
32
  this.log = components.logger.forComponent('libp2p:registrar')
33
+ this.middleware = new Map()
33
34
  this.topologies = new Map()
34
35
  components.metrics?.registerMetricGroup('libp2p_registrar_topologies', {
35
36
  calculate: () => {
@@ -68,7 +69,7 @@ export class Registrar implements RegistrarInterface {
68
69
  const handler = this.handlers.get(protocol)
69
70
 
70
71
  if (handler == null) {
71
- throw new errorsJs.UnhandledProtocolError(`No handler registered for protocol ${protocol}`)
72
+ throw new UnhandledProtocolError(`No handler registered for protocol ${protocol}`)
72
73
  }
73
74
 
74
75
  return handler
@@ -91,17 +92,16 @@ export class Registrar implements RegistrarInterface {
91
92
  */
92
93
  async handle (protocol: string, handler: StreamHandler, opts?: StreamHandlerOptions): Promise<void> {
93
94
  if (this.handlers.has(protocol) && opts?.force !== true) {
94
- throw new errorsJs.DuplicateProtocolHandlerError(`Handler already registered for protocol ${protocol}`)
95
+ throw new DuplicateProtocolHandlerError(`Handler already registered for protocol ${protocol}`)
95
96
  }
96
97
 
97
- const options = mergeOptions.bind({ ignoreUndefined: true })({
98
- maxInboundStreams: DEFAULT_MAX_INBOUND_STREAMS,
99
- maxOutboundStreams: DEFAULT_MAX_OUTBOUND_STREAMS
100
- }, opts)
101
-
102
98
  this.handlers.set(protocol, {
103
99
  handler,
104
- options
100
+ options: {
101
+ maxInboundStreams: DEFAULT_MAX_INBOUND_STREAMS,
102
+ maxOutboundStreams: DEFAULT_MAX_OUTBOUND_STREAMS,
103
+ ...opts
104
+ }
105
105
  })
106
106
 
107
107
  // Add new protocol to self protocols in the peer store
@@ -165,69 +165,89 @@ export class Registrar implements RegistrarInterface {
165
165
  }
166
166
  }
167
167
 
168
+ use (protocol: string, middleware: StreamMiddleware[]): void {
169
+ this.middleware.set(protocol, middleware)
170
+ }
171
+
172
+ unuse (protocol: string): void {
173
+ this.middleware.delete(protocol)
174
+ }
175
+
176
+ getMiddleware (protocol: string): StreamMiddleware[] {
177
+ return this.middleware.get(protocol) ?? []
178
+ }
179
+
168
180
  /**
169
181
  * Remove a disconnected peer from the record
170
182
  */
171
- _onDisconnect (evt: CustomEvent<PeerId>): void {
183
+ async _onDisconnect (evt: CustomEvent<PeerId>): Promise<void> {
172
184
  const remotePeer = evt.detail
173
185
  const options = {
174
186
  signal: AbortSignal.timeout(5_000)
175
187
  }
176
188
 
177
- void this.components.peerStore.get(remotePeer, options)
178
- .then(peer => {
179
- for (const protocol of peer.protocols) {
180
- const topologies = this.topologies.get(protocol)
189
+ try {
190
+ const peer = await this.components.peerStore.get(remotePeer, options)
181
191
 
182
- if (topologies == null) {
183
- // no topologies are interested in this protocol
184
- continue
185
- }
192
+ for (const protocol of peer.protocols) {
193
+ const topologies = this.topologies.get(protocol)
186
194
 
187
- for (const topology of topologies.values()) {
195
+ if (topologies == null) {
196
+ // no topologies are interested in this protocol
197
+ continue
198
+ }
199
+
200
+ await Promise.all(
201
+ [...topologies.values()].map(async topology => {
188
202
  if (topology.filter?.has(remotePeer) === false) {
189
- continue
203
+ return
190
204
  }
191
205
 
192
206
  topology.filter?.remove(remotePeer)
193
- topology.onDisconnect?.(remotePeer)
194
- }
195
- }
196
- })
197
- .catch(err => {
198
- if (err.name === 'NotFoundError') {
199
- // peer has not completed identify so they are not in the peer store
200
- return
201
- }
207
+ await topology.onDisconnect?.(remotePeer)
208
+ })
209
+ )
210
+ }
211
+ } catch (err: any) {
212
+ if (err.name === 'NotFoundError') {
213
+ // peer has not completed identify so they are not in the peer store
214
+ return
215
+ }
202
216
 
203
- this.log.error('could not inform topologies of disconnecting peer %p', remotePeer, err)
204
- })
217
+ this.log.error('could not inform topologies of disconnecting peer %p - %e', remotePeer, err)
218
+ }
205
219
  }
206
220
 
207
221
  /**
208
222
  * When a peer is updated, if they have removed supported protocols notify any
209
223
  * topologies interested in the removed protocols.
210
224
  */
211
- _onPeerUpdate (evt: CustomEvent<PeerUpdate>): void {
225
+ async _onPeerUpdate (evt: CustomEvent<PeerUpdate>): Promise<void> {
212
226
  const { peer, previous } = evt.detail
213
227
  const removed = (previous?.protocols ?? []).filter(protocol => !peer.protocols.includes(protocol))
214
228
 
215
- for (const protocol of removed) {
216
- const topologies = this.topologies.get(protocol)
229
+ try {
230
+ for (const protocol of removed) {
231
+ const topologies = this.topologies.get(protocol)
217
232
 
218
- if (topologies == null) {
219
- // no topologies are interested in this protocol
220
- continue
221
- }
222
-
223
- for (const topology of topologies.values()) {
224
- if (topology.filter?.has(peer.id) === false) {
233
+ if (topologies == null) {
234
+ // no topologies are interested in this protocol
225
235
  continue
226
236
  }
227
237
 
228
- topology.filter?.remove(peer.id)
229
- topology.onDisconnect?.(peer.id)
238
+ await Promise.all(
239
+ [...topologies.values()].map(async topology => {
240
+ if (topology.filter?.has(peer.id) === false) {
241
+ return
242
+ }
243
+
244
+ topology.filter?.remove(peer.id)
245
+ await topology.onDisconnect?.(peer.id)
246
+ })
247
+ )
230
248
  }
249
+ } catch (err: any) {
250
+ this.log.error('could not inform topologies of updated peer %p - %e', peer.id, err)
231
251
  }
232
252
  }
233
253
 
@@ -235,31 +255,37 @@ export class Registrar implements RegistrarInterface {
235
255
  * After identify has completed and we have received the list of supported
236
256
  * protocols, notify any topologies interested in those protocols.
237
257
  */
238
- _onPeerIdentify (evt: CustomEvent<IdentifyResult>): void {
258
+ async _onPeerIdentify (evt: CustomEvent<IdentifyResult>): Promise<void> {
239
259
  const protocols = evt.detail.protocols
240
260
  const connection = evt.detail.connection
241
261
  const peerId = evt.detail.peerId
242
262
 
243
- for (const protocol of protocols) {
244
- const topologies = this.topologies.get(protocol)
263
+ try {
264
+ for (const protocol of protocols) {
265
+ const topologies = this.topologies.get(protocol)
245
266
 
246
- if (topologies == null) {
247
- // no topologies are interested in this protocol
248
- continue
249
- }
250
-
251
- for (const topology of topologies.values()) {
252
- if (connection.limits != null && topology.notifyOnLimitedConnection !== true) {
267
+ if (topologies == null) {
268
+ // no topologies are interested in this protocol
253
269
  continue
254
270
  }
255
271
 
256
- if (topology.filter?.has(peerId) === true) {
257
- continue
258
- }
272
+ await Promise.all(
273
+ [...topologies.values()].map(async topology => {
274
+ if (connection.limits != null && topology.notifyOnLimitedConnection !== true) {
275
+ return
276
+ }
277
+
278
+ if (topology.filter?.has(peerId) === true) {
279
+ return
280
+ }
259
281
 
260
- topology.filter?.add(peerId)
261
- topology.onConnect?.(peerId, connection)
282
+ topology.filter?.add(peerId)
283
+ await topology.onConnect?.(peerId, connection)
284
+ })
285
+ )
262
286
  }
287
+ } catch (err: any) {
288
+ this.log.error('could not inform topologies of updated peer after identify %p - %e', peerId, err)
263
289
  }
264
290
  }
265
291
  }
@@ -1,5 +1,5 @@
1
1
  import { FaultTolerance, InvalidParametersError, NotStartedError } from '@libp2p/interface'
2
- import { trackedMap } from '@libp2p/utils/tracked-map'
2
+ import { trackedMap } from '@libp2p/utils'
3
3
  import { IP4, IP6 } from '@multiformats/multiaddr-matcher'
4
4
  import { CustomProgressEvent } from 'progress-events'
5
5
  import { TransportUnavailableError, UnsupportedListenAddressError, UnsupportedListenAddressesError } from './errors.js'
@@ -318,7 +318,7 @@ export class DefaultTransportManager implements TransportManager, Startable {
318
318
  throw new UnsupportedListenAddressesError(`Some configured addresses failed to be listened on, you may need to remove one or more listen addresses from your configuration or set \`transportManager.faultTolerance\` to NO_FATAL:\n${
319
319
  [...listenStats.errors.entries()].map(([addr, err]) => {
320
320
  return `
321
- ${addr}: ${`${err.stack ?? err}`.split('\n').join('\n ')}
321
+ ${addr}: ${`${getErrorMessage(err)}`.split('\n').join('\n ')}
322
322
  `
323
323
  }).join('')
324
324
  }`)
@@ -376,3 +376,19 @@ export class DefaultTransportManager implements TransportManager, Startable {
376
376
  await Promise.all(tasks)
377
377
  }
378
378
  }
379
+
380
+ /**
381
+ * Not every error has useful fields, browsers particularly often have an empty
382
+ * string for the "stack" so try a few different fields here.
383
+ */
384
+ function getErrorMessage (err: Error): string {
385
+ if (err.stack != null && err.stack.trim() !== '') {
386
+ return err.stack
387
+ }
388
+
389
+ if (err.message != null) {
390
+ return err.message
391
+ }
392
+
393
+ return err.toString()
394
+ }