@libp2p/circuit-relay-v2 2.1.4 → 2.1.5-3bc9769b8
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 +4 -4
- package/dist/src/constants.d.ts +0 -5
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +0 -5
- package/dist/src/constants.js.map +1 -1
- package/dist/src/errors.d.ts +22 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +22 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +16 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/pb/index.d.ts +12 -1
- package/dist/src/pb/index.d.ts.map +1 -1
- package/dist/src/pb/index.js +78 -2
- package/dist/src/pb/index.js.map +1 -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/server/reservation-store.d.ts +5 -9
- package/dist/src/server/reservation-store.d.ts.map +1 -1
- package/dist/src/server/reservation-store.js +32 -33
- package/dist/src/server/reservation-store.js.map +1 -1
- package/dist/src/server/reservation-voucher.d.ts +1 -1
- package/dist/src/transport/discovery.d.ts +1 -0
- package/dist/src/transport/discovery.d.ts.map +1 -1
- package/dist/src/transport/discovery.js +38 -8
- package/dist/src/transport/discovery.js.map +1 -1
- package/dist/src/transport/index.d.ts +0 -6
- package/dist/src/transport/index.d.ts.map +1 -1
- package/dist/src/transport/index.js.map +1 -1
- package/dist/src/transport/listener.d.ts +3 -0
- package/dist/src/transport/listener.d.ts.map +1 -1
- package/dist/src/transport/listener.js +57 -27
- package/dist/src/transport/listener.js.map +1 -1
- package/dist/src/transport/reservation-store.d.ts +37 -14
- package/dist/src/transport/reservation-store.d.ts.map +1 -1
- package/dist/src/transport/reservation-store.js +144 -74
- package/dist/src/transport/reservation-store.js.map +1 -1
- package/dist/src/transport/transport.d.ts +2 -13
- package/dist/src/transport/transport.d.ts.map +1 -1
- package/dist/src/transport/transport.js +30 -54
- package/dist/src/transport/transport.js.map +1 -1
- package/dist/src/utils.d.ts +10 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +22 -8
- package/dist/src/utils.js.map +1 -1
- package/package.json +14 -12
- package/src/constants.ts +0 -7
- package/src/errors.ts +25 -0
- package/src/index.ts +19 -1
- package/src/pb/index.proto +20 -1
- package/src/pb/index.ts +99 -3
- package/src/server/index.ts +21 -11
- package/src/server/reservation-store.ts +38 -42
- package/src/server/reservation-voucher.ts +2 -2
- package/src/transport/discovery.ts +47 -9
- package/src/transport/index.ts +0 -7
- package/src/transport/listener.ts +75 -35
- package/src/transport/reservation-store.ts +209 -95
- package/src/transport/transport.ts +34 -76
- package/src/utils.ts +29 -8
- package/dist/typedoc-urls.json +0 -23
@@ -2,14 +2,14 @@ import { DialError, InvalidMessageError, serviceCapabilities, serviceDependencie
|
|
2
2
|
import { peerFilter } from '@libp2p/peer-collections'
|
3
3
|
import { peerIdFromMultihash, peerIdFromString } from '@libp2p/peer-id'
|
4
4
|
import { streamToMaConnection } from '@libp2p/utils/stream-to-ma-conn'
|
5
|
-
import * as mafmt from '@multiformats/mafmt'
|
6
5
|
import { multiaddr } from '@multiformats/multiaddr'
|
6
|
+
import { Circuit } from '@multiformats/multiaddr-matcher'
|
7
7
|
import { pbStream } from 'it-protobuf-stream'
|
8
8
|
import * as Digest from 'multiformats/hashes/digest'
|
9
9
|
import { CustomProgressEvent } from 'progress-events'
|
10
10
|
import { CIRCUIT_PROTO_CODE, DEFAULT_DISCOVERY_FILTER_ERROR_RATE, DEFAULT_DISCOVERY_FILTER_SIZE, MAX_CONNECTIONS, RELAY_V2_HOP_CODEC, RELAY_V2_STOP_CODEC } from '../constants.js'
|
11
11
|
import { StopMessage, HopMessage, Status } from '../pb/index.js'
|
12
|
-
import { LimitTracker } from '../utils.js'
|
12
|
+
import { CircuitListen, CircuitSearch, LimitTracker } from '../utils.js'
|
13
13
|
import { RelayDiscovery } from './discovery.js'
|
14
14
|
import { createListener } from './listener.js'
|
15
15
|
import { ReservationStore } from './reservation-store.js'
|
@@ -17,7 +17,7 @@ import type { CircuitRelayTransportComponents, CircuitRelayTransportInit } from
|
|
17
17
|
import type { Transport, CreateListenerOptions, Listener, Upgrader, ComponentLogger, Logger, Connection, Stream, ConnectionGater, PeerId, PeerStore, OutboundConnectionUpgradeEvents, DialTransportOptions, OpenConnectionProgressEvents } from '@libp2p/interface'
|
18
18
|
import type { AddressManager, ConnectionManager, IncomingStreamData, Registrar, TransportManager } from '@libp2p/interface-internal'
|
19
19
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
20
|
-
import type { ProgressEvent
|
20
|
+
import type { ProgressEvent } from 'progress-events'
|
21
21
|
|
22
22
|
const isValidStop = (request: StopMessage): request is Required<StopMessage> => {
|
23
23
|
if (request.peer == null) {
|
@@ -33,16 +33,6 @@ const isValidStop = (request: StopMessage): request is Required<StopMessage> =>
|
|
33
33
|
return true
|
34
34
|
}
|
35
35
|
|
36
|
-
interface ConnectOptions extends ProgressOptions<CircuitRelayDialEvents> {
|
37
|
-
stream: Stream
|
38
|
-
connection: Connection
|
39
|
-
destinationPeer: PeerId
|
40
|
-
destinationAddr: Multiaddr
|
41
|
-
relayAddr: Multiaddr
|
42
|
-
ma: Multiaddr
|
43
|
-
disconnectOnFailure: boolean
|
44
|
-
}
|
45
|
-
|
46
36
|
const defaults = {
|
47
37
|
maxInboundStopStreams: MAX_CONNECTIONS,
|
48
38
|
maxOutboundStopStreams: MAX_CONNECTIONS,
|
@@ -91,28 +81,23 @@ export class CircuitRelayTransport implements Transport<CircuitRelayDialEvents>
|
|
91
81
|
this.maxOutboundStopStreams = init.maxOutboundStopStreams ?? defaults.maxOutboundStopStreams
|
92
82
|
this.stopTimeout = init.stopTimeout ?? defaults.stopTimeout
|
93
83
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
this.reservationStore.addRelay(evt.detail, 'discovered')
|
102
|
-
.catch(err => {
|
84
|
+
this.discovery = new RelayDiscovery(components, {
|
85
|
+
filter: init.discoveryFilter ?? peerFilter(DEFAULT_DISCOVERY_FILTER_SIZE, DEFAULT_DISCOVERY_FILTER_ERROR_RATE)
|
86
|
+
})
|
87
|
+
this.discovery.addEventListener('relay:discover', (evt) => {
|
88
|
+
this.reservationStore.addRelay(evt.detail, 'discovered')
|
89
|
+
.catch(err => {
|
90
|
+
if (err.name !== 'HadEnoughRelaysError' && err.name !== 'RelayQueueFullError') {
|
103
91
|
this.log.error('could not add discovered relay %p', evt.detail, err)
|
104
|
-
}
|
105
|
-
|
106
|
-
}
|
107
|
-
|
92
|
+
}
|
93
|
+
})
|
94
|
+
})
|
108
95
|
this.reservationStore = new ReservationStore(components, init)
|
109
96
|
this.reservationStore.addEventListener('relay:not-enough-relays', () => {
|
110
97
|
this.discovery?.startDiscovery()
|
111
98
|
})
|
112
|
-
this.reservationStore.addEventListener('relay:
|
113
|
-
|
114
|
-
this.discovery?.stopDiscovery()
|
115
|
-
}
|
99
|
+
this.reservationStore.addEventListener('relay:found-enough-relays', () => {
|
100
|
+
this.discovery?.stopDiscovery()
|
116
101
|
})
|
117
102
|
|
118
103
|
this.started = false
|
@@ -184,15 +169,14 @@ export class CircuitRelayTransport implements Transport<CircuitRelayDialEvents>
|
|
184
169
|
const destinationId = destinationAddr.getPeerId()
|
185
170
|
|
186
171
|
if (relayId == null || destinationId == null) {
|
187
|
-
const errMsg = `
|
188
|
-
this.log.error(errMsg)
|
189
|
-
throw new DialError(errMsg)
|
172
|
+
const errMsg = `ircuit relay dial to ${ma.toString()} failed as address did not have both relay and destination PeerIDs`
|
173
|
+
this.log.error(`c${errMsg}`)
|
174
|
+
throw new DialError(`C${errMsg}`)
|
190
175
|
}
|
191
176
|
|
192
177
|
const relayPeer = peerIdFromString(relayId)
|
193
178
|
const destinationPeer = peerIdFromString(destinationId)
|
194
179
|
|
195
|
-
let disconnectOnFailure = false
|
196
180
|
const relayConnections = this.connectionManager.getConnections(relayPeer)
|
197
181
|
let relayConnection = relayConnections[0]
|
198
182
|
|
@@ -203,7 +187,6 @@ export class CircuitRelayTransport implements Transport<CircuitRelayDialEvents>
|
|
203
187
|
|
204
188
|
options.onProgress?.(new CustomProgressEvent('circuit-relay:open-connection'))
|
205
189
|
relayConnection = await this.connectionManager.openConnection(relayPeer, options)
|
206
|
-
disconnectOnFailure = true
|
207
190
|
} else {
|
208
191
|
options.onProgress?.(new CustomProgressEvent('circuit-relay:reuse-connection'))
|
209
192
|
}
|
@@ -212,52 +195,22 @@ export class CircuitRelayTransport implements Transport<CircuitRelayDialEvents>
|
|
212
195
|
|
213
196
|
try {
|
214
197
|
options.onProgress?.(new CustomProgressEvent('circuit-relay:open-hop-stream'))
|
215
|
-
stream = await relayConnection.newStream(RELAY_V2_HOP_CODEC)
|
216
|
-
|
217
|
-
return await this.connectV2({
|
218
|
-
stream,
|
219
|
-
connection: relayConnection,
|
220
|
-
destinationPeer,
|
221
|
-
destinationAddr,
|
222
|
-
relayAddr,
|
223
|
-
ma,
|
224
|
-
disconnectOnFailure,
|
225
|
-
onProgress: options.onProgress
|
226
|
-
})
|
227
|
-
} catch (err: any) {
|
228
|
-
this.log.error('circuit relay dial to destination %p via relay %p failed', destinationPeer, relayPeer, err)
|
198
|
+
stream = await relayConnection.newStream(RELAY_V2_HOP_CODEC, options)
|
229
199
|
|
230
|
-
if (stream != null) {
|
231
|
-
stream.abort(err)
|
232
|
-
}
|
233
|
-
disconnectOnFailure && await relayConnection.close()
|
234
|
-
throw err
|
235
|
-
}
|
236
|
-
}
|
237
|
-
|
238
|
-
async connectV2 (
|
239
|
-
{
|
240
|
-
stream, connection, destinationPeer,
|
241
|
-
destinationAddr, relayAddr, ma,
|
242
|
-
disconnectOnFailure,
|
243
|
-
onProgress
|
244
|
-
}: ConnectOptions
|
245
|
-
): Promise<Connection> {
|
246
|
-
try {
|
247
200
|
const pbstr = pbStream(stream)
|
248
201
|
const hopstr = pbstr.pb(HopMessage)
|
249
202
|
|
250
|
-
onProgress?.(new CustomProgressEvent('circuit-relay:write-connect-message'))
|
203
|
+
options.onProgress?.(new CustomProgressEvent('circuit-relay:write-connect-message'))
|
251
204
|
await hopstr.write({
|
252
205
|
type: HopMessage.Type.CONNECT,
|
253
206
|
peer: {
|
254
207
|
id: destinationPeer.toMultihash().bytes,
|
255
208
|
addrs: [multiaddr(destinationAddr).bytes]
|
256
209
|
}
|
257
|
-
})
|
210
|
+
}, options)
|
258
211
|
|
259
|
-
onProgress?.(new CustomProgressEvent('circuit-relay:read-connect-response'))
|
260
|
-
const status = await hopstr.read()
|
212
|
+
options.onProgress?.(new CustomProgressEvent('circuit-relay:read-connect-response'))
|
213
|
+
const status = await hopstr.read(options)
|
261
214
|
|
262
215
|
if (status.status !== Status.OK) {
|
263
216
|
throw new InvalidMessageError(`failed to connect via relay with status ${status?.status?.toString() ?? 'undefined'}`)
|
@@ -277,12 +230,13 @@ export class CircuitRelayTransport implements Transport<CircuitRelayDialEvents>
|
|
277
230
|
this.log('new outbound relayed connection %a', maConn.remoteAddr)
|
278
231
|
|
279
232
|
return await this.upgrader.upgradeOutbound(maConn, {
|
280
|
-
|
281
|
-
|
233
|
+
...options,
|
234
|
+
limits: limits.getLimits()
|
282
235
|
})
|
283
236
|
} catch (err: any) {
|
284
|
-
this.log.error(
|
285
|
-
|
237
|
+
this.log.error('circuit relay dial to destination %p via relay %p failed', destinationPeer, relayPeer, err)
|
238
|
+
stream?.abort(err)
|
239
|
+
|
286
240
|
throw err
|
287
241
|
}
|
288
242
|
}
|
@@ -305,7 +259,7 @@ export class CircuitRelayTransport implements Transport<CircuitRelayDialEvents>
|
|
305
259
|
multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [multiaddrs]
|
306
260
|
|
307
261
|
return multiaddrs.filter((ma) => {
|
308
|
-
return
|
262
|
+
return CircuitListen.exactMatch(ma) || CircuitSearch.exactMatch(ma)
|
309
263
|
})
|
310
264
|
}
|
311
265
|
|
@@ -313,7 +267,11 @@ export class CircuitRelayTransport implements Transport<CircuitRelayDialEvents>
|
|
313
267
|
* Filter check for all Multiaddrs that this transport can dial
|
314
268
|
*/
|
315
269
|
dialFilter (multiaddrs: Multiaddr[]): Multiaddr[] {
|
316
|
-
|
270
|
+
multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [multiaddrs]
|
271
|
+
|
272
|
+
return multiaddrs.filter((ma) => {
|
273
|
+
return Circuit.exactMatch(ma)
|
274
|
+
})
|
317
275
|
}
|
318
276
|
|
319
277
|
/**
|
package/src/utils.ts
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
import { P2P } from '@multiformats/multiaddr-matcher'
|
2
|
+
import { fmt, literal, and } from '@multiformats/multiaddr-matcher/utils'
|
1
3
|
import { anySignal } from 'any-signal'
|
2
4
|
import { CID } from 'multiformats/cid'
|
3
5
|
import { sha256 } from 'multiformats/hashes/sha2'
|
4
6
|
import { DurationLimitError, TransferLimitError } from './errors.js'
|
7
|
+
import type { RelayReservation } from './index.js'
|
5
8
|
import type { Limit } from './pb/index.js'
|
6
9
|
import type { ConnectionLimits, LoggerOptions, Stream } from '@libp2p/interface'
|
7
10
|
import type { Source } from 'it-stream-types'
|
@@ -34,16 +37,18 @@ async function * countStreamBytes (source: Source<Uint8Array | Uint8ArrayList>,
|
|
34
37
|
}
|
35
38
|
}
|
36
39
|
|
37
|
-
export function createLimitedRelay (src: Stream, dst: Stream, abortSignal: AbortSignal,
|
40
|
+
export function createLimitedRelay (src: Stream, dst: Stream, abortSignal: AbortSignal, reservation: RelayReservation, options: LoggerOptions): void {
|
38
41
|
function abortStreams (err: Error): void {
|
39
42
|
src.abort(err)
|
40
43
|
dst.abort(err)
|
41
44
|
}
|
42
45
|
|
43
|
-
|
46
|
+
// combine shutdown signal and reservation expiry signal
|
47
|
+
const signals = [abortSignal, reservation.signal]
|
44
48
|
|
45
|
-
if (limit?.duration != null) {
|
46
|
-
|
49
|
+
if (reservation.limit?.duration != null) {
|
50
|
+
options.log('limiting relayed connection duration to %dms', reservation.limit.duration)
|
51
|
+
signals.push(AbortSignal.timeout(reservation.limit.duration))
|
47
52
|
}
|
48
53
|
|
49
54
|
const signal = anySignal(signals)
|
@@ -53,15 +58,16 @@ export function createLimitedRelay (src: Stream, dst: Stream, abortSignal: Abort
|
|
53
58
|
|
54
59
|
let dataLimit: { remaining: bigint } | undefined
|
55
60
|
|
56
|
-
if (limit?.data != null) {
|
61
|
+
if (reservation.limit?.data != null) {
|
57
62
|
dataLimit = {
|
58
|
-
remaining: limit.data
|
63
|
+
remaining: reservation.limit.data
|
59
64
|
}
|
60
65
|
}
|
61
66
|
|
62
67
|
queueMicrotask(() => {
|
63
68
|
const onAbort = (): void => {
|
64
|
-
|
69
|
+
options.log('relayed connection reached time limit')
|
70
|
+
dst.abort(new DurationLimitError(`duration limit of ${reservation.limit?.duration} ms exceeded`))
|
65
71
|
}
|
66
72
|
|
67
73
|
signal.addEventListener('abort', onAbort, { once: true })
|
@@ -83,7 +89,8 @@ export function createLimitedRelay (src: Stream, dst: Stream, abortSignal: Abort
|
|
83
89
|
|
84
90
|
queueMicrotask(() => {
|
85
91
|
const onAbort = (): void => {
|
86
|
-
|
92
|
+
options.log('relayed connection reached time limit')
|
93
|
+
src.abort(new DurationLimitError(`duration limit of ${reservation.limit?.duration} ms exceeded`))
|
87
94
|
}
|
88
95
|
|
89
96
|
signal.addEventListener('abort', onAbort, { once: true })
|
@@ -185,3 +192,17 @@ export class LimitTracker {
|
|
185
192
|
return output
|
186
193
|
}
|
187
194
|
}
|
195
|
+
|
196
|
+
/**
|
197
|
+
* A custom matcher that tells us to listen on a particular relay
|
198
|
+
*/
|
199
|
+
export const CircuitListen = fmt(
|
200
|
+
and(P2P.matchers[0], literal('p2p-circuit'))
|
201
|
+
)
|
202
|
+
|
203
|
+
/**
|
204
|
+
* A custom matcher that tells us to discover available relays
|
205
|
+
*/
|
206
|
+
export const CircuitSearch = fmt(
|
207
|
+
literal('p2p-circuit')
|
208
|
+
)
|
package/dist/typedoc-urls.json
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"codec": "https://libp2p.github.io/js-libp2p/functions/_libp2p_circuit_relay_v2.Limit.codec.html",
|
3
|
-
"decode": "https://libp2p.github.io/js-libp2p/functions/_libp2p_circuit_relay_v2.Limit.decode.html",
|
4
|
-
"encode": "https://libp2p.github.io/js-libp2p/functions/_libp2p_circuit_relay_v2.Limit.encode.html",
|
5
|
-
"CircuitRelayServerComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayServerComponents.html",
|
6
|
-
"CircuitRelayServerInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayServerInit.html",
|
7
|
-
"CircuitRelayService": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayService.html",
|
8
|
-
".:CircuitRelayService": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayService.html",
|
9
|
-
"CircuitRelayServiceEvents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayServiceEvents.html",
|
10
|
-
".:CircuitRelayServiceEvents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayServiceEvents.html",
|
11
|
-
"CircuitRelayTransportComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayTransportComponents.html",
|
12
|
-
"CircuitRelayTransportInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.CircuitRelayTransportInit.html",
|
13
|
-
"Limit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.Limit-1.html",
|
14
|
-
"RelayDiscoveryComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.RelayDiscoveryComponents.html",
|
15
|
-
"RelayReservation": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.RelayReservation.html",
|
16
|
-
".:RelayReservation": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.RelayReservation.html",
|
17
|
-
"ServerReservationStoreInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.ServerReservationStoreInit.html",
|
18
|
-
"TransportReservationStoreInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_circuit_relay_v2.TransportReservationStoreInit.html",
|
19
|
-
"RELAY_V2_HOP_CODEC": "https://libp2p.github.io/js-libp2p/variables/_libp2p_circuit_relay_v2.RELAY_V2_HOP_CODEC.html",
|
20
|
-
"RELAY_V2_STOP_CODEC": "https://libp2p.github.io/js-libp2p/variables/_libp2p_circuit_relay_v2.RELAY_V2_STOP_CODEC.html",
|
21
|
-
"circuitRelayServer": "https://libp2p.github.io/js-libp2p/functions/_libp2p_circuit_relay_v2.circuitRelayServer.html",
|
22
|
-
"circuitRelayTransport": "https://libp2p.github.io/js-libp2p/functions/_libp2p_circuit_relay_v2.circuitRelayTransport.html"
|
23
|
-
}
|