libp2p 0.37.3-676cee2 → 0.37.3-6eaab2e

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 (50) hide show
  1. package/README.md +1 -0
  2. package/dist/src/config.d.ts.map +1 -1
  3. package/dist/src/config.js +7 -3
  4. package/dist/src/config.js.map +1 -1
  5. package/dist/src/connection-manager/dialer/index.d.ts +4 -4
  6. package/dist/src/connection-manager/dialer/index.d.ts.map +1 -1
  7. package/dist/src/connection-manager/dialer/index.js +10 -10
  8. package/dist/src/connection-manager/dialer/index.js.map +1 -1
  9. package/dist/src/connection-manager/index.d.ts +15 -11
  10. package/dist/src/connection-manager/index.d.ts.map +1 -1
  11. package/dist/src/connection-manager/index.js +169 -62
  12. package/dist/src/connection-manager/index.js.map +1 -1
  13. package/dist/src/constants.d.ts +4 -0
  14. package/dist/src/constants.d.ts.map +1 -1
  15. package/dist/src/constants.js +4 -0
  16. package/dist/src/constants.js.map +1 -1
  17. package/dist/src/fetch/index.d.ts +4 -0
  18. package/dist/src/fetch/index.d.ts.map +1 -1
  19. package/dist/src/fetch/index.js +15 -5
  20. package/dist/src/fetch/index.js.map +1 -1
  21. package/dist/src/identify/index.d.ts +1 -1
  22. package/dist/src/identify/index.d.ts.map +1 -1
  23. package/dist/src/identify/index.js +9 -10
  24. package/dist/src/identify/index.js.map +1 -1
  25. package/dist/src/libp2p.d.ts.map +1 -1
  26. package/dist/src/libp2p.js +2 -12
  27. package/dist/src/libp2p.js.map +1 -1
  28. package/dist/src/metrics/index.d.ts +2 -2
  29. package/dist/src/metrics/index.d.ts.map +1 -1
  30. package/dist/src/metrics/index.js +6 -2
  31. package/dist/src/metrics/index.js.map +1 -1
  32. package/dist/src/ping/index.d.ts +4 -0
  33. package/dist/src/ping/index.d.ts.map +1 -1
  34. package/dist/src/ping/index.js +16 -6
  35. package/dist/src/ping/index.js.map +1 -1
  36. package/dist/src/upgrader.d.ts +6 -0
  37. package/dist/src/upgrader.d.ts.map +1 -1
  38. package/dist/src/upgrader.js +83 -59
  39. package/dist/src/upgrader.js.map +1 -1
  40. package/package.json +14 -13
  41. package/src/config.ts +7 -3
  42. package/src/connection-manager/dialer/index.ts +10 -10
  43. package/src/connection-manager/index.ts +220 -76
  44. package/src/constants.ts +5 -0
  45. package/src/fetch/index.ts +23 -6
  46. package/src/identify/index.ts +11 -12
  47. package/src/libp2p.ts +2 -13
  48. package/src/metrics/index.ts +8 -4
  49. package/src/ping/index.ts +24 -8
  50. package/src/upgrader.ts +95 -61
package/src/ping/index.ts CHANGED
@@ -11,8 +11,8 @@ import type { PeerId } from '@libp2p/interface-peer-id'
11
11
  import type { Startable } from '@libp2p/interfaces/startable'
12
12
  import type { Components } from '@libp2p/components'
13
13
  import type { AbortOptions } from '@libp2p/interfaces'
14
- import type { Duplex } from 'it-stream-types'
15
14
  import { abortableDuplex } from 'abortable-iterator'
15
+ import { TimeoutController } from 'timeout-abort-controller'
16
16
 
17
17
  const log = logger('libp2p:ping')
18
18
 
@@ -20,6 +20,11 @@ export interface PingServiceInit {
20
20
  protocolPrefix: string
21
21
  maxInboundStreams: number
22
22
  maxOutboundStreams: number
23
+
24
+ /**
25
+ * How long we should wait for a ping response
26
+ */
27
+ timeout: number
23
28
  }
24
29
 
25
30
  export class PingService implements Startable {
@@ -73,18 +78,25 @@ export class PingService implements Startable {
73
78
  async ping (peer: PeerId, options: AbortOptions = {}): Promise<number> {
74
79
  log('dialing %s to %p', this.protocol, peer)
75
80
 
76
- const connection = await this.components.getConnectionManager().openConnection(peer, options)
77
- const stream = await connection.newStream([this.protocol], options)
78
81
  const start = Date.now()
79
82
  const data = randomBytes(PING_LENGTH)
83
+ const connection = await this.components.getConnectionManager().openConnection(peer, options)
84
+ let timeoutController
85
+ let signal = options.signal
80
86
 
81
- let source: Duplex<Uint8Array> = stream
82
-
83
- // make stream abortable if AbortSignal passed
84
- if (options.signal != null) {
85
- source = abortableDuplex(stream, options.signal)
87
+ // create a timeout if no abort signal passed
88
+ if (signal == null) {
89
+ timeoutController = new TimeoutController(this.init.timeout)
90
+ signal = timeoutController.signal
86
91
  }
87
92
 
93
+ const stream = await connection.newStream([this.protocol], {
94
+ signal
95
+ })
96
+
97
+ // make stream abortable
98
+ const source = abortableDuplex(stream, signal)
99
+
88
100
  try {
89
101
  const result = await pipe(
90
102
  [data],
@@ -99,6 +111,10 @@ export class PingService implements Startable {
99
111
 
100
112
  return end - start
101
113
  } finally {
114
+ if (timeoutController != null) {
115
+ timeoutController.clear()
116
+ }
117
+
102
118
  stream.close()
103
119
  }
104
120
  }
package/src/upgrader.ts CHANGED
@@ -18,6 +18,8 @@ import { Components, isInitializable } from '@libp2p/components'
18
18
  import type { AbortOptions } from '@libp2p/interfaces'
19
19
  import type { Registrar } from '@libp2p/interface-registrar'
20
20
  import { DEFAULT_MAX_INBOUND_STREAMS, DEFAULT_MAX_OUTBOUND_STREAMS } from './registrar.js'
21
+ import { TimeoutController } from 'timeout-abort-controller'
22
+ import { abortableDuplex } from 'abortable-iterator'
21
23
 
22
24
  const log = logger('libp2p:upgrader')
23
25
 
@@ -43,6 +45,12 @@ export interface CryptoResult extends SecuredConnection {
43
45
  export interface UpgraderInit {
44
46
  connectionEncryption: ConnectionEncrypter[]
45
47
  muxers: StreamMuxerFactory[]
48
+
49
+ /**
50
+ * An amount of ms by which an inbound connection upgrade
51
+ * must complete
52
+ */
53
+ inboundUpgradeTimeout: number
46
54
  }
47
55
 
48
56
  function findIncomingStreamLimit (protocol: string, registrar: Registrar) {
@@ -89,6 +97,7 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
89
97
  private readonly components: Components
90
98
  private readonly connectionEncryption: Map<string, ConnectionEncrypter>
91
99
  private readonly muxers: Map<string, StreamMuxerFactory>
100
+ private readonly inboundUpgradeTimeout: number
92
101
 
93
102
  constructor (components: Components, init: UpgraderInit) {
94
103
  super()
@@ -105,6 +114,8 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
105
114
  init.muxers.forEach(muxer => {
106
115
  this.muxers.set(muxer.protocol, muxer)
107
116
  })
117
+
118
+ this.inboundUpgradeTimeout = init.inboundUpgradeTimeout
108
119
  }
109
120
 
110
121
  /**
@@ -120,82 +131,92 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
120
131
  let proxyPeer
121
132
  const metrics = this.components.getMetrics()
122
133
 
123
- if (await this.components.getConnectionGater().denyInboundConnection(maConn)) {
124
- throw errCode(new Error('The multiaddr connection is blocked by gater.acceptConnection'), codes.ERR_CONNECTION_INTERCEPTED)
125
- }
134
+ const timeoutController = new TimeoutController(this.inboundUpgradeTimeout)
126
135
 
127
- if (metrics != null) {
128
- ({ setTarget: setPeer, proxy: proxyPeer } = mutableProxy())
129
- const idString = `${(Math.random() * 1e9).toString(36)}${Date.now()}`
130
- setPeer({ toString: () => idString })
131
- maConn = metrics.trackStream({ stream: maConn, remotePeer: proxyPeer })
132
- }
136
+ try {
137
+ const abortableStream = abortableDuplex(maConn, timeoutController.signal)
138
+ maConn.source = abortableStream.source
139
+ maConn.sink = abortableStream.sink
133
140
 
134
- log('starting the inbound connection upgrade')
141
+ if (await this.components.getConnectionGater().denyInboundConnection(maConn)) {
142
+ throw errCode(new Error('The multiaddr connection is blocked by gater.acceptConnection'), codes.ERR_CONNECTION_INTERCEPTED)
143
+ }
135
144
 
136
- // Protect
137
- let protectedConn = maConn
138
- const protector = this.components.getConnectionProtector()
145
+ if (metrics != null) {
146
+ ({ setTarget: setPeer, proxy: proxyPeer } = mutableProxy())
147
+ const idString = `${(Math.random() * 1e9).toString(36)}${Date.now()}`
148
+ setPeer({ toString: () => idString })
149
+ maConn = metrics.trackStream({ stream: maConn, remotePeer: proxyPeer })
150
+ }
139
151
 
140
- if (protector != null) {
141
- log('protecting the inbound connection')
142
- protectedConn = await protector.protect(maConn)
143
- }
152
+ log('starting the inbound connection upgrade')
144
153
 
145
- try {
146
- // Encrypt the connection
147
- ({
148
- conn: encryptedConn,
149
- remotePeer,
150
- protocol: cryptoProtocol
151
- } = await this._encryptInbound(protectedConn))
154
+ // Protect
155
+ let protectedConn = maConn
156
+ const protector = this.components.getConnectionProtector()
157
+
158
+ if (protector != null) {
159
+ log('protecting the inbound connection')
160
+ protectedConn = await protector.protect(maConn)
161
+ }
152
162
 
153
- if (await this.components.getConnectionGater().denyInboundEncryptedConnection(remotePeer, {
163
+ try {
164
+ // Encrypt the connection
165
+ ({
166
+ conn: encryptedConn,
167
+ remotePeer,
168
+ protocol: cryptoProtocol
169
+ } = await this._encryptInbound(protectedConn))
170
+
171
+ if (await this.components.getConnectionGater().denyInboundEncryptedConnection(remotePeer, {
172
+ ...protectedConn,
173
+ ...encryptedConn
174
+ })) {
175
+ throw errCode(new Error('The multiaddr connection is blocked by gater.acceptEncryptedConnection'), codes.ERR_CONNECTION_INTERCEPTED)
176
+ }
177
+
178
+ // Multiplex the connection
179
+ if (this.muxers.size > 0) {
180
+ const multiplexed = await this._multiplexInbound({
181
+ ...protectedConn,
182
+ ...encryptedConn
183
+ }, this.muxers)
184
+ muxerFactory = multiplexed.muxerFactory
185
+ upgradedConn = multiplexed.stream
186
+ } else {
187
+ upgradedConn = encryptedConn
188
+ }
189
+ } catch (err: any) {
190
+ log.error('Failed to upgrade inbound connection', err)
191
+ await maConn.close(err)
192
+ throw err
193
+ }
194
+
195
+ if (await this.components.getConnectionGater().denyInboundUpgradedConnection(remotePeer, {
154
196
  ...protectedConn,
155
197
  ...encryptedConn
156
198
  })) {
157
199
  throw errCode(new Error('The multiaddr connection is blocked by gater.acceptEncryptedConnection'), codes.ERR_CONNECTION_INTERCEPTED)
158
200
  }
159
201
 
160
- // Multiplex the connection
161
- if (this.muxers.size > 0) {
162
- const multiplexed = await this._multiplexInbound({
163
- ...protectedConn,
164
- ...encryptedConn
165
- }, this.muxers)
166
- muxerFactory = multiplexed.muxerFactory
167
- upgradedConn = multiplexed.stream
168
- } else {
169
- upgradedConn = encryptedConn
202
+ if (metrics != null) {
203
+ metrics.updatePlaceholder(proxyPeer, remotePeer)
204
+ setPeer(remotePeer)
170
205
  }
171
- } catch (err: any) {
172
- log.error('Failed to upgrade inbound connection', err)
173
- await maConn.close(err)
174
- throw err
175
- }
176
206
 
177
- if (await this.components.getConnectionGater().denyInboundUpgradedConnection(remotePeer, {
178
- ...protectedConn,
179
- ...encryptedConn
180
- })) {
181
- throw errCode(new Error('The multiaddr connection is blocked by gater.acceptEncryptedConnection'), codes.ERR_CONNECTION_INTERCEPTED)
182
- }
207
+ log('Successfully upgraded inbound connection')
183
208
 
184
- if (metrics != null) {
185
- metrics.updatePlaceholder(proxyPeer, remotePeer)
186
- setPeer(remotePeer)
209
+ return this._createConnection({
210
+ cryptoProtocol,
211
+ direction: 'inbound',
212
+ maConn,
213
+ upgradedConn,
214
+ muxerFactory,
215
+ remotePeer
216
+ })
217
+ } finally {
218
+ timeoutController.clear()
187
219
  }
188
-
189
- log('Successfully upgraded inbound connection')
190
-
191
- return this._createConnection({
192
- cryptoProtocol,
193
- direction: 'inbound',
194
- maConn,
195
- upgradedConn,
196
- muxerFactory,
197
- remotePeer
198
- })
199
220
  }
200
221
 
201
222
  /**
@@ -315,6 +336,7 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
315
336
  if (muxerFactory != null) {
316
337
  // Create the muxer
317
338
  muxer = muxerFactory.createStreamMuxer({
339
+ direction,
318
340
  // Run anytime a remote stream is created
319
341
  onIncomingStream: muxedStream => {
320
342
  if (connection == null) {
@@ -377,8 +399,16 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
377
399
  const muxedStream = muxer.newStream()
378
400
  const mss = new Dialer(muxedStream)
379
401
  const metrics = this.components.getMetrics()
402
+ let controller: TimeoutController | undefined
380
403
 
381
404
  try {
405
+ if (options.signal == null) {
406
+ log('No abort signal was passed while trying to negotiate protocols %s falling back to default timeout', protocols)
407
+
408
+ controller = new TimeoutController(30000)
409
+ options.signal = controller.signal
410
+ }
411
+
382
412
  let { stream, protocol } = await mss.select(protocols, options)
383
413
 
384
414
  if (metrics != null) {
@@ -414,6 +444,10 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
414
444
  }
415
445
 
416
446
  throw errCode(err, codes.ERR_UNSUPPORTED_PROTOCOL)
447
+ } finally {
448
+ if (controller != null) {
449
+ controller.clear()
450
+ }
417
451
  }
418
452
  }
419
453
 
@@ -469,7 +503,7 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
469
503
  await maConn.close()
470
504
  // Ensure remaining streams are closed
471
505
  if (muxer != null) {
472
- muxer.streams.forEach(s => s.close())
506
+ muxer.close()
473
507
  }
474
508
  }
475
509
  })