@libp2p/circuit-relay-v2 1.0.24-7aec7bd45 → 1.0.24-90d10b565

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) 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/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,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
- }