From 4837430d8bcdbee0865eeba6fe694bc71fc6c9bb Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Tue, 10 May 2022 12:35:33 +0100 Subject: [PATCH] fix: encode enums correctly (#1210) Updates protons and regenerates protobuf code to encode enums correctly --- package.json | 13 ++------ src/circuit/pb/index.ts | 37 ++++++++++++++++++++--- src/circuit/transport.ts | 2 +- src/connection-manager/index.ts | 2 +- src/dht/dummy-dht.ts | 9 ++++++ src/fetch/pb/proto.ts | 13 ++++++-- src/identify/pb/message.ts | 3 +- src/insecure/pb/proto.ts | 19 ++++++++---- src/registrar.ts | 20 ++---------- test/registrar/registrar.spec.ts | 20 ++++++++++++ test/transports/transport-manager.spec.ts | 2 +- 11 files changed, 95 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index b4be4f38..1f0d018a 100644 --- a/package.json +++ b/package.json @@ -111,12 +111,8 @@ "@multiformats/mafmt": "^11.0.2", "@multiformats/multiaddr": "^10.1.8", "abortable-iterator": "^4.0.2", - "aggregate-error": "^4.0.0", "any-signal": "^3.0.0", - "bignumber.js": "^9.0.1", - "class-is": "^1.1.0", "datastore-core": "^7.0.0", - "debug": "^4.3.3", "err-code": "^3.0.1", "events": "^3.3.0", "hashlru": "^2.3.0", @@ -135,9 +131,7 @@ "it-sort": "^1.0.1", "it-stream-types": "^1.0.4", "it-take": "^1.0.2", - "it-to-buffer": "^2.0.2", "merge-options": "^3.0.4", - "mortice": "^3.0.0", "multiformats": "^9.6.3", "mutable-proxy": "^1.0.0", "node-forge": "^1.2.1", @@ -145,14 +139,12 @@ "p-retry": "^5.0.0", "p-settle": "^5.0.0", "private-ip": "^2.3.3", - "protons-runtime": "^1.0.2", + "protons-runtime": "^1.0.4", "retimer": "^3.0.0", "sanitize-filename": "^1.6.3", "set-delayed-interval": "^1.0.0", - "streaming-iterables": "^6.0.0", "timeout-abort-controller": "^3.0.0", "uint8arrays": "^3.0.0", - "varint": "^6.0.0", "wherearewe": "^1.0.0", "xsalsa20": "^1.1.0" }, @@ -189,13 +181,14 @@ "into-stream": "^7.0.0", "ipfs-http-client": "^56.0.1", "it-pushable": "^2.0.1", + "it-to-buffer": "^2.0.2", "nock": "^13.0.3", "npm-run-all": "^4.1.5", "p-defer": "^4.0.0", "p-event": "^5.0.1", "p-times": "^4.0.0", "p-wait-for": "^4.1.0", - "protons": "^3.0.2", + "protons": "^3.0.4", "rimraf": "^3.0.2", "sinon": "^13.0.1", "ts-sinon": "^2.0.2" diff --git a/src/circuit/pb/index.ts b/src/circuit/pb/index.ts index 5337cc4e..71ee1b9d 100644 --- a/src/circuit/pb/index.ts +++ b/src/circuit/pb/index.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-namespace */ import { enumeration, encodeMessage, decodeMessage, message, bytes } from 'protons-runtime' +import type { Codec } from 'protons-runtime' export interface CircuitRelay { type?: CircuitRelay.Type @@ -30,11 +31,31 @@ export namespace CircuitRelay { MALFORMED_MESSAGE = 'MALFORMED_MESSAGE' } + enum __StatusValues { + SUCCESS = 100, + HOP_SRC_ADDR_TOO_LONG = 220, + HOP_DST_ADDR_TOO_LONG = 221, + HOP_SRC_MULTIADDR_INVALID = 250, + HOP_DST_MULTIADDR_INVALID = 251, + HOP_NO_CONN_TO_DST = 260, + HOP_CANT_DIAL_DST = 261, + HOP_CANT_OPEN_DST_STREAM = 262, + HOP_CANT_SPEAK_RELAY = 270, + HOP_CANT_RELAY_TO_SELF = 280, + STOP_SRC_ADDR_TOO_LONG = 320, + STOP_DST_ADDR_TOO_LONG = 321, + STOP_SRC_MULTIADDR_INVALID = 350, + STOP_DST_MULTIADDR_INVALID = 351, + STOP_RELAY_REFUSED = 390, + MALFORMED_MESSAGE = 400 + } + export namespace Status { export const codec = () => { - return enumeration(Status) + return enumeration(__StatusValues) } } + export enum Type { HOP = 'HOP', STOP = 'STOP', @@ -42,18 +63,26 @@ export namespace CircuitRelay { CAN_HOP = 'CAN_HOP' } + enum __TypeValues { + HOP = 1, + STOP = 2, + STATUS = 3, + CAN_HOP = 4 + } + export namespace Type { export const codec = () => { - return enumeration(Type) + return enumeration(__TypeValues) } } + export interface Peer { id: Uint8Array addrs: Uint8Array[] } export namespace Peer { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'id', codec: bytes }, 2: { name: 'addrs', codec: bytes, repeats: true } @@ -69,7 +98,7 @@ export namespace CircuitRelay { } } - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'type', codec: CircuitRelay.Type.codec(), optional: true }, 2: { name: 'srcPeer', codec: CircuitRelay.Peer.codec(), optional: true }, diff --git a/src/circuit/transport.ts b/src/circuit/transport.ts index 4b4940d2..1ff71d4e 100644 --- a/src/circuit/transport.ts +++ b/src/circuit/transport.ts @@ -49,7 +49,7 @@ export class Circuit implements Transport, Initializable { } get [Symbol.toStringTag] () { - return this.constructor.name + return 'libp2p/circuit-relay-v1' } async _onProtocol (data: IncomingStreamData) { diff --git a/src/connection-manager/index.ts b/src/connection-manager/index.ts index 3c207bc4..65de6efd 100644 --- a/src/connection-manager/index.ts +++ b/src/connection-manager/index.ts @@ -296,7 +296,7 @@ export class DefaultConnectionManager extends EventEmitter implements DualDHT { + get [symbol] (): true { + return true + } + + get [Symbol.toStringTag] () { + return '@libp2p/dummy-dht' + } + get wan (): SingleDHT { throw errCode(new Error(messages.DHT_DISABLED), codes.DHT_DISABLED) } diff --git a/src/fetch/pb/proto.ts b/src/fetch/pb/proto.ts index b6c112ef..919f94a7 100644 --- a/src/fetch/pb/proto.ts +++ b/src/fetch/pb/proto.ts @@ -2,13 +2,14 @@ /* eslint-disable @typescript-eslint/no-namespace */ import { encodeMessage, decodeMessage, message, string, enumeration, bytes } from 'protons-runtime' +import type { Codec } from 'protons-runtime' export interface FetchRequest { identifier: string } export namespace FetchRequest { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'identifier', codec: string } }) @@ -35,13 +36,19 @@ export namespace FetchResponse { ERROR = 'ERROR' } + enum __StatusCodeValues { + OK = 0, + NOT_FOUND = 1, + ERROR = 2 + } + export namespace StatusCode { export const codec = () => { - return enumeration(StatusCode) + return enumeration(__StatusCodeValues) } } - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'status', codec: FetchResponse.StatusCode.codec() }, 2: { name: 'data', codec: bytes } diff --git a/src/identify/pb/message.ts b/src/identify/pb/message.ts index 72701356..04aad2a8 100644 --- a/src/identify/pb/message.ts +++ b/src/identify/pb/message.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-namespace */ import { encodeMessage, decodeMessage, message, string, bytes } from 'protons-runtime' +import type { Codec } from 'protons-runtime' export interface Identify { protocolVersion?: string @@ -14,7 +15,7 @@ export interface Identify { } export namespace Identify { - export const codec = () => { + export const codec = (): Codec => { return message({ 5: { name: 'protocolVersion', codec: string, optional: true }, 6: { name: 'agentVersion', codec: string, optional: true }, diff --git a/src/insecure/pb/proto.ts b/src/insecure/pb/proto.ts index 03909f9e..24b0020a 100644 --- a/src/insecure/pb/proto.ts +++ b/src/insecure/pb/proto.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-namespace */ import { encodeMessage, decodeMessage, message, bytes, enumeration } from 'protons-runtime' +import type { Codec } from 'protons-runtime' export interface Exchange { id?: Uint8Array @@ -9,7 +10,7 @@ export interface Exchange { } export namespace Exchange { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'id', codec: bytes, optional: true }, 2: { name: 'pubkey', codec: PublicKey.codec(), optional: true } @@ -32,19 +33,25 @@ export enum KeyType { ECDSA = 'ECDSA' } -export namespace KeyType { - export const codec = () => { - return enumeration(KeyType) - } +enum __KeyTypeValues { + RSA = 0, + Ed25519 = 1, + Secp256k1 = 2, + ECDSA = 3 } +export namespace KeyType { + export const codec = () => { + return enumeration(__KeyTypeValues) + } +} export interface PublicKey { Type: KeyType Data: Uint8Array } export namespace PublicKey { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'Type', codec: KeyType.codec() }, 2: { name: 'Data', codec: bytes } diff --git a/src/registrar.ts b/src/registrar.ts index 1e9e4d7c..ef6fd501 100644 --- a/src/registrar.ts +++ b/src/registrar.ts @@ -33,11 +33,11 @@ export class DefaultRegistrar implements Registrar { this.components = components this._onDisconnect = this._onDisconnect.bind(this) - this._onConnect = this._onConnect.bind(this) this._onProtocolChange = this._onProtocolChange.bind(this) this.components.getConnectionManager().addEventListener('peer:disconnect', this._onDisconnect) - this.components.getConnectionManager().addEventListener('peer:connect', this._onConnect) + + // happens after identify this.components.getPeerStore().addEventListener('change:protocols', this._onProtocolChange) } @@ -159,22 +159,6 @@ export class DefaultRegistrar implements Registrar { }) } - _onConnect (evt: CustomEvent) { - const connection = evt.detail - - void this.components.getPeerStore().protoBook.get(connection.remotePeer) - .then(peerProtocols => { - for (const { topology, protocols } of this.topologies.values()) { - if (supportsProtocol(peerProtocols, protocols)) { - topology.onConnect(connection.remotePeer, connection) - } - } - }) - .catch(err => { - log.error(err) - }) - } - /** * Check if a new peer support the multicodecs for this topology */ diff --git a/test/registrar/registrar.spec.ts b/test/registrar/registrar.spec.ts index 6b49bec8..259ae13e 100644 --- a/test/registrar/registrar.spec.ts +++ b/test/registrar/registrar.spec.ts @@ -20,6 +20,7 @@ import { DefaultConnectionManager } from '../../src/connection-manager/index.js' import { Plaintext } from '../../src/insecure/index.js' import { WebSockets } from '@libp2p/websockets' import { Mplex } from '@libp2p/mplex' +import type { PeerProtocolsChangeData } from '@libp2p/interfaces/peer-store' const protocol = '/test/1.0.0' @@ -145,6 +146,15 @@ describe('registrar', () => { detail: conn })) + // identify completes + await libp2p.components.getPeerStore().dispatchEvent(new CustomEvent('change:protocols', { + detail: { + peerId: conn.remotePeer, + protocols: [protocol], + oldProtocols: [] + } + })) + // remote peer disconnects await conn.close() await libp2p.components.getUpgrader().dispatchEvent(new CustomEvent('connectionEnd', { @@ -186,10 +196,20 @@ describe('registrar', () => { // Add protocol to peer and update it await libp2p.peerStore.protoBook.add(remotePeerId, [protocol]) + // remote peer connects await libp2p.components.getUpgrader().dispatchEvent(new CustomEvent('connection', { detail: conn })) + // identify completes + await libp2p.components.getPeerStore().dispatchEvent(new CustomEvent('change:protocols', { + detail: { + peerId: conn.remotePeer, + protocols: [protocol], + oldProtocols: [] + } + })) + await onConnectDefer.promise // Peer no longer supports the protocol our topology is registered for diff --git a/test/transports/transport-manager.spec.ts b/test/transports/transport-manager.spec.ts index 19d0902d..059b5c10 100644 --- a/test/transports/transport-manager.spec.ts +++ b/test/transports/transport-manager.spec.ts @@ -47,7 +47,7 @@ describe('Transport Manager (WebSockets)', () => { tm.add(transport) expect(tm.getTransports()).to.have.lengthOf(1) - await tm.remove(transport.constructor.name) + await tm.remove(transport[Symbol.toStringTag]) expect(tm.getTransports()).to.have.lengthOf(0) })