@libp2p/circuit-relay-v2 3.2.23 → 3.2.24-8484de8a2

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 (52) hide show
  1. package/dist/index.min.js +1 -1
  2. package/dist/index.min.js.map +4 -4
  3. package/dist/src/constants.d.ts +0 -4
  4. package/dist/src/constants.d.ts.map +1 -1
  5. package/dist/src/constants.js +0 -4
  6. package/dist/src/constants.js.map +1 -1
  7. package/dist/src/index.d.ts +170 -7
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +12 -2
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/server/index.d.ts +41 -45
  12. package/dist/src/server/index.d.ts.map +1 -1
  13. package/dist/src/server/index.js +30 -47
  14. package/dist/src/server/index.js.map +1 -1
  15. package/dist/src/server/reservation-store.d.ts +2 -36
  16. package/dist/src/server/reservation-store.d.ts.map +1 -1
  17. package/dist/src/server/reservation-store.js.map +1 -1
  18. package/dist/src/transport/discovery.d.ts +2 -17
  19. package/dist/src/transport/discovery.d.ts.map +1 -1
  20. package/dist/src/transport/discovery.js +2 -2
  21. package/dist/src/transport/discovery.js.map +1 -1
  22. package/dist/src/transport/index.d.ts +34 -42
  23. package/dist/src/transport/index.d.ts.map +1 -1
  24. package/dist/src/transport/index.js +291 -5
  25. package/dist/src/transport/index.js.map +1 -1
  26. package/dist/src/transport/reservation-store.d.ts +3 -37
  27. package/dist/src/transport/reservation-store.d.ts.map +1 -1
  28. package/dist/src/transport/reservation-store.js +4 -6
  29. package/dist/src/transport/reservation-store.js.map +1 -1
  30. package/dist/src/transport/stream-to-conn.d.ts +19 -0
  31. package/dist/src/transport/stream-to-conn.d.ts.map +1 -0
  32. package/dist/src/transport/stream-to-conn.js +60 -0
  33. package/dist/src/transport/stream-to-conn.js.map +1 -0
  34. package/dist/src/utils.d.ts.map +1 -1
  35. package/dist/src/utils.js +36 -59
  36. package/dist/src/utils.js.map +1 -1
  37. package/package.json +19 -24
  38. package/src/constants.ts +0 -5
  39. package/src/index.ts +207 -8
  40. package/src/server/index.ts +35 -100
  41. package/src/server/reservation-store.ts +2 -42
  42. package/src/transport/discovery.ts +4 -22
  43. package/src/transport/index.ts +338 -46
  44. package/src/transport/reservation-store.ts +8 -46
  45. package/src/transport/stream-to-conn.ts +91 -0
  46. package/src/utils.ts +37 -66
  47. package/dist/src/transport/transport.d.ts +0 -54
  48. package/dist/src/transport/transport.d.ts.map +0 -1
  49. package/dist/src/transport/transport.js +0 -314
  50. package/dist/src/transport/transport.js.map +0 -1
  51. package/dist/typedoc-urls.json +0 -23
  52. package/src/transport/transport.ts +0 -378
package/src/index.ts CHANGED
@@ -40,7 +40,11 @@
40
40
  */
41
41
 
42
42
  import { TypedEventEmitter } from 'main-event'
43
+ import { CircuitRelayServer } from './server/index.js'
44
+ import { CircuitRelayTransport } from './transport/index.ts'
43
45
  import type { Limit } from './pb/index.js'
46
+ import type { ComponentLogger, ConnectionGater, Libp2pEvents, Metrics, PeerId, PeerStore, PrivateKey, TopologyFilter, Transport, TypedEventTarget, Upgrader } from '@libp2p/interface'
47
+ import type { AddressManager, ConnectionManager, RandomWalk, Registrar, TransportManager } from '@libp2p/interface-internal'
44
48
  import type { PeerMap } from '@libp2p/peer-collections'
45
49
  import type { Multiaddr } from '@multiformats/multiaddr'
46
50
  import type { RetimeableAbortSignal } from 'retimeable-signal'
@@ -80,15 +84,210 @@ export interface CircuitRelayService extends TypedEventEmitter<CircuitRelayServi
80
84
  reservations: PeerMap<RelayReservation>
81
85
  }
82
86
 
83
- export { circuitRelayServer } from './server/index.js'
84
- export type { CircuitRelayServerInit, CircuitRelayServerComponents } from './server/index.js'
85
- export type { ReservationStoreInit as ServerReservationStoreInit } from './server/reservation-store.js'
86
- export { circuitRelayTransport } from './transport/index.js'
87
- export type { RelayDiscoveryComponents } from './transport/discovery.js'
88
- export type { ReservationStoreInit as TransportReservationStoreInit } from './transport/reservation-store.js'
89
- export type { CircuitRelayTransportInit, CircuitRelayTransportComponents } from './transport/index.js'
90
-
91
87
  export {
92
88
  RELAY_V2_HOP_CODEC,
93
89
  RELAY_V2_STOP_CODEC
94
90
  } from './constants.js'
91
+
92
+ export interface ServerReservationStoreInit {
93
+ /**
94
+ * maximum number of reservations allowed
95
+ *
96
+ * @default 15
97
+ */
98
+ maxReservations?: number
99
+
100
+ /**
101
+ * interval after which stale reservations are cleared
102
+ *
103
+ * @default 300000
104
+ */
105
+ reservationClearInterval?: number
106
+
107
+ /**
108
+ * apply default relay limits to a new reservation
109
+ *
110
+ * @default true
111
+ */
112
+ applyDefaultLimit?: boolean
113
+
114
+ /**
115
+ * reservation ttl
116
+ *
117
+ * @default 7200000
118
+ */
119
+ reservationTtl?: number
120
+
121
+ /**
122
+ * The maximum time a relayed connection can be open for
123
+ */
124
+ defaultDurationLimit?: number
125
+
126
+ /**
127
+ * The maximum amount of data allowed to be transferred over a relayed connection
128
+ */
129
+ defaultDataLimit?: bigint
130
+ }
131
+
132
+ export interface CircuitRelayServerComponents {
133
+ registrar: Registrar
134
+ peerStore: PeerStore
135
+ addressManager: AddressManager
136
+ peerId: PeerId
137
+ privateKey: PrivateKey
138
+ connectionManager: ConnectionManager
139
+ connectionGater: ConnectionGater
140
+ logger: ComponentLogger
141
+ metrics?: Metrics
142
+ }
143
+
144
+ export interface CircuitRelayServerInit {
145
+ /**
146
+ * Incoming hop requests must complete within this time in ms otherwise
147
+ * the stream will be reset
148
+ *
149
+ * @default 30000
150
+ */
151
+ hopTimeout?: number
152
+
153
+ /**
154
+ * Configuration of reservations
155
+ */
156
+ reservations?: ServerReservationStoreInit
157
+
158
+ /**
159
+ * The maximum number of simultaneous HOP inbound streams that can be open at once
160
+ */
161
+ maxInboundHopStreams?: number
162
+
163
+ /**
164
+ * The maximum number of simultaneous HOP outbound streams that can be open at once
165
+ */
166
+ maxOutboundHopStreams?: number
167
+
168
+ /**
169
+ * The maximum number of simultaneous STOP outbound streams that can be open at
170
+ * once.
171
+ *
172
+ * @default 300
173
+ */
174
+ maxOutboundStopStreams?: number
175
+ }
176
+
177
+ export function circuitRelayServer (init: CircuitRelayServerInit = {}): (components: CircuitRelayServerComponents) => CircuitRelayService {
178
+ return (components) => {
179
+ return new CircuitRelayServer(components, init)
180
+ }
181
+ }
182
+
183
+ export interface RelayDiscoveryEvents {
184
+ 'relay:discover': CustomEvent<PeerId>
185
+ }
186
+
187
+ export interface TransportReservationStoreComponents {
188
+ peerId: PeerId
189
+ connectionManager: ConnectionManager
190
+ peerStore: PeerStore
191
+ events: TypedEventTarget<Libp2pEvents>
192
+ logger: ComponentLogger
193
+ metrics?: Metrics
194
+ }
195
+
196
+ export interface TransportReservationStoreInit {
197
+ /**
198
+ * Multiple relays may be discovered simultaneously - to prevent listening
199
+ * on too many relays, this value controls how many to attempt to reserve a
200
+ * slot on at once. If set to more than one, we may end up listening on
201
+ * more relays than the `maxReservations` value, but on networks with poor
202
+ * connectivity the user may wish to attempt to reserve on multiple relays
203
+ * simultaneously.
204
+ *
205
+ * @default 1
206
+ */
207
+ reservationConcurrency?: number
208
+
209
+ /**
210
+ * Limit the number of potential relays we will dial
211
+ *
212
+ * @default 100
213
+ */
214
+ maxReservationQueueLength?: number
215
+
216
+ /**
217
+ * When creating a reservation it must complete within this number of ms
218
+ *
219
+ * @default 5000
220
+ */
221
+ reservationCompletionTimeout?: number
222
+ }
223
+
224
+ export interface RelayDiscoveryComponents {
225
+ peerStore: PeerStore
226
+ connectionManager: ConnectionManager
227
+ transportManager: TransportManager
228
+ registrar: Registrar
229
+ logger: ComponentLogger
230
+ randomWalk: RandomWalk
231
+ events: TypedEventTarget<Libp2pEvents>
232
+ }
233
+
234
+ export interface RelayDiscoveryInit {
235
+ filter?: TopologyFilter
236
+ }
237
+
238
+ export interface CircuitRelayTransportComponents extends RelayDiscoveryComponents {
239
+ peerId: PeerId
240
+ upgrader: Upgrader
241
+ addressManager: AddressManager
242
+ connectionGater: ConnectionGater
243
+ }
244
+
245
+ /**
246
+ * RelayConfig configures the circuit v2 relay transport.
247
+ */
248
+ export interface CircuitRelayTransportInit extends TransportReservationStoreInit {
249
+ /**
250
+ * An optional filter used to prevent duplicate attempts to reserve relay
251
+ * slots on the same peer
252
+ */
253
+ discoveryFilter?: TopologyFilter
254
+
255
+ /**
256
+ * The maximum number of simultaneous STOP inbound streams that can be open at
257
+ * once - each inbound relayed connection uses a STOP stream
258
+ *
259
+ * @default 300
260
+ */
261
+ maxInboundStopStreams?: number
262
+
263
+ /**
264
+ * The maximum number of simultaneous STOP outbound streams that can be open
265
+ * at once. If this transport is used along with the relay server these
266
+ * settings should be set to the same value
267
+ *
268
+ * @default 300
269
+ */
270
+ maxOutboundStopStreams?: number
271
+
272
+ /**
273
+ * Incoming STOP requests (e.g. when a remote peer wants to dial us via a
274
+ * relay) must finish the initial protocol negotiation within this timeout in
275
+ * ms
276
+ *
277
+ * @deprecated Configure `connectionManager.inboundUpgradeTimeout` instead
278
+ */
279
+ stopTimeout?: number
280
+
281
+ /**
282
+ * When creating a reservation it must complete within this number of ms
283
+ *
284
+ * @default 10_000
285
+ */
286
+ reservationCompletionTimeout?: number
287
+ }
288
+
289
+ export function circuitRelayTransport (init: CircuitRelayTransportInit = {}): (components: CircuitRelayTransportComponents) => Transport {
290
+ return (components) => {
291
+ return new CircuitRelayTransport(components, init)
292
+ }
293
+ }
@@ -1,12 +1,12 @@
1
1
  import { publicKeyToProtobuf } from '@libp2p/crypto/keys'
2
2
  import { peerIdFromMultihash } from '@libp2p/peer-id'
3
3
  import { RecordEnvelope } from '@libp2p/peer-record'
4
+ import { pbStream } from '@libp2p/utils'
4
5
  import { multiaddr } from '@multiformats/multiaddr'
5
- import { pbStream } from 'it-protobuf-stream'
6
+ import { Circuit } from '@multiformats/multiaddr-matcher'
6
7
  import { TypedEventEmitter, setMaxListeners } from 'main-event'
7
8
  import * as Digest from 'multiformats/hashes/digest'
8
9
  import {
9
- CIRCUIT_PROTO_CODE,
10
10
  DEFAULT_HOP_TIMEOUT,
11
11
  KEEP_ALIVE_SOURCE_TAG,
12
12
  MAX_CONNECTIONS,
@@ -18,49 +18,11 @@ import { HopMessage, Status, StopMessage } from '../pb/index.js'
18
18
  import { createLimitedRelay } from '../utils.js'
19
19
  import { ReservationStore } from './reservation-store.js'
20
20
  import { ReservationVoucherRecord } from './reservation-voucher.js'
21
- import type { ReservationStoreInit } from './reservation-store.js'
22
- import type { CircuitRelayService, RelayReservation } from '../index.js'
21
+ import type { CircuitRelayServerComponents, CircuitRelayServerInit, CircuitRelayService, RelayReservation } from '../index.js'
23
22
  import type { Reservation } from '../pb/index.js'
24
- import type { ComponentLogger, Logger, Connection, Stream, ConnectionGater, PeerId, PeerStore, Startable, PrivateKey, Metrics, AbortOptions, IncomingStreamData } from '@libp2p/interface'
25
- import type { AddressManager, ConnectionManager, Registrar } from '@libp2p/interface-internal'
23
+ import type { Logger, Connection, Stream, PeerId, Startable, AbortOptions } from '@libp2p/interface'
26
24
  import type { PeerMap } from '@libp2p/peer-collections'
27
- import type { Multiaddr } from '@multiformats/multiaddr'
28
- import type { ProtobufStream } from 'it-protobuf-stream'
29
-
30
- const isRelayAddr = (ma: Multiaddr): boolean => ma.protoCodes().includes(CIRCUIT_PROTO_CODE)
31
-
32
- export interface CircuitRelayServerInit {
33
- /**
34
- * Incoming hop requests must complete within this time in ms otherwise
35
- * the stream will be reset
36
- *
37
- * @default 30000
38
- */
39
- hopTimeout?: number
40
-
41
- /**
42
- * Configuration of reservations
43
- */
44
- reservations?: ReservationStoreInit
45
-
46
- /**
47
- * The maximum number of simultaneous HOP inbound streams that can be open at once
48
- */
49
- maxInboundHopStreams?: number
50
-
51
- /**
52
- * The maximum number of simultaneous HOP outbound streams that can be open at once
53
- */
54
- maxOutboundHopStreams?: number
55
-
56
- /**
57
- * The maximum number of simultaneous STOP outbound streams that can be open at
58
- * once.
59
- *
60
- * @default 300
61
- */
62
- maxOutboundStopStreams?: number
63
- }
25
+ import type { ProtobufStream } from '@libp2p/utils'
64
26
 
65
27
  export interface HopProtocolOptions {
66
28
  connection: Connection
@@ -73,18 +35,6 @@ export interface StopOptions {
73
35
  request: StopMessage
74
36
  }
75
37
 
76
- export interface CircuitRelayServerComponents {
77
- registrar: Registrar
78
- peerStore: PeerStore
79
- addressManager: AddressManager
80
- peerId: PeerId
81
- privateKey: PrivateKey
82
- connectionManager: ConnectionManager
83
- connectionGater: ConnectionGater
84
- logger: ComponentLogger
85
- metrics?: Metrics
86
- }
87
-
88
38
  export interface RelayServerEvents {
89
39
  'relay:reservation': CustomEvent<RelayReservation>
90
40
  'relay:advert:success': CustomEvent<unknown>
@@ -95,14 +45,8 @@ const defaults = {
95
45
  maxOutboundStopStreams: MAX_CONNECTIONS
96
46
  }
97
47
 
98
- class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements Startable, CircuitRelayService {
99
- private readonly registrar: Registrar
100
- private readonly peerStore: PeerStore
101
- private readonly addressManager: AddressManager
102
- private readonly peerId: PeerId
103
- private readonly privateKey: PrivateKey
104
- private readonly connectionManager: ConnectionManager
105
- private readonly connectionGater: ConnectionGater
48
+ export class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements Startable, CircuitRelayService {
49
+ private readonly components: CircuitRelayServerComponents
106
50
  private readonly reservationStore: ReservationStore
107
51
  private started: boolean
108
52
  private readonly hopTimeout: number
@@ -119,13 +63,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
119
63
  super()
120
64
 
121
65
  this.log = components.logger.forComponent('libp2p:circuit-relay:server')
122
- this.registrar = components.registrar
123
- this.peerStore = components.peerStore
124
- this.addressManager = components.addressManager
125
- this.peerId = components.peerId
126
- this.privateKey = components.privateKey
127
- this.connectionManager = components.connectionManager
128
- this.connectionGater = components.connectionGater
66
+ this.components = components
129
67
  this.started = false
130
68
  this.hopTimeout = init?.hopTimeout ?? DEFAULT_HOP_TIMEOUT
131
69
  this.maxInboundHopStreams = init.maxInboundHopStreams
@@ -135,6 +73,8 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
135
73
 
136
74
  this.shutdownController = new AbortController()
137
75
  setMaxListeners(Infinity, this.shutdownController.signal)
76
+
77
+ this.onHop = this.onHop.bind(this)
138
78
  }
139
79
 
140
80
  readonly [Symbol.toStringTag] = '@libp2p/circuit-relay-v2-server'
@@ -151,11 +91,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
151
91
  return
152
92
  }
153
93
 
154
- await this.registrar.handle(RELAY_V2_HOP_CODEC, (data) => {
155
- void this.onHop(data).catch(err => {
156
- this.log.error(err)
157
- })
158
- }, {
94
+ await this.components.registrar.handle(RELAY_V2_HOP_CODEC, this.onHop, {
159
95
  maxInboundStreams: this.maxInboundHopStreams,
160
96
  maxOutboundStreams: this.maxOutboundHopStreams,
161
97
  runOnLimitedConnection: true
@@ -170,16 +106,19 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
170
106
  async stop (): Promise<void> {
171
107
  this.reservationStore.clear()
172
108
  this.shutdownController.abort()
173
- await this.registrar.unhandle(RELAY_V2_HOP_CODEC)
109
+ await this.components.registrar.unhandle(RELAY_V2_HOP_CODEC)
174
110
 
175
111
  this.started = false
176
112
  }
177
113
 
178
- async onHop ({ connection, stream }: IncomingStreamData): Promise<void> {
114
+ async onHop (stream: Stream, connection: Connection): Promise<void> {
179
115
  this.log('received circuit v2 hop protocol stream from %p', connection.remotePeer)
180
116
 
117
+ const signal = AbortSignal.timeout(this.hopTimeout)
118
+ setMaxListeners(Infinity, signal)
119
+
181
120
  const options = {
182
- signal: AbortSignal.timeout(this.hopTimeout)
121
+ signal
183
122
  }
184
123
  const pbstr = pbStream(stream)
185
124
 
@@ -223,13 +162,13 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
223
162
  const hopstr = stream.pb(HopMessage)
224
163
  this.log('hop reserve request from %p', connection.remotePeer)
225
164
 
226
- if (isRelayAddr(connection.remoteAddr)) {
165
+ if (Circuit.exactMatch(connection.remoteAddr)) {
227
166
  this.log.error('relay reservation over circuit connection denied for peer: %p', connection.remotePeer)
228
167
  await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, options)
229
168
  return
230
169
  }
231
170
 
232
- if ((await this.connectionGater.denyInboundRelayReservation?.(connection.remotePeer)) === true) {
171
+ if ((await this.components.connectionGater.denyInboundRelayReservation?.(connection.remotePeer)) === true) {
233
172
  this.log.error('reservation for %p denied by connection gater', connection.remotePeer)
234
173
  await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, options)
235
174
  return
@@ -247,12 +186,12 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
247
186
  // result.expire is non-null if `ReservationStore.reserve` returns with status == OK
248
187
  if (result.expire != null) {
249
188
  const ttl = (result.expire * 1000) - Date.now()
250
- await this.peerStore.merge(connection.remotePeer, {
189
+ await this.components.peerStore.merge(connection.remotePeer, {
251
190
  tags: {
252
191
  [RELAY_SOURCE_TAG]: { value: 1, ttl },
253
192
  [KEEP_ALIVE_SOURCE_TAG]: { value: 1, ttl }
254
193
  }
255
- })
194
+ }, options)
256
195
  }
257
196
 
258
197
  await hopstr.write({
@@ -262,17 +201,20 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
262
201
  limit: this.reservationStore.get(connection.remotePeer)?.limit
263
202
  }, options)
264
203
  this.log('sent confirmation response to %s', connection.remotePeer)
204
+
205
+ // close writable end of stream
206
+ await hopstr.unwrap().unwrap().close(options)
265
207
  } catch (err) {
266
208
  this.log.error('failed to send confirmation response to %p - %e', connection.remotePeer, err)
267
209
  this.reservationStore.removeReservation(connection.remotePeer)
268
210
 
269
211
  try {
270
- await this.peerStore.merge(connection.remotePeer, {
212
+ await this.components.peerStore.merge(connection.remotePeer, {
271
213
  tags: {
272
214
  [RELAY_SOURCE_TAG]: undefined,
273
215
  [KEEP_ALIVE_SOURCE_TAG]: undefined
274
216
  }
275
- })
217
+ }, options)
276
218
  } catch (err) {
277
219
  this.log.error('failed to untag relay source peer %p - %e', connection.remotePeer, err)
278
220
  }
@@ -285,7 +227,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
285
227
  ): Promise<Reservation> {
286
228
  const addrs = []
287
229
 
288
- for (const relayAddr of this.addressManager.getAddresses()) {
230
+ for (const relayAddr of this.components.addressManager.getAddresses()) {
289
231
  if (relayAddr.toString().includes('/p2p-circuit')) {
290
232
  continue
291
233
  }
@@ -295,9 +237,9 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
295
237
 
296
238
  const envelope = await RecordEnvelope.seal(new ReservationVoucherRecord({
297
239
  peer: remotePeer,
298
- relay: this.peerId,
240
+ relay: this.components.peerId,
299
241
  expiration: expire
300
- }), this.privateKey)
242
+ }), this.components.privateKey)
301
243
 
302
244
  return {
303
245
  addrs,
@@ -307,7 +249,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
307
249
  payloadType: envelope.payloadType,
308
250
  payload: {
309
251
  peer: remotePeer.toMultihash().bytes,
310
- relay: this.peerId.toMultihash().bytes,
252
+ relay: this.components.peerId.toMultihash().bytes,
311
253
  expiration: expire
312
254
  },
313
255
  signature: envelope.signature
@@ -318,7 +260,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
318
260
  async handleConnect ({ stream, request, connection }: HopProtocolOptions, options: AbortOptions): Promise<void> {
319
261
  const hopstr = stream.pb(HopMessage)
320
262
 
321
- if (isRelayAddr(connection.remoteAddr)) {
263
+ if (Circuit.matches(connection.remoteAddr)) {
322
264
  this.log.error('relay reservation over circuit connection denied for peer: %p', connection.remotePeer)
323
265
  await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, options)
324
266
  return
@@ -350,13 +292,13 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
350
292
  return
351
293
  }
352
294
 
353
- if ((await this.connectionGater.denyOutboundRelayedConnection?.(connection.remotePeer, dstPeer)) === true) {
295
+ if ((await this.components.connectionGater.denyOutboundRelayedConnection?.(connection.remotePeer, dstPeer)) === true) {
354
296
  this.log.error('hop connect for %p to %p denied by connection gater', connection.remotePeer, dstPeer)
355
297
  await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, options)
356
298
  return
357
299
  }
358
300
 
359
- const connections = this.connectionManager.getConnections(dstPeer)
301
+ const connections = this.components.connectionManager.getConnections(dstPeer)
360
302
 
361
303
  if (connections.length === 0) {
362
304
  this.log('hop connect denied for destination peer %p not having a connection for %p as there is no destination connection', dstPeer, connection.remotePeer)
@@ -389,12 +331,11 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
389
331
  status: Status.OK,
390
332
  limit: reservation?.limit
391
333
  }, options)
392
- const sourceStream = stream.unwrap()
393
334
 
394
335
  this.log('connection from %p to %p established - merging streams', connection.remotePeer, dstPeer)
395
336
 
396
337
  // Short circuit the two streams to create the relayed connection
397
- createLimitedRelay(sourceStream, destinationStream, this.shutdownController.signal, reservation, {
338
+ createLimitedRelay(stream.unwrap(), destinationStream, this.shutdownController.signal, reservation, {
398
339
  log: this.log
399
340
  })
400
341
  }
@@ -404,7 +345,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
404
345
  */
405
346
  async stopHop ({ connection, request }: StopOptions, options: AbortOptions): Promise<Stream | undefined> {
406
347
  this.log('starting circuit relay v2 stop request to %s', connection.remotePeer)
407
- const stream = await connection.newStream([RELAY_V2_STOP_CODEC], {
348
+ const stream = await connection.newStream(RELAY_V2_STOP_CODEC, {
408
349
  maxOutboundStreams: this.maxOutboundStopStreams,
409
350
  runOnLimitedConnection: true,
410
351
  ...options
@@ -439,9 +380,3 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
439
380
  return this.reservationStore.reservations
440
381
  }
441
382
  }
442
-
443
- export function circuitRelayServer (init: CircuitRelayServerInit = {}): (components: CircuitRelayServerComponents) => CircuitRelayService {
444
- return (components) => {
445
- return new CircuitRelayServer(components, init)
446
- }
447
- }
@@ -2,7 +2,7 @@ import { trackedPeerMap } from '@libp2p/peer-collections'
2
2
  import { retimeableSignal } from 'retimeable-signal'
3
3
  import { DEFAULT_DATA_LIMIT, DEFAULT_DURATION_LIMIT, DEFAULT_MAX_RESERVATION_STORE_SIZE, DEFAULT_MAX_RESERVATION_TTL } from '../constants.js'
4
4
  import { Status } from '../pb/index.js'
5
- import type { RelayReservation } from '../index.js'
5
+ import type { RelayReservation, ServerReservationStoreInit } from '../index.js'
6
6
  import type { Limit } from '../pb/index.js'
7
7
  import type { ComponentLogger, Logger, Metrics, PeerId } from '@libp2p/interface'
8
8
  import type { PeerMap } from '@libp2p/peer-collections'
@@ -15,46 +15,6 @@ export interface ReservationStoreComponents {
15
15
  metrics?: Metrics
16
16
  }
17
17
 
18
- export interface ReservationStoreInit {
19
- /**
20
- * maximum number of reservations allowed
21
- *
22
- * @default 15
23
- */
24
- maxReservations?: number
25
-
26
- /**
27
- * interval after which stale reservations are cleared
28
- *
29
- * @default 300000
30
- */
31
- reservationClearInterval?: number
32
-
33
- /**
34
- * apply default relay limits to a new reservation
35
- *
36
- * @default true
37
- */
38
- applyDefaultLimit?: boolean
39
-
40
- /**
41
- * reservation ttl
42
- *
43
- * @default 7200000
44
- */
45
- reservationTtl?: number
46
-
47
- /**
48
- * The maximum time a relayed connection can be open for
49
- */
50
- defaultDurationLimit?: number
51
-
52
- /**
53
- * The maximum amount of data allowed to be transferred over a relayed connection
54
- */
55
- defaultDataLimit?: bigint
56
- }
57
-
58
18
  export class ReservationStore {
59
19
  public readonly reservations: PeerMap<RelayReservation>
60
20
  private readonly maxReservations: number
@@ -64,7 +24,7 @@ export class ReservationStore {
64
24
  private readonly defaultDataLimit: bigint
65
25
  private readonly log: Logger
66
26
 
67
- constructor (components: ReservationStoreComponents, init: ReservationStoreInit = {}) {
27
+ constructor (components: ReservationStoreComponents, init: ServerReservationStoreInit = {}) {
68
28
  this.log = components.logger.forComponent('libp2p:circuit-relay:server:reservation-store')
69
29
  this.maxReservations = init.maxReservations ?? DEFAULT_MAX_RESERVATION_STORE_SIZE
70
30
  this.applyDefaultLimit = init.applyDefaultLimit !== false
@@ -1,30 +1,12 @@
1
- import { PeerQueue } from '@libp2p/utils/peer-queue'
1
+ import { PeerQueue } from '@libp2p/utils'
2
2
  import { anySignal } from 'any-signal'
3
3
  import { TypedEventEmitter, setMaxListeners } from 'main-event'
4
4
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
5
5
  import {
6
6
  RELAY_V2_HOP_CODEC
7
7
  } from '../constants.js'
8
- import type { ComponentLogger, Libp2pEvents, Logger, Peer, PeerId, PeerInfo, PeerStore, Startable, TopologyFilter, TypedEventTarget } from '@libp2p/interface'
9
- import type { ConnectionManager, RandomWalk, Registrar, TransportManager } from '@libp2p/interface-internal'
10
-
11
- export interface RelayDiscoveryEvents {
12
- 'relay:discover': CustomEvent<PeerId>
13
- }
14
-
15
- export interface RelayDiscoveryComponents {
16
- peerStore: PeerStore
17
- connectionManager: ConnectionManager
18
- transportManager: TransportManager
19
- registrar: Registrar
20
- logger: ComponentLogger
21
- randomWalk: RandomWalk
22
- events: TypedEventTarget<Libp2pEvents>
23
- }
24
-
25
- export interface RelayDiscoveryInit {
26
- filter?: TopologyFilter
27
- }
8
+ import type { RelayDiscoveryComponents, RelayDiscoveryEvents, RelayDiscoveryInit } from '../index.ts'
9
+ import type { Logger, Peer, PeerId, PeerInfo, Startable, TopologyFilter } from '@libp2p/interface'
28
10
 
29
11
  /**
30
12
  * ReservationManager automatically makes a circuit v2 reservation on any connected
@@ -221,7 +203,7 @@ export class RelayDiscovery extends TypedEventEmitter<RelayDiscoveryEvents> impl
221
203
  }
222
204
 
223
205
  onPeer (evt: CustomEvent<PeerInfo>): void {
224
- this.log.trace('maybe dialing discovered peer %p - %e', evt.detail.id)
206
+ this.log.trace('maybe dialing discovered peer %p', evt.detail.id)
225
207
 
226
208
  this.maybeDialPeer(evt)
227
209
  .catch(err => {