@libp2p/circuit-relay-v2 1.0.24 → 1.0.25-863b3de03

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 (43) hide show
  1. package/dist/index.min.js +5 -5
  2. package/dist/src/constants.d.ts +13 -12
  3. package/dist/src/constants.d.ts.map +1 -1
  4. package/dist/src/constants.js +13 -12
  5. package/dist/src/constants.js.map +1 -1
  6. package/dist/src/pb/index.d.ts +7 -7
  7. package/dist/src/pb/index.d.ts.map +1 -1
  8. package/dist/src/pb/index.js +94 -52
  9. package/dist/src/pb/index.js.map +1 -1
  10. package/dist/src/server/index.d.ts +1 -7
  11. package/dist/src/server/index.d.ts.map +1 -1
  12. package/dist/src/server/index.js +10 -19
  13. package/dist/src/server/index.js.map +1 -1
  14. package/dist/src/transport/discovery.d.ts +15 -10
  15. package/dist/src/transport/discovery.d.ts.map +1 -1
  16. package/dist/src/transport/discovery.js +103 -51
  17. package/dist/src/transport/discovery.js.map +1 -1
  18. package/dist/src/transport/index.d.ts +27 -18
  19. package/dist/src/transport/index.d.ts.map +1 -1
  20. package/dist/src/transport/index.js +0 -3
  21. package/dist/src/transport/index.js.map +1 -1
  22. package/dist/src/transport/reservation-store.d.ts +7 -3
  23. package/dist/src/transport/reservation-store.d.ts.map +1 -1
  24. package/dist/src/transport/reservation-store.js +37 -13
  25. package/dist/src/transport/reservation-store.js.map +1 -1
  26. package/dist/src/transport/transport.d.ts +0 -1
  27. package/dist/src/transport/transport.d.ts.map +1 -1
  28. package/dist/src/transport/transport.js +20 -19
  29. package/dist/src/transport/transport.js.map +1 -1
  30. package/package.json +12 -13
  31. package/src/constants.ts +16 -15
  32. package/src/pb/index.ts +96 -53
  33. package/src/server/index.ts +11 -29
  34. package/src/transport/discovery.ts +121 -56
  35. package/src/transport/index.ts +28 -18
  36. package/src/transport/reservation-store.ts +45 -13
  37. package/src/transport/transport.ts +21 -21
  38. package/dist/src/server/advert-service.d.ts +0 -44
  39. package/dist/src/server/advert-service.d.ts.map +0 -1
  40. package/dist/src/server/advert-service.js +0 -72
  41. package/dist/src/server/advert-service.js.map +0 -1
  42. package/dist/typedoc-urls.json +0 -12
  43. package/src/server/advert-service.ts +0 -107
@@ -1,20 +1,16 @@
1
- import { type Transport, type Upgrader, type Libp2pEvents, type ComponentLogger, type ConnectionGater, type ContentRouting, type TypedEventTarget, type PeerId, type PeerStore } from '@libp2p/interface'
2
- import { type RelayDiscoveryComponents } from './discovery.js'
3
- import { type RelayStoreInit } from './reservation-store.js'
4
1
  import { CircuitRelayTransport } from './transport.js'
5
- import type { AddressManager, ConnectionManager, Registrar } from '@libp2p/interface-internal'
2
+ import type { RelayDiscoveryComponents } from './discovery.js'
3
+ import type { RelayStoreInit } from './reservation-store.js'
4
+ import type { Transport, Upgrader, Libp2pEvents, ConnectionGater, TypedEventTarget, PeerId, TopologyFilter } from '@libp2p/interface'
5
+ import type { AddressManager, Registrar } from '@libp2p/interface-internal'
6
6
 
7
7
  export interface CircuitRelayTransportComponents extends RelayDiscoveryComponents {
8
8
  peerId: PeerId
9
- peerStore: PeerStore
10
9
  registrar: Registrar
11
- connectionManager: ConnectionManager
12
10
  upgrader: Upgrader
13
11
  addressManager: AddressManager
14
- contentRouting: ContentRouting
15
12
  connectionGater: ConnectionGater
16
13
  events: TypedEventTarget<Libp2pEvents>
17
- logger: ComponentLogger
18
14
  }
19
15
 
20
16
  /**
@@ -22,34 +18,48 @@ export interface CircuitRelayTransportComponents extends RelayDiscoveryComponent
22
18
  */
23
19
  export interface CircuitRelayTransportInit extends RelayStoreInit {
24
20
  /**
25
- * The number of peers running diable relays to search for and
26
- * connect to. (default: 0)
21
+ * The number of peers running diable relays to search for and connect to
22
+ *
23
+ * @default 0
27
24
  */
28
25
  discoverRelays?: number
29
26
 
27
+ /**
28
+ * An optional filter used to prevent duplicate attempts to reserve relay
29
+ * slots on the same peer
30
+ */
31
+ discoveryFilter?: TopologyFilter
32
+
30
33
  /**
31
34
  * The maximum number of simultaneous STOP inbound streams that can be open at
32
- * once - each inbound relayed connection uses a STOP stream (default: 300)
35
+ * once - each inbound relayed connection uses a STOP stream
36
+ *
37
+ * @default 300
33
38
  */
34
39
  maxInboundStopStreams?: number
35
40
 
36
41
  /**
37
- * The maximum number of simultaneous STOP outbound streams that can be open at
38
- * once. If this transport is used along with the relay server these settings
39
- * should be set to the same value (default: 300)
42
+ * The maximum number of simultaneous STOP outbound streams that can be open
43
+ * at once. If this transport is used along with the relay server these
44
+ * settings should be set to the same value
45
+ *
46
+ * @default 300
40
47
  */
41
48
  maxOutboundStopStreams?: number
42
49
 
43
50
  /**
44
- * Incoming STOP requests (e.g. when a remote peer wants to dial us via a relay)
45
- * must finish the initial protocol negotiation within this timeout in ms
46
- * (default: 30000)
51
+ * Incoming STOP requests (e.g. when a remote peer wants to dial us via a
52
+ * relay) must finish the initial protocol negotiation within this timeout in
53
+ * ms
54
+ *
55
+ * @default 30000
47
56
  */
48
57
  stopTimeout?: number
49
58
 
50
59
  /**
51
60
  * When creating a reservation it must complete within this number of ms
52
- * (default: 10000)
61
+ *
62
+ * @default 10000
53
63
  */
54
64
  reservationCompletionTimeout?: number
55
65
  }
@@ -1,15 +1,17 @@
1
- import { TypedEventEmitter } from '@libp2p/interface'
1
+ import { TypedEventEmitter, setMaxListeners } from '@libp2p/interface'
2
2
  import { PeerMap } from '@libp2p/peer-collections'
3
+ import { createBloomFilter } from '@libp2p/utils/filters'
3
4
  import { PeerQueue } from '@libp2p/utils/peer-queue'
4
5
  import { multiaddr } from '@multiformats/multiaddr'
5
6
  import { pbStream } from 'it-protobuf-stream'
6
7
  import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
7
- import { DEFAULT_RESERVATION_CONCURRENCY, RELAY_TAG, RELAY_V2_HOP_CODEC } from '../constants.js'
8
+ import { DEFAULT_MAX_RESERVATION_QUEUE_LENGTH, DEFAULT_RESERVATION_COMPLETION_TIMEOUT, DEFAULT_RESERVATION_CONCURRENCY, RELAY_TAG, RELAY_V2_HOP_CODEC } from '../constants.js'
8
9
  import { HopMessage, Status } from '../pb/index.js'
9
10
  import { getExpirationMilliseconds } from '../utils.js'
10
11
  import type { Reservation } from '../pb/index.js'
11
12
  import type { TypedEventTarget, Libp2pEvents, AbortOptions, ComponentLogger, Logger, Connection, PeerId, PeerStore, Startable, Metrics } from '@libp2p/interface'
12
13
  import type { ConnectionManager, TransportManager } from '@libp2p/interface-internal'
14
+ import type { Filter } from '@libp2p/utils/filters'
13
15
 
14
16
  // allow refreshing a relay reservation if it will expire in the next 10 minutes
15
17
  const REFRESH_WINDOW = (60 * 1000) * 10
@@ -69,6 +71,7 @@ interface RelayEntry {
69
71
  export interface ReservationStoreEvents {
70
72
  'relay:not-enough-relays': CustomEvent
71
73
  'relay:removed': CustomEvent<PeerId>
74
+ 'relay:created-reservation': CustomEvent<PeerId>
72
75
  }
73
76
 
74
77
  export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents> implements Startable {
@@ -84,6 +87,7 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
84
87
  private readonly reservationCompletionTimeout: number
85
88
  private started: boolean
86
89
  private readonly log: Logger
90
+ private readonly relayFilter: Filter
87
91
 
88
92
  constructor (components: RelayStoreComponents, init?: RelayStoreInit) {
89
93
  super()
@@ -96,9 +100,10 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
96
100
  this.events = components.events
97
101
  this.reservations = new PeerMap()
98
102
  this.maxDiscoveredRelays = init?.discoverRelays ?? 0
99
- this.maxReservationQueueLength = init?.maxReservationQueueLength ?? 100
100
- this.reservationCompletionTimeout = init?.reservationCompletionTimeout ?? 10000
103
+ this.maxReservationQueueLength = init?.maxReservationQueueLength ?? DEFAULT_MAX_RESERVATION_QUEUE_LENGTH
104
+ this.reservationCompletionTimeout = init?.reservationCompletionTimeout ?? DEFAULT_RESERVATION_COMPLETION_TIMEOUT
101
105
  this.started = false
106
+ this.relayFilter = createBloomFilter(100)
102
107
 
103
108
  // ensure we don't listen on multiple relays simultaneously
104
109
  this.reserveQueue = new PeerQueue({
@@ -123,6 +128,13 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
123
128
  this.started = true
124
129
  }
125
130
 
131
+ afterStart (): void {
132
+ if (this.reservations.size < this.maxDiscoveredRelays) {
133
+ this.log('not enough relays %d/%d', this.reservations.size, this.maxDiscoveredRelays)
134
+ this.safeDispatchEvent('relay:not-enough-relays', {})
135
+ }
136
+ }
137
+
126
138
  stop (): void {
127
139
  this.reserveQueue.clear()
128
140
  this.reservations.forEach(({ timeout }) => {
@@ -134,9 +146,9 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
134
146
 
135
147
  /**
136
148
  * If the number of current relays is beneath the configured `maxReservations`
137
- * value, and the passed peer id is not our own, and we have a non-relayed connection
138
- * to the remote, and the remote peer speaks the hop protocol, try to reserve a slot
139
- * on the remote peer
149
+ * value, and the passed peer id is not our own, and we have a non-relayed
150
+ * connection to the remote, and the remote peer speaks the hop protocol, try
151
+ * to reserve a slot on the remote peer
140
152
  */
141
153
  async addRelay (peerId: PeerId, type: RelayType): Promise<void> {
142
154
  if (this.peerId.equals(peerId)) {
@@ -145,18 +157,25 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
145
157
  }
146
158
 
147
159
  if (this.reserveQueue.size > this.maxReservationQueueLength) {
148
- this.log('not adding relay as the queue is full')
160
+ this.log('not adding potential relay peer %p as the queue is full', peerId)
149
161
  return
150
162
  }
151
163
 
152
164
  if (this.reserveQueue.has(peerId)) {
153
- this.log('relay peer is already in the reservation queue')
165
+ this.log('potential relay peer %p is already in the reservation queue', peerId)
166
+ return
167
+ }
168
+
169
+ if (this.relayFilter.has(peerId.toBytes())) {
170
+ this.log('potential relay peer %p has failed previously, not trying again', peerId, new Error('where').stack)
154
171
  return
155
172
  }
156
173
 
157
- this.log('add relay %p', peerId)
174
+ this.log('try to reserve relay slot with %p', peerId)
158
175
 
159
176
  await this.reserveQueue.add(async () => {
177
+ const start = Date.now()
178
+
160
179
  try {
161
180
  // allow refresh of an existing reservation if it is about to expire
162
181
  const existingReservation = this.reservations.get(peerId)
@@ -183,6 +202,7 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
183
202
  }
184
203
 
185
204
  const signal = AbortSignal.timeout(this.reservationCompletionTimeout)
205
+ setMaxListeners(Infinity, signal)
186
206
 
187
207
  const connection = await this.connectionManager.openConnection(peerId, {
188
208
  signal
@@ -230,8 +250,12 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
230
250
 
231
251
  // listen on multiaddr that only the circuit transport is listening for
232
252
  await this.transportManager.listen([multiaddr(`/p2p/${peerId.toString()}/p2p-circuit`)])
253
+
254
+ this.safeDispatchEvent('relay:created-reservation', {
255
+ detail: peerId
256
+ })
233
257
  } catch (err) {
234
- this.log.error('could not reserve slot on %p', peerId, err)
258
+ this.log.error('could not reserve slot on %p after %dms', peerId, Date.now() - start, err)
235
259
 
236
260
  // cancel the renewal timeout if it's been set
237
261
  const reservation = this.reservations.get(peerId)
@@ -242,6 +266,9 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
242
266
 
243
267
  // if listening failed, remove the reservation
244
268
  this.reservations.delete(peerId)
269
+
270
+ // don't try this peer again
271
+ this.relayFilter.add(peerId.toBytes())
245
272
  }
246
273
  }, {
247
274
  peerId
@@ -256,6 +283,10 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
256
283
  return this.reservations.get(peerId)?.reservation
257
284
  }
258
285
 
286
+ reservationCount (): number {
287
+ return this.reservations.size
288
+ }
289
+
259
290
  async #createReservation (connection: Connection, options: AbortOptions): Promise<Reservation> {
260
291
  options.signal?.throwIfAborted()
261
292
 
@@ -270,11 +301,12 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
270
301
  try {
271
302
  response = await hopstr.read(options)
272
303
  } catch (err: any) {
273
- this.log.error('error parsing reserve message response from %p because', connection.remotePeer, err)
274
304
  stream.abort(err)
275
305
  throw err
276
306
  } finally {
277
- await stream.close()
307
+ if (stream.status !== 'closed') {
308
+ await stream.close(options)
309
+ }
278
310
  }
279
311
 
280
312
  if (response.status === Status.OK && (response.reservation != null)) {
@@ -1,11 +1,12 @@
1
- import { CodeError } from '@libp2p/interface'
1
+ import { CodeError, start, stop } from '@libp2p/interface'
2
2
  import { transportSymbol, type Transport, type CreateListenerOptions, type Listener, type Upgrader, type AbortOptions, type ComponentLogger, type Logger, type Connection, type Stream, type ConnectionGater, type PeerId, type PeerStore } from '@libp2p/interface'
3
+ import { peerFilter } from '@libp2p/peer-collections'
3
4
  import { peerIdFromBytes, peerIdFromString } from '@libp2p/peer-id'
4
5
  import { streamToMaConnection } from '@libp2p/utils/stream-to-ma-conn'
5
6
  import * as mafmt from '@multiformats/mafmt'
6
7
  import { multiaddr } from '@multiformats/multiaddr'
7
8
  import { pbStream } from 'it-protobuf-stream'
8
- import { CIRCUIT_PROTO_CODE, ERR_HOP_REQUEST_FAILED, ERR_RELAYED_DIAL, MAX_CONNECTIONS, RELAY_V2_HOP_CODEC, RELAY_V2_STOP_CODEC } from '../constants.js'
9
+ import { CIRCUIT_PROTO_CODE, DEFAULT_DISCOVERY_FILTER_ERROR_RATE, DEFAULT_DISCOVERY_FILTER_SIZE, ERR_HOP_REQUEST_FAILED, ERR_RELAYED_DIAL, MAX_CONNECTIONS, RELAY_V2_HOP_CODEC, RELAY_V2_STOP_CODEC } from '../constants.js'
9
10
  import { StopMessage, HopMessage, Status } from '../pb/index.js'
10
11
  import { RelayDiscovery } from './discovery.js'
11
12
  import { createListener } from './listener.js'
@@ -77,8 +78,12 @@ export class CircuitRelayTransport implements Transport {
77
78
  this.maxOutboundStopStreams = init.maxOutboundStopStreams ?? defaults.maxOutboundStopStreams
78
79
  this.stopTimeout = init.stopTimeout ?? defaults.stopTimeout
79
80
 
80
- if (init.discoverRelays != null && init.discoverRelays > 0) {
81
- this.discovery = new RelayDiscovery(components)
81
+ const discoverRelays = init.discoverRelays ?? 0
82
+
83
+ if (discoverRelays > 0) {
84
+ this.discovery = new RelayDiscovery(components, {
85
+ filter: init.discoveryFilter ?? peerFilter(DEFAULT_DISCOVERY_FILTER_SIZE, DEFAULT_DISCOVERY_FILTER_ERROR_RATE)
86
+ })
82
87
  this.discovery.addEventListener('relay:discover', (evt) => {
83
88
  this.reservationStore.addRelay(evt.detail, 'discovered')
84
89
  .catch(err => {
@@ -89,10 +94,12 @@ export class CircuitRelayTransport implements Transport {
89
94
 
90
95
  this.reservationStore = new ReservationStore(components, init)
91
96
  this.reservationStore.addEventListener('relay:not-enough-relays', () => {
92
- this.discovery?.discover()
93
- .catch(err => {
94
- this.log.error('could not discover relays', err)
95
- })
97
+ this.discovery?.startDiscovery()
98
+ })
99
+ this.reservationStore.addEventListener('relay:created-reservation', () => {
100
+ if (this.reservationStore.reservationCount() >= discoverRelays) {
101
+ this.discovery?.stopDiscovery()
102
+ }
96
103
  })
97
104
 
98
105
  this.started = false
@@ -103,8 +110,6 @@ export class CircuitRelayTransport implements Transport {
103
110
  }
104
111
 
105
112
  async start (): Promise<void> {
106
- this.reservationStore.start()
107
-
108
113
  await this.registrar.handle(RELAY_V2_STOP_CODEC, (data) => {
109
114
  void this.onStop(data).catch(err => {
110
115
  this.log.error('error while handling STOP protocol', err)
@@ -116,18 +121,13 @@ export class CircuitRelayTransport implements Transport {
116
121
  runOnTransientConnection: true
117
122
  })
118
123
 
119
- await this.discovery?.start()
124
+ await start(this.discovery, this.reservationStore)
120
125
 
121
126
  this.started = true
122
127
  }
123
128
 
124
- afterStart (): void {
125
- this.discovery?.afterStart()
126
- }
127
-
128
129
  async stop (): Promise<void> {
129
- this.discovery?.stop()
130
- this.reservationStore.stop()
130
+ await stop(this.discovery, this.reservationStore)
131
131
  await this.registrar.unhandle(RELAY_V2_STOP_CODEC)
132
132
 
133
133
  this.started = false
@@ -231,9 +231,9 @@ export class CircuitRelayTransport implements Transport {
231
231
  logger: this.logger
232
232
  })
233
233
 
234
- this.log('new outbound transient connection %a', maConn.remoteAddr)
234
+ this.log('new outbound relayed connection %a', maConn.remoteAddr)
235
235
  return await this.upgrader.upgradeOutbound(maConn, {
236
- transient: true
236
+ transient: status.limit != null
237
237
  })
238
238
  } catch (err: any) {
239
239
  this.log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${connection.remotePeer.toString()} failed`, err)
@@ -346,9 +346,9 @@ export class CircuitRelayTransport implements Transport {
346
346
  logger: this.logger
347
347
  })
348
348
 
349
- this.log('new inbound transient connection %a', maConn.remoteAddr)
349
+ this.log('new inbound relayed connection %a', maConn.remoteAddr)
350
350
  await this.upgrader.upgradeInbound(maConn, {
351
- transient: true
351
+ transient: request.limit != null
352
352
  })
353
353
  this.log('%s connection %a upgraded', 'inbound', maConn.remoteAddr)
354
354
  }
@@ -1,44 +0,0 @@
1
- import { TypedEventEmitter } from '@libp2p/interface';
2
- import type { ComponentLogger, ContentRouting, Startable } from '@libp2p/interface';
3
- export interface AdvertServiceInit {
4
- /**
5
- * How long to wait after startup to begin advertising the service
6
- * - if some configured content routers take a while to warm up (for
7
- * example, the DHT needs some peers to be able to publish) this
8
- * value should be high enough that they will have warmed up
9
- */
10
- bootDelay?: number;
11
- }
12
- export interface AdvertServiceComponents {
13
- contentRouting: ContentRouting;
14
- logger: ComponentLogger;
15
- }
16
- export interface AdvertServiceEvents {
17
- 'advert:success': CustomEvent<unknown>;
18
- 'advert:error': CustomEvent<Error>;
19
- }
20
- export declare class AdvertService extends TypedEventEmitter<AdvertServiceEvents> implements Startable {
21
- private readonly contentRouting;
22
- private timeout?;
23
- private started;
24
- private readonly bootDelay;
25
- private readonly log;
26
- /**
27
- * Creates an instance of Relay
28
- */
29
- constructor(components: AdvertServiceComponents, init?: AdvertServiceInit);
30
- isStarted(): boolean;
31
- /**
32
- * Start Relay service
33
- */
34
- start(): void;
35
- /**
36
- * Stop Relay service
37
- */
38
- stop(): void;
39
- /**
40
- * Advertise hop relay service in the network.
41
- */
42
- _advertiseService(): Promise<void>;
43
- }
44
- //# sourceMappingURL=advert-service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"advert-service.d.ts","sourceRoot":"","sources":["../../../src/server/advert-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAQrD,OAAO,KAAK,EAAE,eAAe,EAAU,cAAc,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE3F,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,cAAc,CAAA;IAC9B,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IACtC,cAAc,EAAE,WAAW,CAAC,KAAK,CAAC,CAAA;CACnC;AAED,qBAAa,aAAc,SAAQ,iBAAiB,CAAC,mBAAmB,CAAE,YAAW,SAAS;IAC5F,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAK;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAE5B;;OAEG;gBACU,UAAU,EAAE,uBAAuB,EAAE,IAAI,CAAC,EAAE,iBAAiB;IAS1E,SAAS,IAAK,OAAO;IAIrB;;OAEG;IACH,KAAK,IAAK,IAAI;IAed;;OAEG;IACH,IAAI,IAAK,IAAI;IAQb;;OAEG;IACG,iBAAiB,IAAK,OAAO,CAAC,IAAI,CAAC;CAqB1C"}
@@ -1,72 +0,0 @@
1
- import { TypedEventEmitter } from '@libp2p/interface';
2
- import pRetry from 'p-retry';
3
- import { DEFAULT_ADVERT_BOOT_DELAY, ERR_NO_ROUTERS_AVAILABLE, RELAY_RENDEZVOUS_NS } from '../constants.js';
4
- import { namespaceToCid } from '../utils.js';
5
- export class AdvertService extends TypedEventEmitter {
6
- contentRouting;
7
- timeout;
8
- started;
9
- bootDelay;
10
- log;
11
- /**
12
- * Creates an instance of Relay
13
- */
14
- constructor(components, init) {
15
- super();
16
- this.log = components.logger.forComponent('libp2p:circuit-relay:advert-service');
17
- this.contentRouting = components.contentRouting;
18
- this.bootDelay = init?.bootDelay ?? DEFAULT_ADVERT_BOOT_DELAY;
19
- this.started = false;
20
- }
21
- isStarted() {
22
- return this.started;
23
- }
24
- /**
25
- * Start Relay service
26
- */
27
- start() {
28
- if (this.started) {
29
- return;
30
- }
31
- // Advertise service if HOP enabled and advertising enabled
32
- this.timeout = setTimeout(() => {
33
- this._advertiseService().catch(err => {
34
- this.log.error('could not advertise service', err);
35
- });
36
- }, this.bootDelay);
37
- this.started = true;
38
- }
39
- /**
40
- * Stop Relay service
41
- */
42
- stop() {
43
- try {
44
- clearTimeout(this.timeout);
45
- }
46
- catch (err) { }
47
- this.started = false;
48
- }
49
- /**
50
- * Advertise hop relay service in the network.
51
- */
52
- async _advertiseService() {
53
- await pRetry(async () => {
54
- try {
55
- const cid = await namespaceToCid(RELAY_RENDEZVOUS_NS);
56
- await this.contentRouting.provide(cid);
57
- this.safeDispatchEvent('advert:success', { detail: undefined });
58
- }
59
- catch (err) {
60
- this.safeDispatchEvent('advert:error', { detail: err });
61
- if (err.code === ERR_NO_ROUTERS_AVAILABLE) {
62
- this.log.error('a content router, such as a DHT, must be provided in order to advertise the relay service', err);
63
- this.stop();
64
- return;
65
- }
66
- this.log.error('could not advertise service', err);
67
- throw err;
68
- }
69
- });
70
- }
71
- }
72
- //# sourceMappingURL=advert-service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"advert-service.js","sourceRoot":"","sources":["../../../src/server/advert-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,MAAM,MAAM,SAAS,CAAA;AAC5B,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,mBAAmB,EACpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAuB5C,MAAM,OAAO,aAAc,SAAQ,iBAAsC;IACtD,cAAc,CAAgB;IACvC,OAAO,CAAM;IACb,OAAO,CAAS;IACP,SAAS,CAAQ;IACjB,GAAG,CAAQ;IAE5B;;OAEG;IACH,YAAa,UAAmC,EAAE,IAAwB;QACxE,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,qCAAqC,CAAC,CAAA;QAChF,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,cAAc,CAAA;QAC/C,IAAI,CAAC,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,yBAAyB,CAAA;QAC7D,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IACtB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QAED,2DAA2D;QAC3D,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC7B,IAAI,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;gBACnC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAA;YACpD,CAAC,CAAC,CAAA;QACJ,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QAElB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;IACrB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,CAAC;YACH,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;QAEjB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB;QACrB,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;YACtB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,mBAAmB,CAAC,CAAA;gBACrD,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;gBAEtC,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;YACjE,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;gBAEvD,IAAI,GAAG,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;oBAC1C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,2FAA2F,EAAE,GAAG,CAAC,CAAA;oBAChH,IAAI,CAAC,IAAI,EAAE,CAAA;oBACX,OAAM;gBACR,CAAC;gBAED,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAA;gBAClD,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;CACF"}
@@ -1,12 +0,0 @@
1
- {
2
- "CircuitRelayService": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayService.html",
3
- ".:CircuitRelayService": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayService.html",
4
- "CircuitRelayServiceEvents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayServiceEvents.html",
5
- ".:CircuitRelayServiceEvents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayServiceEvents.html",
6
- "RelayReservation": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.RelayReservation.html",
7
- ".:RelayReservation": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.RelayReservation.html",
8
- "RELAY_V2_HOP_CODEC": "https://libp2p.github.io/js-libp2p/variables/_libp2p_circuit_relay_v2.RELAY_V2_HOP_CODEC.html",
9
- "RELAY_V2_STOP_CODEC": "https://libp2p.github.io/js-libp2p/variables/_libp2p_circuit_relay_v2.RELAY_V2_STOP_CODEC.html",
10
- "circuitRelayServer": "https://libp2p.github.io/js-libp2p/functions/_libp2p_circuit_relay_v2.circuitRelayServer.html",
11
- "circuitRelayTransport": "https://libp2p.github.io/js-libp2p/functions/_libp2p_circuit_relay_v2.circuitRelayTransport.html"
12
- }
@@ -1,107 +0,0 @@
1
- import { TypedEventEmitter } from '@libp2p/interface'
2
- import pRetry from 'p-retry'
3
- import {
4
- DEFAULT_ADVERT_BOOT_DELAY,
5
- ERR_NO_ROUTERS_AVAILABLE,
6
- RELAY_RENDEZVOUS_NS
7
- } from '../constants.js'
8
- import { namespaceToCid } from '../utils.js'
9
- import type { ComponentLogger, Logger, ContentRouting, Startable } from '@libp2p/interface'
10
-
11
- export interface AdvertServiceInit {
12
- /**
13
- * How long to wait after startup to begin advertising the service
14
- * - if some configured content routers take a while to warm up (for
15
- * example, the DHT needs some peers to be able to publish) this
16
- * value should be high enough that they will have warmed up
17
- */
18
- bootDelay?: number
19
- }
20
-
21
- export interface AdvertServiceComponents {
22
- contentRouting: ContentRouting
23
- logger: ComponentLogger
24
- }
25
-
26
- export interface AdvertServiceEvents {
27
- 'advert:success': CustomEvent<unknown>
28
- 'advert:error': CustomEvent<Error>
29
- }
30
-
31
- export class AdvertService extends TypedEventEmitter<AdvertServiceEvents> implements Startable {
32
- private readonly contentRouting: ContentRouting
33
- private timeout?: any
34
- private started: boolean
35
- private readonly bootDelay: number
36
- private readonly log: Logger
37
-
38
- /**
39
- * Creates an instance of Relay
40
- */
41
- constructor (components: AdvertServiceComponents, init?: AdvertServiceInit) {
42
- super()
43
-
44
- this.log = components.logger.forComponent('libp2p:circuit-relay:advert-service')
45
- this.contentRouting = components.contentRouting
46
- this.bootDelay = init?.bootDelay ?? DEFAULT_ADVERT_BOOT_DELAY
47
- this.started = false
48
- }
49
-
50
- isStarted (): boolean {
51
- return this.started
52
- }
53
-
54
- /**
55
- * Start Relay service
56
- */
57
- start (): void {
58
- if (this.started) {
59
- return
60
- }
61
-
62
- // Advertise service if HOP enabled and advertising enabled
63
- this.timeout = setTimeout(() => {
64
- this._advertiseService().catch(err => {
65
- this.log.error('could not advertise service', err)
66
- })
67
- }, this.bootDelay)
68
-
69
- this.started = true
70
- }
71
-
72
- /**
73
- * Stop Relay service
74
- */
75
- stop (): void {
76
- try {
77
- clearTimeout(this.timeout)
78
- } catch (err) { }
79
-
80
- this.started = false
81
- }
82
-
83
- /**
84
- * Advertise hop relay service in the network.
85
- */
86
- async _advertiseService (): Promise<void> {
87
- await pRetry(async () => {
88
- try {
89
- const cid = await namespaceToCid(RELAY_RENDEZVOUS_NS)
90
- await this.contentRouting.provide(cid)
91
-
92
- this.safeDispatchEvent('advert:success', { detail: undefined })
93
- } catch (err: any) {
94
- this.safeDispatchEvent('advert:error', { detail: err })
95
-
96
- if (err.code === ERR_NO_ROUTERS_AVAILABLE) {
97
- this.log.error('a content router, such as a DHT, must be provided in order to advertise the relay service', err)
98
- this.stop()
99
- return
100
- }
101
-
102
- this.log.error('could not advertise service', err)
103
- throw err
104
- }
105
- })
106
- }
107
- }