@libp2p/circuit-relay-v2 1.0.24-62e32252a → 1.0.24-757fb2674
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|