@libp2p/circuit-relay-v2 2.1.4 → 2.1.5-3bc9769b8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
}
|