@libp2p/mplex 9.0.12 → 10.0.0-06e6d235f
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/README.md +6 -4
- package/dist/index.min.js +5 -5
- package/dist/src/decode.js.map +1 -1
- package/dist/src/encode.d.ts +2 -1
- package/dist/src/encode.d.ts.map +1 -1
- package/dist/src/encode.js +5 -21
- package/dist/src/encode.js.map +1 -1
- package/dist/src/index.d.ts +3 -13
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/mplex.d.ts +8 -5
- package/dist/src/mplex.d.ts.map +1 -1
- package/dist/src/mplex.js +31 -25
- package/dist/src/mplex.js.map +1 -1
- package/dist/src/stream.d.ts +3 -1
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +2 -3
- package/dist/src/stream.js.map +1 -1
- package/package.json +14 -11
- package/src/encode.ts +5 -25
- package/src/index.ts +8 -18
- package/src/mplex.ts +39 -32
- package/src/stream.ts +4 -3
- package/dist/typedoc-urls.json +0 -6
package/src/mplex.ts
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
import { CodeError } from '@libp2p/interface
|
2
|
-
import {
|
3
|
-
import { abortableSource } from 'abortable-iterator'
|
1
|
+
import { CodeError } from '@libp2p/interface'
|
2
|
+
import { closeSource } from '@libp2p/utils/close-source'
|
4
3
|
import { pipe } from 'it-pipe'
|
5
|
-
import { type
|
4
|
+
import { type Pushable, pushable } from 'it-pushable'
|
6
5
|
import { RateLimiterMemory } from 'rate-limiter-flexible'
|
7
6
|
import { toString as uint8ArrayToString } from 'uint8arrays'
|
8
7
|
import { Decoder } from './decode.js'
|
@@ -10,14 +9,10 @@ import { encode } from './encode.js'
|
|
10
9
|
import { MessageTypes, MessageTypeNames, type Message } from './message-types.js'
|
11
10
|
import { createStream, type MplexStream } from './stream.js'
|
12
11
|
import type { MplexInit } from './index.js'
|
13
|
-
import type { AbortOptions } from '@libp2p/interface'
|
14
|
-
import type { Stream } from '@libp2p/interface/connection'
|
15
|
-
import type { StreamMuxer, StreamMuxerInit } from '@libp2p/interface/stream-muxer'
|
12
|
+
import type { AbortOptions, ComponentLogger, Logger, Stream, StreamMuxer, StreamMuxerInit } from '@libp2p/interface'
|
16
13
|
import type { Sink, Source } from 'it-stream-types'
|
17
14
|
import type { Uint8ArrayList } from 'uint8arraylist'
|
18
15
|
|
19
|
-
const log = logger('libp2p:mplex')
|
20
|
-
|
21
16
|
const MAX_STREAMS_INBOUND_STREAMS_PER_CONNECTION = 1024
|
22
17
|
const MAX_STREAMS_OUTBOUND_STREAMS_PER_CONNECTION = 1024
|
23
18
|
const MAX_STREAM_BUFFER_SIZE = 1024 * 1024 * 4 // 4MB
|
@@ -41,6 +36,10 @@ function printMessage (msg: Message): any {
|
|
41
36
|
return output
|
42
37
|
}
|
43
38
|
|
39
|
+
export interface MplexComponents {
|
40
|
+
logger: ComponentLogger
|
41
|
+
}
|
42
|
+
|
44
43
|
interface MplexStreamMuxerInit extends MplexInit, StreamMuxerInit {
|
45
44
|
/**
|
46
45
|
* The default timeout to use in ms when shutting down the muxer.
|
@@ -52,19 +51,23 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
52
51
|
public protocol = '/mplex/6.7.0'
|
53
52
|
|
54
53
|
public sink: Sink<Source<Uint8ArrayList | Uint8Array>, Promise<void>>
|
55
|
-
public source: AsyncGenerator<Uint8Array>
|
54
|
+
public source: AsyncGenerator<Uint8ArrayList | Uint8Array>
|
56
55
|
|
56
|
+
private readonly log: Logger
|
57
57
|
private _streamId: number
|
58
58
|
private readonly _streams: { initiators: Map<number, MplexStream>, receivers: Map<number, MplexStream> }
|
59
59
|
private readonly _init: MplexStreamMuxerInit
|
60
|
-
private readonly _source:
|
60
|
+
private readonly _source: Pushable<Message>
|
61
61
|
private readonly closeController: AbortController
|
62
62
|
private readonly rateLimiter: RateLimiterMemory
|
63
63
|
private readonly closeTimeout: number
|
64
|
+
private readonly logger: ComponentLogger
|
64
65
|
|
65
|
-
constructor (init?: MplexStreamMuxerInit) {
|
66
|
+
constructor (components: MplexComponents, init?: MplexStreamMuxerInit) {
|
66
67
|
init = init ?? {}
|
67
68
|
|
69
|
+
this.log = components.logger.forComponent('libp2p:mplex')
|
70
|
+
this.logger = components.logger
|
68
71
|
this._streamId = 0
|
69
72
|
this._streams = {
|
70
73
|
/**
|
@@ -87,7 +90,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
87
90
|
/**
|
88
91
|
* An iterable source
|
89
92
|
*/
|
90
|
-
this._source =
|
93
|
+
this._source = pushable<Message>({
|
91
94
|
objectMode: true,
|
92
95
|
onEnd: (): void => {
|
93
96
|
// the source has ended, we can't write any more messages to gracefully
|
@@ -103,7 +106,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
103
106
|
})
|
104
107
|
this.source = pipe(
|
105
108
|
this._source,
|
106
|
-
source => encode(source
|
109
|
+
source => encode(source)
|
107
110
|
)
|
108
111
|
|
109
112
|
/**
|
@@ -199,7 +202,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
199
202
|
_newStream (options: { id: number, name: string, type: 'initiator' | 'receiver', registry: Map<number, MplexStream> }): MplexStream {
|
200
203
|
const { id, name, type, registry } = options
|
201
204
|
|
202
|
-
log('new %s stream %s', type, id)
|
205
|
+
this.log('new %s stream %s', type, id)
|
203
206
|
|
204
207
|
if (type === 'initiator' && this._streams.initiators.size === (this._init.maxOutboundStreams ?? MAX_STREAMS_OUTBOUND_STREAMS_PER_CONNECTION)) {
|
205
208
|
throw new CodeError('Too many outbound streams open', 'ERR_TOO_MANY_OUTBOUND_STREAMS')
|
@@ -210,15 +213,15 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
210
213
|
}
|
211
214
|
|
212
215
|
const send = async (msg: Message): Promise<void> => {
|
213
|
-
if (log.enabled) {
|
214
|
-
log.trace('%s stream %s send', type, id, printMessage(msg))
|
216
|
+
if (this.log.enabled) {
|
217
|
+
this.log.trace('%s stream %s send', type, id, printMessage(msg))
|
215
218
|
}
|
216
219
|
|
217
220
|
this._source.push(msg)
|
218
221
|
}
|
219
222
|
|
220
223
|
const onEnd = (): void => {
|
221
|
-
log('%s stream with id %s and protocol %s ended', type, id, stream.protocol)
|
224
|
+
this.log('%s stream with id %s and protocol %s ended', type, id, stream.protocol)
|
222
225
|
registry.delete(id)
|
223
226
|
|
224
227
|
if (this._init.onStreamEnd != null) {
|
@@ -226,7 +229,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
226
229
|
}
|
227
230
|
}
|
228
231
|
|
229
|
-
const stream = createStream({ id, name, send, type, onEnd, maxMsgSize: this._init.maxMsgSize })
|
232
|
+
const stream = createStream({ id, name, send, type, onEnd, maxMsgSize: this._init.maxMsgSize, logger: this.logger })
|
230
233
|
registry.set(id, stream)
|
231
234
|
return stream
|
232
235
|
}
|
@@ -237,11 +240,13 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
237
240
|
*/
|
238
241
|
_createSink (): Sink<Source<Uint8ArrayList | Uint8Array>, Promise<void>> {
|
239
242
|
const sink: Sink<Source<Uint8ArrayList | Uint8Array>, Promise<void>> = async source => {
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
})
|
243
|
+
const abortListener = (): void => {
|
244
|
+
closeSource(source, this.log)
|
245
|
+
}
|
244
246
|
|
247
|
+
this.closeController.signal.addEventListener('abort', abortListener)
|
248
|
+
|
249
|
+
try {
|
245
250
|
const decoder = new Decoder(this._init.maxMsgSize, this._init.maxUnprocessedMessageQueueSize)
|
246
251
|
|
247
252
|
for await (const chunk of source) {
|
@@ -252,8 +257,10 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
252
257
|
|
253
258
|
this._source.end()
|
254
259
|
} catch (err: any) {
|
255
|
-
log('error in sink', err)
|
260
|
+
this.log('error in sink', err)
|
256
261
|
this._source.end(err) // End the source with an error
|
262
|
+
} finally {
|
263
|
+
this.closeController.signal.removeEventListener('abort', abortListener)
|
257
264
|
}
|
258
265
|
}
|
259
266
|
|
@@ -263,14 +270,14 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
263
270
|
async _handleIncoming (message: Message): Promise<void> {
|
264
271
|
const { id, type } = message
|
265
272
|
|
266
|
-
if (log.enabled) {
|
267
|
-
log.trace('incoming message', printMessage(message))
|
273
|
+
if (this.log.enabled) {
|
274
|
+
this.log.trace('incoming message', printMessage(message))
|
268
275
|
}
|
269
276
|
|
270
277
|
// Create a new stream?
|
271
278
|
if (message.type === MessageTypes.NEW_STREAM) {
|
272
279
|
if (this._streams.receivers.size === (this._init.maxInboundStreams ?? MAX_STREAMS_INBOUND_STREAMS_PER_CONNECTION)) {
|
273
|
-
log('too many inbound streams open')
|
280
|
+
this.log('too many inbound streams open')
|
274
281
|
|
275
282
|
// not going to allow this stream, send the reset message manually
|
276
283
|
// instead of setting it up just to tear it down
|
@@ -285,7 +292,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
285
292
|
try {
|
286
293
|
await this.rateLimiter.consume('new-stream', 1)
|
287
294
|
} catch {
|
288
|
-
log('rate limit hit when opening too many new streams over the inbound stream limit - closing remote connection')
|
295
|
+
this.log('rate limit hit when opening too many new streams over the inbound stream limit - closing remote connection')
|
289
296
|
// since there's no backpressure in mplex, the only thing we can really do to protect ourselves is close the connection
|
290
297
|
this.abort(new Error('Too many open streams'))
|
291
298
|
return
|
@@ -307,7 +314,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
307
314
|
const stream = list.get(id)
|
308
315
|
|
309
316
|
if (stream == null) {
|
310
|
-
log('missing stream %s for message type %s', id, MessageTypeNames[type])
|
317
|
+
this.log('missing stream %s for message type %s', id, MessageTypeNames[type])
|
311
318
|
|
312
319
|
// if the remote keeps sending us messages for streams that have been
|
313
320
|
// closed or were never opened they may be attacking us so if they do
|
@@ -315,7 +322,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
315
322
|
try {
|
316
323
|
await this.rateLimiter.consume('missing-stream', 1)
|
317
324
|
} catch {
|
318
|
-
log('rate limit hit when receiving messages for streams that do not exist - closing remote connection')
|
325
|
+
this.log('rate limit hit when receiving messages for streams that do not exist - closing remote connection')
|
319
326
|
// since there's no backpressure in mplex, the only thing we can really do to protect ourselves is close the connection
|
320
327
|
this.abort(new Error('Too many messages for missing streams'))
|
321
328
|
return
|
@@ -355,10 +362,10 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
355
362
|
stream.reset()
|
356
363
|
break
|
357
364
|
default:
|
358
|
-
log('unknown message type %s', type)
|
365
|
+
this.log('unknown message type %s', type)
|
359
366
|
}
|
360
367
|
} catch (err: any) {
|
361
|
-
log.error('error while processing message', err)
|
368
|
+
this.log.error('error while processing message', err)
|
362
369
|
stream.abort(err)
|
363
370
|
}
|
364
371
|
}
|
package/src/stream.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
import { AbstractStream, type AbstractStreamInit } from '@libp2p/
|
2
|
-
import { logger } from '@libp2p/logger'
|
1
|
+
import { AbstractStream, type AbstractStreamInit } from '@libp2p/utils/abstract-stream'
|
3
2
|
import { Uint8ArrayList } from 'uint8arraylist'
|
4
3
|
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
5
4
|
import { MAX_MSG_SIZE } from './decode.js'
|
6
5
|
import { InitiatorMessageTypes, ReceiverMessageTypes } from './message-types.js'
|
7
6
|
import type { Message } from './message-types.js'
|
7
|
+
import type { ComponentLogger } from '@libp2p/interface'
|
8
8
|
|
9
9
|
export interface Options {
|
10
10
|
id: number
|
@@ -13,6 +13,7 @@ export interface Options {
|
|
13
13
|
onEnd?(err?: Error): void
|
14
14
|
type?: 'initiator' | 'receiver'
|
15
15
|
maxMsgSize?: number
|
16
|
+
logger: ComponentLogger
|
16
17
|
}
|
17
18
|
|
18
19
|
interface MplexStreamInit extends AbstractStreamInit {
|
@@ -87,6 +88,6 @@ export function createStream (options: Options): MplexStream {
|
|
87
88
|
maxDataSize: maxMsgSize,
|
88
89
|
onEnd,
|
89
90
|
send,
|
90
|
-
log: logger(`libp2p:mplex:stream:${type}:${id}`)
|
91
|
+
log: options.logger.forComponent(`libp2p:mplex:stream:${type}:${id}`)
|
91
92
|
})
|
92
93
|
}
|
package/dist/typedoc-urls.json
DELETED
@@ -1,6 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"MplexInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_mplex.MplexInit.html",
|
3
|
-
".:MplexInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_mplex.MplexInit.html",
|
4
|
-
"mplex": "https://libp2p.github.io/js-libp2p/functions/_libp2p_mplex.mplex.html",
|
5
|
-
".:mplex": "https://libp2p.github.io/js-libp2p/functions/_libp2p_mplex.mplex.html"
|
6
|
-
}
|