From 55910c87975ca145baa0bfc4593931239aff3d44 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 3 Dec 2020 16:46:36 +0100 Subject: [PATCH 1/4] chore: minor changes from lodestar testing --- src/content-routing.js | 215 +++++++++++++++++++++-------------------- src/index.js | 4 +- src/peer-store/book.js | 13 +-- 3 files changed, 118 insertions(+), 114 deletions(-) diff --git a/src/content-routing.js b/src/content-routing.js index 185865d8..d2989d81 100644 --- a/src/content-routing.js +++ b/src/content-routing.js @@ -18,111 +18,118 @@ const pAny = require('p-any') * @property {Uint8Array} val */ -module.exports = (node) => { - const routers = node._modules.contentRouting || [] - const dht = node._dht +class ContentRouting { + /** + * @class + * @param {import('./')} libp2p + */ + constructor (libp2p) { + this.libp2p = libp2p + this.routers = libp2p._modules.contentRouting || [] + this.dht = libp2p._dht - // If we have the dht, make it first - if (dht) { - routers.unshift(dht) - } - - return { - /** - * Iterates over all content routers in series to find providers of the given key. - * Once a content router succeeds, iteration will stop. - * - * @param {CID} key - The CID key of the content to find - * @param {object} [options] - * @param {number} [options.timeout] - How long the query should run - * @param {number} [options.maxNumProviders] - maximum number of providers to find - * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} - */ - async * findProviders (key, options) { - if (!routers.length) { - throw errCode(new Error('No content routers available'), 'NO_ROUTERS_AVAILABLE') - } - - const result = await pAny( - routers.map(async (router) => { - const provs = await all(router.findProviders(key, options)) - - if (!provs || !provs.length) { - throw errCode(new Error('not found'), 'NOT_FOUND') - } - return provs - }) - ) - - for (const peer of result) { - yield peer - } - }, - - /** - * Iterates over all content routers in parallel to notify it is - * a provider of the given key. - * - * @param {CID} key - The CID key of the content to find - * @returns {Promise} - */ - async provide (key) { // eslint-disable-line require-await - if (!routers.length) { - throw errCode(new Error('No content routers available'), 'NO_ROUTERS_AVAILABLE') - } - - return Promise.all(routers.map((router) => router.provide(key))) - }, - - /** - * Store the given key/value pair in the DHT. - * - * @param {Uint8Array} key - * @param {Uint8Array} value - * @param {Object} [options] - put options - * @param {number} [options.minPeers] - minimum number of peers required to successfully put - * @returns {Promise} - */ - async put (key, value, options) { // eslint-disable-line require-await - if (!node.isStarted() || !dht.isStarted) { - throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED) - } - - return dht.put(key, value, options) - }, - - /** - * Get the value to the given key. - * Times out after 1 minute by default. - * - * @param {Uint8Array} key - * @param {Object} [options] - get options - * @param {number} [options.timeout] - optional timeout (default: 60000) - * @returns {Promise} - */ - async get (key, options) { // eslint-disable-line require-await - if (!node.isStarted() || !dht.isStarted) { - throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED) - } - - return dht.get(key, options) - }, - - /** - * Get the `n` values to the given key without sorting. - * - * @param {Uint8Array} key - * @param {number} nVals - * @param {Object} [options] - get options - * @param {number} [options.timeout] - optional timeout (default: 60000) - * @returns {Promise} - */ - async getMany (key, nVals, options) { // eslint-disable-line require-await - if (!node.isStarted() || !dht.isStarted) { - throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED) - } - - return dht.getMany(key, nVals, options) + // If we have the dht, make it first + if (this.dht) { + this.routers.unshift(this.dht) } } + + /** + * Iterates over all content routers in series to find providers of the given key. + * Once a content router succeeds, iteration will stop. + * + * @param {CID} key - The CID key of the content to find + * @param {object} [options] + * @param {number} [options.timeout] - How long the query should run + * @param {number} [options.maxNumProviders] - maximum number of providers to find + * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} + */ + async * findProviders (key, options) { + if (!this.routers.length) { + throw errCode(new Error('No content this.routers available'), 'NO_ROUTERS_AVAILABLE') + } + + const result = await pAny( + this.routers.map(async (router) => { + const provs = await all(router.findProviders(key, options)) + + if (!provs || !provs.length) { + throw errCode(new Error('not found'), 'NOT_FOUND') + } + return provs + }) + ) + + for (const peer of result) { + yield peer + } + } + + /** + * Iterates over all content routers in parallel to notify it is + * a provider of the given key. + * + * @param {CID} key - The CID key of the content to find + * @returns {Promise} + */ + async provide (key) { // eslint-disable-line require-await + if (!this.routers.length) { + throw errCode(new Error('No content routers available'), 'NO_ROUTERS_AVAILABLE') + } + + return Promise.all(this.routers.map((router) => router.provide(key))) + } + + /** + * Store the given key/value pair in the DHT. + * + * @param {Uint8Array} key + * @param {Uint8Array} value + * @param {Object} [options] - put options + * @param {number} [options.minPeers] - minimum number of peers required to successfully put + * @returns {Promise} + */ + async put (key, value, options) { // eslint-disable-line require-await + if (!this.libp2p.isStarted() || !this.dht.isStarted) { + throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED) + } + + return this.dht.put(key, value, options) + } + + /** + * Get the value to the given key. + * Times out after 1 minute by default. + * + * @param {Uint8Array} key + * @param {Object} [options] - get options + * @param {number} [options.timeout] - optional timeout (default: 60000) + * @returns {Promise} + */ + async get (key, options) { // eslint-disable-line require-await + if (!this.libp2p.isStarted() || !this.dht.isStarted) { + throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED) + } + + return this.dht.get(key, options) + } + + /** + * Get the `n` values to the given key without sorting. + * + * @param {Uint8Array} key + * @param {number} nVals + * @param {Object} [options] - get options + * @param {number} [options.timeout] - optional timeout (default: 60000) + * @returns {Promise} + */ + async getMany (key, nVals, options) { // eslint-disable-line require-await + if (!this.libp2p.isStarted() || !this.dht.isStarted) { + throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED) + } + + return this.dht.getMany(key, nVals, options) + } } + +module.exports = ContentRouting diff --git a/src/index.js b/src/index.js index 175dd724..f7daaa4c 100644 --- a/src/index.js +++ b/src/index.js @@ -11,7 +11,7 @@ const errCode = require('err-code') const PeerId = require('peer-id') const PeerRouting = require('./peer-routing') -const contentRouting = require('./content-routing') +const ContentRouting = require('./content-routing') const getPeer = require('./get-peer') const { validate: validateConfig } = require('./config') const { codes, messages } = require('./errors') @@ -242,7 +242,7 @@ class Libp2p extends EventEmitter { // Attach remaining APIs // peer and content routing will automatically get modules from _modules and _dht this.peerRouting = new PeerRouting(this) - this.contentRouting = contentRouting(this) + this.contentRouting = new ContentRouting(this) // Mount default protocols ping.mount(this) diff --git a/src/peer-store/book.js b/src/peer-store/book.js index 42bb749f..48855c15 100644 --- a/src/peer-store/book.js +++ b/src/peer-store/book.js @@ -13,9 +13,6 @@ const passthrough = data => data * @typedef {import('./')} PeerStore */ -/** - * @template T - */ class Book { /** * The Book is the skeleton for the PeerStore books. @@ -25,7 +22,7 @@ class Book { * @param {PeerStore} properties.peerStore - PeerStore instance. * @param {string} properties.eventName - Name of the event to emit by the PeerStore. * @param {string} properties.eventProperty - Name of the property to emit by the PeerStore. - * @param {(data: T) => T[]} [properties.eventTransformer] - Transformer function of the provided data for being emitted. + * @param {(data: any) => any[]} [properties.eventTransformer] - Transformer function of the provided data for being emitted. */ constructor ({ peerStore, eventName, eventProperty, eventTransformer = passthrough }) { this._ps = peerStore @@ -36,7 +33,7 @@ class Book { /** * Map known peers to their data. * - * @type {Map} + * @type {Map} */ this.data = new Map() } @@ -45,7 +42,7 @@ class Book { * Set known data of a provided peer. * * @param {PeerId} peerId - * @param {T[]|T} data + * @param {any[]|any} data */ set (peerId, data) { throw errcode(new Error('set must be implemented by the subclass'), 'ERR_NOT_IMPLEMENTED') @@ -56,7 +53,7 @@ class Book { * * @protected * @param {PeerId} peerId - peerId of the data to store - * @param {T} data - data to store. + * @param {any} data - data to store. * @param {Object} [options] - storing options. * @param {boolean} [options.emit = true] - emit the provided data. * @returns {void} @@ -90,7 +87,7 @@ class Book { * Returns `undefined` if there is no available data for the given peer. * * @param {PeerId} peerId - * @returns {T[]|T|undefined} + * @returns {any[]|any|undefined} */ get (peerId) { if (!PeerId.isPeerId(peerId)) { From 1992609f5814b031349b405ac3831af52a54d604 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Tue, 8 Dec 2020 15:49:51 +0100 Subject: [PATCH 2/4] chore: add libp2p modules typedef --- src/index.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index f7daaa4c..8c04e4d8 100644 --- a/src/index.js +++ b/src/index.js @@ -37,6 +37,9 @@ const IDENTIFY_PROTOCOLS = IdentifyService.multicodecs * @typedef {import('multiaddr')} Multiaddr * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream + * @typedef {import('libp2p-interfaces/src/transport/types').TransportFactory} TransportFactory + * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxerFactory} MuxerFactory + * @typedef {import('libp2p-interfaces/src/crypto/types').Crypto} Crypto * @typedef {import('libp2p-interfaces/src/pubsub')} Pubsub */ @@ -60,8 +63,13 @@ const IDENTIFY_PROTOCOLS = IdentifyService.multicodecs * @property {RelayOptions} [relay] * @property {Object} [transport] transport options indexed by transport key * + * @typedef {Object} Libp2pModules + * @property {TransportFactory[]} transport + * @property {MuxerFactory[]} streamMuxer + * @property {Crypto[]} connEncryption + * * @typedef {Object} Libp2pOptions - * @property {Object[]} modules libp2p modules to use + * @property {Libp2pModules} modules libp2p modules to use * @property {import('./address-manager').AddressManagerOptions} [addresses] * @property {import('./connection-manager').ConnectionManagerOptions} [connectionManager] * @property {import('./dialer').DialerOptions} [dialer] From 9b863bd4530d438a6b780ddfb57f7542ee883ec7 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 9 Dec 2020 11:42:24 +0100 Subject: [PATCH 3/4] chore: apply suggestions from code review Co-authored-by: Irakli Gozalishvili --- .github/workflows/main.yml | 4 ++-- src/circuit/circuit/stop.js | 4 ++-- src/circuit/circuit/stream-handler.js | 1 + src/connection-manager/index.js | 1 - src/content-routing.js | 10 +++++----- src/ping/index.js | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8641a8a5..ade1dcbc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v2 - run: yarn - run: yarn lint - # - uses: gozala/typescript-error-reporter-action@v1.0.4 + - uses: gozala/typescript-error-reporter-action@v1.0.8 - run: yarn build - run: yarn aegir dep-check - uses: ipfs/aegir/actions/bundle-size@master @@ -64,4 +64,4 @@ jobs: steps: - uses: actions/checkout@v2 - run: yarn - - run: cd examples && yarn && npm run test -- auto-relay \ No newline at end of file + - run: cd examples && yarn && npm run test -- auto-relay diff --git a/src/circuit/circuit/stop.js b/src/circuit/circuit/stop.js index 16192ad5..827d68d3 100644 --- a/src/circuit/circuit/stop.js +++ b/src/circuit/circuit/stop.js @@ -19,7 +19,7 @@ const { validateAddrs } = require('./utils') * Handles incoming STOP requests * * @private - * @param {object} options + * @param {Object} options * @param {Connection} options.connection * @param {CircuitPB} options.request - The CircuitRelay protobuf request (unencoded) * @param {StreamHandler} options.streamHandler @@ -50,7 +50,7 @@ module.exports.handleStop = function handleStop ({ * Creates a STOP request * * @private - * @param {object} options + * @param {Object} options * @param {Connection} options.connection * @param {CircuitPB} options.request - The CircuitRelay protobuf request (unencoded) * @returns {Promise} Resolves a duplex iterable diff --git a/src/circuit/circuit/stream-handler.js b/src/circuit/circuit/stream-handler.js index b63dcbff..d94576c5 100644 --- a/src/circuit/circuit/stream-handler.js +++ b/src/circuit/circuit/stream-handler.js @@ -48,6 +48,7 @@ class StreamHandler { * Encode and write array of buffers * * @param {CircuitPB} msg - An unencoded CircuitRelay protobuf message + * @returns {void} */ write (msg) { log('write message type %s', msg.type) diff --git a/src/connection-manager/index.js b/src/connection-manager/index.js index 4ebbd837..4add4840 100644 --- a/src/connection-manager/index.js +++ b/src/connection-manager/index.js @@ -52,7 +52,6 @@ const defaultOptions = { */ /** - * @extends EventEmitter * * @fires ConnectionManager#peer:connect Emitted when a new peer is connected. * @fires ConnectionManager#peer:disconnect Emitted when a peer is disconnected. diff --git a/src/content-routing.js b/src/content-routing.js index d2989d81..cba4a38b 100644 --- a/src/content-routing.js +++ b/src/content-routing.js @@ -70,14 +70,14 @@ class ContentRouting { * a provider of the given key. * * @param {CID} key - The CID key of the content to find - * @returns {Promise} + * @returns {Promise} */ - async provide (key) { // eslint-disable-line require-await + async provide (key) { if (!this.routers.length) { throw errCode(new Error('No content routers available'), 'NO_ROUTERS_AVAILABLE') } - return Promise.all(this.routers.map((router) => router.provide(key))) + await Promise.all(this.routers.map((router) => router.provide(key))) } /** @@ -89,7 +89,7 @@ class ContentRouting { * @param {number} [options.minPeers] - minimum number of peers required to successfully put * @returns {Promise} */ - async put (key, value, options) { // eslint-disable-line require-await + put (key, value, options) { if (!this.libp2p.isStarted() || !this.dht.isStarted) { throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED) } @@ -106,7 +106,7 @@ class ContentRouting { * @param {number} [options.timeout] - optional timeout (default: 60000) * @returns {Promise} */ - async get (key, options) { // eslint-disable-line require-await + get (key, options) { if (!this.libp2p.isStarted() || !this.dht.isStarted) { throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED) } diff --git a/src/ping/index.js b/src/ping/index.js index 53e3f679..eb8d7b96 100644 --- a/src/ping/index.js +++ b/src/ping/index.js @@ -33,7 +33,7 @@ async function ping (node, peer) { const { stream } = await node.dialProtocol(peer, PROTOCOL) - const start = new Date().getTime() + const start = Date.now() const data = crypto.randomBytes(PING_LENGTH) const [result] = await pipe( From b221e970374748df254f1484db7a7ee38cae55ef Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 9 Dec 2020 15:04:49 +0100 Subject: [PATCH 4/4] chore: address rest of review --- src/circuit/circuit/hop.js | 15 ++++++---- src/circuit/circuit/stop.js | 8 ++++-- src/circuit/circuit/stream-handler.js | 11 ++++++-- src/circuit/transport.js | 28 +++++++++++++++---- .../visibility-change-emitter.js | 2 -- src/dialer/index.js | 20 +++++++------ src/index.js | 15 ++++++---- src/keychain/cms.js | 6 ++-- src/peer-store/address-book.js | 2 +- src/types.ts | 11 ++++++++ 10 files changed, 81 insertions(+), 37 deletions(-) diff --git a/src/circuit/circuit/hop.js b/src/circuit/circuit/hop.js index 59de474f..3c1730ce 100644 --- a/src/circuit/circuit/hop.js +++ b/src/circuit/circuit/hop.js @@ -18,15 +18,18 @@ const { stop } = require('./stop') const multicodec = require('./../multicodec') /** + * @typedef {import('../../types').CircuitRequest} Request * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('./stream-handler')} StreamHandlerT + * @typedef {import('../transport')} Transport */ /** * @typedef {Object} HopRequest * @property {Connection} connection - * @property {any} request - * @property {any} streamHandler - * @property {import('../transport')} circuit + * @property {Request} request + * @property {StreamHandlerT} streamHandler + * @property {Transport} circuit */ /** @@ -110,7 +113,7 @@ async function handleHop ({ * * @param {object} options * @param {Connection} options.connection - Connection to the relay - * @param {CircuitPB} options.request + * @param {Request} options.request * @returns {Promise} */ async function hop ({ @@ -168,8 +171,8 @@ async function canHop ({ * * @param {Object} options * @param {Connection} options.connection - * @param {StreamHandler} options.streamHandler - * @param {import('../transport')} options.circuit + * @param {StreamHandlerT} options.streamHandler + * @param {Transport} options.circuit * @private */ function handleCanHop ({ diff --git a/src/circuit/circuit/stop.js b/src/circuit/circuit/stop.js index 827d68d3..2e41e48c 100644 --- a/src/circuit/circuit/stop.js +++ b/src/circuit/circuit/stop.js @@ -13,6 +13,8 @@ const { validateAddrs } = require('./utils') /** * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream + * @typedef {import('../../types').CircuitRequest} Request + * @typedef {import('./stream-handler')} StreamHandlerT */ /** @@ -21,8 +23,8 @@ const { validateAddrs } = require('./utils') * @private * @param {Object} options * @param {Connection} options.connection - * @param {CircuitPB} options.request - The CircuitRelay protobuf request (unencoded) - * @param {StreamHandler} options.streamHandler + * @param {Request} options.request - The CircuitRelay protobuf request (unencoded) + * @param {StreamHandlerT} options.streamHandler * @returns {Promise|void} Resolves a duplex iterable */ module.exports.handleStop = function handleStop ({ @@ -52,7 +54,7 @@ module.exports.handleStop = function handleStop ({ * @private * @param {Object} options * @param {Connection} options.connection - * @param {CircuitPB} options.request - The CircuitRelay protobuf request (unencoded) + * @param {Request} options.request - The CircuitRelay protobuf request (unencoded) * @returns {Promise} Resolves a duplex iterable */ module.exports.stop = async function stop ({ diff --git a/src/circuit/circuit/stream-handler.js b/src/circuit/circuit/stream-handler.js index d94576c5..5be2c6ed 100644 --- a/src/circuit/circuit/stream-handler.js +++ b/src/circuit/circuit/stream-handler.js @@ -9,13 +9,20 @@ const lp = require('it-length-prefixed') const handshake = require('it-handshake') const { CircuitRelay: CircuitPB } = require('../protocol') +/** + * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream + */ + +/** + * @template T + */ class StreamHandler { /** * Create a stream handler for connection * * @class * @param {object} options - * @param {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} options.stream - A duplex iterable + * @param {MuxedStream} options.stream - A duplex iterable * @param {number} [options.maxLength = 4096] - max bytes length of message */ constructor ({ stream, maxLength = 4096 }) { @@ -29,7 +36,7 @@ class StreamHandler { * Read and decode message * * @async - * @returns {Promise} + * @returns {Promise} */ async read () { const msg = await this.decoder.next() diff --git a/src/circuit/transport.js b/src/circuit/transport.js index 4eea0610..650bb97d 100644 --- a/src/circuit/transport.js +++ b/src/circuit/transport.js @@ -8,7 +8,6 @@ const log = Object.assign(debug('libp2p:circuit'), { const mafmt = require('mafmt') const multiaddr = require('multiaddr') const PeerId = require('peer-id') -const withIs = require('class-is') const { CircuitRelay: CircuitPB } = require('./protocol') const toConnection = require('libp2p-utils/src/stream-to-ma-conn') @@ -19,9 +18,12 @@ const { handleCanHop, handleHop, hop } = require('./circuit/hop') const { handleStop } = require('./circuit/stop') const StreamHandler = require('./circuit/stream-handler') +const transportSymbol = Symbol.for('@libp2p/js-libp2p-circuit/circuit') + /** * @typedef {import('multiaddr')} Multiaddr * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream */ class Circuit { @@ -45,6 +47,11 @@ class Circuit { this._registrar.handle(multicodec, this._onProtocol.bind(this)) } + /** + * @param {Object} props + * @param {Connection} props.connection + * @param {MuxedStream} props.stream + */ async _onProtocol ({ connection, stream }) { const streamHandler = new StreamHandler({ stream }) const request = await streamHandler.read() @@ -190,9 +197,20 @@ class Circuit { return mafmt.Circuit.matches(ma) }) } + + get [Symbol.toStringTag] () { + return 'Circuit' + } + + /** + * Checks if the given value is a Transport instance. + * + * @param {any} other + * @returns {other is Transport} + */ + static isTransport (other) { + return Boolean(other && other[transportSymbol]) + } } -/** - * @type {Circuit} - */ -module.exports = withIs(Circuit, { className: 'Circuit', symbolName: '@libp2p/js-libp2p-circuit/circuit' }) +module.exports = Circuit diff --git a/src/connection-manager/visibility-change-emitter.js b/src/connection-manager/visibility-change-emitter.js index b69ba78f..ebe5e7d0 100644 --- a/src/connection-manager/visibility-change-emitter.js +++ b/src/connection-manager/visibility-change-emitter.js @@ -13,8 +13,6 @@ const debug = require('debug')('latency-monitor:VisibilityChangeEmitter') /** * Listen to page visibility change events (i.e. when the page is focused / blurred) by an event emitter. * - * @extends {EventEmitter} - * * Warning: This does not work on all browsers, but should work on all modern browsers * * @example diff --git a/src/dialer/index.js b/src/dialer/index.js index c334d449..09ae2627 100644 --- a/src/dialer/index.js +++ b/src/dialer/index.js @@ -34,12 +34,14 @@ const { * @property {PeerStore} peerStore * @property {TransportManager} transportManager * + * @typedef {(addr:Multiaddr) => Promise} Resolver + * * @typedef {Object} DialerOptions - * @param {(addresses: Address[]) => Address[]} [options.addressSorter = publicAddressesFirst] - Sort the known addresses of a peer before trying to dial. + * @property {(addresses: Address[]) => Address[]} [options.addressSorter = publicAddressesFirst] - Sort the known addresses of a peer before trying to dial. * @property {number} [concurrency = MAX_PARALLEL_DIALS] - Number of max concurrent dials. * @property {number} [perPeerLimit = MAX_PER_PEER_DIALS] - Number of max concurrent dials per peer. * @property {number} [timeout = DIAL_TIMEOUT] - How long a dial attempt is allowed to take. - * @property {Object} [resolvers = {}] - multiaddr resolvers to use when dialing + * @property {Record} [resolvers = {}] - multiaddr resolvers to use when dialing * * @typedef DialTarget * @property {string} id @@ -240,13 +242,13 @@ class Dialer { return this._resolve(nm) })) - return recursiveMultiaddrs.flat() - .reduce((/** @type {Multiaddr[]} */ array, /** @type {Multiaddr} */ newM) => { - if (!array.find(m => m.equals(newM))) { - array.push(newM) - } - return array - }, []) // Unique addresses + const addrs = recursiveMultiaddrs.flat() + return addrs.reduce((array, newM) => { + if (!array.find(m => m.equals(newM))) { + array.push(newM) + } + return array + }, /** @type {Multiaddr[]} */([])) } /** diff --git a/src/index.js b/src/index.js index 8c04e4d8..7e620403 100644 --- a/src/index.js +++ b/src/index.js @@ -57,11 +57,11 @@ const IDENTIFY_PROTOCOLS = IdentifyService.multicodecs * @property {import('./circuit').AutoRelayOptions} autoRelay * * @typedef {Object} Libp2pConfig - * @property {any} [dht] dht module options + * @property {Object} [dht] dht module options * @property {PeerDiscoveryOptions} [peerDiscovery] * @property {Pubsub} [pubsub] pubsub module options * @property {RelayOptions} [relay] - * @property {Object} [transport] transport options indexed by transport key + * @property {Record} [transport] transport options indexed by transport key * * @typedef {Object} Libp2pModules * @property {TransportFactory[]} transport @@ -141,7 +141,6 @@ class Libp2p extends EventEmitter { const keychainOpts = Keychain.generateOptions() - /** @type {Keychain} */ this.keychain = new Keychain(this._options.keychain.datastore, { passPhrase: this._options.keychain.pass, ...keychainOpts, @@ -350,6 +349,10 @@ class Libp2p extends EventEmitter { * @returns {Promise} */ async loadKeychain () { + if (!this.keychain) { + return + } + try { await this.keychain.findKeyByName('self') } catch (err) { @@ -381,7 +384,7 @@ class Libp2p extends EventEmitter { * @returns {Promise} */ dial (peer, options) { - return this.dialProtocol(peer, undefined, options) + return this.dialProtocol(peer, [], options) } /** @@ -391,7 +394,7 @@ class Libp2p extends EventEmitter { * * @async * @param {PeerId|Multiaddr|string} peer - The peer to dial - * @param {undefined|string[]|string} protocols + * @param {null|string[]|string} protocols * @param {object} [options] * @param {AbortSignal} [options.signal] * @returns {Promise} @@ -407,7 +410,7 @@ class Libp2p extends EventEmitter { } // If a protocol was provided, create a new stream - if (protocols) { + if (protocols && protocols.length) { return connection.newStream(protocols) } diff --git a/src/keychain/cms.js b/src/keychain/cms.js index c808ed69..3ba99cfb 100644 --- a/src/keychain/cms.js +++ b/src/keychain/cms.js @@ -22,7 +22,7 @@ class CMS { /** * Creates a new instance with a keychain * - * @param {Keychain} keychain - the available keys + * @param {import('./index')} keychain - the available keys */ constructor (keychain) { if (!keychain) { @@ -39,7 +39,7 @@ class CMS { * * @param {string} name - The local key name. * @param {Uint8Array} plain - The data to encrypt. - * @returns {undefined} + * @returns {Promise} */ async encrypt (name, plain) { if (!(plain instanceof Uint8Array)) { @@ -69,7 +69,7 @@ class CMS { * exists, an Error is returned with the property 'missingKeys'. It is array of key ids. * * @param {Uint8Array} cmsData - The CMS encrypted data to decrypt. - * @returns {undefined} + * @returns {Promise} */ async decrypt (cmsData) { if (!(cmsData instanceof Uint8Array)) { diff --git a/src/peer-store/address-book.js b/src/peer-store/address-book.js index 516d908f..74b6049a 100644 --- a/src/peer-store/address-book.js +++ b/src/peer-store/address-book.js @@ -206,7 +206,7 @@ class AddressBook extends Book { log(`stored provided multiaddrs for ${id}`) // Notify the existance of a new peer - if (!(entry && entry.addresses)) { + if (!entry) { this._ps.emit('peer', peerId) } diff --git a/src/types.ts b/src/types.ts index fe58c0e5..3e87d7c8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -43,6 +43,17 @@ export type CAN_HOP = 4; export type CircuitType = HOP | STOP | STATUS | CAN_HOP +export type CircuitPeer = { + id: Uint8Array + addrs: Uint8Array[] +} + +export type CircuitRequest = { + type: CircuitType + dstPeer: CircuitPeer + srcPeer: CircuitPeer +} + export type CircuitMessageProto = { encode(value: any): Uint8Array decode(bytes: Uint8Array): any