@libp2p/circuit-relay-v2 1.0.24-352699ab5 → 1.0.24-4bd8e4f79
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.min.js +5 -5
- package/dist/src/constants.d.ts +13 -12
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +13 -12
- package/dist/src/constants.js.map +1 -1
- package/dist/src/pb/index.d.ts +7 -7
- package/dist/src/pb/index.d.ts.map +1 -1
- package/dist/src/pb/index.js +94 -52
- package/dist/src/pb/index.js.map +1 -1
- package/dist/src/server/index.d.ts +1 -7
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +10 -19
- package/dist/src/server/index.js.map +1 -1
- package/dist/src/transport/discovery.d.ts +15 -10
- package/dist/src/transport/discovery.d.ts.map +1 -1
- package/dist/src/transport/discovery.js +103 -51
- package/dist/src/transport/discovery.js.map +1 -1
- package/dist/src/transport/index.d.ts +27 -18
- package/dist/src/transport/index.d.ts.map +1 -1
- package/dist/src/transport/index.js +0 -3
- package/dist/src/transport/index.js.map +1 -1
- package/dist/src/transport/reservation-store.d.ts +7 -3
- package/dist/src/transport/reservation-store.d.ts.map +1 -1
- package/dist/src/transport/reservation-store.js +37 -13
- package/dist/src/transport/reservation-store.js.map +1 -1
- package/dist/src/transport/transport.d.ts +0 -1
- package/dist/src/transport/transport.d.ts.map +1 -1
- package/dist/src/transport/transport.js +20 -19
- package/dist/src/transport/transport.js.map +1 -1
- package/package.json +12 -13
- package/src/constants.ts +16 -15
- package/src/pb/index.ts +96 -53
- package/src/server/index.ts +11 -29
- package/src/transport/discovery.ts +121 -56
- package/src/transport/index.ts +28 -18
- package/src/transport/reservation-store.ts +45 -13
- package/src/transport/transport.ts +21 -21
- package/dist/src/server/advert-service.d.ts +0 -44
- package/dist/src/server/advert-service.d.ts.map +0 -1
- package/dist/src/server/advert-service.js +0 -72
- package/dist/src/server/advert-service.js.map +0 -1
- package/src/server/advert-service.ts +0 -107
package/src/transport/index.ts
CHANGED
@@ -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 {
|
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
|
-
*
|
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
|
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
|
38
|
-
* once. If this transport is used along with the relay server these
|
39
|
-
* should be set to the same value
|
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
|
45
|
-
* must finish the initial protocol negotiation within this timeout in
|
46
|
-
*
|
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
|
-
*
|
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
|
-
this.reservationCompletionTimeout = init?.reservationCompletionTimeout ??
|
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
|
138
|
-
* to the remote, and the remote peer speaks the hop protocol, try
|
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('
|
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
|
-
|
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
|
-
|
81
|
-
|
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?.
|
93
|
-
|
94
|
-
|
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
|
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
|
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
|
234
|
+
this.log('new outbound relayed connection %a', maConn.remoteAddr)
|
235
235
|
return await this.upgrader.upgradeOutbound(maConn, {
|
236
|
-
transient:
|
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
|
349
|
+
this.log('new inbound relayed connection %a', maConn.remoteAddr)
|
350
350
|
await this.upgrader.upgradeInbound(maConn, {
|
351
|
-
transient:
|
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
|
-
}
|