libp2p 0.45.9 → 0.46.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 (194) hide show
  1. package/README.md +96 -77
  2. package/dist/index.min.js +27 -27
  3. package/dist/src/address-manager/index.d.ts +5 -5
  4. package/dist/src/address-manager/index.d.ts.map +1 -1
  5. package/dist/src/address-manager/utils.d.ts.map +1 -1
  6. package/dist/src/address-manager/utils.js.map +1 -1
  7. package/dist/src/autonat/index.d.ts +26 -6
  8. package/dist/src/autonat/index.d.ts.map +1 -1
  9. package/dist/src/autonat/index.js +23 -3
  10. package/dist/src/autonat/index.js.map +1 -1
  11. package/dist/src/circuit-relay/index.d.ts +36 -1
  12. package/dist/src/circuit-relay/index.d.ts.map +1 -1
  13. package/dist/src/circuit-relay/index.js +35 -0
  14. package/dist/src/circuit-relay/index.js.map +1 -1
  15. package/dist/src/circuit-relay/server/advert-service.d.ts +3 -3
  16. package/dist/src/circuit-relay/server/advert-service.d.ts.map +1 -1
  17. package/dist/src/circuit-relay/server/advert-service.js +1 -1
  18. package/dist/src/circuit-relay/server/advert-service.js.map +1 -1
  19. package/dist/src/circuit-relay/server/index.d.ts +8 -8
  20. package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
  21. package/dist/src/circuit-relay/server/index.js +30 -28
  22. package/dist/src/circuit-relay/server/index.js.map +1 -1
  23. package/dist/src/circuit-relay/server/reservation-store.d.ts +3 -3
  24. package/dist/src/circuit-relay/server/reservation-store.d.ts.map +1 -1
  25. package/dist/src/circuit-relay/server/reservation-voucher.d.ts +2 -2
  26. package/dist/src/circuit-relay/transport/discovery.d.ts +8 -8
  27. package/dist/src/circuit-relay/transport/discovery.d.ts.map +1 -1
  28. package/dist/src/circuit-relay/transport/discovery.js +3 -4
  29. package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
  30. package/dist/src/circuit-relay/transport/index.d.ts +21 -10
  31. package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
  32. package/dist/src/circuit-relay/transport/index.js +52 -25
  33. package/dist/src/circuit-relay/transport/index.js.map +1 -1
  34. package/dist/src/circuit-relay/transport/listener.d.ts +2 -2
  35. package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
  36. package/dist/src/circuit-relay/transport/listener.js +4 -3
  37. package/dist/src/circuit-relay/transport/listener.js.map +1 -1
  38. package/dist/src/circuit-relay/transport/reservation-store.d.ts +13 -7
  39. package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
  40. package/dist/src/circuit-relay/transport/reservation-store.js +24 -10
  41. package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
  42. package/dist/src/circuit-relay/utils.d.ts +1 -1
  43. package/dist/src/components.d.ts +15 -14
  44. package/dist/src/components.d.ts.map +1 -1
  45. package/dist/src/components.js +2 -2
  46. package/dist/src/components.js.map +1 -1
  47. package/dist/src/config/connection-gater.browser.d.ts +1 -1
  48. package/dist/src/config/connection-gater.d.ts +1 -1
  49. package/dist/src/config.d.ts +1 -2
  50. package/dist/src/config.d.ts.map +1 -1
  51. package/dist/src/config.js +2 -2
  52. package/dist/src/config.js.map +1 -1
  53. package/dist/src/connection/index.d.ts +22 -13
  54. package/dist/src/connection/index.d.ts.map +1 -1
  55. package/dist/src/connection/index.js +54 -30
  56. package/dist/src/connection/index.js.map +1 -1
  57. package/dist/src/connection-manager/auto-dial.d.ts +5 -5
  58. package/dist/src/connection-manager/auto-dial.d.ts.map +1 -1
  59. package/dist/src/connection-manager/auto-dial.js +3 -1
  60. package/dist/src/connection-manager/auto-dial.js.map +1 -1
  61. package/dist/src/connection-manager/connection-pruner.d.ts +4 -4
  62. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  63. package/dist/src/connection-manager/connection-pruner.js +2 -2
  64. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  65. package/dist/src/connection-manager/constants.d.ts.map +1 -1
  66. package/dist/src/connection-manager/constants.js.map +1 -1
  67. package/dist/src/connection-manager/dial-queue.d.ts +11 -17
  68. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  69. package/dist/src/connection-manager/dial-queue.js +6 -6
  70. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  71. package/dist/src/connection-manager/index.d.ts +11 -12
  72. package/dist/src/connection-manager/index.d.ts.map +1 -1
  73. package/dist/src/connection-manager/index.js +17 -11
  74. package/dist/src/connection-manager/index.js.map +1 -1
  75. package/dist/src/content-routing/index.d.ts +5 -5
  76. package/dist/src/content-routing/index.d.ts.map +1 -1
  77. package/dist/src/content-routing/index.js +1 -1
  78. package/dist/src/content-routing/index.js.map +1 -1
  79. package/dist/src/content-routing/utils.d.ts +2 -2
  80. package/dist/src/content-routing/utils.js +1 -1
  81. package/dist/src/content-routing/utils.js.map +1 -1
  82. package/dist/src/fetch/constants.d.ts.map +1 -1
  83. package/dist/src/fetch/constants.js.map +1 -1
  84. package/dist/src/fetch/index.d.ts +5 -5
  85. package/dist/src/fetch/index.d.ts.map +1 -1
  86. package/dist/src/fetch/index.js +5 -5
  87. package/dist/src/fetch/index.js.map +1 -1
  88. package/dist/src/get-peer.d.ts +1 -1
  89. package/dist/src/get-peer.js +2 -2
  90. package/dist/src/get-peer.js.map +1 -1
  91. package/dist/src/identify/consts.d.ts.map +1 -1
  92. package/dist/src/identify/consts.js.map +1 -1
  93. package/dist/src/identify/identify.d.ts +8 -7
  94. package/dist/src/identify/identify.d.ts.map +1 -1
  95. package/dist/src/identify/identify.js +66 -72
  96. package/dist/src/identify/identify.js.map +1 -1
  97. package/dist/src/identify/index.d.ts +28 -9
  98. package/dist/src/identify/index.d.ts.map +1 -1
  99. package/dist/src/identify/index.js.map +1 -1
  100. package/dist/src/index.d.ts +11 -12
  101. package/dist/src/index.d.ts.map +1 -1
  102. package/dist/src/index.js.map +1 -1
  103. package/dist/src/insecure/index.d.ts +1 -1
  104. package/dist/src/insecure/index.js +1 -1
  105. package/dist/src/insecure/index.js.map +1 -1
  106. package/dist/src/libp2p.d.ts +13 -13
  107. package/dist/src/libp2p.d.ts.map +1 -1
  108. package/dist/src/libp2p.js +13 -8
  109. package/dist/src/libp2p.js.map +1 -1
  110. package/dist/src/peer-routing.d.ts +5 -5
  111. package/dist/src/peer-routing.d.ts.map +1 -1
  112. package/dist/src/peer-routing.js +1 -1
  113. package/dist/src/peer-routing.js.map +1 -1
  114. package/dist/src/ping/constants.d.ts.map +1 -1
  115. package/dist/src/ping/constants.js.map +1 -1
  116. package/dist/src/ping/index.d.ts +5 -4
  117. package/dist/src/ping/index.d.ts.map +1 -1
  118. package/dist/src/ping/index.js +32 -21
  119. package/dist/src/ping/index.js.map +1 -1
  120. package/dist/src/pnet/index.d.ts +1 -1
  121. package/dist/src/pnet/index.js +1 -1
  122. package/dist/src/pnet/index.js.map +1 -1
  123. package/dist/src/registrar.d.ts +7 -6
  124. package/dist/src/registrar.d.ts.map +1 -1
  125. package/dist/src/registrar.js +7 -11
  126. package/dist/src/registrar.js.map +1 -1
  127. package/dist/src/transport-manager.d.ts +9 -9
  128. package/dist/src/transport-manager.d.ts.map +1 -1
  129. package/dist/src/transport-manager.js +7 -4
  130. package/dist/src/transport-manager.js.map +1 -1
  131. package/dist/src/upgrader.d.ts +13 -12
  132. package/dist/src/upgrader.d.ts.map +1 -1
  133. package/dist/src/upgrader.js +37 -26
  134. package/dist/src/upgrader.js.map +1 -1
  135. package/dist/src/upnp-nat/index.d.ts +4 -4
  136. package/dist/src/upnp-nat/index.d.ts.map +1 -1
  137. package/dist/src/upnp-nat/index.js +1 -1
  138. package/dist/src/upnp-nat/index.js.map +1 -1
  139. package/dist/src/utils/peer-job-queue.d.ts +1 -1
  140. package/dist/src/utils/peer-job-queue.js +1 -1
  141. package/dist/src/utils/peer-job-queue.js.map +1 -1
  142. package/dist/src/version.d.ts +1 -1
  143. package/dist/src/version.js +1 -1
  144. package/package.json +52 -85
  145. package/src/address-manager/README.md +1 -1
  146. package/src/address-manager/index.ts +5 -5
  147. package/src/address-manager/utils.ts +0 -1
  148. package/src/autonat/index.ts +33 -12
  149. package/src/circuit-relay/index.ts +37 -1
  150. package/src/circuit-relay/server/advert-service.ts +3 -3
  151. package/src/circuit-relay/server/index.ts +41 -38
  152. package/src/circuit-relay/server/reservation-store.ts +3 -3
  153. package/src/circuit-relay/server/reservation-voucher.ts +2 -2
  154. package/src/circuit-relay/transport/discovery.ts +10 -11
  155. package/src/circuit-relay/transport/index.ts +76 -38
  156. package/src/circuit-relay/transport/listener.ts +9 -7
  157. package/src/circuit-relay/transport/reservation-store.ts +41 -18
  158. package/src/circuit-relay/utils.ts +1 -1
  159. package/src/components.ts +16 -15
  160. package/src/config/connection-gater.browser.ts +1 -1
  161. package/src/config/connection-gater.ts +1 -1
  162. package/src/config.ts +3 -4
  163. package/src/connection/index.ts +82 -40
  164. package/src/connection-manager/auto-dial.ts +8 -6
  165. package/src/connection-manager/connection-pruner.ts +6 -6
  166. package/src/connection-manager/constants.ts +0 -1
  167. package/src/connection-manager/dial-queue.ts +20 -27
  168. package/src/connection-manager/index.ts +27 -22
  169. package/src/content-routing/index.ts +6 -6
  170. package/src/content-routing/utils.ts +3 -3
  171. package/src/fetch/constants.ts +0 -1
  172. package/src/fetch/index.ts +11 -11
  173. package/src/get-peer.ts +3 -3
  174. package/src/identify/consts.ts +0 -1
  175. package/src/identify/identify.ts +85 -92
  176. package/src/identify/index.ts +32 -8
  177. package/src/index.ts +11 -12
  178. package/src/insecure/index.ts +3 -3
  179. package/src/libp2p.ts +24 -18
  180. package/src/peer-routing.ts +6 -6
  181. package/src/ping/constants.ts +0 -1
  182. package/src/ping/index.ts +45 -27
  183. package/src/pnet/index.ts +2 -2
  184. package/src/registrar.ts +14 -17
  185. package/src/transport-manager.ts +16 -12
  186. package/src/upgrader.ts +52 -39
  187. package/src/upnp-nat/index.ts +5 -5
  188. package/src/utils/peer-job-queue.ts +2 -2
  189. package/src/version.ts +1 -1
  190. package/dist/src/pubsub/dummy-pubsub.d.ts +0 -18
  191. package/dist/src/pubsub/dummy-pubsub.d.ts.map +0 -1
  192. package/dist/src/pubsub/dummy-pubsub.js +0 -38
  193. package/dist/src/pubsub/dummy-pubsub.js.map +0 -1
  194. package/src/pubsub/dummy-pubsub.ts +0 -53
@@ -1,5 +1,5 @@
1
- import { KEEP_ALIVE } from '@libp2p/interface-peer-store/tags'
2
- import { CodeError } from '@libp2p/interfaces/errors'
1
+ import { CodeError } from '@libp2p/interface/errors'
2
+ import { KEEP_ALIVE } from '@libp2p/interface/peer-store/tags'
3
3
  import { logger } from '@libp2p/logger'
4
4
  import { PeerMap } from '@libp2p/peer-collections'
5
5
  import { publicAddressesFirst } from '@libp2p/utils/address-sort'
@@ -12,17 +12,16 @@ import { AutoDial } from './auto-dial.js'
12
12
  import { ConnectionPruner } from './connection-pruner.js'
13
13
  import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_MAX_QUEUE_LENGTH, AUTO_DIAL_PRIORITY, DIAL_TIMEOUT, INBOUND_CONNECTION_THRESHOLD, MAX_CONNECTIONS, MAX_INCOMING_PENDING_CONNECTIONS, MAX_PARALLEL_DIALS, MAX_PEER_ADDRS_TO_DIAL, MIN_CONNECTIONS } from './constants.js'
14
14
  import { DialQueue } from './dial-queue.js'
15
- import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection'
16
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
17
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
18
- import type { PendingDial, AddressSorter, Libp2pEvents } from '@libp2p/interface-libp2p'
19
- import type { Metrics } from '@libp2p/interface-metrics'
20
- import type { PeerId } from '@libp2p/interface-peer-id'
21
- import type { Peer, PeerStore } from '@libp2p/interface-peer-store'
22
- import type { TransportManager } from '@libp2p/interface-transport'
23
- import type { AbortOptions } from '@libp2p/interfaces'
24
- import type { EventEmitter } from '@libp2p/interfaces/events'
25
- import type { Startable } from '@libp2p/interfaces/startable'
15
+ import type { PendingDial, AddressSorter, Libp2pEvents, AbortOptions } from '@libp2p/interface'
16
+ import type { Connection, MultiaddrConnection } from '@libp2p/interface/connection'
17
+ import type { ConnectionGater } from '@libp2p/interface/connection-gater'
18
+ import type { EventEmitter } from '@libp2p/interface/events'
19
+ import type { Metrics } from '@libp2p/interface/metrics'
20
+ import type { PeerId } from '@libp2p/interface/peer-id'
21
+ import type { Peer, PeerStore } from '@libp2p/interface/peer-store'
22
+ import type { Startable } from '@libp2p/interface/startable'
23
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
24
+ import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
26
25
 
27
26
  const log = logger('libp2p:connection-manager')
28
27
 
@@ -274,7 +273,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
274
273
 
275
274
  for (const conns of this.connections.values()) {
276
275
  for (const conn of conns) {
277
- if (conn.stat.direction === 'inbound') {
276
+ if (conn.direction === 'inbound') {
278
277
  metric.inbound++
279
278
  } else {
280
279
  metric.outbound++
@@ -295,7 +294,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
295
294
  for (const conns of this.connections.values()) {
296
295
  for (const conn of conns) {
297
296
  for (const stream of conn.streams) {
298
- const key = `${stream.stat.direction} ${stream.stat.protocol ?? 'unnegotiated'}`
297
+ const key = `${stream.direction} ${stream.protocol ?? 'unnegotiated'}`
299
298
 
300
299
  metric[key] = (metric[key] ?? 0) + 1
301
300
  }
@@ -317,7 +316,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
317
316
  const streams: Record<string, number> = {}
318
317
 
319
318
  for (const stream of conn.streams) {
320
- const key = `${stream.stat.direction} ${stream.stat.protocol ?? 'unnegotiated'}`
319
+ const key = `${stream.direction} ${stream.protocol ?? 'unnegotiated'}`
321
320
 
322
321
  streams[key] = (streams[key] ?? 0) + 1
323
322
  }
@@ -489,6 +488,8 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
489
488
  throw new CodeError('Not started', codes.ERR_NODE_NOT_STARTED)
490
489
  }
491
490
 
491
+ options.signal?.throwIfAborted()
492
+
492
493
  const { peerId } = getPeerAddress(peerIdOrMultiaddr)
493
494
 
494
495
  if (peerId != null) {
@@ -531,12 +532,16 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
531
532
  return connection
532
533
  }
533
534
 
534
- async closeConnections (peerId: PeerId): Promise<void> {
535
+ async closeConnections (peerId: PeerId, options: AbortOptions = {}): Promise<void> {
535
536
  const connections = this.connections.get(peerId) ?? []
536
537
 
537
538
  await Promise.all(
538
539
  connections.map(async connection => {
539
- await connection.close()
540
+ try {
541
+ await connection.close(options)
542
+ } catch (err: any) {
543
+ connection.abort(err)
544
+ }
540
545
  })
541
546
  )
542
547
  }
@@ -548,7 +553,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
548
553
  })
549
554
 
550
555
  if (denyConnection) {
551
- log('connection from %s refused - connection remote address was in deny list', maConn.remoteAddr)
556
+ log('connection from %a refused - connection remote address was in deny list', maConn.remoteAddr)
552
557
  return false
553
558
  }
554
559
 
@@ -565,7 +570,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
565
570
 
566
571
  // check pending connections
567
572
  if (this.incomingPendingConnections === this.maxIncomingPendingConnections) {
568
- log('connection from %s refused - incomingPendingConnections exceeded by peer %s', maConn.remoteAddr)
573
+ log('connection from %a refused - incomingPendingConnections exceeded by host', maConn.remoteAddr)
569
574
  return false
570
575
  }
571
576
 
@@ -575,7 +580,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
575
580
  try {
576
581
  await this.inboundConnectionRateLimiter.consume(host, 1)
577
582
  } catch {
578
- log('connection from %s refused - inboundConnectionThreshold exceeded by host %s', host, maConn.remoteAddr)
583
+ log('connection from %a refused - inboundConnectionThreshold exceeded by host %s', maConn.remoteAddr, host)
579
584
  return false
580
585
  }
581
586
  }
@@ -586,7 +591,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
586
591
  return true
587
592
  }
588
593
 
589
- log('connection from %s refused - maxConnections exceeded', maConn.remoteAddr)
594
+ log('connection from %a refused - maxConnections exceeded', maConn.remoteAddr)
590
595
  return false
591
596
  }
592
597
 
@@ -1,4 +1,4 @@
1
- import { CodeError } from '@libp2p/interfaces/errors'
1
+ import { CodeError } from '@libp2p/interface/errors'
2
2
  import merge from 'it-merge'
3
3
  import { pipe } from 'it-pipe'
4
4
  import { messages, codes } from '../errors.js'
@@ -7,11 +7,11 @@ import {
7
7
  uniquePeers,
8
8
  requirePeers
9
9
  } from './utils.js'
10
- import type { ContentRouting } from '@libp2p/interface-content-routing'
11
- import type { PeerInfo } from '@libp2p/interface-peer-info'
12
- import type { PeerStore } from '@libp2p/interface-peer-store'
13
- import type { AbortOptions } from '@libp2p/interfaces'
14
- import type { Startable } from '@libp2p/interfaces/startable'
10
+ import type { AbortOptions } from '@libp2p/interface'
11
+ import type { ContentRouting } from '@libp2p/interface/content-routing'
12
+ import type { PeerInfo } from '@libp2p/interface/peer-info'
13
+ import type { PeerStore } from '@libp2p/interface/peer-store'
14
+ import type { Startable } from '@libp2p/interface/startable'
15
15
  import type { CID } from 'multiformats/cid'
16
16
 
17
17
  export interface CompoundContentRoutingInit {
@@ -1,8 +1,8 @@
1
- import { CodeError } from '@libp2p/interfaces/errors'
1
+ import { CodeError } from '@libp2p/interface/errors'
2
2
  import filter from 'it-filter'
3
3
  import map from 'it-map'
4
- import type { PeerInfo } from '@libp2p/interface-peer-info'
5
- import type { PeerStore } from '@libp2p/interface-peer-store'
4
+ import type { PeerInfo } from '@libp2p/interface/peer-info'
5
+ import type { PeerStore } from '@libp2p/interface/peer-store'
6
6
  import type { Source } from 'it-stream-types'
7
7
 
8
8
  /**
@@ -1,4 +1,3 @@
1
-
2
1
  // https://github.com/libp2p/specs/tree/master/fetch#wire-protocol
3
2
  export const PROTOCOL_VERSION = '0.0.1'
4
3
  export const PROTOCOL_NAME = 'fetch'
@@ -1,5 +1,5 @@
1
1
  import { setMaxListeners } from 'events'
2
- import { CodeError } from '@libp2p/interfaces/errors'
2
+ import { CodeError } from '@libp2p/interface/errors'
3
3
  import { logger } from '@libp2p/logger'
4
4
  import { abortableDuplex } from 'abortable-iterator'
5
5
  import first from 'it-first'
@@ -10,12 +10,12 @@ import { toString as uint8arrayToString } from 'uint8arrays/to-string'
10
10
  import { codes } from '../errors.js'
11
11
  import { PROTOCOL_NAME, PROTOCOL_VERSION } from './constants.js'
12
12
  import { FetchRequest, FetchResponse } from './pb/proto.js'
13
- import type { Stream } from '@libp2p/interface-connection'
14
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
15
- import type { PeerId } from '@libp2p/interface-peer-id'
16
- import type { IncomingStreamData, Registrar } from '@libp2p/interface-registrar'
17
- import type { AbortOptions } from '@libp2p/interfaces'
18
- import type { Startable } from '@libp2p/interfaces/startable'
13
+ import type { AbortOptions } from '@libp2p/interface'
14
+ import type { Stream } from '@libp2p/interface/connection'
15
+ import type { PeerId } from '@libp2p/interface/peer-id'
16
+ import type { Startable } from '@libp2p/interface/startable'
17
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
18
+ import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal/registrar'
19
19
 
20
20
  const log = logger('libp2p:fetch')
21
21
 
@@ -109,12 +109,12 @@ class DefaultFetchService implements Startable, FetchService {
109
109
  async start (): Promise<void> {
110
110
  await this.components.registrar.handle(this.protocol, (data) => {
111
111
  void this.handleMessage(data)
112
+ .then(async () => {
113
+ await data.stream.close()
114
+ })
112
115
  .catch(err => {
113
116
  log.error(err)
114
117
  })
115
- .finally(() => {
116
- data.stream.close()
117
- })
118
118
  }, {
119
119
  maxInboundStreams: this.init.maxInboundStreams,
120
120
  maxOutboundStreams: this.init.maxOutboundStreams
@@ -201,7 +201,7 @@ class DefaultFetchService implements Startable, FetchService {
201
201
  return result ?? null
202
202
  } finally {
203
203
  if (stream != null) {
204
- stream.close()
204
+ await stream.close()
205
205
  }
206
206
  }
207
207
  }
package/src/get-peer.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { isPeerId } from '@libp2p/interface-peer-id'
2
- import { CodeError } from '@libp2p/interfaces/errors'
1
+ import { CodeError } from '@libp2p/interface/errors'
2
+ import { isPeerId } from '@libp2p/interface/peer-id'
3
3
  import { logger } from '@libp2p/logger'
4
4
  import { peerIdFromString } from '@libp2p/peer-id'
5
5
  import { isMultiaddr } from '@multiformats/multiaddr'
6
6
  import { codes } from './errors.js'
7
- import type { PeerId } from '@libp2p/interface-peer-id'
7
+ import type { PeerId } from '@libp2p/interface/peer-id'
8
8
  import type { Multiaddr } from '@multiformats/multiaddr'
9
9
 
10
10
  const log = logger('libp2p:get-peer')
@@ -1,4 +1,3 @@
1
-
2
1
  import { version } from '../version.js'
3
2
 
4
3
  export const PROTOCOL_VERSION = 'ipfs/0.1.0' // deprecated
@@ -1,15 +1,10 @@
1
1
  import { setMaxListeners } from 'events'
2
- import { CodeError } from '@libp2p/interfaces/errors'
2
+ import { CodeError } from '@libp2p/interface/errors'
3
3
  import { logger } from '@libp2p/logger'
4
4
  import { peerIdFromKeys } from '@libp2p/peer-id'
5
5
  import { RecordEnvelope, PeerRecord } from '@libp2p/peer-record'
6
6
  import { type Multiaddr, multiaddr, protocols } from '@multiformats/multiaddr'
7
- import { abortableDuplex } from 'abortable-iterator'
8
- import { anySignal } from 'any-signal'
9
- import first from 'it-first'
10
- import * as lp from 'it-length-prefixed'
11
- import { pbStream } from 'it-pb-stream'
12
- import { pipe } from 'it-pipe'
7
+ import { pbStream } from 'it-protobuf-stream'
13
8
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
14
9
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
15
10
  import { isNode, isBrowser, isWebWorker, isElectronMain, isElectronRenderer, isReactNative } from 'wherearewe'
@@ -23,17 +18,16 @@ import {
23
18
  MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION
24
19
  } from './consts.js'
25
20
  import { Identify } from './pb/message.js'
26
- import type { IdentifyServiceComponents, IdentifyServiceInit } from './index.js'
27
- import type { AddressManager } from '@libp2p/interface-address-manager'
28
- import type { Connection, Stream } from '@libp2p/interface-connection'
29
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
30
- import type { Libp2pEvents, IdentifyResult, SignedPeerRecord } from '@libp2p/interface-libp2p'
31
- import type { PeerId } from '@libp2p/interface-peer-id'
32
- import type { Peer, PeerStore } from '@libp2p/interface-peer-store'
33
- import type { IncomingStreamData, Registrar } from '@libp2p/interface-registrar'
34
- import type { AbortOptions } from '@libp2p/interfaces'
35
- import type { EventEmitter } from '@libp2p/interfaces/events'
36
- import type { Startable } from '@libp2p/interfaces/startable'
21
+ import type { IdentifyService, IdentifyServiceComponents, IdentifyServiceInit } from './index.js'
22
+ import type { Libp2pEvents, IdentifyResult, SignedPeerRecord, AbortOptions } from '@libp2p/interface'
23
+ import type { Connection, Stream } from '@libp2p/interface/connection'
24
+ import type { EventEmitter } from '@libp2p/interface/events'
25
+ import type { PeerId } from '@libp2p/interface/peer-id'
26
+ import type { Peer, PeerStore } from '@libp2p/interface/peer-store'
27
+ import type { Startable } from '@libp2p/interface/startable'
28
+ import type { AddressManager } from '@libp2p/interface-internal/address-manager'
29
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
30
+ import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal/registrar'
37
31
 
38
32
  const log = logger('libp2p:identify')
39
33
 
@@ -50,10 +44,12 @@ const defaultValues = {
50
44
  maxPushIncomingStreams: 1,
51
45
  maxPushOutgoingStreams: 1,
52
46
  maxObservedAddresses: 10,
53
- maxIdentifyMessageSize: 8192
47
+ maxIdentifyMessageSize: 8192,
48
+ runOnConnectionOpen: true,
49
+ runOnTransientConnection: true
54
50
  }
55
51
 
56
- export class DefaultIdentifyService implements Startable {
52
+ export class DefaultIdentifyService implements Startable, IdentifyService {
57
53
  private readonly identifyProtocolStr: string
58
54
  private readonly identifyPushProtocolStr: string
59
55
  public readonly host: {
@@ -75,6 +71,7 @@ export class DefaultIdentifyService implements Startable {
75
71
  private readonly maxIdentifyMessageSize: number
76
72
  private readonly maxObservedAddresses: number
77
73
  private readonly events: EventEmitter<Libp2pEvents>
74
+ private readonly runOnTransientConnection: boolean
78
75
 
79
76
  constructor (components: IdentifyServiceComponents, init: IdentifyServiceInit) {
80
77
  this.started = false
@@ -94,6 +91,7 @@ export class DefaultIdentifyService implements Startable {
94
91
  this.maxPushOutgoingStreams = init.maxPushOutgoingStreams ?? defaultValues.maxPushOutgoingStreams
95
92
  this.maxIdentifyMessageSize = init.maxIdentifyMessageSize ?? defaultValues.maxIdentifyMessageSize
96
93
  this.maxObservedAddresses = init.maxObservedAddresses ?? defaultValues.maxObservedAddresses
94
+ this.runOnTransientConnection = init.runOnTransientConnection ?? defaultValues.runOnTransientConnection
97
95
 
98
96
  // Store self host metadata
99
97
  this.host = {
@@ -101,11 +99,13 @@ export class DefaultIdentifyService implements Startable {
101
99
  agentVersion: init.agentVersion ?? defaultValues.agentVersion
102
100
  }
103
101
 
104
- // When a new connection happens, trigger identify
105
- components.events.addEventListener('connection:open', (evt) => {
106
- const connection = evt.detail
107
- this.identify(connection).catch(err => { log.error('error during identify trigged by connection:open', err) })
108
- })
102
+ if (init.runOnConnectionOpen ?? defaultValues.runOnConnectionOpen) {
103
+ // When a new connection happens, trigger identify
104
+ components.events.addEventListener('connection:open', (evt) => {
105
+ const connection = evt.detail
106
+ this.identify(connection).catch(err => { log.error('error during identify trigged by connection:open', err) })
107
+ })
108
+ }
109
109
 
110
110
  // When self peer record changes, trigger identify-push
111
111
  components.events.addEventListener('self:peer:update', (evt) => {
@@ -144,7 +144,8 @@ export class DefaultIdentifyService implements Startable {
144
144
  })
145
145
  }, {
146
146
  maxInboundStreams: this.maxInboundStreams,
147
- maxOutboundStreams: this.maxOutboundStreams
147
+ maxOutboundStreams: this.maxOutboundStreams,
148
+ runOnTransientConnection: this.runOnTransientConnection
148
149
  })
149
150
  await this.registrar.handle(this.identifyPushProtocolStr, (data) => {
150
151
  void this._handlePush(data).catch(err => {
@@ -152,7 +153,8 @@ export class DefaultIdentifyService implements Startable {
152
153
  })
153
154
  }, {
154
155
  maxInboundStreams: this.maxPushIncomingStreams,
155
- maxOutboundStreams: this.maxPushOutgoingStreams
156
+ maxOutboundStreams: this.maxPushOutgoingStreams,
157
+ runOnTransientConnection: this.runOnTransientConnection
156
158
  })
157
159
 
158
160
  this.started = true
@@ -192,29 +194,31 @@ export class DefaultIdentifyService implements Startable {
192
194
 
193
195
  try {
194
196
  stream = await connection.newStream([this.identifyPushProtocolStr], {
197
+ signal,
198
+ runOnTransientConnection: this.runOnTransientConnection
199
+ })
200
+
201
+ const pb = pbStream(stream, {
202
+ maxDataLength: this.maxIdentifyMessageSize ?? MAX_IDENTIFY_MESSAGE_SIZE
203
+ }).pb(Identify)
204
+
205
+ await pb.write({
206
+ listenAddrs: listenAddresses.map(ma => ma.bytes),
207
+ signedPeerRecord: signedPeerRecord.marshal(),
208
+ protocols: supportedProtocols,
209
+ agentVersion,
210
+ protocolVersion
211
+ }, {
195
212
  signal
196
213
  })
197
214
 
198
- // make stream abortable
199
- const source = abortableDuplex(stream, signal)
200
-
201
- await source.sink(pipe(
202
- [Identify.encode({
203
- listenAddrs: listenAddresses.map(ma => ma.bytes),
204
- signedPeerRecord: signedPeerRecord.marshal(),
205
- protocols: supportedProtocols,
206
- agentVersion,
207
- protocolVersion
208
- })],
209
- (source) => lp.encode(source)
210
- ))
215
+ await stream.close({
216
+ signal
217
+ })
211
218
  } catch (err: any) {
212
219
  // Just log errors
213
220
  log.error('could not push identify update to peer', err)
214
- } finally {
215
- if (stream != null) {
216
- stream.close()
217
- }
221
+ stream?.abort(err)
218
222
  }
219
223
  })
220
224
 
@@ -256,48 +260,31 @@ export class DefaultIdentifyService implements Startable {
256
260
  async _identify (connection: Connection, options: AbortOptions = {}): Promise<Identify> {
257
261
  let stream: Stream | undefined
258
262
 
259
- const signal = anySignal([AbortSignal.timeout(this.timeout), options?.signal])
260
-
261
- try {
262
- // fails on node < 15.4
263
- setMaxListeners?.(Infinity, signal)
264
- } catch {}
263
+ options.signal = options.signal ?? AbortSignal.timeout(this.timeout)
265
264
 
266
265
  try {
267
266
  stream = await connection.newStream([this.identifyProtocolStr], {
268
- signal
267
+ ...options,
268
+ runOnTransientConnection: this.runOnTransientConnection
269
269
  })
270
270
 
271
- // make stream abortable
272
- const source = abortableDuplex(stream, signal)
271
+ const pb = pbStream(stream, {
272
+ maxDataLength: this.maxIdentifyMessageSize ?? MAX_IDENTIFY_MESSAGE_SIZE
273
+ }).pb(Identify)
273
274
 
274
- const data = await pipe(
275
- [],
276
- source,
277
- (source) => lp.decode(source, {
278
- maxDataLength: this.maxIdentifyMessageSize ?? MAX_IDENTIFY_MESSAGE_SIZE
279
- }),
280
- async (source) => first(source)
281
- )
275
+ const message = await pb.read(options)
282
276
 
283
- if (data == null) {
284
- throw new CodeError('No data could be retrieved', codes.ERR_CONNECTION_ENDED)
285
- }
277
+ await stream.close(options)
286
278
 
287
- try {
288
- return Identify.decode(data)
289
- } catch (err: any) {
290
- throw new CodeError(String(err), codes.ERR_INVALID_MESSAGE)
291
- }
292
- } finally {
293
- if (stream != null) {
294
- stream.close()
295
- }
296
- signal.clear()
279
+ return message
280
+ } catch (err: any) {
281
+ log.error('error while reading identify message', err)
282
+ stream?.abort(err)
283
+ throw err
297
284
  }
298
285
  }
299
286
 
300
- async identify (connection: Connection, options: AbortOptions = {}): Promise<void> {
287
+ async identify (connection: Connection, options: AbortOptions = {}): Promise<IdentifyResult> {
301
288
  const message = await this._identify(connection, options)
302
289
  const {
303
290
  publicKey,
@@ -323,11 +310,11 @@ export class DefaultIdentifyService implements Startable {
323
310
  const cleanObservedAddr = getCleanMultiaddr(observedAddr)
324
311
 
325
312
  log('identify completed for peer %p and protocols %o', id, protocols)
326
- log('our observed address is %s', cleanObservedAddr)
313
+ log('our observed address is %a', cleanObservedAddr)
327
314
 
328
315
  if (cleanObservedAddr != null &&
329
316
  this.addressManager.getObservedAddrs().length < (this.maxObservedAddresses ?? Infinity)) {
330
- log('storing our observed address %s', cleanObservedAddr?.toString())
317
+ log('storing our observed address %a', cleanObservedAddr)
331
318
  this.addressManager.addObservedAddr(cleanObservedAddr)
332
319
  }
333
320
 
@@ -345,6 +332,8 @@ export class DefaultIdentifyService implements Startable {
345
332
  }
346
333
 
347
334
  this.events.safeDispatchEvent('peer:identify', { detail: result })
335
+
336
+ return result
348
337
  }
349
338
 
350
339
  /**
@@ -377,7 +366,9 @@ export class DefaultIdentifyService implements Startable {
377
366
  signedPeerRecord = envelope.marshal().subarray()
378
367
  }
379
368
 
380
- const message = Identify.encode({
369
+ const pb = pbStream(stream).pb(Identify)
370
+
371
+ await pb.write({
381
372
  protocolVersion: this.host.protocolVersion,
382
373
  agentVersion: this.host.agentVersion,
383
374
  publicKey,
@@ -385,17 +376,16 @@ export class DefaultIdentifyService implements Startable {
385
376
  signedPeerRecord,
386
377
  observedAddr: connection.remoteAddr.bytes,
387
378
  protocols: peerData.protocols
379
+ }, {
380
+ signal
388
381
  })
389
382
 
390
- // make stream abortable
391
- const source = abortableDuplex(stream, signal)
392
-
393
- const msgWithLenPrefix = pipe([message], (source) => lp.encode(source))
394
- await source.sink(msgWithLenPrefix)
383
+ await stream.close({
384
+ signal
385
+ })
395
386
  } catch (err: any) {
396
387
  log.error('could not respond to identify request', err)
397
- } finally {
398
- stream.close()
388
+ stream.abort(err)
399
389
  }
400
390
  }
401
391
 
@@ -410,19 +400,22 @@ export class DefaultIdentifyService implements Startable {
410
400
  throw new Error('received push from ourselves?')
411
401
  }
412
402
 
413
- // make stream abortable
414
- const source = abortableDuplex(stream, AbortSignal.timeout(this.timeout))
415
- const pb = pbStream(source, {
403
+ const options = {
404
+ signal: AbortSignal.timeout(this.timeout)
405
+ }
406
+
407
+ const pb = pbStream(stream, {
416
408
  maxDataLength: this.maxIdentifyMessageSize ?? MAX_IDENTIFY_MESSAGE_SIZE
417
- })
418
- const message = await pb.readPB(Identify)
409
+ }).pb(Identify)
410
+
411
+ const message = await pb.read(options)
412
+ await stream.close(options)
419
413
 
420
414
  await this.#consumeIdentifyMessage(connection.remotePeer, message)
421
415
  } catch (err: any) {
422
416
  log.error('received invalid message', err)
417
+ stream.abort(err)
423
418
  return
424
- } finally {
425
- stream.close()
426
419
  }
427
420
 
428
421
  log('handled push from %p', connection.remotePeer)
@@ -4,13 +4,14 @@ import {
4
4
  } from './consts.js'
5
5
  import { DefaultIdentifyService } from './identify.js'
6
6
  import { Identify } from './pb/message.js'
7
- import type { AddressManager } from '@libp2p/interface-address-manager'
8
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
9
- import type { Libp2pEvents } from '@libp2p/interface-libp2p'
10
- import type { PeerId } from '@libp2p/interface-peer-id'
11
- import type { PeerStore } from '@libp2p/interface-peer-store'
12
- import type { Registrar } from '@libp2p/interface-registrar'
13
- import type { EventEmitter } from '@libp2p/interfaces/events'
7
+ import type { AbortOptions, IdentifyResult, Libp2pEvents } from '@libp2p/interface'
8
+ import type { EventEmitter } from '@libp2p/interface/events'
9
+ import type { PeerId } from '@libp2p/interface/peer-id'
10
+ import type { PeerStore } from '@libp2p/interface/peer-store'
11
+ import type { Connection } from '@libp2p/interface/src/connection/index.js'
12
+ import type { AddressManager } from '@libp2p/interface-internal/address-manager'
13
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
14
+ import type { Registrar } from '@libp2p/interface-internal/registrar'
14
15
 
15
16
  export interface IdentifyServiceInit {
16
17
  /**
@@ -39,6 +40,16 @@ export interface IdentifyServiceInit {
39
40
  maxPushIncomingStreams?: number
40
41
  maxPushOutgoingStreams?: number
41
42
  maxObservedAddresses?: number
43
+
44
+ /**
45
+ * Whether to automatically dial identify on newly opened connections (default: true)
46
+ */
47
+ runOnConnectionOpen?: boolean
48
+
49
+ /**
50
+ * Whether to run on connections with data or duration limits (default: true)
51
+ */
52
+ runOnTransientConnection?: boolean
42
53
  }
43
54
 
44
55
  export interface IdentifyServiceComponents {
@@ -60,6 +71,19 @@ export const multicodecs = {
60
71
 
61
72
  export const Message = { Identify }
62
73
 
63
- export function identifyService (init: IdentifyServiceInit = {}): (components: IdentifyServiceComponents) => DefaultIdentifyService {
74
+ export interface IdentifyService {
75
+ /**
76
+ * due to the default limits on inbound/outbound streams for this protocol,
77
+ * invoking this method when runOnConnectionOpen is true can lead to unpredictable results
78
+ * as streams may be closed by the local or the remote node.
79
+ * Please use with caution. If you find yourself needing to call this method to discover other peers that support your protocol,
80
+ * you may be better off configuring a topology to be notified instead.
81
+ */
82
+ identify: (connection: Connection, options?: AbortOptions) => Promise<IdentifyResult>
83
+
84
+ push: () => Promise<void>
85
+ }
86
+
87
+ export function identifyService (init: IdentifyServiceInit = {}): (components: IdentifyServiceComponents) => IdentifyService {
64
88
  return (components) => new DefaultIdentifyService(components, init)
65
89
  }
package/src/index.ts CHANGED
@@ -19,18 +19,17 @@ import type { AddressManagerInit } from './address-manager/index.js'
19
19
  import type { Components } from './components.js'
20
20
  import type { ConnectionManagerInit } from './connection-manager/index.js'
21
21
  import type { TransportManagerInit } from './transport-manager.js'
22
- import type { ConnectionProtector } from '@libp2p/interface-connection'
23
- import type { ConnectionEncrypter } from '@libp2p/interface-connection-encrypter'
24
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
25
- import type { ContentRouting } from '@libp2p/interface-content-routing'
26
- import type { Libp2p, ServiceMap } from '@libp2p/interface-libp2p'
27
- import type { Metrics } from '@libp2p/interface-metrics'
28
- import type { PeerDiscovery } from '@libp2p/interface-peer-discovery'
29
- import type { PeerId } from '@libp2p/interface-peer-id'
30
- import type { PeerRouting } from '@libp2p/interface-peer-routing'
31
- import type { StreamMuxerFactory } from '@libp2p/interface-stream-muxer'
32
- import type { Transport } from '@libp2p/interface-transport'
33
- import type { RecursivePartial } from '@libp2p/interfaces'
22
+ import type { Libp2p, ServiceMap, RecursivePartial } from '@libp2p/interface'
23
+ import type { ConnectionProtector } from '@libp2p/interface/connection'
24
+ import type { ConnectionEncrypter } from '@libp2p/interface/connection-encrypter'
25
+ import type { ConnectionGater } from '@libp2p/interface/connection-gater'
26
+ import type { ContentRouting } from '@libp2p/interface/content-routing'
27
+ import type { Metrics } from '@libp2p/interface/metrics'
28
+ import type { PeerDiscovery } from '@libp2p/interface/peer-discovery'
29
+ import type { PeerId } from '@libp2p/interface/peer-id'
30
+ import type { PeerRouting } from '@libp2p/interface/peer-routing'
31
+ import type { StreamMuxerFactory } from '@libp2p/interface/stream-muxer'
32
+ import type { Transport } from '@libp2p/interface/transport'
34
33
  import type { KeyChainInit } from '@libp2p/keychain'
35
34
  import type { PersistentPeerStoreInit } from '@libp2p/peer-store'
36
35
  import type { Datastore } from 'interface-datastore'