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,14 +1,14 @@
1
- import { CodeError } from '@libp2p/interfaces/errors'
2
- import { EventEmitter } from '@libp2p/interfaces/events'
1
+ import { CodeError } from '@libp2p/interface/errors'
2
+ import { EventEmitter } from '@libp2p/interface/events'
3
3
  import { logger } from '@libp2p/logger'
4
4
  import { PeerMap } from '@libp2p/peer-collections'
5
5
  import { peerIdFromString } from '@libp2p/peer-id'
6
6
  import { multiaddr } from '@multiformats/multiaddr'
7
7
  import type { ReservationStore } from './reservation-store.js'
8
- import type { Connection } from '@libp2p/interface-connection'
9
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
10
- import type { PeerId } from '@libp2p/interface-peer-id'
11
- import type { Listener, ListenerEvents } from '@libp2p/interface-transport'
8
+ import type { Connection } from '@libp2p/interface/connection'
9
+ import type { PeerId } from '@libp2p/interface/peer-id'
10
+ import type { Listener, ListenerEvents } from '@libp2p/interface/transport'
11
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
12
12
  import type { Multiaddr } from '@multiformats/multiaddr'
13
13
 
14
14
  const log = logger('libp2p:circuit-relay:transport:listener')
@@ -37,7 +37,7 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
37
37
  }
38
38
 
39
39
  async listen (addr: Multiaddr): Promise<void> {
40
- log('listen on %s', addr)
40
+ log('listen on %a', addr)
41
41
 
42
42
  const relayPeerStr = addr.getPeerId()
43
43
  let relayConn: Connection | undefined
@@ -95,6 +95,8 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
95
95
  #removeRelayPeer (peerId: PeerId): void {
96
96
  const had = this.listeningAddrs.has(peerId)
97
97
 
98
+ log('relay peer removed %p - had reservation', peerId, had)
99
+
98
100
  this.listeningAddrs.delete(peerId)
99
101
 
100
102
  if (had) {
@@ -1,20 +1,20 @@
1
- import { EventEmitter } from '@libp2p/interfaces/events'
1
+ import { EventEmitter } from '@libp2p/interface/events'
2
2
  import { logger } from '@libp2p/logger'
3
3
  import { PeerMap } from '@libp2p/peer-collections'
4
4
  import { multiaddr } from '@multiformats/multiaddr'
5
- import { pbStream } from 'it-pb-stream'
5
+ import { pbStream } from 'it-protobuf-stream'
6
6
  import { PeerJobQueue } from '../../utils/peer-job-queue.js'
7
7
  import { DEFAULT_RESERVATION_CONCURRENCY, RELAY_TAG, RELAY_V2_HOP_CODEC } from '../constants.js'
8
8
  import { HopMessage, Status } from '../pb/index.js'
9
9
  import { getExpirationMilliseconds } from '../utils.js'
10
10
  import type { Reservation } from '../pb/index.js'
11
- import type { Connection } from '@libp2p/interface-connection'
12
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
13
- import type { Libp2pEvents } from '@libp2p/interface-libp2p'
14
- import type { PeerId } from '@libp2p/interface-peer-id'
15
- import type { PeerStore } from '@libp2p/interface-peer-store'
16
- import type { TransportManager } from '@libp2p/interface-transport'
17
- import type { Startable } from '@libp2p/interfaces/startable'
11
+ import type { Libp2pEvents, AbortOptions } from '@libp2p/interface'
12
+ import type { Connection } from '@libp2p/interface/connection'
13
+ import type { PeerId } from '@libp2p/interface/peer-id'
14
+ import type { PeerStore } from '@libp2p/interface/peer-store'
15
+ import type { Startable } from '@libp2p/interface/startable'
16
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
17
+ import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
18
18
 
19
19
  const log = logger('libp2p:circuit-relay:transport:reservation-store')
20
20
 
@@ -55,6 +55,12 @@ export interface RelayStoreInit {
55
55
  * Limit the number of potential relays we will dial (default: 100)
56
56
  */
57
57
  maxReservationQueueLength?: number
58
+
59
+ /**
60
+ * When creating a reservation it must complete within this number of ms
61
+ * (default: 5000)
62
+ */
63
+ reservationCompletionTimeout?: number
58
64
  }
59
65
 
60
66
  export type RelayType = 'discovered' | 'configured'
@@ -80,6 +86,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
80
86
  private readonly reservations: PeerMap<RelayEntry>
81
87
  private readonly maxDiscoveredRelays: number
82
88
  private readonly maxReservationQueueLength: number
89
+ private readonly reservationCompletionTimeout: number
83
90
  private started: boolean
84
91
 
85
92
  constructor (components: RelayStoreComponents, init?: RelayStoreInit) {
@@ -93,6 +100,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
93
100
  this.reservations = new PeerMap()
94
101
  this.maxDiscoveredRelays = init?.discoverRelays ?? 0
95
102
  this.maxReservationQueueLength = init?.maxReservationQueueLength ?? 100
103
+ this.reservationCompletionTimeout = init?.reservationCompletionTimeout ?? 10000
96
104
  this.started = false
97
105
 
98
106
  // ensure we don't listen on multiple relays simultaneously
@@ -117,12 +125,12 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
117
125
  }
118
126
 
119
127
  async stop (): Promise<void> {
128
+ this.reserveQueue.clear()
120
129
  this.reservations.forEach(({ timeout }) => {
121
130
  clearTimeout(timeout)
122
131
  })
123
132
  this.reservations.clear()
124
-
125
- this.started = true
133
+ this.started = false
126
134
  }
127
135
 
128
136
  /**
@@ -175,14 +183,20 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
175
183
  return
176
184
  }
177
185
 
178
- const connection = await this.connectionManager.openConnection(peerId)
186
+ const signal = AbortSignal.timeout(this.reservationCompletionTimeout)
187
+
188
+ const connection = await this.connectionManager.openConnection(peerId, {
189
+ signal
190
+ })
179
191
 
180
192
  if (connection.remoteAddr.protoNames().includes('p2p-circuit')) {
181
193
  log('not creating reservation over relayed connection')
182
194
  return
183
195
  }
184
196
 
185
- const reservation = await this.#createReservation(connection)
197
+ const reservation = await this.#createReservation(connection, {
198
+ signal
199
+ })
186
200
 
187
201
  log('created reservation on relay peer %p', peerId)
188
202
 
@@ -220,6 +234,13 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
220
234
  } catch (err) {
221
235
  log.error('could not reserve slot on %p', peerId, err)
222
236
 
237
+ // cancel the renewal timeout if it's been set
238
+ const reservation = this.reservations.get(peerId)
239
+
240
+ if (reservation != null) {
241
+ clearTimeout(reservation.timeout)
242
+ }
243
+
223
244
  // if listening failed, remove the reservation
224
245
  this.reservations.delete(peerId)
225
246
  }
@@ -236,22 +257,24 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
236
257
  return this.reservations.get(peerId)?.reservation
237
258
  }
238
259
 
239
- async #createReservation (connection: Connection): Promise<Reservation> {
240
- log('requesting reservation from %s', connection.remotePeer)
260
+ async #createReservation (connection: Connection, options: AbortOptions): Promise<Reservation> {
261
+ options.signal?.throwIfAborted()
262
+
263
+ log('requesting reservation from %p', connection.remotePeer)
241
264
  const stream = await connection.newStream(RELAY_V2_HOP_CODEC)
242
265
  const pbstr = pbStream(stream)
243
266
  const hopstr = pbstr.pb(HopMessage)
244
- hopstr.write({ type: HopMessage.Type.RESERVE })
267
+ await hopstr.write({ type: HopMessage.Type.RESERVE }, options)
245
268
 
246
269
  let response: HopMessage
247
270
 
248
271
  try {
249
- response = await hopstr.read()
272
+ response = await hopstr.read(options)
250
273
  } catch (err: any) {
251
274
  log.error('error parsing reserve message response from %p because', connection.remotePeer, err)
252
275
  throw err
253
276
  } finally {
254
- stream.close()
277
+ await stream.close()
255
278
  }
256
279
 
257
280
  if (response.status === Status.OK && (response.reservation != null)) {
@@ -5,7 +5,7 @@ import { CID } from 'multiformats/cid'
5
5
  import { sha256 } from 'multiformats/hashes/sha2'
6
6
  import { DEFAULT_DATA_LIMIT, DEFAULT_DURATION_LIMIT } from './constants.js'
7
7
  import type { Limit } from './pb/index.js'
8
- import type { Stream } from '@libp2p/interface-connection'
8
+ import type { Stream } from '@libp2p/interface/connection'
9
9
  import type { Source } from 'it-stream-types'
10
10
  import type { Uint8ArrayList } from 'uint8arraylist'
11
11
 
package/src/components.ts CHANGED
@@ -1,18 +1,19 @@
1
- import { CodeError } from '@libp2p/interfaces/errors'
2
- import { isStartable, type Startable } from '@libp2p/interfaces/startable'
3
- import type { AddressManager } from '@libp2p/interface-address-manager'
4
- import type { ConnectionProtector } from '@libp2p/interface-connection'
5
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
6
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
7
- import type { ContentRouting } from '@libp2p/interface-content-routing'
8
- import type { Libp2pEvents } from '@libp2p/interface-libp2p'
9
- import type { Metrics } from '@libp2p/interface-metrics'
10
- import type { PeerId } from '@libp2p/interface-peer-id'
11
- import type { PeerRouting } from '@libp2p/interface-peer-routing'
12
- import type { PeerStore } from '@libp2p/interface-peer-store'
13
- import type { Registrar } from '@libp2p/interface-registrar'
14
- import type { TransportManager, Upgrader } from '@libp2p/interface-transport'
15
- import type { EventEmitter } from '@libp2p/interfaces/events'
1
+ import { CodeError } from '@libp2p/interface/errors'
2
+ import { isStartable, type Startable } from '@libp2p/interface/startable'
3
+ import type { Libp2pEvents } from '@libp2p/interface'
4
+ import type { ConnectionProtector } from '@libp2p/interface/connection'
5
+ import type { ConnectionGater } from '@libp2p/interface/connection-gater'
6
+ import type { ContentRouting } from '@libp2p/interface/content-routing'
7
+ import type { EventEmitter } from '@libp2p/interface/events'
8
+ import type { Metrics } from '@libp2p/interface/metrics'
9
+ import type { PeerId } from '@libp2p/interface/peer-id'
10
+ import type { PeerRouting } from '@libp2p/interface/peer-routing'
11
+ import type { PeerStore } from '@libp2p/interface/peer-store'
12
+ import type { Upgrader } from '@libp2p/interface/transport'
13
+ import type { AddressManager } from '@libp2p/interface-internal/address-manager'
14
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
15
+ import type { Registrar } from '@libp2p/interface-internal/registrar'
16
+ import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
16
17
  import type { Datastore } from 'interface-datastore'
17
18
 
18
19
  export interface Components extends Record<string, any>, Startable {
@@ -1,5 +1,5 @@
1
1
  import isPrivate from 'private-ip'
2
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
2
+ import type { ConnectionGater } from '@libp2p/interface/connection-gater'
3
3
  import type { Multiaddr } from '@multiformats/multiaddr'
4
4
 
5
5
  /**
@@ -1,4 +1,4 @@
1
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
1
+ import type { ConnectionGater } from '@libp2p/interface/connection-gater'
2
2
 
3
3
  /**
4
4
  * Returns a default connection gater implementation that allows everything
package/src/config.ts CHANGED
@@ -1,12 +1,11 @@
1
- import { FaultTolerance } from '@libp2p/interface-transport'
2
- import { CodeError } from '@libp2p/interfaces/errors'
1
+ import { CodeError } from '@libp2p/interface/errors'
2
+ import { FaultTolerance } from '@libp2p/interface/transport'
3
3
  import { publicAddressesFirst } from '@libp2p/utils/address-sort'
4
4
  import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
5
5
  import mergeOptions from 'merge-options'
6
6
  import { codes, messages } from './errors.js'
7
7
  import type { Libp2pInit } from './index.js'
8
- import type { ServiceMap } from '@libp2p/interface-libp2p'
9
- import type { RecursivePartial } from '@libp2p/interfaces'
8
+ import type { ServiceMap, RecursivePartial } from '@libp2p/interface'
10
9
  import type { Multiaddr } from '@multiformats/multiaddr'
11
10
 
12
11
  const DefaultConfig: Partial<Libp2pInit> = {
@@ -1,21 +1,29 @@
1
- import { symbol } from '@libp2p/interface-connection'
2
- import { OPEN, CLOSING, CLOSED } from '@libp2p/interface-connection/status'
3
- import { CodeError } from '@libp2p/interfaces/errors'
1
+ import { setMaxListeners } from 'events'
2
+ import { symbol } from '@libp2p/interface/connection'
3
+ import { CodeError } from '@libp2p/interface/errors'
4
4
  import { logger } from '@libp2p/logger'
5
- import type { Connection, ConnectionStat, Stream } from '@libp2p/interface-connection'
6
- import type { PeerId } from '@libp2p/interface-peer-id'
7
- import type { AbortOptions } from '@libp2p/interfaces'
5
+ import type { AbortOptions } from '@libp2p/interface'
6
+ import type { Direction, Connection, Stream, ConnectionTimeline, ConnectionStatus, NewStreamOptions } from '@libp2p/interface/connection'
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:connection')
11
11
 
12
+ const CLOSE_TIMEOUT = 500
13
+
12
14
  interface ConnectionInit {
13
15
  remoteAddr: Multiaddr
14
16
  remotePeer: PeerId
15
17
  newStream: (protocols: string[], options?: AbortOptions) => Promise<Stream>
16
- close: () => Promise<void>
18
+ close: (options?: AbortOptions) => Promise<void>
19
+ abort: (err: Error) => void
17
20
  getStreams: () => Stream[]
18
- stat: ConnectionStat
21
+ status: ConnectionStatus
22
+ direction: Direction
23
+ timeline: ConnectionTimeline
24
+ multiplexer?: string
25
+ encryption?: string
26
+ transient?: boolean
19
27
  }
20
28
 
21
29
  /**
@@ -38,10 +46,12 @@ export class ConnectionImpl implements Connection {
38
46
  */
39
47
  public readonly remotePeer: PeerId
40
48
 
41
- /**
42
- * Connection metadata
43
- */
44
- public readonly stat: ConnectionStat
49
+ public direction: Direction
50
+ public timeline: ConnectionTimeline
51
+ public multiplexer?: string
52
+ public encryption?: string
53
+ public status: ConnectionStatus
54
+ public transient: boolean
45
55
 
46
56
  /**
47
57
  * User provided tags
@@ -52,39 +62,42 @@ export class ConnectionImpl implements Connection {
52
62
  /**
53
63
  * Reference to the new stream function of the multiplexer
54
64
  */
55
- private readonly _newStream: (protocols: string[], options?: AbortOptions) => Promise<Stream>
65
+ private readonly _newStream: (protocols: string[], options?: NewStreamOptions) => Promise<Stream>
56
66
 
57
67
  /**
58
68
  * Reference to the close function of the raw connection
59
69
  */
60
- private readonly _close: () => Promise<void>
70
+ private readonly _close: (options?: AbortOptions) => Promise<void>
71
+
72
+ private readonly _abort: (err: Error) => void
61
73
 
62
74
  /**
63
75
  * Reference to the getStreams function of the muxer
64
76
  */
65
77
  private readonly _getStreams: () => Stream[]
66
78
 
67
- private _closing: boolean
68
-
69
79
  /**
70
80
  * An implementation of the js-libp2p connection.
71
81
  * Any libp2p transport should use an upgrader to return this connection.
72
82
  */
73
83
  constructor (init: ConnectionInit) {
74
- const { remoteAddr, remotePeer, newStream, close, getStreams, stat } = init
84
+ const { remoteAddr, remotePeer, newStream, close, abort, getStreams } = init
75
85
 
76
86
  this.id = `${(parseInt(String(Math.random() * 1e9))).toString(36)}${Date.now()}`
77
87
  this.remoteAddr = remoteAddr
78
88
  this.remotePeer = remotePeer
79
- this.stat = {
80
- ...stat,
81
- status: OPEN
82
- }
89
+ this.direction = init.direction
90
+ this.status = 'open'
91
+ this.timeline = init.timeline
92
+ this.multiplexer = init.multiplexer
93
+ this.encryption = init.encryption
94
+ this.transient = init.transient ?? false
95
+
83
96
  this._newStream = newStream
84
97
  this._close = close
98
+ this._abort = abort
85
99
  this._getStreams = getStreams
86
100
  this.tags = []
87
- this._closing = false
88
101
  }
89
102
 
90
103
  readonly [Symbol.toStringTag] = 'Connection'
@@ -101,12 +114,12 @@ export class ConnectionImpl implements Connection {
101
114
  /**
102
115
  * Create a new stream from this connection
103
116
  */
104
- async newStream (protocols: string | string[], options?: AbortOptions): Promise<Stream> {
105
- if (this.stat.status === CLOSING) {
117
+ async newStream (protocols: string | string[], options?: NewStreamOptions): Promise<Stream> {
118
+ if (this.status === 'closing') {
106
119
  throw new CodeError('the connection is being closed', 'ERR_CONNECTION_BEING_CLOSED')
107
120
  }
108
121
 
109
- if (this.stat.status === CLOSED) {
122
+ if (this.status === 'closed') {
110
123
  throw new CodeError('the connection is closed', 'ERR_CONNECTION_CLOSED')
111
124
  }
112
125
 
@@ -114,9 +127,13 @@ export class ConnectionImpl implements Connection {
114
127
  protocols = [protocols]
115
128
  }
116
129
 
130
+ if (this.transient && options?.runOnTransientConnection !== true) {
131
+ throw new CodeError('Cannot open protocol stream on transient connection', 'ERR_TRANSIENT_CONNECTION')
132
+ }
133
+
117
134
  const stream = await this._newStream(protocols, options)
118
135
 
119
- stream.stat.direction = 'outbound'
136
+ stream.direction = 'outbound'
120
137
 
121
138
  return stream
122
139
  }
@@ -125,7 +142,7 @@ export class ConnectionImpl implements Connection {
125
142
  * Add a stream when it is opened to the registry
126
143
  */
127
144
  addStream (stream: Stream): void {
128
- stream.stat.direction = 'inbound'
145
+ stream.direction = 'inbound'
129
146
  }
130
147
 
131
148
  /**
@@ -138,27 +155,52 @@ export class ConnectionImpl implements Connection {
138
155
  /**
139
156
  * Close the connection
140
157
  */
141
- async close (): Promise<void> {
142
- if (this.stat.status === CLOSED || this._closing) {
158
+ async close (options: AbortOptions = {}): Promise<void> {
159
+ if (this.status === 'closed' || this.status === 'closing') {
143
160
  return
144
161
  }
145
162
 
146
- this.stat.status = CLOSING
163
+ log('closing connection to %a', this.remoteAddr)
164
+
165
+ this.status = 'closing'
166
+
167
+ options.signal = options?.signal ?? AbortSignal.timeout(CLOSE_TIMEOUT)
168
+
169
+ try {
170
+ // fails on node < 15.4
171
+ setMaxListeners?.(Infinity, options.signal)
172
+ } catch { }
147
173
 
148
- // close all streams - this can throw if we're not multiplexed
149
174
  try {
150
- this.streams.forEach(s => { s.close() })
151
- } catch (err) {
152
- log.error(err)
175
+ // close all streams gracefully - this can throw if we're not multiplexed
176
+ await Promise.all(
177
+ this.streams.map(async s => s.close(options))
178
+ )
179
+
180
+ // Close raw connection
181
+ await this._close(options)
182
+
183
+ this.timeline.close = Date.now()
184
+ this.status = 'closed'
185
+ } catch (err: any) {
186
+ log.error('error encountered during graceful close of connection to %a', this.remoteAddr, err)
187
+ this.abort(err)
153
188
  }
189
+ }
190
+
191
+ abort (err: Error): void {
192
+ log.error('aborting connection to %a due to error', this.remoteAddr, err)
193
+
194
+ this.status = 'closing'
195
+ this.streams.forEach(s => { s.abort(err) })
196
+
197
+ log.error('all streams aborted', this.streams.length)
154
198
 
155
- // Close raw connection
156
- this._closing = true
157
- await this._close()
158
- this._closing = false
199
+ // Abort raw connection
200
+ this._abort(err)
159
201
 
160
- this.stat.timeline.close = Date.now()
161
- this.stat.status = CLOSED
202
+ this.timeline.close = Date.now()
203
+ this.status = 'closed'
162
204
  }
163
205
  }
164
206
 
@@ -2,11 +2,11 @@ import { logger } from '@libp2p/logger'
2
2
  import { PeerMap, PeerSet } from '@libp2p/peer-collections'
3
3
  import { PeerJobQueue } from '../utils/peer-job-queue.js'
4
4
  import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_INTERVAL, AUTO_DIAL_MAX_QUEUE_LENGTH, AUTO_DIAL_PRIORITY, MIN_CONNECTIONS } from './constants.js'
5
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
6
- import type { Libp2pEvents } from '@libp2p/interface-libp2p'
7
- import type { PeerStore } from '@libp2p/interface-peer-store'
8
- import type { EventEmitter } from '@libp2p/interfaces/events'
9
- import type { Startable } from '@libp2p/interfaces/startable'
5
+ import type { Libp2pEvents } from '@libp2p/interface'
6
+ import type { EventEmitter } from '@libp2p/interface/events'
7
+ import type { PeerStore } from '@libp2p/interface/peer-store'
8
+ import type { Startable } from '@libp2p/interface/startable'
9
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
10
10
 
11
11
  const log = logger('libp2p:connection-manager:auto-dial')
12
12
 
@@ -113,7 +113,9 @@ export class AutoDial implements Startable {
113
113
 
114
114
  // Already has enough connections
115
115
  if (numConnections >= this.minConnections) {
116
- log.trace('have enough connections %d/%d', numConnections, this.minConnections)
116
+ if (this.minConnections > 0) {
117
+ log.trace('have enough connections %d/%d', numConnections, this.minConnections)
118
+ }
117
119
  return
118
120
  }
119
121
 
@@ -1,10 +1,10 @@
1
1
  import { logger } from '@libp2p/logger'
2
2
  import { PeerMap } from '@libp2p/peer-collections'
3
3
  import { MAX_CONNECTIONS } from './constants.js'
4
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
5
- import type { Libp2pEvents } from '@libp2p/interface-libp2p'
6
- import type { PeerStore } from '@libp2p/interface-peer-store'
7
- import type { EventEmitter } from '@libp2p/interfaces/events'
4
+ import type { Libp2pEvents } from '@libp2p/interface'
5
+ import type { EventEmitter } from '@libp2p/interface/events'
6
+ import type { PeerStore } from '@libp2p/interface/peer-store'
7
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
8
8
  import type { Multiaddr } from '@multiformats/multiaddr'
9
9
 
10
10
  const log = logger('libp2p:connection-manager:connection-pruner')
@@ -106,8 +106,8 @@ export class ConnectionPruner {
106
106
  }
107
107
 
108
108
  // if the peers have an equal tag value then we want to close short-lived connections first
109
- const connectionALifespan = a.stat.timeline.open
110
- const connectionBLifespan = b.stat.timeline.open
109
+ const connectionALifespan = a.timeline.open
110
+ const connectionBLifespan = b.timeline.open
111
111
 
112
112
  if (connectionALifespan < connectionBLifespan) {
113
113
  return 1
@@ -1,4 +1,3 @@
1
-
2
1
  /**
3
2
  * @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#dialTimeout
4
3
  */
@@ -1,5 +1,5 @@
1
1
  import { setMaxListeners } from 'events'
2
- import { AbortError, CodeError } from '@libp2p/interfaces/errors'
2
+ import { AbortError, CodeError } from '@libp2p/interface/errors'
3
3
  import { logger } from '@libp2p/logger'
4
4
  import { publicAddressesFirst } from '@libp2p/utils/address-sort'
5
5
  import { type Multiaddr, type Resolver, resolvers } from '@multiformats/multiaddr'
@@ -16,27 +16,16 @@ import {
16
16
  MAX_PEER_ADDRS_TO_DIAL
17
17
  } from './constants.js'
18
18
  import { combineSignals, resolveMultiaddrs } from './utils.js'
19
- import type { Connection } from '@libp2p/interface-connection'
20
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
21
- import type { AddressSorter } from '@libp2p/interface-libp2p'
22
- import type { Metric, Metrics } from '@libp2p/interface-metrics'
23
- import type { PeerId } from '@libp2p/interface-peer-id'
24
- import type { Address, PeerStore } from '@libp2p/interface-peer-store'
25
- import type { TransportManager } from '@libp2p/interface-transport'
26
- import type { AbortOptions } from '@libp2p/interfaces'
19
+ import type { AddressSorter, AbortOptions, PendingDial } from '@libp2p/interface'
20
+ import type { Connection } from '@libp2p/interface/connection'
21
+ import type { ConnectionGater } from '@libp2p/interface/connection-gater'
22
+ import type { Metric, Metrics } from '@libp2p/interface/metrics'
23
+ import type { PeerId } from '@libp2p/interface/peer-id'
24
+ import type { Address, PeerStore } from '@libp2p/interface/peer-store'
25
+ import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
27
26
 
28
27
  const log = logger('libp2p:connection-manager:dial-queue')
29
28
 
30
- export type PendingDialStatus = 'queued' | 'active' | 'error' | 'success'
31
-
32
- export interface PendingDial {
33
- id: string
34
- status: PendingDialStatus
35
- peerId?: PeerId
36
- multiaddrs: Multiaddr[]
37
- promise: Promise<Connection>
38
- }
39
-
40
29
  export interface PendingDialTarget {
41
30
  resolve: (value: any) => void
42
31
  reject: (err: Error) => void
@@ -46,6 +35,10 @@ export interface DialOptions extends AbortOptions {
46
35
  priority?: number
47
36
  }
48
37
 
38
+ interface PendingDialInternal extends PendingDial {
39
+ promise: Promise<Connection>
40
+ }
41
+
49
42
  interface DialerInit {
50
43
  addressSorter?: AddressSorter
51
44
  maxParallelDials?: number
@@ -75,7 +68,7 @@ interface DialQueueComponents {
75
68
  }
76
69
 
77
70
  export class DialQueue {
78
- public pendingDials: PendingDial[]
71
+ public pendingDials: PendingDialInternal[]
79
72
  public queue: PQueue
80
73
  private readonly peerId: PeerId
81
74
  private readonly peerStore: PeerStore
@@ -219,7 +212,7 @@ export class DialQueue {
219
212
 
220
213
  log('creating dial target for', addrsToDial.map(({ multiaddr }) => multiaddr.toString()))
221
214
  // @ts-expect-error .promise property is set below
222
- const pendingDial: PendingDial = {
215
+ const pendingDial: PendingDialInternal = {
223
216
  id: randomId(),
224
217
  status: 'queued',
225
218
  peerId,
@@ -395,7 +388,7 @@ export class DialQueue {
395
388
  return sortedGatedAddrs
396
389
  }
397
390
 
398
- private async performDial (pendingDial: PendingDial, options: DialOptions = {}): Promise<Connection> {
391
+ private async performDial (pendingDial: PendingDialInternal, options: DialOptions = {}): Promise<Connection> {
399
392
  const dialAbortControllers: Array<(AbortController | undefined)> = pendingDial.multiaddrs.map(() => new AbortController())
400
393
 
401
394
  try {
@@ -419,13 +412,13 @@ export class DialQueue {
419
412
  // let any signal abort the dial
420
413
  const signal = combineSignals(controller.signal, options.signal)
421
414
  signal.addEventListener('abort', () => {
422
- log('dial to %s aborted', addr)
415
+ log('dial to %a aborted', addr)
423
416
  })
424
417
  const deferred = pDefer<Connection>()
425
418
 
426
419
  await peerDialQueue.add(async () => {
427
420
  if (signal.aborted) {
428
- log('dial to %s was aborted before reaching the head of the peer dial queue', addr)
421
+ log('dial to %a was aborted before reaching the head of the peer dial queue', addr)
429
422
  deferred.reject(new AbortError())
430
423
  return
431
424
  }
@@ -434,7 +427,7 @@ export class DialQueue {
434
427
  await this.queue.add(async () => {
435
428
  try {
436
429
  if (signal.aborted) {
437
- log('dial to %s was aborted before reaching the head of the dial queue', addr)
430
+ log('dial to %a was aborted before reaching the head of the dial queue', addr)
438
431
  deferred.reject(new AbortError())
439
432
  return
440
433
  }
@@ -469,13 +462,13 @@ export class DialQueue {
469
462
  }
470
463
  })
471
464
 
472
- log('dial to %s succeeded', addr)
465
+ log('dial to %a succeeded', addr)
473
466
 
474
467
  // resolve the connection promise
475
468
  deferred.resolve(conn)
476
469
  } catch (err: any) {
477
470
  // something only went wrong if our signal was not aborted
478
- log.error('error during dial of %s', addr, err)
471
+ log.error('error during dial of %a', addr, err)
479
472
  deferred.reject(err)
480
473
  }
481
474
  }, {