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

feat!: change connection encryption interface to uint8arraylist #278

Merged
merged 2 commits into from
Aug 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ docs
node_modules
# Lock files
package-lock.json
yarn.lock
yarn.lock
.vscode
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
"it-pair": "^2.0.2",
"it-pipe": "^2.0.3",
"it-stream-types": "^1.0.4",
"uint8arraylist": "^2.1.1",
"uint8arrays": "^3.0.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createMaConnPair } from './utils/index.js'
import type { TestSetup } from '@libp2p/interface-compliance-tests'
import type { ConnectionEncrypter } from '@libp2p/interface-connection-encrypter'
import type { PeerId } from '@libp2p/interface-peer-id'
import type { Source } from 'it-stream-types'
import { Uint8ArrayList } from 'uint8arraylist'

export default (common: TestSetup<ConnectionEncrypter>) => {
describe('interface-connection-encrypter compliance tests', () => {
Expand Down Expand Up @@ -56,16 +56,10 @@ export default (common: TestSetup<ConnectionEncrypter>) => {
void pipe(inboundResult.conn, inboundResult.conn)

// Send some data and collect the result
const input = uint8ArrayFromString('data to encrypt')
const input = new Uint8ArrayList(uint8ArrayFromString('data to encrypt'))
const result = await pipe(
[input],
outboundResult.conn,
// Convert BufferList to Buffer via slice
(source: Source<Uint8Array>) => (async function * toBuffer () {
for await (const chunk of source) {
yield chunk.slice()
}
})(),
async (source) => await all(source)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { duplexPair } from 'it-pair/duplex'
import { Multiaddr } from '@multiformats/multiaddr'
import type { MultiaddrConnection } from '@libp2p/interface-connection'
import type { Duplex } from 'it-stream-types'
import type { Uint8ArrayList } from 'uint8arraylist'

export function createMaConnPair (): [MultiaddrConnection, MultiaddrConnection] {
const [local, remote] = duplexPair<Uint8Array>()
export function createMaConnPair (): [MultiaddrConnection<Uint8ArrayList>, MultiaddrConnection<Uint8ArrayList>] {
const [local, remote] = duplexPair<Uint8ArrayList>()

function duplexToMaConn (duplex: Duplex<Uint8Array>): MultiaddrConnection {
const output: MultiaddrConnection = {
function duplexToMaConn (duplex: Duplex<Uint8ArrayList>): MultiaddrConnection<Uint8ArrayList> {
const output: MultiaddrConnection<Uint8ArrayList> = {
...duplex,
close: async () => {},
remoteAddr: new Multiaddr('/ip4/127.0.0.1/tcp/4001'),
Expand Down
3 changes: 2 additions & 1 deletion packages/interface-connection-encrypter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@
},
"dependencies": {
"@libp2p/interface-peer-id": "^1.0.0",
"it-stream-types": "^1.0.4"
"it-stream-types": "^1.0.4",
"uint8arraylist": "^2.1.1"
},
"devDependencies": {
"aegir": "^37.4.0"
Expand Down
7 changes: 4 additions & 3 deletions packages/interface-connection-encrypter/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { PeerId } from '@libp2p/interface-peer-id'
import type { Duplex } from 'it-stream-types'
import type { Uint8ArrayList } from 'uint8arraylist'

/**
* A libp2p connection encrypter module must be compliant to this interface
Expand All @@ -11,15 +12,15 @@ export interface ConnectionEncrypter {
/**
* Encrypt outgoing data to the remote party.
*/
secureOutbound: (localPeer: PeerId, connection: Duplex<Uint8Array>, remotePeer: PeerId) => Promise<SecuredConnection>
secureOutbound: (localPeer: PeerId, connection: Duplex<Uint8ArrayList>, remotePeer: PeerId) => Promise<SecuredConnection>
/**
* Decrypt incoming data.
*/
secureInbound: (localPeer: PeerId, connection: Duplex<Uint8Array>, remotePeer?: PeerId) => Promise<SecuredConnection>
secureInbound: (localPeer: PeerId, connection: Duplex<Uint8ArrayList>, remotePeer?: PeerId) => Promise<SecuredConnection>
}

export interface SecuredConnection {
conn: Duplex<Uint8Array>
conn: Duplex<Uint8ArrayList>
remoteEarlyData: Uint8Array
remotePeer: PeerId
}
3 changes: 2 additions & 1 deletion packages/interface-connection/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@
"@libp2p/interface-peer-id": "^1.0.0",
"@libp2p/interfaces": "^3.0.0",
"@multiformats/multiaddr": "^10.2.0",
"it-stream-types": "^1.0.4"
"it-stream-types": "^1.0.4",
"uint8arraylist": "^2.1.1"
},
"devDependencies": {
"aegir": "^37.4.0"
Expand Down
13 changes: 7 additions & 6 deletions packages/interface-connection/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { PeerId } from '@libp2p/interface-peer-id'
import type * as Status from './status.js'
import type { Duplex } from 'it-stream-types'
import type { AbortOptions } from '@libp2p/interfaces'
import type { Uint8ArrayList } from 'uint8arraylist'

export interface ConnectionTimeline {
open: number
Expand Down Expand Up @@ -71,7 +72,7 @@ export interface StreamStat {
* It may be encrypted and multiplexed depending on the
* configuration of the nodes.
*/
export interface Stream extends Duplex<Uint8Array> {
export interface Stream<T extends Uint8Array | Uint8ArrayList = Uint8Array> extends Duplex<T> {
/**
* Close a stream for reading and writing
*/
Expand Down Expand Up @@ -119,23 +120,23 @@ export interface Stream extends Duplex<Uint8Array> {
* multiplexed, depending on the configuration of the nodes
* between which the connection is made.
*/
export interface Connection {
export interface Connection<T extends Uint8Array | Uint8ArrayList = Uint8Array> {
id: string
stat: ConnectionStat
remoteAddr: Multiaddr
remotePeer: PeerId
tags: string[]
streams: Stream[]
streams: Array<Stream<T>>

newStream: (multicodecs: string | string[], options?: AbortOptions) => Promise<Stream>
addStream: (stream: Stream) => void
addStream: (stream: Stream<T>) => void
removeStream: (id: string) => void
close: () => Promise<void>
}

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

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

Expand Down Expand Up @@ -255,7 +256,7 @@ export interface MultiaddrConnectionTimeline {
* a peer. It is a low-level primitive and is the raw connection
* without encryption or stream multiplexing.
*/
export interface MultiaddrConnection extends Duplex<Uint8Array> {
export interface MultiaddrConnection<T extends Uint8Array | Uint8ArrayList = Uint8Array> extends Duplex<T> {
close: (err?: Error) => Promise<void>
remoteAddr: Multiaddr
timeline: MultiaddrConnectionTimeline
Expand Down
25 changes: 13 additions & 12 deletions packages/interface-mocks/src/connection-encrypter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import { UnexpectedPeerError } from '@libp2p/interface-connection-encrypter/erro
import { Multiaddr } from '@multiformats/multiaddr'
import type { ConnectionEncrypter } from '@libp2p/interface-connection-encrypter'
import type { Transform, Source } from 'it-stream-types'
import { Uint8ArrayList } from 'uint8arraylist'

// A basic transform that does nothing to the data
const transform = (): Transform<Uint8Array, Uint8Array> => {
return (source: Source<Uint8Array>) => (async function * () {
const transform = <T>(): Transform<T, T> => {
return (source: Source<T>) => (async function * () {
for await (const chunk of source) {
yield chunk
}
Expand All @@ -21,8 +22,8 @@ export function mockConnectionEncrypter () {
protocol: 'insecure',
secureInbound: async (localPeer, duplex, expectedPeer) => {
// 1. Perform a basic handshake.
const shake = handshake(duplex)
shake.write(localPeer.toBytes())
const shake = handshake<Uint8ArrayList>(duplex)
shake.write(new Uint8ArrayList(localPeer.toBytes()))
const remoteId = await shake.read()

if (remoteId == null) {
Expand All @@ -37,9 +38,9 @@ export function mockConnectionEncrypter () {
}

// 2. Create your encryption box/unbox wrapper
const wrapper = duplexPair<Uint8Array>()
const encrypt = transform() // Use transform iterables to modify data
const decrypt = transform()
const wrapper = duplexPair<Uint8ArrayList>()
const encrypt = transform<Uint8ArrayList>() // Use transform iterables to modify data
const decrypt = transform<Uint8ArrayList>()

void pipe(
wrapper[0], // We write to wrapper
Expand All @@ -66,8 +67,8 @@ export function mockConnectionEncrypter () {
},
secureOutbound: async (localPeer, duplex, remotePeer) => {
// 1. Perform a basic handshake.
const shake = handshake(duplex)
shake.write(localPeer.toBytes())
const shake = handshake<Uint8ArrayList>(duplex)
shake.write(new Uint8ArrayList(localPeer.toBytes()))
const remoteId = await shake.read()

if (remoteId == null) {
Expand All @@ -77,9 +78,9 @@ export function mockConnectionEncrypter () {
shake.rest()

// 2. Create your encryption box/unbox wrapper
const wrapper = duplexPair<Uint8Array>()
const encrypt = transform()
const decrypt = transform()
const wrapper = duplexPair<Uint8ArrayList>()
const encrypt = transform<Uint8ArrayList>()
const decrypt = transform<Uint8ArrayList>()

void pipe(
wrapper[0], // We write to wrapper
Expand Down