@libp2p/circuit-relay-v2 1.0.24-62e32252a → 1.0.24-757fb2674
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.
- package/dist/index.min.js +3 -3
- package/dist/src/constants.d.ts +12 -13
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +12 -13
- 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 +52 -94
- package/dist/src/pb/index.js.map +1 -1
- package/dist/src/server/advert-service.d.ts +44 -0
- package/dist/src/server/advert-service.d.ts.map +1 -0
- package/dist/src/server/advert-service.js +72 -0
- package/dist/src/server/advert-service.js.map +1 -0
- package/dist/src/server/index.d.ts +7 -1
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +19 -10
- package/dist/src/server/index.js.map +1 -1
- package/dist/src/transport/discovery.d.ts +10 -15
- package/dist/src/transport/discovery.d.ts.map +1 -1
- package/dist/src/transport/discovery.js +51 -103
- package/dist/src/transport/discovery.js.map +1 -1
- package/dist/src/transport/index.d.ts +18 -27
- package/dist/src/transport/index.d.ts.map +1 -1
- package/dist/src/transport/index.js +3 -0
- package/dist/src/transport/index.js.map +1 -1
- package/dist/src/transport/reservation-store.d.ts +3 -7
- package/dist/src/transport/reservation-store.d.ts.map +1 -1
- package/dist/src/transport/reservation-store.js +13 -37
- package/dist/src/transport/reservation-store.js.map +1 -1
- package/dist/src/transport/transport.d.ts +1 -0
- package/dist/src/transport/transport.d.ts.map +1 -1
- package/dist/src/transport/transport.js +19 -20
- package/dist/src/transport/transport.js.map +1 -1
- package/package.json +12 -11
- package/src/constants.ts +15 -16
- package/src/pb/index.ts +53 -96
- package/src/server/advert-service.ts +107 -0
- package/src/server/index.ts +29 -11
- package/src/transport/discovery.ts +56 -121
- package/src/transport/index.ts +18 -28
- package/src/transport/reservation-store.ts +13 -45
- package/src/transport/transport.ts +21 -21
@@ -1,28 +1,24 @@
|
|
1
|
-
import { TypedEventEmitter
|
2
|
-
import { PeerQueue } from '@libp2p/utils/peer-queue'
|
3
|
-
import { anySignal } from 'any-signal'
|
4
|
-
import { raceSignal } from 'race-signal'
|
1
|
+
import { TypedEventEmitter } from '@libp2p/interface'
|
5
2
|
import {
|
3
|
+
RELAY_RENDEZVOUS_NS,
|
6
4
|
RELAY_V2_HOP_CODEC
|
7
5
|
} from '../constants.js'
|
8
|
-
import
|
9
|
-
import type {
|
6
|
+
import { namespaceToCid } from '../utils.js'
|
7
|
+
import type { ComponentLogger, Logger, ContentRouting, PeerId, PeerStore, Startable } from '@libp2p/interface'
|
8
|
+
import type { ConnectionManager, Registrar, TransportManager } from '@libp2p/interface-internal'
|
10
9
|
|
11
10
|
export interface RelayDiscoveryEvents {
|
12
11
|
'relay:discover': CustomEvent<PeerId>
|
13
12
|
}
|
14
13
|
|
15
14
|
export interface RelayDiscoveryComponents {
|
15
|
+
peerId: PeerId
|
16
16
|
peerStore: PeerStore
|
17
17
|
connectionManager: ConnectionManager
|
18
18
|
transportManager: TransportManager
|
19
|
+
contentRouting: ContentRouting
|
19
20
|
registrar: Registrar
|
20
21
|
logger: ComponentLogger
|
21
|
-
randomWalk: RandomWalk
|
22
|
-
}
|
23
|
-
|
24
|
-
export interface RelayDiscoveryInit {
|
25
|
-
filter?: TopologyFilter
|
26
22
|
}
|
27
23
|
|
28
24
|
/**
|
@@ -30,30 +26,23 @@ export interface RelayDiscoveryInit {
|
|
30
26
|
* peers that support the circuit v2 HOP protocol.
|
31
27
|
*/
|
32
28
|
export class RelayDiscovery extends TypedEventEmitter<RelayDiscoveryEvents> implements Startable {
|
29
|
+
private readonly peerId: PeerId
|
33
30
|
private readonly peerStore: PeerStore
|
31
|
+
private readonly contentRouting: ContentRouting
|
34
32
|
private readonly registrar: Registrar
|
35
|
-
private readonly connectionManager: ConnectionManager
|
36
|
-
private readonly randomWalk: RandomWalk
|
37
33
|
private started: boolean
|
38
|
-
private running: boolean
|
39
34
|
private topologyId?: string
|
40
35
|
private readonly log: Logger
|
41
|
-
private discoveryController: AbortController
|
42
|
-
private readonly filter?: TopologyFilter
|
43
36
|
|
44
|
-
constructor (components: RelayDiscoveryComponents
|
37
|
+
constructor (components: RelayDiscoveryComponents) {
|
45
38
|
super()
|
46
39
|
|
47
40
|
this.log = components.logger.forComponent('libp2p:circuit-relay:discover-relays')
|
48
41
|
this.started = false
|
49
|
-
this.
|
42
|
+
this.peerId = components.peerId
|
50
43
|
this.peerStore = components.peerStore
|
44
|
+
this.contentRouting = components.contentRouting
|
51
45
|
this.registrar = components.registrar
|
52
|
-
this.connectionManager = components.connectionManager
|
53
|
-
this.randomWalk = components.randomWalk
|
54
|
-
this.filter = init.filter
|
55
|
-
this.discoveryController = new AbortController()
|
56
|
-
setMaxListeners(Infinity, this.discoveryController.signal)
|
57
46
|
}
|
58
47
|
|
59
48
|
isStarted (): boolean {
|
@@ -64,9 +53,8 @@ export class RelayDiscovery extends TypedEventEmitter<RelayDiscoveryEvents> impl
|
|
64
53
|
// register a topology listener for when new peers are encountered
|
65
54
|
// that support the hop protocol
|
66
55
|
this.topologyId = await this.registrar.register(RELAY_V2_HOP_CODEC, {
|
67
|
-
|
56
|
+
notifyOnTransient: true,
|
68
57
|
onConnect: (peerId) => {
|
69
|
-
this.log('discovered relay %p', peerId)
|
70
58
|
this.safeDispatchEvent('relay:discover', { detail: peerId })
|
71
59
|
}
|
72
60
|
})
|
@@ -74,12 +62,18 @@ export class RelayDiscovery extends TypedEventEmitter<RelayDiscoveryEvents> impl
|
|
74
62
|
this.started = true
|
75
63
|
}
|
76
64
|
|
65
|
+
afterStart (): void {
|
66
|
+
void this.discover()
|
67
|
+
.catch(err => {
|
68
|
+
this.log.error('error discovering relays', err)
|
69
|
+
})
|
70
|
+
}
|
71
|
+
|
77
72
|
stop (): void {
|
78
73
|
if (this.topologyId != null) {
|
79
74
|
this.registrar.unregister(this.topologyId)
|
80
75
|
}
|
81
76
|
|
82
|
-
this.discoveryController?.abort()
|
83
77
|
this.started = false
|
84
78
|
}
|
85
79
|
|
@@ -87,113 +81,54 @@ export class RelayDiscovery extends TypedEventEmitter<RelayDiscoveryEvents> impl
|
|
87
81
|
* Try to listen on available hop relay connections.
|
88
82
|
* The following order will happen while we do not have enough relays:
|
89
83
|
*
|
90
|
-
* 1. Check the metadata store for known relays, try to listen on the ones we are already connected
|
84
|
+
* 1. Check the metadata store for known relays, try to listen on the ones we are already connected
|
91
85
|
* 2. Dial and try to listen on the peers we know that support hop but are not connected
|
92
86
|
* 3. Search the network
|
93
87
|
*/
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
this.discoveryController = new AbortController()
|
102
|
-
setMaxListeners(Infinity, this.discoveryController.signal)
|
103
|
-
|
104
|
-
Promise.resolve()
|
105
|
-
.then(async () => {
|
106
|
-
this.log('searching peer store for relays')
|
107
|
-
|
108
|
-
const peers = (await this.peerStore.all({
|
109
|
-
filters: [
|
110
|
-
// filter by a list of peers supporting RELAY_V2_HOP and ones we are not listening on
|
111
|
-
(peer) => {
|
112
|
-
return peer.protocols.includes(RELAY_V2_HOP_CODEC)
|
113
|
-
}
|
114
|
-
],
|
115
|
-
orders: [
|
116
|
-
() => Math.random() < 0.5 ? 1 : -1
|
117
|
-
]
|
118
|
-
}))
|
119
|
-
|
120
|
-
for (const peer of peers) {
|
121
|
-
this.log.trace('found relay peer %p in peer store', peer.id)
|
122
|
-
this.safeDispatchEvent('relay:discover', { detail: peer.id })
|
88
|
+
async discover (): Promise<void> {
|
89
|
+
this.log('searching peer store for relays')
|
90
|
+
const peers = (await this.peerStore.all({
|
91
|
+
filters: [
|
92
|
+
// filter by a list of peers supporting RELAY_V2_HOP and ones we are not listening on
|
93
|
+
(peer) => {
|
94
|
+
return peer.protocols.includes(RELAY_V2_HOP_CODEC)
|
123
95
|
}
|
96
|
+
],
|
97
|
+
orders: [
|
98
|
+
() => Math.random() < 0.5 ? 1 : -1
|
99
|
+
]
|
100
|
+
}))
|
101
|
+
|
102
|
+
for (const peer of peers) {
|
103
|
+
this.log('found relay peer %p in content peer store', peer.id)
|
104
|
+
this.safeDispatchEvent('relay:discover', { detail: peer.id })
|
105
|
+
}
|
124
106
|
|
125
|
-
|
126
|
-
|
127
|
-
// perform random walk and dial peers - after identify has run, the network
|
128
|
-
// topology will be notified of new relays
|
129
|
-
const queue = new PeerQueue({
|
130
|
-
concurrency: 5
|
131
|
-
})
|
132
|
-
|
133
|
-
this.log('start random walk')
|
134
|
-
for await (const peer of this.randomWalk.walk({ signal: this.discoveryController.signal })) {
|
135
|
-
this.log.trace('found random peer %p', peer.id)
|
136
|
-
|
137
|
-
if (queue.has(peer.id)) {
|
138
|
-
this.log.trace('random peer %p was already in queue', peer.id)
|
139
|
-
|
140
|
-
// skip peers already in the queue
|
141
|
-
continue
|
142
|
-
}
|
143
|
-
|
144
|
-
if (this.connectionManager.getConnections(peer.id)?.length > 0) {
|
145
|
-
this.log.trace('random peer %p was already connected', peer.id)
|
146
|
-
|
147
|
-
// skip peers we are already connected to
|
148
|
-
continue
|
149
|
-
}
|
150
|
-
|
151
|
-
if (!(await this.connectionManager.isDialable(peer.multiaddrs))) {
|
152
|
-
this.log.trace('random peer %p was not dialable', peer.id, peer.multiaddrs.map(ma => ma.toString()))
|
153
|
-
|
154
|
-
// skip peers we can't dial
|
155
|
-
continue
|
156
|
-
}
|
157
|
-
|
158
|
-
this.log.trace('wait for space in queue for %p', peer.id)
|
107
|
+
this.log('found %d relay peers in peer store', peers.length)
|
159
108
|
|
160
|
-
|
161
|
-
|
109
|
+
try {
|
110
|
+
this.log('searching content routing for relays')
|
111
|
+
const cid = await namespaceToCid(RELAY_RENDEZVOUS_NS)
|
162
112
|
|
163
|
-
|
113
|
+
let found = 0
|
164
114
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
const signal = anySignal([this.discoveryController.signal, AbortSignal.timeout(5000)])
|
169
|
-
setMaxListeners(Infinity, signal)
|
115
|
+
for await (const provider of this.contentRouting.findProviders(cid)) {
|
116
|
+
if (provider.multiaddrs.length > 0 && !provider.id.equals(this.peerId)) {
|
117
|
+
const peerId = provider.id
|
170
118
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
signal.clear()
|
175
|
-
}
|
176
|
-
}, {
|
177
|
-
peerId: peer.id,
|
178
|
-
signal: this.discoveryController.signal
|
119
|
+
found++
|
120
|
+
await this.peerStore.merge(peerId, {
|
121
|
+
multiaddrs: provider.multiaddrs
|
179
122
|
})
|
180
|
-
.catch(err => {
|
181
|
-
this.log.error('error opening connection to random peer %p', peer.id, err)
|
182
|
-
})
|
183
|
-
}
|
184
123
|
|
185
|
-
|
186
|
-
|
187
|
-
.catch(err => {
|
188
|
-
if (!this.discoveryController.signal.aborted) {
|
189
|
-
this.log.error('failed when finding relays on the network', err)
|
124
|
+
this.log('found relay peer %p in content routing', peerId)
|
125
|
+
this.safeDispatchEvent('relay:discover', { detail: peerId })
|
190
126
|
}
|
191
|
-
}
|
192
|
-
}
|
127
|
+
}
|
193
128
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
129
|
+
this.log('found %d relay peers in content routing', found)
|
130
|
+
} catch (err: any) {
|
131
|
+
this.log.error('failed when finding relays on the network', err)
|
132
|
+
}
|
198
133
|
}
|
199
134
|
}
|
package/src/transport/index.ts
CHANGED
@@ -1,16 +1,20 @@
|
|
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'
|
1
4
|
import { CircuitRelayTransport } from './transport.js'
|
2
|
-
import type {
|
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'
|
5
|
+
import type { AddressManager, ConnectionManager, Registrar } from '@libp2p/interface-internal'
|
6
6
|
|
7
7
|
export interface CircuitRelayTransportComponents extends RelayDiscoveryComponents {
|
8
8
|
peerId: PeerId
|
9
|
+
peerStore: PeerStore
|
9
10
|
registrar: Registrar
|
11
|
+
connectionManager: ConnectionManager
|
10
12
|
upgrader: Upgrader
|
11
13
|
addressManager: AddressManager
|
14
|
+
contentRouting: ContentRouting
|
12
15
|
connectionGater: ConnectionGater
|
13
16
|
events: TypedEventTarget<Libp2pEvents>
|
17
|
+
logger: ComponentLogger
|
14
18
|
}
|
15
19
|
|
16
20
|
/**
|
@@ -18,48 +22,34 @@ export interface CircuitRelayTransportComponents extends RelayDiscoveryComponent
|
|
18
22
|
*/
|
19
23
|
export interface CircuitRelayTransportInit extends RelayStoreInit {
|
20
24
|
/**
|
21
|
-
* The number of peers running diable relays to search for and
|
22
|
-
*
|
23
|
-
* @default 0
|
25
|
+
* The number of peers running diable relays to search for and
|
26
|
+
* connect to. (default: 0)
|
24
27
|
*/
|
25
28
|
discoverRelays?: number
|
26
29
|
|
27
|
-
/**
|
28
|
-
* An optional filter used to prevent duplicate attempts to reserve relay
|
29
|
-
* slots on the same peer
|
30
|
-
*/
|
31
|
-
discoveryFilter?: TopologyFilter
|
32
|
-
|
33
30
|
/**
|
34
31
|
* The maximum number of simultaneous STOP inbound streams that can be open at
|
35
|
-
* once - each inbound relayed connection uses a STOP stream
|
36
|
-
*
|
37
|
-
* @default 300
|
32
|
+
* once - each inbound relayed connection uses a STOP stream (default: 300)
|
38
33
|
*/
|
39
34
|
maxInboundStopStreams?: number
|
40
35
|
|
41
36
|
/**
|
42
|
-
* The maximum number of simultaneous STOP outbound streams that can be open
|
43
|
-
*
|
44
|
-
*
|
45
|
-
*
|
46
|
-
* @default 300
|
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)
|
47
40
|
*/
|
48
41
|
maxOutboundStopStreams?: number
|
49
42
|
|
50
43
|
/**
|
51
|
-
* Incoming STOP requests (e.g. when a remote peer wants to dial us via a
|
52
|
-
*
|
53
|
-
*
|
54
|
-
*
|
55
|
-
* @default 30000
|
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)
|
56
47
|
*/
|
57
48
|
stopTimeout?: number
|
58
49
|
|
59
50
|
/**
|
60
51
|
* When creating a reservation it must complete within this number of ms
|
61
|
-
*
|
62
|
-
* @default 10000
|
52
|
+
* (default: 10000)
|
63
53
|
*/
|
64
54
|
reservationCompletionTimeout?: number
|
65
55
|
}
|
@@ -1,17 +1,15 @@
|
|
1
|
-
import { TypedEventEmitter
|
1
|
+
import { TypedEventEmitter } from '@libp2p/interface'
|
2
2
|
import { PeerMap } from '@libp2p/peer-collections'
|
3
|
-
import { createBloomFilter } from '@libp2p/utils/filters'
|
4
3
|
import { PeerQueue } from '@libp2p/utils/peer-queue'
|
5
4
|
import { multiaddr } from '@multiformats/multiaddr'
|
6
5
|
import { pbStream } from 'it-protobuf-stream'
|
7
6
|
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
|
8
|
-
import {
|
7
|
+
import { DEFAULT_RESERVATION_CONCURRENCY, RELAY_TAG, RELAY_V2_HOP_CODEC } from '../constants.js'
|
9
8
|
import { HopMessage, Status } from '../pb/index.js'
|
10
9
|
import { getExpirationMilliseconds } from '../utils.js'
|
11
10
|
import type { Reservation } from '../pb/index.js'
|
12
11
|
import type { TypedEventTarget, Libp2pEvents, AbortOptions, ComponentLogger, Logger, Connection, PeerId, PeerStore, Startable, Metrics } from '@libp2p/interface'
|
13
12
|
import type { ConnectionManager, TransportManager } from '@libp2p/interface-internal'
|
14
|
-
import type { Filter } from '@libp2p/utils/filters'
|
15
13
|
|
16
14
|
// allow refreshing a relay reservation if it will expire in the next 10 minutes
|
17
15
|
const REFRESH_WINDOW = (60 * 1000) * 10
|
@@ -71,7 +69,6 @@ interface RelayEntry {
|
|
71
69
|
export interface ReservationStoreEvents {
|
72
70
|
'relay:not-enough-relays': CustomEvent
|
73
71
|
'relay:removed': CustomEvent<PeerId>
|
74
|
-
'relay:created-reservation': CustomEvent<PeerId>
|
75
72
|
}
|
76
73
|
|
77
74
|
export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents> implements Startable {
|
@@ -87,7 +84,6 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
87
84
|
private readonly reservationCompletionTimeout: number
|
88
85
|
private started: boolean
|
89
86
|
private readonly log: Logger
|
90
|
-
private readonly relayFilter: Filter
|
91
87
|
|
92
88
|
constructor (components: RelayStoreComponents, init?: RelayStoreInit) {
|
93
89
|
super()
|
@@ -100,10 +96,9 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
100
96
|
this.events = components.events
|
101
97
|
this.reservations = new PeerMap()
|
102
98
|
this.maxDiscoveredRelays = init?.discoverRelays ?? 0
|
103
|
-
this.maxReservationQueueLength = init?.maxReservationQueueLength ??
|
104
|
-
this.reservationCompletionTimeout = init?.reservationCompletionTimeout ??
|
99
|
+
this.maxReservationQueueLength = init?.maxReservationQueueLength ?? 100
|
100
|
+
this.reservationCompletionTimeout = init?.reservationCompletionTimeout ?? 10000
|
105
101
|
this.started = false
|
106
|
-
this.relayFilter = createBloomFilter(100)
|
107
102
|
|
108
103
|
// ensure we don't listen on multiple relays simultaneously
|
109
104
|
this.reserveQueue = new PeerQueue({
|
@@ -128,13 +123,6 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
128
123
|
this.started = true
|
129
124
|
}
|
130
125
|
|
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
|
-
|
138
126
|
stop (): void {
|
139
127
|
this.reserveQueue.clear()
|
140
128
|
this.reservations.forEach(({ timeout }) => {
|
@@ -146,9 +134,9 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
146
134
|
|
147
135
|
/**
|
148
136
|
* If the number of current relays is beneath the configured `maxReservations`
|
149
|
-
* value, and the passed peer id is not our own, and we have a non-relayed
|
150
|
-
*
|
151
|
-
*
|
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
|
152
140
|
*/
|
153
141
|
async addRelay (peerId: PeerId, type: RelayType): Promise<void> {
|
154
142
|
if (this.peerId.equals(peerId)) {
|
@@ -157,25 +145,18 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
157
145
|
}
|
158
146
|
|
159
147
|
if (this.reserveQueue.size > this.maxReservationQueueLength) {
|
160
|
-
this.log('not adding
|
148
|
+
this.log('not adding relay as the queue is full')
|
161
149
|
return
|
162
150
|
}
|
163
151
|
|
164
152
|
if (this.reserveQueue.has(peerId)) {
|
165
|
-
this.log('
|
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)
|
153
|
+
this.log('relay peer is already in the reservation queue')
|
171
154
|
return
|
172
155
|
}
|
173
156
|
|
174
|
-
this.log('
|
157
|
+
this.log('add relay %p', peerId)
|
175
158
|
|
176
159
|
await this.reserveQueue.add(async () => {
|
177
|
-
const start = Date.now()
|
178
|
-
|
179
160
|
try {
|
180
161
|
// allow refresh of an existing reservation if it is about to expire
|
181
162
|
const existingReservation = this.reservations.get(peerId)
|
@@ -202,7 +183,6 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
202
183
|
}
|
203
184
|
|
204
185
|
const signal = AbortSignal.timeout(this.reservationCompletionTimeout)
|
205
|
-
setMaxListeners(Infinity, signal)
|
206
186
|
|
207
187
|
const connection = await this.connectionManager.openConnection(peerId, {
|
208
188
|
signal
|
@@ -250,12 +230,8 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
250
230
|
|
251
231
|
// listen on multiaddr that only the circuit transport is listening for
|
252
232
|
await this.transportManager.listen([multiaddr(`/p2p/${peerId.toString()}/p2p-circuit`)])
|
253
|
-
|
254
|
-
this.safeDispatchEvent('relay:created-reservation', {
|
255
|
-
detail: peerId
|
256
|
-
})
|
257
233
|
} catch (err) {
|
258
|
-
this.log.error('could not reserve slot on %p
|
234
|
+
this.log.error('could not reserve slot on %p', peerId, err)
|
259
235
|
|
260
236
|
// cancel the renewal timeout if it's been set
|
261
237
|
const reservation = this.reservations.get(peerId)
|
@@ -266,9 +242,6 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
266
242
|
|
267
243
|
// if listening failed, remove the reservation
|
268
244
|
this.reservations.delete(peerId)
|
269
|
-
|
270
|
-
// don't try this peer again
|
271
|
-
this.relayFilter.add(peerId.toBytes())
|
272
245
|
}
|
273
246
|
}, {
|
274
247
|
peerId
|
@@ -283,10 +256,6 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
283
256
|
return this.reservations.get(peerId)?.reservation
|
284
257
|
}
|
285
258
|
|
286
|
-
reservationCount (): number {
|
287
|
-
return this.reservations.size
|
288
|
-
}
|
289
|
-
|
290
259
|
async #createReservation (connection: Connection, options: AbortOptions): Promise<Reservation> {
|
291
260
|
options.signal?.throwIfAborted()
|
292
261
|
|
@@ -301,12 +270,11 @@ export class ReservationStore extends TypedEventEmitter<ReservationStoreEvents>
|
|
301
270
|
try {
|
302
271
|
response = await hopstr.read(options)
|
303
272
|
} catch (err: any) {
|
273
|
+
this.log.error('error parsing reserve message response from %p because', connection.remotePeer, err)
|
304
274
|
stream.abort(err)
|
305
275
|
throw err
|
306
276
|
} finally {
|
307
|
-
|
308
|
-
await stream.close(options)
|
309
|
-
}
|
277
|
+
await stream.close()
|
310
278
|
}
|
311
279
|
|
312
280
|
if (response.status === Status.OK && (response.reservation != null)) {
|
@@ -1,12 +1,11 @@
|
|
1
|
-
import { CodeError
|
1
|
+
import { CodeError } 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'
|
4
3
|
import { peerIdFromBytes, peerIdFromString } from '@libp2p/peer-id'
|
5
4
|
import { streamToMaConnection } from '@libp2p/utils/stream-to-ma-conn'
|
6
5
|
import * as mafmt from '@multiformats/mafmt'
|
7
6
|
import { multiaddr } from '@multiformats/multiaddr'
|
8
7
|
import { pbStream } from 'it-protobuf-stream'
|
9
|
-
import { CIRCUIT_PROTO_CODE,
|
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'
|
10
9
|
import { StopMessage, HopMessage, Status } from '../pb/index.js'
|
11
10
|
import { RelayDiscovery } from './discovery.js'
|
12
11
|
import { createListener } from './listener.js'
|
@@ -78,12 +77,8 @@ export class CircuitRelayTransport implements Transport {
|
|
78
77
|
this.maxOutboundStopStreams = init.maxOutboundStopStreams ?? defaults.maxOutboundStopStreams
|
79
78
|
this.stopTimeout = init.stopTimeout ?? defaults.stopTimeout
|
80
79
|
|
81
|
-
|
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
|
-
})
|
80
|
+
if (init.discoverRelays != null && init.discoverRelays > 0) {
|
81
|
+
this.discovery = new RelayDiscovery(components)
|
87
82
|
this.discovery.addEventListener('relay:discover', (evt) => {
|
88
83
|
this.reservationStore.addRelay(evt.detail, 'discovered')
|
89
84
|
.catch(err => {
|
@@ -94,12 +89,10 @@ export class CircuitRelayTransport implements Transport {
|
|
94
89
|
|
95
90
|
this.reservationStore = new ReservationStore(components, init)
|
96
91
|
this.reservationStore.addEventListener('relay:not-enough-relays', () => {
|
97
|
-
this.discovery?.
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
this.discovery?.stopDiscovery()
|
102
|
-
}
|
92
|
+
this.discovery?.discover()
|
93
|
+
.catch(err => {
|
94
|
+
this.log.error('could not discover relays', err)
|
95
|
+
})
|
103
96
|
})
|
104
97
|
|
105
98
|
this.started = false
|
@@ -110,6 +103,8 @@ export class CircuitRelayTransport implements Transport {
|
|
110
103
|
}
|
111
104
|
|
112
105
|
async start (): Promise<void> {
|
106
|
+
this.reservationStore.start()
|
107
|
+
|
113
108
|
await this.registrar.handle(RELAY_V2_STOP_CODEC, (data) => {
|
114
109
|
void this.onStop(data).catch(err => {
|
115
110
|
this.log.error('error while handling STOP protocol', err)
|
@@ -121,13 +116,18 @@ export class CircuitRelayTransport implements Transport {
|
|
121
116
|
runOnTransientConnection: true
|
122
117
|
})
|
123
118
|
|
124
|
-
await
|
119
|
+
await this.discovery?.start()
|
125
120
|
|
126
121
|
this.started = true
|
127
122
|
}
|
128
123
|
|
124
|
+
afterStart (): void {
|
125
|
+
this.discovery?.afterStart()
|
126
|
+
}
|
127
|
+
|
129
128
|
async stop (): Promise<void> {
|
130
|
-
|
129
|
+
this.discovery?.stop()
|
130
|
+
this.reservationStore.stop()
|
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 transient connection %a', maConn.remoteAddr)
|
235
235
|
return await this.upgrader.upgradeOutbound(maConn, {
|
236
|
-
transient:
|
236
|
+
transient: true
|
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 transient connection %a', maConn.remoteAddr)
|
350
350
|
await this.upgrader.upgradeInbound(maConn, {
|
351
|
-
transient:
|
351
|
+
transient: true
|
352
352
|
})
|
353
353
|
this.log('%s connection %a upgraded', 'inbound', maConn.remoteAddr)
|
354
354
|
}
|