Skip to content
This repository was archived by the owner on Jun 26, 2023. It is now read-only.

Commit 1ebe269

Browse files
feat!: change stream muxer interface (#279)
* feat!: change connection encryption interface to uint8arraylist * feat!: change stream muxer interface * chore: update types * chore: linting * chore: remove unused dep * chore: types Co-authored-by: achingbrain <[email protected]>
1 parent 1fa580c commit 1ebe269

File tree

9 files changed

+34
-31
lines changed

9 files changed

+34
-31
lines changed

packages/interface-connection/src/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export interface StreamStat {
7272
* It may be encrypted and multiplexed depending on the
7373
* configuration of the nodes.
7474
*/
75-
export interface Stream<T extends Uint8Array | Uint8ArrayList = Uint8Array> extends Duplex<T> {
75+
export interface Stream extends Duplex<Uint8ArrayList, Uint8ArrayList | Uint8Array> {
7676
/**
7777
* Close a stream for reading and writing
7878
*/
@@ -120,23 +120,23 @@ export interface Stream<T extends Uint8Array | Uint8ArrayList = Uint8Array> exte
120120
* multiplexed, depending on the configuration of the nodes
121121
* between which the connection is made.
122122
*/
123-
export interface Connection<T extends Uint8Array | Uint8ArrayList = Uint8Array> {
123+
export interface Connection {
124124
id: string
125125
stat: ConnectionStat
126126
remoteAddr: Multiaddr
127127
remotePeer: PeerId
128128
tags: string[]
129-
streams: Array<Stream<T>>
129+
streams: Stream[]
130130

131131
newStream: (multicodecs: string | string[], options?: AbortOptions) => Promise<Stream>
132-
addStream: (stream: Stream<T>) => void
132+
addStream: (stream: Stream) => void
133133
removeStream: (id: string) => void
134134
close: () => Promise<void>
135135
}
136136

137137
export const symbol = Symbol.for('@libp2p/connection')
138138

139-
export function isConnection (other: any): other is Connection<Uint8Array | Uint8ArrayList> {
139+
export function isConnection (other: any): other is Connection {
140140
return other != null && Boolean(other[symbol])
141141
}
142142

packages/interface-metrics/src/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ export interface Stats {
4646
push: (counter: string, inc: number) => void
4747
}
4848

49-
export interface TrackStreamOptions <T extends Duplex<Uint8Array>> {
49+
export interface TrackStreamOptions {
5050
/**
5151
* A duplex iterable stream
5252
*/
53-
stream: T
53+
stream: Duplex<{ byteLength: number }, any>
5454

5555
/**
5656
* The id of the remote peer that's connected
@@ -111,7 +111,7 @@ export interface StreamMetrics {
111111
* When the `PeerId` is known, `Metrics.updatePlaceholder` should be called
112112
* with the placeholder string returned from here, and the known `PeerId`.
113113
*/
114-
trackStream: <T extends Duplex<Uint8Array>> (data: TrackStreamOptions<T>) => T
114+
trackStream: (data: TrackStreamOptions) => void
115115
}
116116

117117
/**

packages/interface-mocks/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
"@libp2p/interface-transport": "^1.0.0",
152152
"@libp2p/interfaces": "^3.0.0",
153153
"@libp2p/logger": "^2.0.0",
154-
"@libp2p/multistream-select": "^2.0.0",
154+
"@libp2p/multistream-select": "^3.0.0",
155155
"@libp2p/peer-id": "^1.1.12",
156156
"@libp2p/peer-id-factory": "^1.0.12",
157157
"@multiformats/multiaddr": "^10.2.0",

packages/interface-mocks/src/connection.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ import type { PeerId } from '@libp2p/interface-peer-id'
88
import { mockMultiaddrConnection } from './multiaddr-connection.js'
99
import type { Registrar } from '@libp2p/interface-registrar'
1010
import { mockRegistrar } from './registrar.js'
11-
import { Dialer, Listener } from '@libp2p/multistream-select'
11+
import * as mss from '@libp2p/multistream-select'
1212
import { logger } from '@libp2p/logger'
1313
import * as STATUS from '@libp2p/interface-connection/status'
1414
import type { Multiaddr } from '@multiformats/multiaddr'
1515
import type { StreamMuxer } from '@libp2p/interface-stream-muxer'
1616
import type { Components } from '@libp2p/components'
1717
import type { AbortOptions } from '@libp2p/interfaces'
1818
import errCode from 'err-code'
19+
import type { Uint8ArrayList } from 'uint8arraylist'
1920

2021
const log = logger('libp2p:mock-connection')
2122

@@ -79,8 +80,7 @@ class MockConnection implements Connection {
7980

8081
const id = `${Math.random()}`
8182
const stream: Stream = this.muxer.newStream(id)
82-
const mss = new Dialer(stream)
83-
const result = await mss.select(protocols, options)
83+
const result = await mss.select(stream, protocols, options)
8484

8585
const streamWithProtocol: Stream = {
8686
...stream,
@@ -130,9 +130,8 @@ export function mockConnection (maConn: MultiaddrConnection, opts: MockConnectio
130130
const muxer = muxerFactory.createStreamMuxer({
131131
direction: direction,
132132
onIncomingStream: (muxedStream) => {
133-
const mss = new Listener(muxedStream)
134133
try {
135-
mss.handle(registrar.getProtocols())
134+
mss.handle(muxedStream, registrar.getProtocols())
136135
.then(({ stream, protocol }) => {
137136
log('%s: incoming stream opened on %s', direction, protocol)
138137
muxedStream = { ...muxedStream, ...stream }
@@ -169,7 +168,7 @@ export function mockConnection (maConn: MultiaddrConnection, opts: MockConnectio
169168
return connection
170169
}
171170

172-
export function mockStream (stream: Duplex<Uint8Array>): Stream {
171+
export function mockStream (stream: Duplex<Uint8ArrayList, Uint8ArrayList | Uint8Array>): Stream {
173172
return {
174173
...stream,
175174
close: () => {},

packages/interface-mocks/src/muxer.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type StreamMessage = DataMessage | ResetMessage | CloseMessage | CreateMessage
4646

4747
class MuxedStream {
4848
public id: string
49-
public input: Pushable<Uint8Array>
49+
public input: Pushable<Uint8ArrayList>
5050
public stream: Stream
5151
public type: 'initiator' | 'recipient'
5252

@@ -299,7 +299,7 @@ class MockMuxer implements StreamMuxer {
299299
try {
300300
await pipe(
301301
abortableSource(source, this.closeController.signal),
302-
(source) => map(source, buf => uint8ArrayToString(buf)),
302+
(source) => map(source, buf => uint8ArrayToString(buf.subarray())),
303303
ndjson.parse,
304304
async (source) => {
305305
for await (const message of source) {
@@ -344,7 +344,7 @@ class MockMuxer implements StreamMuxer {
344344
}
345345

346346
if (message.type === 'data') {
347-
muxedStream.input.push(uint8ArrayFromString(message.chunk, 'base64'))
347+
muxedStream.input.push(new Uint8ArrayList(uint8ArrayFromString(message.chunk, 'base64')))
348348
} else if (message.type === 'reset') {
349349
this.log('-> reset stream %s %s', muxedStream.type, muxedStream.stream.id)
350350
muxedStream.stream.reset()
@@ -422,10 +422,10 @@ class MockMuxerFactory implements StreamMuxerFactory {
422422
void pipe(
423423
mockMuxer.streamInput,
424424
ndjson.stringify,
425-
(source) => map(source, str => uint8ArrayFromString(str)),
425+
(source) => map(source, str => new Uint8ArrayList(uint8ArrayFromString(str))),
426426
async (source) => {
427427
for await (const buf of source) {
428-
mockMuxer.input.push(buf)
428+
mockMuxer.input.push(buf.subarray())
429429
}
430430
}
431431
)

packages/interface-stream-muxer-compliance-tests/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@
146146
"it-stream-types": "^1.0.4",
147147
"p-defer": "^4.0.0",
148148
"p-limit": "^4.0.0",
149+
"uint8arraylist": "^2.1.2",
149150
"uint8arrays": "^3.0.0"
150151
}
151152
}

packages/interface-stream-muxer-compliance-tests/src/base-test.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ import type { TestSetup } from '@libp2p/interface-compliance-tests'
1313
import type { Stream } from '@libp2p/interface-connection'
1414
import type { StreamMuxerFactory } from '@libp2p/interface-stream-muxer'
1515
import type { Source, Duplex } from 'it-stream-types'
16+
import { Uint8ArrayList } from 'uint8arraylist'
1617

17-
async function drainAndClose (stream: Duplex<Uint8Array>) {
18+
async function drainAndClose (stream: Duplex<any>) {
1819
return await pipe([], stream, drain)
1920
}
2021

@@ -144,7 +145,7 @@ export default (common: TestSetup<StreamMuxerFactory>) => {
144145
})
145146

146147
it('Open a stream on one side, write, open a stream on the other side', async () => {
147-
const toString = (source: Source<Uint8Array>) => map(source, (u) => uint8ArrayToString(u))
148+
const toString = (source: Source<Uint8ArrayList>) => map(source, (u) => uint8ArrayToString(u.subarray()))
148149
const p = duplexPair<Uint8Array>()
149150
const onDialerStreamPromise: DeferredPromise<Stream> = defer()
150151
const onListenerStreamPromise: DeferredPromise<Stream> = defer()
@@ -169,8 +170,8 @@ export default (common: TestSetup<StreamMuxerFactory>) => {
169170
const dialerConn = dialer.newStream()
170171
const listenerConn = listener.newStream()
171172

172-
void pipe([uint8ArrayFromString('hey')], dialerConn)
173-
void pipe([uint8ArrayFromString('hello')], listenerConn)
173+
void pipe([new Uint8ArrayList(uint8ArrayFromString('hey'))], dialerConn)
174+
void pipe([new Uint8ArrayList(uint8ArrayFromString('hello'))], listenerConn)
174175

175176
const [
176177
dialerStream,

packages/interface-stream-muxer-compliance-tests/src/close-test.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { TestSetup } from '@libp2p/interface-compliance-tests'
1010
import type { StreamMuxerFactory } from '@libp2p/interface-stream-muxer'
1111
import pDefer from 'p-defer'
1212
import all from 'it-all'
13+
import { Uint8ArrayList } from 'uint8arraylist'
1314

1415
function randomBuffer () {
1516
return uint8ArrayFromString(Math.random().toString())
@@ -18,7 +19,7 @@ function randomBuffer () {
1819
const infiniteRandom = {
1920
[Symbol.asyncIterator]: async function * () {
2021
while (true) {
21-
yield randomBuffer()
22+
yield new Uint8ArrayList(randomBuffer())
2223
await delay(50)
2324
}
2425
}
@@ -220,7 +221,7 @@ export default (common: TestSetup<StreamMuxerFactory>) => {
220221

221222
// Pause, and then send some data and close the first stream
222223
await delay(50)
223-
await pipe([randomBuffer()], stream, drain)
224+
await pipe([new Uint8ArrayList(randomBuffer())], stream, drain)
224225
closed = true
225226

226227
// Abort all the other streams later
@@ -232,7 +233,7 @@ export default (common: TestSetup<StreamMuxerFactory>) => {
232233
})
233234

234235
it('can close a stream for writing', async () => {
235-
const deferred = pDefer<any>()
236+
const deferred = pDefer<Error>()
236237

237238
const p = duplexPair<Uint8Array>()
238239
const dialerFactory = await common.setup()
@@ -257,8 +258,8 @@ export default (common: TestSetup<StreamMuxerFactory>) => {
257258
expect(results).to.eql(data)
258259

259260
try {
260-
await stream.sink([randomBuffer()])
261-
} catch (err) {
261+
await stream.sink([new Uint8ArrayList(randomBuffer())])
262+
} catch (err: any) {
262263
deferred.resolve(err)
263264
}
264265

@@ -283,7 +284,7 @@ export default (common: TestSetup<StreamMuxerFactory>) => {
283284
const p = duplexPair<Uint8Array>()
284285
const dialerFactory = await common.setup()
285286
const dialer = dialerFactory.createStreamMuxer({ direction: 'outbound' })
286-
const data = [randomBuffer(), randomBuffer()]
287+
const data = [randomBuffer(), randomBuffer()].map(d => new Uint8ArrayList(d))
287288

288289
const listenerFactory = await common.setup()
289290
const listener = listenerFactory.createStreamMuxer({

packages/interface-stream-muxer-compliance-tests/src/spawner.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
66
import drain from 'it-drain'
77
import all from 'it-all'
88
import type { StreamMuxer, StreamMuxerInit } from '@libp2p/interface-stream-muxer'
9+
import { Uint8ArrayList } from 'uint8arraylist'
910

1011
export default async (createMuxer: (init?: StreamMuxerInit) => Promise<StreamMuxer>, nStreams: number, nMsg: number, limit?: number) => {
1112
const [dialerSocket, listenerSocket] = duplexPair<Uint8Array>()
1213

13-
const msg = uint8ArrayFromString('simple msg')
14+
const msg = new Uint8ArrayList(uint8ArrayFromString('simple msg'))
1415

1516
const listener = await createMuxer({
1617
direction: 'inbound',

0 commit comments

Comments
 (0)