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

Commit

Permalink
fix: simpler topologies (#164)
Browse files Browse the repository at this point in the history
A topology is a topology, let the registrar worry if it's handling multiple protocols.

Also, make the registrar do the work of calling topology methods instead of each topology maintaining its own set of event listeners.
  • Loading branch information
achingbrain authored Feb 11, 2022
1 parent 237efe5 commit 45fcaa1
Show file tree
Hide file tree
Showing 38 changed files with 325 additions and 527 deletions.
35 changes: 4 additions & 31 deletions packages/libp2p-interface-compliance-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,37 +88,9 @@
"import": "./dist/src/transport/utils/index.js",
"types": "./dist/src/transport/utils/index.d.ts"
},
"./utils/mock-connection": {
"import": "./dist/src/utils/mock-connection.js",
"types": "./dist/src/utils/mock-connection.d.ts"
},
"./utils/mock-connection-gater": {
"import": "./dist/src/utils/mock-connection-gater.js",
"types": "./dist/src/utils/mock-connection-gater.d.ts"
},
"./utils/mock-connection-manager": {
"import": "./dist/src/utils/mock-connection-manager.js",
"types": "./dist/src/utils/mock-connection-manager.d.ts"
},
"./utils/mock-multiaddr-connection": {
"import": "./dist/src/utils/mock-multiaddr-connection.js",
"types": "./dist/src/utils/mock-multiaddr-connection.d.ts"
},
"./utils/mock-muxer": {
"import": "./dist/src/utils/mock-muxer.js",
"types": "./dist/src/utils/mock-muxer.d.ts"
},
"./utils/mock-peer-store": {
"import": "./dist/src/utils/mock-peer-store.js",
"types": "./dist/src/utils/mock-peer-store.d.ts"
},
"./utils/mock-registrar": {
"import": "./dist/src/utils/mock-registrar.js",
"types": "./dist/src/utils/mock-registrar.d.ts"
},
"./utils/mock-upgrader": {
"import": "./dist/src/utils/mock-upgrader.js",
"types": "./dist/src/utils/mock-upgrader.d.ts"
"./mocks": {
"import": "./dist/src/mocks/index.js",
"types": "./dist/src/mocks/index.d.ts"
},
"./utils/peers": {
"import": "./dist/src/utils/peers.js",
Expand Down Expand Up @@ -242,6 +214,7 @@
"it-pair": "^2.0.0",
"it-pipe": "^2.0.2",
"it-pushable": "^2.0.1",
"it-stream-types": "^1.0.4",
"multiformats": "^9.4.10",
"p-defer": "^4.0.0",
"p-limit": "^4.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { PeerId } from '@libp2p/peer-id'
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
import { pipe } from 'it-pipe'
import { duplexPair } from 'it-pair/duplex'
import type { MultiaddrConnection } from '@libp2p/interfaces/transport'
import type { Connection, Stream, Metadata, ProtocolStream } from '@libp2p/interfaces/connection'
import type { Muxer } from '@libp2p/interfaces/stream-muxer'
import type { Duplex } from 'it-stream-types'
import { mockMuxer } from './muxer.js'

export async function mockConnection (maConn: MultiaddrConnection, direction: 'inbound' | 'outbound', muxer: Muxer): Promise<Connection> {
export async function mockConnection (maConn: MultiaddrConnection, direction: 'inbound' | 'outbound' = 'inbound', muxer: Muxer = mockMuxer()): Promise<Connection> {
const remoteAddr = maConn.remoteAddr
const remotePeerIdStr = remoteAddr.getPeerId()
const remotePeer = remotePeerIdStr != null ? PeerId.fromString(remotePeerIdStr) : await createEd25519PeerId()

const registry = new Map()
const streams: Stream[] = []
let streamId = 0

const registry = new Map()

void pipe(
maConn, muxer, maConn
)
Expand Down Expand Up @@ -64,3 +65,37 @@ export async function mockConnection (maConn: MultiaddrConnection, direction: 'i
}
}
}

export function mockStream (stream: Duplex<Uint8Array>): Stream {
return {
...stream,
close: () => {},
abort: () => {},
reset: () => {},
timeline: {
open: Date.now()
},
id: `stream-${Date.now()}`
}
}

export function connectionPair (): [ Connection, Connection ] {
const [d0, d1] = duplexPair<Uint8Array>()

return [
// @ts-expect-error not a complete implementation
{
newStream: async (multicodecs: string[]) => await Promise.resolve({
stream: mockStream(d0),
protocol: multicodecs[0]
})
},
// @ts-expect-error not a complete implementation
{
newStream: async (multicodecs: string[]) => await Promise.resolve({
stream: mockStream(d1),
protocol: multicodecs[0]
})
}
]
}
9 changes: 9 additions & 0 deletions packages/libp2p-interface-compliance-tests/src/mocks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

export { mockConnectionGater } from './connection-gater.js'
export { mockConnectionManager } from './connection-manager.js'
export { mockConnection, mockStream, connectionPair } from './connection.js'
export { mockMultiaddrConnection } from './multiaddr-connection.js'
export { mockMuxer } from './muxer.js'
export { mockRegistrar } from './registrar.js'
export { mockUpgrader } from './upgrader.js'
export type { MockUpgraderOptions } from './upgrader.js'
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import { Multiaddr } from '@multiformats/multiaddr'
import type { MultiaddrConnection } from '@libp2p/interfaces/transport'
import type { Duplex } from 'it-stream-types'

export function mockMultiaddrConnection (source: Duplex<Uint8Array>): MultiaddrConnection {
export function mockMultiaddrConnection (source: Duplex<Uint8Array> & Partial<MultiaddrConnection>): MultiaddrConnection {
const maConn: MultiaddrConnection = {
...source,
async close () {

},
timeline: {
open: Date.now()
},
remoteAddr: new Multiaddr('/ip4/127.0.0.1/tcp/4001')
remoteAddr: new Multiaddr('/ip4/127.0.0.1/tcp/4001'),
...source
}

return maConn
Expand Down
71 changes: 71 additions & 0 deletions packages/libp2p-interface-compliance-tests/src/mocks/registrar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import type { Registrar, StreamHandler } from '@libp2p/interfaces/registrar'
import type { Topology } from '@libp2p/interfaces/topology'

export class MockRegistrar implements Registrar {
private readonly topologies: Map<string, { topology: Topology, protocols: string[] }> = new Map()
private readonly handlers: Map<string, { handler: StreamHandler, protocols: string[] }> = new Map()

async handle (protocols: string | string[], handler: StreamHandler) {
if (!Array.isArray(protocols)) {
protocols = [protocols]
}

const id = `handler-id-${Math.random()}`

this.handlers.set(id, {
handler,
protocols
})

return id
}

async unhandle (id: string) {
this.handlers.delete(id)
}

getHandlers (protocol: string) {
const output: StreamHandler[] = []

for (const { handler, protocols } of this.handlers.values()) {
if (protocols.includes(protocol)) {
output.push(handler)
}
}

return output
}

register (protocols: string | string[], topology: Topology) {
if (!Array.isArray(protocols)) {
protocols = [protocols]
}

const id = `topology-id-${Math.random()}`

this.topologies.set(id, {
topology,
protocols
})

return id
}

unregister (id: string | string[]) {
if (!Array.isArray(id)) {
id = [id]
}

id.forEach(id => this.topologies.delete(id))
}

getTopologies (protocol: string) {
const output: Topology[] = []

return output
}
}

export function mockRegistrar () {
return new MockRegistrar()
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect } from 'aegir/utils/chai.js'
import { mockMuxer } from './mock-muxer.js'
import { mockConnection } from './mock-connection.js'
import { mockMuxer } from './muxer.js'
import { mockConnection } from './connection.js'
import type { Upgrader, MultiaddrConnection } from '@libp2p/interfaces/transport'
import type { Muxer } from '@libp2p/interfaces/stream-muxer'

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { expect } from 'aegir/utils/chai.js'
import sinon from 'sinon'
import * as PeerIdFactory from '@libp2p/peer-id-factory'
import peers from '../utils/peers.js'
import type { TestSetup } from '../index.js'
import type { Topology } from '@libp2p/interfaces/topology'
import type { PeerId } from '@libp2p/interfaces/peer-id'

export default (test: TestSetup<Topology>) => {
describe('topology', () => {
let topology: Topology, id: PeerId
let topology: Topology

beforeEach(async () => {
topology = await test.setup()

id = await PeerIdFactory.createFromJSON(peers[0])
})

afterEach(async () => {
Expand All @@ -26,13 +21,5 @@ export default (test: TestSetup<Topology>) => {
expect(topology.max).to.exist()
expect(topology.peers).to.exist()
})

it('should trigger "onDisconnect" on peer disconnected', () => {
// @ts-expect-error protected property
sinon.spy(topology, '_onDisconnect')
topology.disconnect(id)

expect(topology).to.have.nested.property('_onDisconnect.callCount', 1)
})
})
}
Loading

0 comments on commit 45fcaa1

Please sign in to comment.