libp2p 2.1.2 → 2.1.3

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.
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable max-depth */
2
- import { TimeoutError, DialError, setMaxListeners } from '@libp2p/interface'
2
+ import { TimeoutError, DialError, setMaxListeners, AbortError } from '@libp2p/interface'
3
3
  import { PeerMap } from '@libp2p/peer-collections'
4
4
  import { defaultAddressSort } from '@libp2p/utils/address-sort'
5
5
  import { PriorityQueue, type PriorityQueueJobOptions } from '@libp2p/utils/priority-queue'
@@ -103,7 +103,9 @@ export class DialQueue {
103
103
  })
104
104
  // a started job errored
105
105
  this.queue.addEventListener('error', (event) => {
106
- this.log.error('error in dial queue', event.detail)
106
+ if (event.detail.name !== AbortError.name) {
107
+ this.log.error('error in dial queue - %e', event.detail)
108
+ }
107
109
  })
108
110
  }
109
111
 
@@ -1,4 +1,4 @@
1
- import { InvalidParametersError, NotStartedError, start, stop } from '@libp2p/interface'
1
+ import { InvalidMultiaddrError, InvalidParametersError, InvalidPeerIdError, NotStartedError, start, stop } from '@libp2p/interface'
2
2
  import { PeerMap } from '@libp2p/peer-collections'
3
3
  import { defaultAddressSort } from '@libp2p/utils/address-sort'
4
4
  import { RateLimiter } from '@libp2p/utils/rate-limiter'
@@ -191,6 +191,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
191
191
  private readonly metrics?: Metrics
192
192
  private readonly events: TypedEventTarget<Libp2pEvents>
193
193
  private readonly log: Logger
194
+ private readonly peerId: PeerId
194
195
 
195
196
  constructor (components: DefaultConnectionManagerComponents, init: ConnectionManagerInit = {}) {
196
197
  this.maxConnections = init.maxConnections ?? defaultOptions.maxConnections
@@ -205,6 +206,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
205
206
  this.connections = new PeerMap()
206
207
 
207
208
  this.started = false
209
+ this.peerId = components.peerId
208
210
  this.peerStore = components.peerStore
209
211
  this.metrics = components.metrics
210
212
  this.events = components.events
@@ -484,6 +486,10 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
484
486
 
485
487
  const { peerId } = getPeerAddress(peerIdOrMultiaddr)
486
488
 
489
+ if (this.peerId.equals(peerId)) {
490
+ throw new InvalidPeerIdError('Can not dial self')
491
+ }
492
+
487
493
  if (peerId != null && options.force !== true) {
488
494
  this.log('dial %p', peerId)
489
495
  const existingConnection = this.getConnections(peerId)
@@ -501,6 +507,13 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
501
507
  ...options,
502
508
  priority: options.priority ?? DEFAULT_DIAL_PRIORITY
503
509
  })
510
+
511
+ if (connection.remotePeer.equals(this.peerId)) {
512
+ const err = new InvalidPeerIdError('Can not dial self')
513
+ connection.abort(err)
514
+ throw err
515
+ }
516
+
504
517
  let peerConnections = this.connections.get(connection.remotePeer)
505
518
 
506
519
  if (peerConnections == null) {
@@ -517,6 +530,14 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
517
530
  if (conn.id === connection.id) {
518
531
  trackedConnection = true
519
532
  }
533
+
534
+ // make sure we don't already have a connection to this multiaddr
535
+ if (options.force !== true && conn.id !== connection.id && conn.remoteAddr.equals(connection.remoteAddr)) {
536
+ connection.abort(new InvalidMultiaddrError('Duplicate multiaddr connection'))
537
+
538
+ // return the existing connection
539
+ return conn
540
+ }
520
541
  }
521
542
 
522
543
  if (!trackedConnection) {
package/src/upgrader.ts CHANGED
@@ -7,7 +7,7 @@ import { createConnection } from './connection/index.js'
7
7
  import { PROTOCOL_NEGOTIATION_TIMEOUT, UPGRADE_TIMEOUT } from './connection-manager/constants.js'
8
8
  import { ConnectionDeniedError, ConnectionInterceptedError, EncryptionFailedError, MuxerUnavailableError } from './errors.js'
9
9
  import { DEFAULT_MAX_INBOUND_STREAMS, DEFAULT_MAX_OUTBOUND_STREAMS } from './registrar.js'
10
- import type { Libp2pEvents, AbortOptions, ComponentLogger, MultiaddrConnection, Connection, Stream, ConnectionProtector, NewStreamOptions, ConnectionEncrypter, SecuredConnection, ConnectionGater, TypedEventTarget, Metrics, PeerId, PeerStore, StreamMuxer, StreamMuxerFactory, Upgrader, UpgraderOptions, ConnectionLimits, SecureConnectionOptions } from '@libp2p/interface'
10
+ import type { Libp2pEvents, AbortOptions, ComponentLogger, MultiaddrConnection, Connection, Stream, ConnectionProtector, NewStreamOptions, ConnectionEncrypter, SecuredConnection, ConnectionGater, TypedEventTarget, Metrics, PeerId, PeerStore, StreamMuxer, StreamMuxerFactory, Upgrader, UpgraderOptions, ConnectionLimits, SecureConnectionOptions, CounterGroup } from '@libp2p/interface'
11
11
  import type { ConnectionManager, Registrar } from '@libp2p/interface-internal'
12
12
 
13
13
  interface CreateConnectionOptions {
@@ -130,6 +130,10 @@ export class DefaultUpgrader implements Upgrader {
130
130
  private readonly inboundStreamProtocolNegotiationTimeout: number
131
131
  private readonly outboundStreamProtocolNegotiationTimeout: number
132
132
  private readonly events: TypedEventTarget<Libp2pEvents>
133
+ private readonly metrics: {
134
+ dials?: CounterGroup<'inbound' | 'outbound'>
135
+ errors?: CounterGroup<'inbound' | 'outbound'>
136
+ }
133
137
 
134
138
  constructor (components: DefaultUpgraderComponents, init: UpgraderInit) {
135
139
  this.components = components
@@ -150,6 +154,10 @@ export class DefaultUpgrader implements Upgrader {
150
154
  this.inboundStreamProtocolNegotiationTimeout = init.inboundStreamProtocolNegotiationTimeout ?? PROTOCOL_NEGOTIATION_TIMEOUT
151
155
  this.outboundStreamProtocolNegotiationTimeout = init.outboundStreamProtocolNegotiationTimeout ?? PROTOCOL_NEGOTIATION_TIMEOUT
152
156
  this.events = components.events
157
+ this.metrics = {
158
+ dials: components.metrics?.registerCounterGroup('libp2p_connection_manager_dials_total'),
159
+ errors: components.metrics?.registerCounterGroup('libp2p_connection_manager_dial_errors_total')
160
+ }
153
161
  }
154
162
 
155
163
  readonly [Symbol.toStringTag] = '@libp2p/upgrader'
@@ -175,6 +183,10 @@ export class DefaultUpgrader implements Upgrader {
175
183
  */
176
184
  async upgradeInbound (maConn: MultiaddrConnection, opts: UpgraderOptions = {}): Promise<Connection> {
177
185
  try {
186
+ this.metrics.dials?.increment({
187
+ inbound: true
188
+ })
189
+
178
190
  const accept = await this.components.connectionManager.acceptIncomingConnection(maConn)
179
191
 
180
192
  if (!accept) {
@@ -183,7 +195,15 @@ export class DefaultUpgrader implements Upgrader {
183
195
 
184
196
  await this.shouldBlockConnection('denyInboundConnection', maConn)
185
197
 
186
- return await this._performUpgrade(maConn, 'inbound', opts)
198
+ const conn = await this._performUpgrade(maConn, 'inbound', opts)
199
+
200
+ return conn
201
+ } catch (err) {
202
+ this.metrics.errors?.increment({
203
+ inbound: true
204
+ })
205
+
206
+ throw err
187
207
  } finally {
188
208
  this.components.connectionManager.afterUpgradeInbound()
189
209
  }
@@ -193,15 +213,27 @@ export class DefaultUpgrader implements Upgrader {
193
213
  * Upgrades an outbound connection
194
214
  */
195
215
  async upgradeOutbound (maConn: MultiaddrConnection, opts: UpgraderOptions = {}): Promise<Connection> {
196
- const idStr = maConn.remoteAddr.getPeerId()
197
- let remotePeerId: PeerId | undefined
216
+ try {
217
+ this.metrics.dials?.increment({
218
+ outbound: true
219
+ })
198
220
 
199
- if (idStr != null) {
200
- remotePeerId = peerIdFromString(idStr)
201
- await this.shouldBlockConnection('denyOutboundConnection', remotePeerId, maConn)
202
- }
221
+ const idStr = maConn.remoteAddr.getPeerId()
222
+ let remotePeerId: PeerId | undefined
203
223
 
204
- return this._performUpgrade(maConn, 'outbound', opts)
224
+ if (idStr != null) {
225
+ remotePeerId = peerIdFromString(idStr)
226
+ await this.shouldBlockConnection('denyOutboundConnection', remotePeerId, maConn)
227
+ }
228
+
229
+ return await this._performUpgrade(maConn, 'outbound', opts)
230
+ } catch (err) {
231
+ this.metrics.errors?.increment({
232
+ outbound: true
233
+ })
234
+
235
+ throw err
236
+ }
205
237
  }
206
238
 
207
239
  private async _performUpgrade (maConn: MultiaddrConnection, direction: 'inbound' | 'outbound', opts: UpgraderOptions): Promise<Connection> {
@@ -218,7 +250,7 @@ export class DefaultUpgrader implements Upgrader {
218
250
 
219
251
  this.components.metrics?.trackMultiaddrConnection(maConn)
220
252
 
221
- maConn.log('starting the %s connection upgrade', direction)
253
+ maConn.log.trace('starting the %s connection upgrade', direction)
222
254
 
223
255
  // Protect
224
256
  let protectedConn = maConn
@@ -292,13 +324,13 @@ export class DefaultUpgrader implements Upgrader {
292
324
  upgradedConn = multiplexed.stream
293
325
  }
294
326
  } catch (err: any) {
295
- maConn.log.error('failed to upgrade inbound connection', err)
327
+ maConn.log.error('failed to upgrade inbound connection %s %a - %e', direction === 'inbound' ? 'from' : 'to', maConn.remoteAddr, err)
296
328
  throw err
297
329
  }
298
330
 
299
331
  await this.shouldBlockConnection(direction === 'inbound' ? 'denyInboundUpgradedConnection' : 'denyOutboundUpgradedConnection', remotePeer, maConn)
300
332
 
301
- maConn.log('successfully %s inbound connection', direction)
333
+ maConn.log('successfully upgraded %s connection', direction)
302
334
 
303
335
  return this._createConnection({
304
336
  cryptoProtocol,
@@ -399,7 +431,7 @@ export class DefaultUpgrader implements Upgrader {
399
431
  this._onStream({ connection, stream: muxedStream, protocol })
400
432
  })
401
433
  .catch(async err => {
402
- connection.log.error('error handling incoming stream id %s', muxedStream.id, err.message, err.code, err.stack)
434
+ connection.log.error('error handling incoming stream id %s - %e', muxedStream.id, err)
403
435
 
404
436
  if (muxedStream.timeline.close == null) {
405
437
  await muxedStream.close()
@@ -413,7 +445,7 @@ export class DefaultUpgrader implements Upgrader {
413
445
  throw new MuxerUnavailableError('Connection is not multiplexed')
414
446
  }
415
447
 
416
- connection.log('starting new stream for protocols %s', protocols)
448
+ connection.log.trace('starting new stream for protocols %s', protocols)
417
449
  const muxedStream = await muxer.newStream()
418
450
  connection.log.trace('started new stream %s for protocols %s', muxedStream.id, protocols)
419
451
 
@@ -441,7 +473,7 @@ export class DefaultUpgrader implements Upgrader {
441
473
  yieldBytes: true
442
474
  })
443
475
 
444
- muxedStream.log('selected protocol %s', protocol)
476
+ muxedStream.log.trace('selected protocol %s', protocol)
445
477
 
446
478
  const outgoingLimit = findOutgoingStreamLimit(protocol, this.components.registrar, options)
447
479
  const streamCount = countStreams(protocol, 'outbound', connection)
@@ -484,7 +516,7 @@ export class DefaultUpgrader implements Upgrader {
484
516
 
485
517
  return muxedStream
486
518
  } catch (err: any) {
487
- connection.log.error('could not create new stream for protocols %s', protocols, err)
519
+ connection.log.error('could not create new outbound stream on connection %s %a for protocols %s - %e', direction === 'inbound' ? 'from' : 'to', opts.maConn.remoteAddr, protocols, err)
488
520
 
489
521
  if (muxedStream.timeline.close == null) {
490
522
  muxedStream.abort(err)
@@ -499,7 +531,7 @@ export class DefaultUpgrader implements Upgrader {
499
531
  muxer.sink(upgradedConn.source),
500
532
  upgradedConn.sink(muxer.source)
501
533
  ]).catch(err => {
502
- connection.log.error('error piping data through muxer', err)
534
+ connection.log.error('error piping data through muxer - %e', err)
503
535
  })
504
536
  }
505
537
 
@@ -594,7 +626,6 @@ export class DefaultUpgrader implements Upgrader {
594
626
  */
595
627
  async _encryptInbound (connection: MultiaddrConnection, options?: AbortOptions): Promise<CryptoResult> {
596
628
  const protocols = Array.from(this.connectionEncrypters.keys())
597
- connection.log('handling inbound crypto protocol selection', protocols)
598
629
 
599
630
  try {
600
631
  const { stream, protocol } = await mss.handle(connection, protocols, {
@@ -604,17 +635,17 @@ export class DefaultUpgrader implements Upgrader {
604
635
  const encrypter = this.connectionEncrypters.get(protocol)
605
636
 
606
637
  if (encrypter == null) {
607
- throw new Error(`no crypto module found for ${protocol}`)
638
+ throw new EncryptionFailedError(`no crypto module found for ${protocol}`)
608
639
  }
609
640
 
610
- connection.log('encrypting inbound connection using', protocol)
641
+ connection.log('encrypting inbound connection to %a using %s', connection.remoteAddr, protocol)
611
642
 
612
643
  return {
613
644
  ...await encrypter.secureInbound(stream, options),
614
645
  protocol
615
646
  }
616
647
  } catch (err: any) {
617
- connection.log.error('encrypting inbound connection failed', err)
648
+ connection.log.error('encrypting inbound connection from %a failed', connection.remoteAddr, err)
618
649
  throw new EncryptionFailedError(err.message)
619
650
  }
620
651
  }
@@ -625,34 +656,29 @@ export class DefaultUpgrader implements Upgrader {
625
656
  */
626
657
  async _encryptOutbound (connection: MultiaddrConnection, options: SecureConnectionOptions): Promise<CryptoResult> {
627
658
  const protocols = Array.from(this.connectionEncrypters.keys())
628
- connection.log('selecting outbound crypto protocol', protocols)
629
659
 
630
660
  try {
631
661
  connection.log.trace('selecting encrypter from %s', protocols)
632
662
 
633
- const {
634
- stream,
635
- protocol
636
- } = await mss.select(connection, protocols, {
663
+ const { stream, protocol } = await mss.select(connection, protocols, {
637
664
  ...options,
638
665
  log: connection.log,
639
666
  yieldBytes: true
640
667
  })
641
-
642
668
  const encrypter = this.connectionEncrypters.get(protocol)
643
669
 
644
670
  if (encrypter == null) {
645
- throw new Error(`no crypto module found for ${protocol}`)
671
+ throw new EncryptionFailedError(`no crypto module found for ${protocol}`)
646
672
  }
647
673
 
648
- connection.log('encrypting outbound connection to %p using %s', options?.remotePeer, encrypter)
674
+ connection.log('encrypting outbound connection to %a using %s', connection.remoteAddr, protocol)
649
675
 
650
676
  return {
651
677
  ...await encrypter.secureOutbound(stream, options),
652
678
  protocol
653
679
  }
654
680
  } catch (err: any) {
655
- connection.log.error('encrypting outbound connection to %p failed', options?.remotePeer, err)
681
+ connection.log.error('encrypting outbound connection to %a failed', connection.remoteAddr, err)
656
682
  throw new EncryptionFailedError(err.message)
657
683
  }
658
684
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '2.1.2'
1
+ export const version = '2.1.3'
2
2
  export const name = 'libp2p'