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,3 +1,24 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Use the `autoNATService` function to add support for the [AutoNAT protocol](https://docs.libp2p.io/concepts/nat/autonat/)
5
+ * to libp2p.
6
+ *
7
+ * @example
8
+ *
9
+ * ```typescript
10
+ * import { createLibp2p } from 'libp2p'
11
+ * import { autoNATService } from 'libp2p/autonat'
12
+ *
13
+ * const node = await createLibp2p({
14
+ * // ...other options
15
+ * services: {
16
+ * autoNAT: autoNATService()
17
+ * }
18
+ * })
19
+ * ```
20
+ */
21
+
1
22
  import { setMaxListeners } from 'events'
2
23
  import { logger } from '@libp2p/logger'
3
24
  import { peerIdFromBytes } from '@libp2p/peer-id'
@@ -17,15 +38,15 @@ import {
17
38
  PROTOCOL_NAME, PROTOCOL_PREFIX, PROTOCOL_VERSION, REFRESH_INTERVAL, STARTUP_DELAY, TIMEOUT
18
39
  } from './constants.js'
19
40
  import { Message } from './pb/index.js'
20
- import type { AddressManager } from '@libp2p/interface-address-manager'
21
- import type { Connection } from '@libp2p/interface-connection'
22
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
23
- import type { PeerId } from '@libp2p/interface-peer-id'
24
- import type { PeerInfo } from '@libp2p/interface-peer-info'
25
- import type { PeerRouting } from '@libp2p/interface-peer-routing'
26
- import type { IncomingStreamData, Registrar } from '@libp2p/interface-registrar'
27
- import type { TransportManager } from '@libp2p/interface-transport'
28
- import type { Startable } from '@libp2p/interfaces/startable'
41
+ import type { Connection } from '@libp2p/interface/connection'
42
+ import type { PeerId } from '@libp2p/interface/peer-id'
43
+ import type { PeerInfo } from '@libp2p/interface/peer-info'
44
+ import type { PeerRouting } from '@libp2p/interface/peer-routing'
45
+ import type { Startable } from '@libp2p/interface/startable'
46
+ import type { AddressManager } from '@libp2p/interface-internal/address-manager'
47
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
48
+ import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal/registrar'
49
+ import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
29
50
 
30
51
  const log = logger('libp2p:autonat')
31
52
 
@@ -258,7 +279,7 @@ class DefaultAutoNATService implements Startable {
258
279
  .filter(ma => {
259
280
  const isFromSameHost = ma.toOptions().host === data.connection.remoteAddr.toOptions().host
260
281
 
261
- log.trace('request to dial %s was sent from %s is same host %s', ma, data.connection.remoteAddr, isFromSameHost)
282
+ log.trace('request to dial %a was sent from %a is same host %s', ma, data.connection.remoteAddr, isFromSameHost)
262
283
  // skip any Multiaddrs where the target node's IP does not match the sending node's IP
263
284
  return isFromSameHost
264
285
  })
@@ -281,7 +302,7 @@ class DefaultAutoNATService implements Startable {
281
302
  .filter(ma => {
282
303
  const isSupportedTransport = Boolean(self.components.transportManager.transportForMultiaddr(ma))
283
304
 
284
- log.trace('transport for %s is supported %s', ma, isSupportedTransport)
305
+ log.trace('transport for %a is supported %s', ma, isSupportedTransport)
285
306
  // skip any Multiaddrs that have transports we do not support
286
307
  return isSupportedTransport
287
308
  })
@@ -324,7 +345,7 @@ class DefaultAutoNATService implements Startable {
324
345
  })
325
346
 
326
347
  if (!connection.remoteAddr.equals(multiaddr)) {
327
- log.error('tried to dial %s but dialed %s', multiaddr, connection.remoteAddr)
348
+ log.error('tried to dial %a but dialed %a', multiaddr, connection.remoteAddr)
328
349
  throw new Error('Unexpected remote address')
329
350
  }
330
351
 
@@ -1,5 +1,41 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * The `circuitRelayTransport` allows libp2p to dial and listen on [Circuit Relay](https://docs.libp2p.io/concepts/nat/circuit-relay/)
5
+ * addresses.
6
+ *
7
+ * @example
8
+ *
9
+ * ```typescript
10
+ * import { createLibp2p } from 'libp2p'
11
+ * import { circuitRelayTransport } from 'libp2p/circuit-relay'
12
+ *
13
+ * const node = await createLibp2p({
14
+ * transports: [
15
+ * circuitRelayTransport()
16
+ * ]
17
+ * })
18
+ * ```
19
+ *
20
+ * The `circuitRelayServer` function allows libp2p to function as a [Circuit Relay](https://docs.libp2p.io/concepts/nat/circuit-relay/)
21
+ * server. This will not work in browsers.
22
+ *
23
+ * @example
24
+ *
25
+ * ```typescript
26
+ * import { createLibp2p } from 'libp2p'
27
+ * import { circuitRelayServer } from 'libp2p/circuit-relay'
28
+ *
29
+ * const node = await createLibp2p({
30
+ * services: [
31
+ * circuitRelay: circuitRelayServer()
32
+ * ]
33
+ * })
34
+ * ```
35
+ */
36
+
1
37
  import type { Limit } from './pb/index.js'
2
- import type { EventEmitter } from '@libp2p/interfaces/events'
38
+ import type { EventEmitter } from '@libp2p/interface/events'
3
39
  import type { PeerMap } from '@libp2p/peer-collections'
4
40
  import type { Multiaddr } from '@multiformats/multiaddr'
5
41
 
@@ -1,4 +1,4 @@
1
- import { EventEmitter } from '@libp2p/interfaces/events'
1
+ import { EventEmitter } from '@libp2p/interface/events'
2
2
  import { logger } from '@libp2p/logger'
3
3
  import pRetry from 'p-retry'
4
4
  import { codes } from '../../errors.js'
@@ -7,8 +7,8 @@ import {
7
7
  RELAY_RENDEZVOUS_NS
8
8
  } from '../constants.js'
9
9
  import { namespaceToCid } from '../utils.js'
10
- import type { ContentRouting } from '@libp2p/interface-content-routing'
11
- import type { Startable } from '@libp2p/interfaces/startable'
10
+ import type { ContentRouting } from '@libp2p/interface/content-routing'
11
+ import type { Startable } from '@libp2p/interface/startable'
12
12
 
13
13
  const log = logger('libp2p:circuit-relay:advert-service')
14
14
 
@@ -1,17 +1,18 @@
1
1
  import { setMaxListeners } from 'events'
2
- import { EventEmitter } from '@libp2p/interfaces/events'
2
+ import { EventEmitter } from '@libp2p/interface/events'
3
3
  import { logger } from '@libp2p/logger'
4
4
  import { peerIdFromBytes } from '@libp2p/peer-id'
5
5
  import { RecordEnvelope } from '@libp2p/peer-record'
6
6
  import { type Multiaddr, multiaddr } from '@multiformats/multiaddr'
7
- import { pbStream, type ProtobufStream } from 'it-pb-stream'
7
+ import { pbStream, type ProtobufStream } from 'it-protobuf-stream'
8
8
  import pDefer from 'p-defer'
9
9
  import { MAX_CONNECTIONS } from '../../connection-manager/constants.js'
10
10
  import {
11
11
  CIRCUIT_PROTO_CODE,
12
12
  DEFAULT_HOP_TIMEOUT,
13
- RELAY_SOURCE_TAG
14
- , RELAY_V2_HOP_CODEC, RELAY_V2_STOP_CODEC
13
+ RELAY_SOURCE_TAG,
14
+ RELAY_V2_HOP_CODEC,
15
+ RELAY_V2_STOP_CODEC
15
16
  } from '../constants.js'
16
17
  import { HopMessage, type Reservation, Status, StopMessage } from '../pb/index.js'
17
18
  import { createLimitedRelay } from '../utils.js'
@@ -19,14 +20,14 @@ import { AdvertService, type AdvertServiceComponents, type AdvertServiceInit } f
19
20
  import { ReservationStore, type ReservationStoreInit } from './reservation-store.js'
20
21
  import { ReservationVoucherRecord } from './reservation-voucher.js'
21
22
  import type { CircuitRelayService, RelayReservation } from '../index.js'
22
- import type { AddressManager } from '@libp2p/interface-address-manager'
23
- import type { Connection, Stream } from '@libp2p/interface-connection'
24
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
25
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
26
- import type { PeerId } from '@libp2p/interface-peer-id'
27
- import type { PeerStore } from '@libp2p/interface-peer-store'
28
- import type { IncomingStreamData, Registrar } from '@libp2p/interface-registrar'
29
- import type { Startable } from '@libp2p/interfaces/startable'
23
+ import type { Connection, Stream } from '@libp2p/interface/connection'
24
+ import type { ConnectionGater } from '@libp2p/interface/connection-gater'
25
+ import type { PeerId } from '@libp2p/interface/peer-id'
26
+ import type { 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'
30
31
  import type { PeerMap } from '@libp2p/peer-collections'
31
32
 
32
33
  const log = logger('libp2p:circuit-relay:server')
@@ -172,7 +173,8 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
172
173
  })
173
174
  }, {
174
175
  maxInboundStreams: this.maxInboundHopStreams,
175
- maxOutboundStreams: this.maxOutboundHopStreams
176
+ maxOutboundStreams: this.maxOutboundHopStreams,
177
+ runOnTransientConnection: true
176
178
  })
177
179
 
178
180
  this.reservationStore.start()
@@ -193,7 +195,7 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
193
195
  }
194
196
 
195
197
  async onHop ({ connection, stream }: IncomingStreamData): Promise<void> {
196
- log('received circuit v2 hop protocol stream from %s', connection.remotePeer)
198
+ log('received circuit v2 hop protocol stream from %p', connection.remotePeer)
197
199
 
198
200
  const hopTimeoutPromise = pDefer<HopMessage>()
199
201
  const timeout = setTimeout(() => {
@@ -223,7 +225,7 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
223
225
  ])
224
226
  } catch (err: any) {
225
227
  log.error('error while handling hop', err)
226
- pbstr.pb(HopMessage).write({
228
+ await pbstr.pb(HopMessage).write({
227
229
  type: HopMessage.Type.STATUS,
228
230
  status: Status.MALFORMED_MESSAGE
229
231
  })
@@ -239,32 +241,32 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
239
241
  case HopMessage.Type.RESERVE: await this.handleReserve({ stream, request, connection }); break
240
242
  case HopMessage.Type.CONNECT: await this.handleConnect({ stream, request, connection }); break
241
243
  default: {
242
- log.error('invalid hop request type %s via peer %s', request.type, connection.remotePeer)
243
- stream.pb(HopMessage).write({ type: HopMessage.Type.STATUS, status: Status.UNEXPECTED_MESSAGE })
244
+ log.error('invalid hop request type %s via peer %p', request.type, connection.remotePeer)
245
+ await stream.pb(HopMessage).write({ type: HopMessage.Type.STATUS, status: Status.UNEXPECTED_MESSAGE })
244
246
  }
245
247
  }
246
248
  }
247
249
 
248
250
  async handleReserve ({ stream, request, connection }: HopProtocolOptions): Promise<void> {
249
251
  const hopstr = stream.pb(HopMessage)
250
- log('hop reserve request from %s', connection.remotePeer)
252
+ log('hop reserve request from %p', connection.remotePeer)
251
253
 
252
254
  if (isRelayAddr(connection.remoteAddr)) {
253
255
  log.error('relay reservation over circuit connection denied for peer: %p', connection.remotePeer)
254
- hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED })
256
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED })
255
257
  return
256
258
  }
257
259
 
258
260
  if ((await this.connectionGater.denyInboundRelayReservation?.(connection.remotePeer)) === true) {
259
261
  log.error('reservation for %p denied by connection gater', connection.remotePeer)
260
- hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED })
262
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED })
261
263
  return
262
264
  }
263
265
 
264
266
  const result = this.reservationStore.reserve(connection.remotePeer, connection.remoteAddr)
265
267
 
266
268
  if (result.status !== Status.OK) {
267
- hopstr.write({ type: HopMessage.Type.STATUS, status: result.status })
269
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: result.status })
268
270
  return
269
271
  }
270
272
 
@@ -280,7 +282,7 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
280
282
  })
281
283
  }
282
284
 
283
- hopstr.write({
285
+ await hopstr.write({
284
286
  type: HopMessage.Type.STATUS,
285
287
  status: Status.OK,
286
288
  reservation: await this.makeReservation(connection.remotePeer, BigInt(result.expire ?? 0)),
@@ -325,11 +327,11 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
325
327
 
326
328
  if (isRelayAddr(connection.remoteAddr)) {
327
329
  log.error('relay reservation over circuit connection denied for peer: %p', connection.remotePeer)
328
- hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED })
330
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED })
329
331
  return
330
332
  }
331
333
 
332
- log('hop connect request from %s', connection.remotePeer)
334
+ log('hop connect request from %p', connection.remotePeer)
333
335
 
334
336
  let dstPeer: PeerId
335
337
 
@@ -343,19 +345,19 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
343
345
  dstPeer = peerIdFromBytes(request.peer.id)
344
346
  } catch (err) {
345
347
  log.error('invalid hop connect request via peer %p %s', connection.remotePeer, err)
346
- hopstr.write({ type: HopMessage.Type.STATUS, status: Status.MALFORMED_MESSAGE })
348
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.MALFORMED_MESSAGE })
347
349
  return
348
350
  }
349
351
 
350
352
  if (!this.reservationStore.hasReservation(dstPeer)) {
351
353
  log.error('hop connect denied for destination peer %p not having a reservation for %p with status %s', dstPeer, connection.remotePeer, Status.NO_RESERVATION)
352
- hopstr.write({ type: HopMessage.Type.STATUS, status: Status.NO_RESERVATION })
354
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.NO_RESERVATION })
353
355
  return
354
356
  }
355
357
 
356
358
  if ((await this.connectionGater.denyOutboundRelayedConnection?.(connection.remotePeer, dstPeer)) === true) {
357
359
  log.error('hop connect for %p to %p denied by connection gater', connection.remotePeer, dstPeer)
358
- hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED })
360
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED })
359
361
  return
360
362
  }
361
363
 
@@ -363,7 +365,7 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
363
365
 
364
366
  if (connections.length === 0) {
365
367
  log('hop connect denied for destination peer %p not having a connection for %p as there is no destination connection', dstPeer, connection.remotePeer)
366
- hopstr.write({ type: HopMessage.Type.STATUS, status: Status.NO_RESERVATION })
368
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.NO_RESERVATION })
367
369
  return
368
370
  }
369
371
 
@@ -381,12 +383,12 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
381
383
  })
382
384
 
383
385
  if (destinationStream == null) {
384
- log.error('failed to open stream to destination peer %s', destinationConnection?.remotePeer)
385
- hopstr.write({ type: HopMessage.Type.STATUS, status: Status.CONNECTION_FAILED })
386
+ log.error('failed to open stream to destination peer %p', destinationConnection?.remotePeer)
387
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.CONNECTION_FAILED })
386
388
  return
387
389
  }
388
390
 
389
- hopstr.write({ type: HopMessage.Type.STATUS, status: Status.OK })
391
+ await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.OK })
390
392
  const sourceStream = stream.unwrap()
391
393
 
392
394
  log('connection from %p to %p established - merging streans', connection.remotePeer, dstPeer)
@@ -404,32 +406,33 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
404
406
  }: StopOptions): Promise<Stream | undefined> {
405
407
  log('starting circuit relay v2 stop request to %s', connection.remotePeer)
406
408
  const stream = await connection.newStream([RELAY_V2_STOP_CODEC], {
407
- maxOutboundStreams: this.maxOutboundStopStreams
409
+ maxOutboundStreams: this.maxOutboundStopStreams,
410
+ runOnTransientConnection: true
408
411
  })
409
412
  const pbstr = pbStream(stream)
410
413
  const stopstr = pbstr.pb(StopMessage)
411
- stopstr.write(request)
414
+ await stopstr.write(request)
412
415
  let response
413
416
 
414
417
  try {
415
418
  response = await stopstr.read()
416
419
  } catch (err) {
417
- log.error('error parsing stop message response from %s', connection.remotePeer)
420
+ log.error('error parsing stop message response from %p', connection.remotePeer)
418
421
  }
419
422
 
420
423
  if (response == null) {
421
- log.error('could not read response from %s', connection.remotePeer)
422
- stream.close()
424
+ log.error('could not read response from %p', connection.remotePeer)
425
+ await stream.close()
423
426
  return
424
427
  }
425
428
 
426
429
  if (response.status === Status.OK) {
427
- log('stop request to %s was successful', connection.remotePeer)
430
+ log('stop request to %p was successful', connection.remotePeer)
428
431
  return pbstr.unwrap()
429
432
  }
430
433
 
431
434
  log('stop request failed with code %d', response.status)
432
- stream.close()
435
+ await stream.close()
433
436
  }
434
437
 
435
438
  get reservations (): PeerMap<RelayReservation> {
@@ -2,9 +2,9 @@ import { PeerMap } from '@libp2p/peer-collections'
2
2
  import { DEFAULT_DATA_LIMIT, DEFAULT_DURATION_LIMIT, DEFAULT_MAX_RESERVATION_CLEAR_INTERVAL, DEFAULT_MAX_RESERVATION_STORE_SIZE, DEFAULT_MAX_RESERVATION_TTL } from '../constants.js'
3
3
  import { type Limit, Status } from '../pb/index.js'
4
4
  import type { RelayReservation } from '../index.js'
5
- import type { PeerId } from '@libp2p/interface-peer-id'
6
- import type { RecursivePartial } from '@libp2p/interfaces'
7
- import type { Startable } from '@libp2p/interfaces/startable'
5
+ import type { RecursivePartial } from '@libp2p/interface'
6
+ import type { PeerId } from '@libp2p/interface/peer-id'
7
+ import type { Startable } from '@libp2p/interface/startable'
8
8
  import type { Multiaddr } from '@multiformats/multiaddr'
9
9
 
10
10
  export type ReservationStatus = Status.OK | Status.PERMISSION_DENIED | Status.RESERVATION_REFUSED
@@ -1,6 +1,6 @@
1
1
  import { ReservationVoucher } from '../pb/index.js'
2
- import type { PeerId } from '@libp2p/interface-peer-id'
3
- import type { Record } from '@libp2p/interface-record'
2
+ import type { PeerId } from '@libp2p/interface/peer-id'
3
+ import type { Record } from '@libp2p/interface/record'
4
4
 
5
5
  export interface ReservationVoucherOptions {
6
6
  relay: PeerId
@@ -1,18 +1,17 @@
1
- import { EventEmitter } from '@libp2p/interfaces/events'
1
+ import { EventEmitter } from '@libp2p/interface/events'
2
2
  import { logger } from '@libp2p/logger'
3
- import { createTopology } from '@libp2p/topology'
4
3
  import {
5
4
  RELAY_RENDEZVOUS_NS,
6
5
  RELAY_V2_HOP_CODEC
7
6
  } from '../constants.js'
8
7
  import { namespaceToCid } from '../utils.js'
9
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
10
- import type { ContentRouting } from '@libp2p/interface-content-routing'
11
- import type { PeerId } from '@libp2p/interface-peer-id'
12
- import type { PeerStore } from '@libp2p/interface-peer-store'
13
- import type { Registrar } from '@libp2p/interface-registrar'
14
- import type { TransportManager } from '@libp2p/interface-transport'
15
- import type { Startable } from '@libp2p/interfaces/startable'
8
+ import type { ContentRouting } from '@libp2p/interface/content-routing'
9
+ import type { PeerId } from '@libp2p/interface/peer-id'
10
+ import type { PeerStore } from '@libp2p/interface/peer-store'
11
+ import type { Startable } from '@libp2p/interface/startable'
12
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
13
+ import type { Registrar } from '@libp2p/interface-internal/registrar'
14
+ import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
16
15
 
17
16
  const log = logger('libp2p:circuit-relay:discover-relays')
18
17
 
@@ -57,11 +56,11 @@ export class RelayDiscovery extends EventEmitter<RelayDiscoveryEvents> implement
57
56
  async start (): Promise<void> {
58
57
  // register a topology listener for when new peers are encountered
59
58
  // that support the hop protocol
60
- this.topologyId = await this.registrar.register(RELAY_V2_HOP_CODEC, createTopology({
59
+ this.topologyId = await this.registrar.register(RELAY_V2_HOP_CODEC, {
61
60
  onConnect: (peerId) => {
62
61
  this.safeDispatchEvent('relay:discover', { detail: peerId })
63
62
  }
64
- }))
63
+ })
65
64
 
66
65
  void this.discover()
67
66
  .catch(err => {
@@ -1,11 +1,11 @@
1
- import { symbol, type Upgrader, type Listener, type Transport, type CreateListenerOptions } from '@libp2p/interface-transport'
2
- import { CodeError } from '@libp2p/interfaces/errors'
1
+ import { CodeError } from '@libp2p/interface/errors'
2
+ import { symbol, type Transport, type CreateListenerOptions, type Listener, type Upgrader } from '@libp2p/interface/transport'
3
3
  import { logger } from '@libp2p/logger'
4
4
  import { peerIdFromBytes, peerIdFromString } from '@libp2p/peer-id'
5
5
  import { streamToMaConnection } from '@libp2p/utils/stream-to-ma-conn'
6
6
  import * as mafmt from '@multiformats/mafmt'
7
7
  import { multiaddr } from '@multiformats/multiaddr'
8
- import { pbStream } from 'it-pb-stream'
8
+ import { pbStream } from 'it-protobuf-stream'
9
9
  import { MAX_CONNECTIONS } from '../../connection-manager/constants.js'
10
10
  import { codes } from '../../errors.js'
11
11
  import { CIRCUIT_PROTO_CODE, RELAY_V2_HOP_CODEC, RELAY_V2_STOP_CODEC } from '../constants.js'
@@ -13,17 +13,16 @@ import { StopMessage, HopMessage, Status } from '../pb/index.js'
13
13
  import { RelayDiscovery, type RelayDiscoveryComponents } from './discovery.js'
14
14
  import { createListener } from './listener.js'
15
15
  import { type RelayStoreInit, ReservationStore } from './reservation-store.js'
16
- import type { AddressManager } from '@libp2p/interface-address-manager'
17
- import type { Connection, Stream } from '@libp2p/interface-connection'
18
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
19
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
20
- import type { ContentRouting } from '@libp2p/interface-content-routing'
21
- import type { Libp2pEvents } from '@libp2p/interface-libp2p'
22
- import type { PeerId } from '@libp2p/interface-peer-id'
23
- import type { PeerStore } from '@libp2p/interface-peer-store'
24
- import type { IncomingStreamData, Registrar } from '@libp2p/interface-registrar'
25
- import type { AbortOptions } from '@libp2p/interfaces'
26
- import type { EventEmitter } from '@libp2p/interfaces/events'
16
+ import type { Libp2pEvents, AbortOptions } from '@libp2p/interface'
17
+ import type { Connection, Stream } from '@libp2p/interface/connection'
18
+ import type { ConnectionGater } from '@libp2p/interface/connection-gater'
19
+ import type { ContentRouting } from '@libp2p/interface/content-routing'
20
+ import type { EventEmitter } from '@libp2p/interface/events'
21
+ import type { PeerId } from '@libp2p/interface/peer-id'
22
+ import type { PeerStore } from '@libp2p/interface/peer-store'
23
+ import type { AddressManager } from '@libp2p/interface-internal/address-manager'
24
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
25
+ import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal/registrar'
27
26
  import type { Multiaddr } from '@multiformats/multiaddr'
28
27
 
29
28
  const log = logger('libp2p:circuit-relay:transport')
@@ -86,11 +85,25 @@ export interface CircuitRelayTransportInit extends RelayStoreInit {
86
85
  * should be set to the same value (default: 300)
87
86
  */
88
87
  maxOutboundStopStreams?: number
88
+
89
+ /**
90
+ * Incoming STOP requests (e.g. when a remote peer wants to dial us via a relay)
91
+ * must finish the initial protocol negotiation within this timeout in ms
92
+ * (default: 30000)
93
+ */
94
+ stopTimeout?: number
95
+
96
+ /**
97
+ * When creating a reservation it must complete within this number of ms
98
+ * (default: 10000)
99
+ */
100
+ reservationCompletionTimeout?: number
89
101
  }
90
102
 
91
103
  const defaults = {
92
104
  maxInboundStopStreams: MAX_CONNECTIONS,
93
- maxOutboundStopStreams: MAX_CONNECTIONS
105
+ maxOutboundStopStreams: MAX_CONNECTIONS,
106
+ stopTimeout: 30000
94
107
  }
95
108
 
96
109
  class CircuitRelayTransport implements Transport {
@@ -105,6 +118,7 @@ class CircuitRelayTransport implements Transport {
105
118
  private readonly reservationStore: ReservationStore
106
119
  private readonly maxInboundStopStreams: number
107
120
  private readonly maxOutboundStopStreams?: number
121
+ private readonly stopTimeout: number
108
122
  private started: boolean
109
123
 
110
124
  constructor (components: CircuitRelayTransportComponents, init: CircuitRelayTransportInit) {
@@ -117,6 +131,7 @@ class CircuitRelayTransport implements Transport {
117
131
  this.connectionGater = components.connectionGater
118
132
  this.maxInboundStopStreams = init.maxInboundStopStreams ?? defaults.maxInboundStopStreams
119
133
  this.maxOutboundStopStreams = init.maxOutboundStopStreams ?? defaults.maxOutboundStopStreams
134
+ this.stopTimeout = init.stopTimeout ?? defaults.stopTimeout
120
135
 
121
136
  if (init.discoverRelays != null && init.discoverRelays > 0) {
122
137
  this.discovery = new RelayDiscovery(components)
@@ -149,11 +164,13 @@ class CircuitRelayTransport implements Transport {
149
164
 
150
165
  await this.registrar.handle(RELAY_V2_STOP_CODEC, (data) => {
151
166
  void this.onStop(data).catch(err => {
152
- log.error(err)
167
+ log.error('error while handling STOP protocol', err)
168
+ data.stream.abort(err)
153
169
  })
154
170
  }, {
155
171
  maxInboundStreams: this.maxInboundStopStreams,
156
- maxOutboundStreams: this.maxOutboundStopStreams
172
+ maxOutboundStreams: this.maxOutboundStopStreams,
173
+ runOnTransientConnection: true
157
174
  })
158
175
 
159
176
  this.started = true
@@ -245,7 +262,7 @@ class CircuitRelayTransport implements Transport {
245
262
  try {
246
263
  const pbstr = pbStream(stream)
247
264
  const hopstr = pbstr.pb(HopMessage)
248
- hopstr.write({
265
+ await hopstr.write({
249
266
  type: HopMessage.Type.CONNECT,
250
267
  peer: {
251
268
  id: destinationPeer.toBytes(),
@@ -259,16 +276,16 @@ class CircuitRelayTransport implements Transport {
259
276
  throw new CodeError(`failed to connect via relay with status ${status?.status?.toString() ?? 'undefined'}`, codes.ERR_HOP_REQUEST_FAILED)
260
277
  }
261
278
 
262
- // TODO: do something with limit and transient connection
263
-
264
279
  const maConn = streamToMaConnection({
265
280
  stream: pbstr.unwrap(),
266
281
  remoteAddr: ma,
267
282
  localAddr: relayAddr.encapsulate(`/p2p-circuit/p2p/${this.peerId.toString()}`)
268
283
  })
269
284
 
270
- log('new outbound connection %s', maConn.remoteAddr)
271
- return await this.upgrader.upgradeOutbound(maConn)
285
+ log('new outbound transient connection %a', maConn.remoteAddr)
286
+ return await this.upgrader.upgradeOutbound(maConn, {
287
+ transient: true
288
+ })
272
289
  } catch (err) {
273
290
  log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${connection.remotePeer.toString()} failed`, err)
274
291
  disconnectOnFailure && await connection.close()
@@ -304,50 +321,71 @@ class CircuitRelayTransport implements Transport {
304
321
  * An incoming STOP request means a remote peer wants to dial us via a relay
305
322
  */
306
323
  async onStop ({ connection, stream }: IncomingStreamData): Promise<void> {
307
- const pbstr = pbStream(stream)
308
- const request = await pbstr.readPB(StopMessage)
309
- log('received circuit v2 stop protocol request from %s', connection.remotePeer)
324
+ const signal = AbortSignal.timeout(this.stopTimeout)
325
+ const pbstr = pbStream(stream).pb(StopMessage)
326
+ const request = await pbstr.read({
327
+ signal
328
+ })
329
+
330
+ log('new circuit relay v2 stop stream from %p with type %s', connection.remotePeer, request.type)
310
331
 
311
332
  if (request?.type === undefined) {
333
+ log.error('type was missing from circuit v2 stop protocol request from %s', connection.remotePeer)
334
+ await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.MALFORMED_MESSAGE }, {
335
+ signal
336
+ })
337
+ await stream.close()
312
338
  return
313
339
  }
314
340
 
315
- const stopstr = pbstr.pb(StopMessage)
316
- log('new circuit relay v2 stop stream from %s', connection.remotePeer)
317
-
318
341
  // Validate the STOP request has the required input
319
342
  if (request.type !== StopMessage.Type.CONNECT) {
320
- log.error('invalid stop connect request via peer %s', connection.remotePeer)
321
- stopstr.write({ type: StopMessage.Type.STATUS, status: Status.UNEXPECTED_MESSAGE })
343
+ log.error('invalid stop connect request via peer %p', connection.remotePeer)
344
+ await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.UNEXPECTED_MESSAGE }, {
345
+ signal
346
+ })
347
+ await stream.close()
322
348
  return
323
349
  }
324
350
 
325
351
  if (!isValidStop(request)) {
326
- log.error('invalid stop connect request via peer %s', connection.remotePeer)
327
- stopstr.write({ type: StopMessage.Type.STATUS, status: Status.MALFORMED_MESSAGE })
352
+ log.error('invalid stop connect request via peer %p', connection.remotePeer)
353
+ await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.MALFORMED_MESSAGE }, {
354
+ signal
355
+ })
356
+ await stream.close()
328
357
  return
329
358
  }
330
359
 
331
360
  const remotePeerId = peerIdFromBytes(request.peer.id)
332
361
 
333
362
  if ((await this.connectionGater.denyInboundRelayedConnection?.(connection.remotePeer, remotePeerId)) === true) {
334
- stopstr.write({ type: StopMessage.Type.STATUS, status: Status.PERMISSION_DENIED })
363
+ log.error('connection gater denied inbound relayed connection from %p', connection.remotePeer)
364
+ await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, {
365
+ signal
366
+ })
367
+ await stream.close()
335
368
  return
336
369
  }
337
370
 
338
- stopstr.write({ type: StopMessage.Type.STATUS, status: Status.OK })
371
+ log.trace('sending success response to %p', connection.remotePeer)
372
+ await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.OK }, {
373
+ signal
374
+ })
339
375
 
340
376
  const remoteAddr = connection.remoteAddr.encapsulate(`/p2p-circuit/p2p/${remotePeerId.toString()}`)
341
377
  const localAddr = this.addressManager.getAddresses()[0]
342
378
  const maConn = streamToMaConnection({
343
- stream: pbstr.unwrap(),
379
+ stream: pbstr.unwrap().unwrap(),
344
380
  remoteAddr,
345
381
  localAddr
346
382
  })
347
383
 
348
- log('new inbound connection %s', maConn.remoteAddr)
349
- await this.upgrader.upgradeInbound(maConn)
350
- log('%s connection %s upgraded', 'inbound', maConn.remoteAddr)
384
+ log('new inbound transient connection %a', maConn.remoteAddr)
385
+ await this.upgrader.upgradeInbound(maConn, {
386
+ transient: true
387
+ })
388
+ log('%s connection %a upgraded', 'inbound', maConn.remoteAddr)
351
389
  }
352
390
  }
353
391