libp2p 0.37.3-e6f646e → 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.
Files changed (119) hide show
  1. package/README.md +0 -2
  2. package/dist/src/circuit/circuit/hop.d.ts +5 -3
  3. package/dist/src/circuit/circuit/hop.d.ts.map +1 -1
  4. package/dist/src/circuit/circuit/hop.js +8 -4
  5. package/dist/src/circuit/circuit/hop.js.map +1 -1
  6. package/dist/src/circuit/circuit/stop.d.ts +5 -3
  7. package/dist/src/circuit/circuit/stop.d.ts.map +1 -1
  8. package/dist/src/circuit/circuit/stop.js +4 -2
  9. package/dist/src/circuit/circuit/stop.js.map +1 -1
  10. package/dist/src/circuit/circuit/stream-handler.d.ts +2 -1
  11. package/dist/src/circuit/circuit/stream-handler.d.ts.map +1 -1
  12. package/dist/src/circuit/circuit/stream-handler.js +2 -2
  13. package/dist/src/circuit/circuit/stream-handler.js.map +1 -1
  14. package/dist/src/circuit/index.d.ts +2 -10
  15. package/dist/src/circuit/index.d.ts.map +1 -1
  16. package/dist/src/circuit/index.js.map +1 -1
  17. package/dist/src/circuit/pb/index.d.ts +5 -4
  18. package/dist/src/circuit/pb/index.d.ts.map +1 -1
  19. package/dist/src/circuit/pb/index.js +107 -11
  20. package/dist/src/circuit/pb/index.js.map +1 -1
  21. package/dist/src/circuit/transport.d.ts +3 -0
  22. package/dist/src/circuit/transport.d.ts.map +1 -1
  23. package/dist/src/circuit/transport.js +79 -57
  24. package/dist/src/circuit/transport.js.map +1 -1
  25. package/dist/src/config.d.ts.map +1 -1
  26. package/dist/src/config.js +19 -4
  27. package/dist/src/config.js.map +1 -1
  28. package/dist/src/connection-manager/dialer/auto-dialer.d.ts.map +1 -1
  29. package/dist/src/connection-manager/dialer/auto-dialer.js +6 -0
  30. package/dist/src/connection-manager/dialer/auto-dialer.js.map +1 -1
  31. package/dist/src/connection-manager/dialer/index.d.ts +4 -4
  32. package/dist/src/connection-manager/dialer/index.d.ts.map +1 -1
  33. package/dist/src/connection-manager/dialer/index.js +10 -10
  34. package/dist/src/connection-manager/dialer/index.js.map +1 -1
  35. package/dist/src/connection-manager/index.d.ts +8 -1
  36. package/dist/src/connection-manager/index.d.ts.map +1 -1
  37. package/dist/src/connection-manager/index.js +42 -16
  38. package/dist/src/connection-manager/index.js.map +1 -1
  39. package/dist/src/constants.d.ts +4 -0
  40. package/dist/src/constants.d.ts.map +1 -1
  41. package/dist/src/constants.js +4 -0
  42. package/dist/src/constants.js.map +1 -1
  43. package/dist/src/fetch/index.d.ts +4 -0
  44. package/dist/src/fetch/index.d.ts.map +1 -1
  45. package/dist/src/fetch/index.js +25 -6
  46. package/dist/src/fetch/index.js.map +1 -1
  47. package/dist/src/fetch/pb/proto.d.ts +4 -3
  48. package/dist/src/fetch/pb/proto.d.ts.map +1 -1
  49. package/dist/src/fetch/pb/proto.js +88 -8
  50. package/dist/src/fetch/pb/proto.js.map +1 -1
  51. package/dist/src/identify/index.d.ts +1 -1
  52. package/dist/src/identify/index.d.ts.map +1 -1
  53. package/dist/src/identify/index.js +35 -12
  54. package/dist/src/identify/index.js.map +1 -1
  55. package/dist/src/identify/pb/message.d.ts +2 -1
  56. package/dist/src/identify/pb/message.d.ts.map +1 -1
  57. package/dist/src/identify/pb/message.js +94 -10
  58. package/dist/src/identify/pb/message.js.map +1 -1
  59. package/dist/src/index.d.ts +1 -0
  60. package/dist/src/index.d.ts.map +1 -1
  61. package/dist/src/index.js.map +1 -1
  62. package/dist/src/insecure/index.d.ts.map +1 -1
  63. package/dist/src/insecure/index.js +7 -3
  64. package/dist/src/insecure/index.js.map +1 -1
  65. package/dist/src/insecure/pb/proto.d.ts +4 -3
  66. package/dist/src/insecure/pb/proto.d.ts.map +1 -1
  67. package/dist/src/insecure/pb/proto.js +89 -9
  68. package/dist/src/insecure/pb/proto.js.map +1 -1
  69. package/dist/src/libp2p.d.ts.map +1 -1
  70. package/dist/src/libp2p.js +3 -2
  71. package/dist/src/libp2p.js.map +1 -1
  72. package/dist/src/metrics/index.d.ts +1 -2
  73. package/dist/src/metrics/index.d.ts.map +1 -1
  74. package/dist/src/metrics/index.js +3 -4
  75. package/dist/src/metrics/index.js.map +1 -1
  76. package/dist/src/ping/index.d.ts +4 -0
  77. package/dist/src/ping/index.d.ts.map +1 -1
  78. package/dist/src/ping/index.js +27 -8
  79. package/dist/src/ping/index.js.map +1 -1
  80. package/dist/src/pnet/index.d.ts.map +1 -1
  81. package/dist/src/pnet/index.js +2 -1
  82. package/dist/src/pnet/index.js.map +1 -1
  83. package/dist/src/registrar.d.ts +2 -2
  84. package/dist/src/registrar.d.ts.map +1 -1
  85. package/dist/src/registrar.js +2 -2
  86. package/dist/src/registrar.js.map +1 -1
  87. package/dist/src/upgrader.d.ts +6 -0
  88. package/dist/src/upgrader.d.ts.map +1 -1
  89. package/dist/src/upgrader.js +121 -75
  90. package/dist/src/upgrader.js.map +1 -1
  91. package/dist/src/version.d.ts.map +1 -1
  92. package/dist/src/version.js.map +1 -1
  93. package/package.json +48 -47
  94. package/src/circuit/README.md +2 -2
  95. package/src/circuit/circuit/hop.ts +18 -9
  96. package/src/circuit/circuit/stop.ts +9 -4
  97. package/src/circuit/circuit/stream-handler.ts +5 -4
  98. package/src/circuit/index.ts +2 -11
  99. package/src/circuit/pb/index.ts +133 -15
  100. package/src/circuit/transport.ts +87 -58
  101. package/src/config.ts +19 -4
  102. package/src/connection-manager/dialer/auto-dialer.ts +6 -0
  103. package/src/connection-manager/dialer/index.ts +10 -10
  104. package/src/connection-manager/index.ts +54 -19
  105. package/src/constants.ts +5 -0
  106. package/src/fetch/index.ts +34 -8
  107. package/src/fetch/pb/proto.ts +109 -11
  108. package/src/identify/index.ts +41 -19
  109. package/src/identify/pb/message.ts +111 -11
  110. package/src/index.ts +1 -0
  111. package/src/insecure/index.ts +8 -3
  112. package/src/insecure/pb/proto.ts +111 -12
  113. package/src/libp2p.ts +3 -2
  114. package/src/metrics/index.ts +4 -7
  115. package/src/ping/index.ts +37 -11
  116. package/src/pnet/index.ts +2 -0
  117. package/src/registrar.ts +2 -2
  118. package/src/upgrader.ts +138 -78
  119. package/src/version.ts +1 -2
@@ -6,7 +6,6 @@ import { DefaultStats, StatsInit } from './stats.js'
6
6
  import type { ComponentMetricsUpdate, Metrics, Stats, TrackedMetric, TrackStreamOptions } from '@libp2p/interface-metrics'
7
7
  import type { PeerId } from '@libp2p/interface-peer-id'
8
8
  import type { Startable } from '@libp2p/interfaces/startable'
9
- import type { Duplex } from 'it-stream-types'
10
9
 
11
10
  const initialCounters: ['dataReceived', 'dataSent'] = [
12
11
  'dataReceived',
@@ -263,11 +262,11 @@ export class DefaultMetrics implements Metrics, Startable {
263
262
  * When the `PeerId` is known, `Metrics.updatePlaceholder` should be called
264
263
  * with the placeholder string returned from here, and the known `PeerId`.
265
264
  */
266
- trackStream <T extends Duplex<Uint8Array>> (opts: TrackStreamOptions<T>): T {
265
+ trackStream (opts: TrackStreamOptions): void {
267
266
  const { stream, remotePeer, protocol } = opts
268
267
 
269
268
  if (!this.running) {
270
- return stream
269
+ return
271
270
  }
272
271
 
273
272
  const source = stream.source
@@ -275,7 +274,7 @@ export class DefaultMetrics implements Metrics, Startable {
275
274
  remotePeer,
276
275
  protocol,
277
276
  direction: 'in',
278
- dataLength: chunk.length
277
+ dataLength: chunk.byteLength
279
278
  }))
280
279
 
281
280
  const sink = stream.sink
@@ -287,14 +286,12 @@ export class DefaultMetrics implements Metrics, Startable {
287
286
  remotePeer,
288
287
  protocol,
289
288
  direction: 'out',
290
- dataLength: chunk.length
289
+ dataLength: chunk.byteLength
291
290
  })
292
291
  }),
293
292
  sink
294
293
  )
295
294
  }
296
-
297
- return stream
298
295
  }
299
296
  }
300
297
 
package/src/ping/index.ts CHANGED
@@ -11,8 +11,10 @@ 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
+ import type { Stream } from '@libp2p/interface-connection'
17
+ import { setMaxListeners } from 'events'
16
18
 
17
19
  const log = logger('libp2p:ping')
18
20
 
@@ -20,6 +22,11 @@ export interface PingServiceInit {
20
22
  protocolPrefix: string
21
23
  maxInboundStreams: number
22
24
  maxOutboundStreams: number
25
+
26
+ /**
27
+ * How long we should wait for a ping response
28
+ */
29
+ timeout: number
23
30
  }
24
31
 
25
32
  export class PingService implements Startable {
@@ -73,19 +80,32 @@ export class PingService implements Startable {
73
80
  async ping (peer: PeerId, options: AbortOptions = {}): Promise<number> {
74
81
  log('dialing %s to %p', this.protocol, peer)
75
82
 
76
- const connection = await this.components.getConnectionManager().openConnection(peer, options)
77
- const stream = await connection.newStream([this.protocol], options)
78
83
  const start = Date.now()
79
84
  const data = randomBytes(PING_LENGTH)
80
-
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)
85
+ const connection = await this.components.getConnectionManager().openConnection(peer, options)
86
+ let timeoutController
87
+ let signal = options.signal
88
+ let stream: Stream | undefined
89
+
90
+ // create a timeout if no abort signal passed
91
+ if (signal == null) {
92
+ timeoutController = new TimeoutController(this.init.timeout)
93
+ signal = timeoutController.signal
94
+
95
+ try {
96
+ // fails on node < 15.4
97
+ setMaxListeners?.(Infinity, timeoutController.signal)
98
+ } catch {}
86
99
  }
87
100
 
88
101
  try {
102
+ stream = await connection.newStream([this.protocol], {
103
+ signal
104
+ })
105
+
106
+ // make stream abortable
107
+ const source = abortableDuplex(stream, signal)
108
+
89
109
  const result = await pipe(
90
110
  [data],
91
111
  source,
@@ -93,13 +113,19 @@ export class PingService implements Startable {
93
113
  )
94
114
  const end = Date.now()
95
115
 
96
- if (result == null || !uint8ArrayEquals(data, result)) {
116
+ if (result == null || !uint8ArrayEquals(data, result.subarray())) {
97
117
  throw errCode(new Error('Received wrong ping ack'), codes.ERR_WRONG_PING_ACK)
98
118
  }
99
119
 
100
120
  return end - start
101
121
  } finally {
102
- stream.close()
122
+ if (timeoutController != null) {
123
+ timeoutController.clear()
124
+ }
125
+
126
+ if (stream != null) {
127
+ stream.close()
128
+ }
103
129
  }
104
130
  }
105
131
  }
package/src/pnet/index.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  import { handshake } from 'it-handshake'
14
14
  import { NONCE_LENGTH } from './key-generator.js'
15
15
  import type { ConnectionProtector, MultiaddrConnection } from '@libp2p/interface-connection'
16
+ import map from 'it-map'
16
17
 
17
18
  const log = logger('libp2p:pnet')
18
19
 
@@ -83,6 +84,7 @@ export class PreSharedKeyConnectionProtector implements ConnectionProtector {
83
84
  // Encrypt all outbound traffic
84
85
  createBoxStream(localNonce, this.psk),
85
86
  shake.stream,
87
+ (source) => map(source, (buf) => buf.subarray()),
86
88
  // Decrypt all inbound traffic
87
89
  createUnboxStream(remoteNonce, this.psk),
88
90
  external
package/src/registrar.ts CHANGED
@@ -10,8 +10,8 @@ import type { Components } from '@libp2p/components'
10
10
 
11
11
  const log = logger('libp2p:registrar')
12
12
 
13
- export const DEFAULT_MAX_INBOUND_STREAMS = 1
14
- export const DEFAULT_MAX_OUTBOUND_STREAMS = 1
13
+ export const DEFAULT_MAX_INBOUND_STREAMS = 32
14
+ export const DEFAULT_MAX_OUTBOUND_STREAMS = 64
15
15
 
16
16
  /**
17
17
  * Responsible for notifying registered protocols of events in the network.
package/src/upgrader.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { logger } from '@libp2p/logger'
2
2
  import errCode from 'err-code'
3
- import { Dialer, Listener } from '@libp2p/multistream-select'
3
+ import * as mss from '@libp2p/multistream-select'
4
4
  import { pipe } from 'it-pipe'
5
5
  // @ts-expect-error mutable-proxy does not export types
6
6
  import mutableProxy from 'mutable-proxy'
@@ -18,6 +18,9 @@ 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'
23
+ import { setMaxListeners } from 'events'
21
24
 
22
25
  const log = logger('libp2p:upgrader')
23
26
 
@@ -43,6 +46,12 @@ export interface CryptoResult extends SecuredConnection {
43
46
  export interface UpgraderInit {
44
47
  connectionEncryption: ConnectionEncrypter[]
45
48
  muxers: StreamMuxerFactory[]
49
+
50
+ /**
51
+ * An amount of ms by which an inbound connection upgrade
52
+ * must complete
53
+ */
54
+ inboundUpgradeTimeout: number
46
55
  }
47
56
 
48
57
  function findIncomingStreamLimit (protocol: string, registrar: Registrar) {
@@ -89,6 +98,7 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
89
98
  private readonly components: Components
90
99
  private readonly connectionEncryption: Map<string, ConnectionEncrypter>
91
100
  private readonly muxers: Map<string, StreamMuxerFactory>
101
+ private readonly inboundUpgradeTimeout: number
92
102
 
93
103
  constructor (components: Components, init: UpgraderInit) {
94
104
  super()
@@ -105,6 +115,8 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
105
115
  init.muxers.forEach(muxer => {
106
116
  this.muxers.set(muxer.protocol, muxer)
107
117
  })
118
+
119
+ this.inboundUpgradeTimeout = init.inboundUpgradeTimeout
108
120
  }
109
121
 
110
122
  /**
@@ -120,82 +132,97 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
120
132
  let proxyPeer
121
133
  const metrics = this.components.getMetrics()
122
134
 
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
- }
135
+ const timeoutController = new TimeoutController(this.inboundUpgradeTimeout)
126
136
 
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
- }
137
+ try {
138
+ // fails on node < 15.4
139
+ setMaxListeners?.(Infinity, timeoutController.signal)
140
+ } catch {}
133
141
 
134
- log('starting the inbound connection upgrade')
142
+ try {
143
+ const abortableStream = abortableDuplex(maConn, timeoutController.signal)
144
+ maConn.source = abortableStream.source
145
+ maConn.sink = abortableStream.sink
135
146
 
136
- // Protect
137
- let protectedConn = maConn
138
- const protector = this.components.getConnectionProtector()
147
+ if (await this.components.getConnectionGater().denyInboundConnection(maConn)) {
148
+ throw errCode(new Error('The multiaddr connection is blocked by gater.acceptConnection'), codes.ERR_CONNECTION_INTERCEPTED)
149
+ }
139
150
 
140
- if (protector != null) {
141
- log('protecting the inbound connection')
142
- protectedConn = await protector.protect(maConn)
143
- }
151
+ if (metrics != null) {
152
+ ({ setTarget: setPeer, proxy: proxyPeer } = mutableProxy())
153
+ const idString = `${(Math.random() * 1e9).toString(36)}${Date.now()}`
154
+ setPeer({ toString: () => idString })
155
+ metrics.trackStream({ stream: maConn, remotePeer: proxyPeer })
156
+ }
144
157
 
145
- try {
146
- // Encrypt the connection
147
- ({
148
- conn: encryptedConn,
149
- remotePeer,
150
- protocol: cryptoProtocol
151
- } = await this._encryptInbound(protectedConn))
158
+ log('starting the inbound connection upgrade')
159
+
160
+ // Protect
161
+ let protectedConn = maConn
162
+ const protector = this.components.getConnectionProtector()
152
163
 
153
- if (await this.components.getConnectionGater().denyInboundEncryptedConnection(remotePeer, {
164
+ if (protector != null) {
165
+ log('protecting the inbound connection')
166
+ protectedConn = await protector.protect(maConn)
167
+ }
168
+
169
+ try {
170
+ // Encrypt the connection
171
+ ({
172
+ conn: encryptedConn,
173
+ remotePeer,
174
+ protocol: cryptoProtocol
175
+ } = await this._encryptInbound(protectedConn))
176
+
177
+ if (await this.components.getConnectionGater().denyInboundEncryptedConnection(remotePeer, {
178
+ ...protectedConn,
179
+ ...encryptedConn
180
+ })) {
181
+ throw errCode(new Error('The multiaddr connection is blocked by gater.acceptEncryptedConnection'), codes.ERR_CONNECTION_INTERCEPTED)
182
+ }
183
+
184
+ // Multiplex the connection
185
+ if (this.muxers.size > 0) {
186
+ const multiplexed = await this._multiplexInbound({
187
+ ...protectedConn,
188
+ ...encryptedConn
189
+ }, this.muxers)
190
+ muxerFactory = multiplexed.muxerFactory
191
+ upgradedConn = multiplexed.stream
192
+ } else {
193
+ upgradedConn = encryptedConn
194
+ }
195
+ } catch (err: any) {
196
+ log.error('Failed to upgrade inbound connection', err)
197
+ await maConn.close(err)
198
+ throw err
199
+ }
200
+
201
+ if (await this.components.getConnectionGater().denyInboundUpgradedConnection(remotePeer, {
154
202
  ...protectedConn,
155
203
  ...encryptedConn
156
204
  })) {
157
205
  throw errCode(new Error('The multiaddr connection is blocked by gater.acceptEncryptedConnection'), codes.ERR_CONNECTION_INTERCEPTED)
158
206
  }
159
207
 
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
208
+ if (metrics != null) {
209
+ metrics.updatePlaceholder(proxyPeer, remotePeer)
210
+ setPeer(remotePeer)
170
211
  }
171
- } catch (err: any) {
172
- log.error('Failed to upgrade inbound connection', err)
173
- await maConn.close(err)
174
- throw err
175
- }
176
212
 
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
- }
213
+ log('Successfully upgraded inbound connection')
183
214
 
184
- if (metrics != null) {
185
- metrics.updatePlaceholder(proxyPeer, remotePeer)
186
- setPeer(remotePeer)
215
+ return this._createConnection({
216
+ cryptoProtocol,
217
+ direction: 'inbound',
218
+ maConn,
219
+ upgradedConn,
220
+ muxerFactory,
221
+ remotePeer
222
+ })
223
+ } finally {
224
+ timeoutController.clear()
187
225
  }
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
226
  }
200
227
 
201
228
  /**
@@ -226,7 +253,7 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
226
253
  ({ setTarget: setPeer, proxy: proxyPeer } = mutableProxy())
227
254
  const idString = `${(Math.random() * 1e9).toString(36)}${Date.now()}`
228
255
  setPeer({ toB58String: () => idString })
229
- maConn = metrics.trackStream({ stream: maConn, remotePeer: proxyPeer })
256
+ metrics.trackStream({ stream: maConn, remotePeer: proxyPeer })
230
257
  }
231
258
 
232
259
  log('Starting the outbound connection upgrade')
@@ -315,6 +342,7 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
315
342
  if (muxerFactory != null) {
316
343
  // Create the muxer
317
344
  muxer = muxerFactory.createStreamMuxer({
345
+ direction,
318
346
  // Run anytime a remote stream is created
319
347
  onIncomingStream: muxedStream => {
320
348
  if (connection == null) {
@@ -323,9 +351,8 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
323
351
 
324
352
  void Promise.resolve()
325
353
  .then(async () => {
326
- const mss = new Listener(muxedStream)
327
354
  const protocols = this.components.getRegistrar().getProtocols()
328
- const { stream, protocol } = await mss.handle(protocols)
355
+ const { stream, protocol } = await mss.handle(muxedStream, protocols)
329
356
  log('%s: incoming stream opened on %s', direction, protocol)
330
357
 
331
358
  const metrics = this.components.getMetrics()
@@ -342,11 +369,17 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
342
369
  const streamCount = countStreams(protocol, 'inbound', connection)
343
370
 
344
371
  if (streamCount === incomingLimit) {
345
- throw errCode(new Error('Too many incoming protocol streams'), codes.ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS)
372
+ muxedStream.abort(errCode(new Error(`Too many inbound protocol streams for protocol "${protocol}" - limit ${incomingLimit}`), codes.ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS))
373
+
374
+ return
346
375
  }
347
376
 
348
377
  muxedStream.stat.protocol = protocol
349
378
 
379
+ // If a protocol stream has been successfully negotiated and is to be passed to the application,
380
+ // the peerstore should ensure that the peer is registered with that protocol
381
+ this.components.getPeerStore().protoBook.add(remotePeer, [protocol]).catch(err => log.error(err))
382
+
350
383
  connection.addStream(muxedStream)
351
384
  this._onStream({ connection, stream: { ...muxedStream, ...stream }, protocol })
352
385
  })
@@ -375,25 +408,44 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
375
408
 
376
409
  log('%s: starting new stream on %s', direction, protocols)
377
410
  const muxedStream = muxer.newStream()
378
- const mss = new Dialer(muxedStream)
379
411
  const metrics = this.components.getMetrics()
412
+ let controller: TimeoutController | undefined
380
413
 
381
414
  try {
382
- let { stream, protocol } = await mss.select(protocols, options)
415
+ if (options.signal == null) {
416
+ log('No abort signal was passed while trying to negotiate protocols %s falling back to default timeout', protocols)
417
+
418
+ controller = new TimeoutController(30000)
419
+ options.signal = controller.signal
420
+
421
+ try {
422
+ // fails on node < 15.4
423
+ setMaxListeners?.(Infinity, controller.signal)
424
+ } catch {}
425
+ }
426
+
427
+ const { stream, protocol } = await mss.select(muxedStream, protocols, options)
383
428
 
384
429
  if (metrics != null) {
385
- stream = metrics.trackStream({ stream, remotePeer, protocol })
430
+ metrics.trackStream({ stream, remotePeer, protocol })
386
431
  }
387
432
 
388
433
  const outgoingLimit = findOutgoingStreamLimit(protocol, this.components.getRegistrar())
389
434
  const streamCount = countStreams(protocol, 'outbound', connection)
390
435
 
391
436
  if (streamCount === outgoingLimit) {
392
- throw errCode(new Error('Too many outgoing protocol streams'), codes.ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS)
437
+ const err = errCode(new Error(`Too many outbound protocol streams for protocol "${protocol}" - limit ${outgoingLimit}`), codes.ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS)
438
+ muxedStream.abort(err)
439
+
440
+ throw err
393
441
  }
394
442
 
395
443
  muxedStream.stat.protocol = protocol
396
444
 
445
+ // If a protocol stream has been successfully negotiated and is to be passed to the application,
446
+ // the peerstore should ensure that the peer is registered with that protocol
447
+ this.components.getPeerStore().protoBook.add(remotePeer, [protocol]).catch(err => log.error(err))
448
+
397
449
  return {
398
450
  ...muxedStream,
399
451
  ...stream,
@@ -414,6 +466,10 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
414
466
  }
415
467
 
416
468
  throw errCode(err, codes.ERR_UNSUPPORTED_PROTOCOL)
469
+ } finally {
470
+ if (controller != null) {
471
+ controller.clear()
472
+ }
417
473
  }
418
474
  }
419
475
 
@@ -469,7 +525,7 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
469
525
  await maConn.close()
470
526
  // Ensure remaining streams are closed
471
527
  if (muxer != null) {
472
- muxer.streams.forEach(s => s.close())
528
+ muxer.close()
473
529
  }
474
530
  }
475
531
  })
@@ -495,12 +551,13 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
495
551
  * Attempts to encrypt the incoming `connection` with the provided `cryptos`
496
552
  */
497
553
  async _encryptInbound (connection: Duplex<Uint8Array>): Promise<CryptoResult> {
498
- const mss = new Listener(connection)
499
554
  const protocols = Array.from(this.connectionEncryption.keys())
500
555
  log('handling inbound crypto protocol selection', protocols)
501
556
 
502
557
  try {
503
- const { stream, protocol } = await mss.handle(protocols)
558
+ const { stream, protocol } = await mss.handle(connection, protocols, {
559
+ writeBytes: true
560
+ })
504
561
  const encrypter = this.connectionEncryption.get(protocol)
505
562
 
506
563
  if (encrypter == null) {
@@ -523,12 +580,13 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
523
580
  * The first `ConnectionEncrypter` module to succeed will be used
524
581
  */
525
582
  async _encryptOutbound (connection: MultiaddrConnection, remotePeerId: PeerId): Promise<CryptoResult> {
526
- const mss = new Dialer(connection)
527
583
  const protocols = Array.from(this.connectionEncryption.keys())
528
584
  log('selecting outbound crypto protocol', protocols)
529
585
 
530
586
  try {
531
- const { stream, protocol } = await mss.select(protocols)
587
+ const { stream, protocol } = await mss.select(connection, protocols, {
588
+ writeBytes: true
589
+ })
532
590
  const encrypter = this.connectionEncryption.get(protocol)
533
591
 
534
592
  if (encrypter == null) {
@@ -551,11 +609,12 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
551
609
  * muxer will be used for all future streams on the connection.
552
610
  */
553
611
  async _multiplexOutbound (connection: MultiaddrConnection, muxers: Map<string, StreamMuxerFactory>): Promise<{ stream: Duplex<Uint8Array>, muxerFactory?: StreamMuxerFactory}> {
554
- const dialer = new Dialer(connection)
555
612
  const protocols = Array.from(muxers.keys())
556
613
  log('outbound selecting muxer %s', protocols)
557
614
  try {
558
- const { stream, protocol } = await dialer.select(protocols)
615
+ const { stream, protocol } = await mss.select(connection, protocols, {
616
+ writeBytes: true
617
+ })
559
618
  log('%s selected as muxer protocol', protocol)
560
619
  const muxerFactory = muxers.get(protocol)
561
620
  return { stream, muxerFactory }
@@ -570,11 +629,12 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
570
629
  * selected muxer will be used for all future streams on the connection.
571
630
  */
572
631
  async _multiplexInbound (connection: MultiaddrConnection, muxers: Map<string, StreamMuxerFactory>): Promise<{ stream: Duplex<Uint8Array>, muxerFactory?: StreamMuxerFactory}> {
573
- const listener = new Listener(connection)
574
632
  const protocols = Array.from(muxers.keys())
575
633
  log('inbound handling muxers %s', protocols)
576
634
  try {
577
- const { stream, protocol } = await listener.handle(protocols)
635
+ const { stream, protocol } = await mss.handle(connection, protocols, {
636
+ writeBytes: true
637
+ })
578
638
  const muxerFactory = muxers.get(protocol)
579
639
  return { stream, muxerFactory }
580
640
  } catch (err: any) {
package/src/version.ts CHANGED
@@ -1,3 +1,2 @@
1
-
2
- export const version = '0.0.0'
1
+ export const version = '0.38.0'
3
2
  export const name = 'libp2p'