From 26c40c8dfda18ff067663f7988ce22e27dbf016c Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Mon, 16 Nov 2020 11:56:18 +0100 Subject: [PATCH 01/18] chore: add typedefs --- src/address-manager/index.js | 20 +++--- src/circuit/auto-relay.js | 17 ++++- src/circuit/index.js | 17 +++++ src/connection-manager/index.js | 43 +++++++----- src/connection-manager/latency-monitor.js | 18 +++-- .../visibility-change-emitter.js | 13 ++-- src/content-routing.js | 7 +- src/dialer/dial-request.js | 20 ++++-- src/dialer/index.js | 65 +++++++++-------- src/get-peer.js | 9 ++- src/identify/index.js | 69 ++++++++----------- src/index.js | 52 +++++++++++++- src/insecure/plaintext.js | 11 +++ src/metrics/index.js | 20 ++++-- src/peer-routing.js | 5 ++ src/peer-store/address-book.js | 55 +++++++-------- src/peer-store/book.js | 9 ++- src/peer-store/index.js | 4 +- src/peer-store/key-book.js | 4 +- src/peer-store/metadata-book.js | 6 +- src/peer-store/persistent/index.js | 14 ++-- src/peer-store/proto-book.js | 6 +- src/ping/index.js | 6 ++ src/pnet/index.js | 10 ++- src/record/envelope/index.js | 7 +- src/record/peer-record/index.js | 13 +++- src/record/utils.js | 6 +- src/registrar.js | 10 ++- src/transport-manager.js | 25 ++++--- src/upgrader.js | 4 ++ 30 files changed, 382 insertions(+), 183 deletions(-) diff --git a/src/address-manager/index.js b/src/address-manager/index.js index 314f0a1ae6..9a9bc0b0cb 100644 --- a/src/address-manager/index.js +++ b/src/address-manager/index.js @@ -7,17 +7,19 @@ log.error = debug('libp2p:addresses:error') const multiaddr = require('multiaddr') /** - * Responsible for managing the peer addresses. - * Peers can specify their listen and announce addresses. - * The listen addresses will be used by the libp2p transports to listen for new connections, - * while the announce addresses will be used for the peer addresses' to other peers in the network. + * @typedef {Object} AddressManagerOptions + * @property {Array} [listen = []] - list of multiaddrs string representation to listen. + * @property {Array} [announce = []] - list of multiaddrs string representation to announce. */ class AddressManager { /** + * Responsible for managing the peer addresses. + * Peers can specify their listen and announce addresses. + * The listen addresses will be used by the libp2p transports to listen for new connections, + * while the announce addresses will be used for the peer addresses' to other peers in the network. + * * @class - * @param {object} [options] - * @param {Array} [options.listen = []] - list of multiaddrs string representation to listen. - * @param {Array} [options.announce = []] - list of multiaddrs string representation to announce. + * @param {AddressManagerOptions} [options] */ constructor ({ listen = [], announce = [] } = {}) { this.listen = new Set(listen) @@ -27,7 +29,7 @@ class AddressManager { /** * Get peer listen multiaddrs. * - * @returns {Array} + * @returns {Array} */ getListenAddrs () { return Array.from(this.listen).map((a) => multiaddr(a)) @@ -36,7 +38,7 @@ class AddressManager { /** * Get peer announcing multiaddrs. * - * @returns {Array} + * @returns {Array} */ getAnnounceAddrs () { return Array.from(this.announce).map((a) => multiaddr(a)) diff --git a/src/circuit/auto-relay.js b/src/circuit/auto-relay.js index 6b9a40392d..3740bc34fe 100644 --- a/src/circuit/auto-relay.js +++ b/src/circuit/auto-relay.js @@ -19,14 +19,25 @@ const { RELAY_RENDEZVOUS_NS } = require('./constants') +/** + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('../peer-store/address-book').Address} Address + */ + +/** + * @typedef {Object} AutoRelayProperties + * @property {import('../')} libp2p + * + * @typedef {Object} AutoRelayOptions + * @property {number} [maxListeners = 1] - maximum number of relays to listen. + */ + class AutoRelay { /** * Creates an instance of AutoRelay. * * @class - * @param {object} props - * @param {Libp2p} props.libp2p - * @param {number} [props.maxListeners = 1] - maximum number of relays to listen. + * @param {AutoRelayProperties & AutoRelayOptions} props */ constructor ({ libp2p, maxListeners = 1 }) { this._libp2p = libp2p diff --git a/src/circuit/index.js b/src/circuit/index.js index 9e556f7f18..91cb685106 100644 --- a/src/circuit/index.js +++ b/src/circuit/index.js @@ -17,6 +17,23 @@ const { RELAY_RENDEZVOUS_NS } = require('./constants') +/** + * @typedef {import('../')} Libp2p + * + * @typedef {Object} RelayAdvertiseOptions + * @property {number} [bootDelay = ADVERTISE_BOOT_DELAY] + * @property {boolean} [enabled = true] + * @property {number} [ttl = ADVERTISE_TTL] + * + * @typedef {Object} HopOptions + * @property {boolean} [enabled = false] + * @property {boolean} [active = false] + * + * @typedef {Object} AutoRelayOptions + * @property {number} [maxListeners = 2] - maximum number of relays to listen. + * @property {boolean} [enabled = false] + */ + class Relay { /** * Creates an instance of Relay. diff --git a/src/connection-manager/index.js b/src/connection-manager/index.js index 1b1d807cb5..388c99409a 100644 --- a/src/connection-manager/index.js +++ b/src/connection-manager/index.js @@ -31,29 +31,40 @@ const defaultOptions = { } /** - * Responsible for managing known connections. + * @typedef {import('../')} Libp2p + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + */ + +/** + * @typedef {Object} ConnectionManagerOptions + * @property {number} [maxConnections = Infinity] - The maximum number of connections allowed. + * @property {number} [minConnections = 0] - The minimum number of connections to avoid pruning. + * @property {number} [maxData = Infinity] - The max data (in and out), per average interval to allow. + * @property {number} [maxSentData = Infinity] - The max outgoing data, per average interval to allow. + * @property {number} [maxReceivedData = Infinity] - The max incoming data, per average interval to allow. + * @property {number} [maxEventLoopDelay = Infinity] - The upper limit the event loop can take to run. + * @property {number} [pollInterval = 2000] - How often, in milliseconds, metrics and latency should be checked. + * @property {number} [movingAverageInterval = 60000] - How often, in milliseconds, to compute averages. + * @property {number} [defaultPeerValue = 1] - The value of the peer. + * @property {boolean} [autoDial = true] - Should preemptively guarantee connections are above the low watermark. + * @property {number} [autoDialInterval = 10000] - How often, in milliseconds, it should preemptively guarantee connections are above the low watermark. + */ + +/** + * @extends {EventEmitter} * * @fires ConnectionManager#peer:connect Emitted when a new peer is connected. * @fires ConnectionManager#peer:disconnect Emitted when a peer is disconnected. */ class ConnectionManager extends EventEmitter { /** + * Responsible for managing known connections. + * * @class * @param {Libp2p} libp2p - * @param {object} options - * @param {number} options.maxConnections - The maximum number of connections allowed. Default=Infinity - * @param {number} options.minConnections - The minimum number of connections to avoid pruning. Default=0 - * @param {number} options.maxData - The max data (in and out), per average interval to allow. Default=Infinity - * @param {number} options.maxSentData - The max outgoing data, per average interval to allow. Default=Infinity - * @param {number} options.maxReceivedData - The max incoming data, per average interval to allow.. Default=Infinity - * @param {number} options.maxEventLoopDelay - The upper limit the event loop can take to run. Default=Infinity - * @param {number} options.pollInterval - How often, in milliseconds, metrics and latency should be checked. Default=2000 - * @param {number} options.movingAverageInterval - How often, in milliseconds, to compute averages. Default=60000 - * @param {number} options.defaultPeerValue - The value of the peer. Default=1 - * @param {boolean} options.autoDial - Should preemptively guarantee connections are above the low watermark. Default=true - * @param {number} options.autoDialInterval - How often, in milliseconds, it should preemptively guarantee connections are above the low watermark. Default=10000 + * @param {ConnectionManagerOptions} options */ - constructor (libp2p, options) { + constructor (libp2p, options = {}) { super() this._libp2p = libp2p @@ -66,8 +77,6 @@ class ConnectionManager extends EventEmitter { log('options: %j', this._options) - this._libp2p = libp2p - /** * Map of peer identifiers to their peer value for pruning connections. * @@ -78,7 +87,7 @@ class ConnectionManager extends EventEmitter { /** * Map of connections per peer * - * @type {Map>} + * @type {Map>} */ this.connections = new Map() diff --git a/src/connection-manager/latency-monitor.js b/src/connection-manager/latency-monitor.js index db299890b4..6eefa40e60 100644 --- a/src/connection-manager/latency-monitor.js +++ b/src/connection-manager/latency-monitor.js @@ -6,7 +6,7 @@ /* global window */ const globalThis = require('ipfs-utils/src/globalthis') -const EventEmitter = require('events') +const { EventEmitter } = require('events') const VisibilityChangeEmitter = require('./visibility-change-emitter') const debug = require('debug')('latency-monitor:LatencyMonitor') @@ -17,6 +17,12 @@ const debug = require('debug')('latency-monitor:LatencyMonitor') * @property {number} maxMS What was the max time for a cb to be called * @property {number} avgMs What was the average time for a cb to be called * @property {number} lengthMs How long this interval was in ms + * + * @typedef {Object} LatencyMonitorOptions + * @property {number} [latencyCheckIntervalMs=500] - How often to add a latency check event (ms) + * @property {number} [dataEmitIntervalMs=5000] - How often to summarize latency check events. null or 0 disables event firing + * @property {Function} [asyncTestFn] - What cb-style async function to use + * @property {number} [latencyRandomPercentage=5] - What percent (+/-) of latencyCheckIntervalMs should we randomly use? This helps avoid alignment to other events. */ /** @@ -24,6 +30,8 @@ const debug = require('debug')('latency-monitor:LatencyMonitor') * the asyncTestFn and timing how long it takes the callback to be called. It can also periodically emit stats about this. * This can be disabled and stats can be pulled via setting dataEmitIntervalMs = 0. * + * @extends {EventEmitter} + * * The default implementation is an event loop latency monitor. This works by firing periodic events into the event loop * and timing how long it takes to get back. * @@ -37,11 +45,8 @@ const debug = require('debug')('latency-monitor:LatencyMonitor') */ class LatencyMonitor extends EventEmitter { /** - * @param {object} [options] - * @param {number} [options.latencyCheckIntervalMs=500] - How often to add a latency check event (ms) - * @param {number} [options.dataEmitIntervalMs=5000] - How often to summarize latency check events. null or 0 disables event firing - * @param {Function} [options.asyncTestFn] - What cb-style async function to use - * @param {number} [options.latencyRandomPercentage=5] - What percent (+/-) of latencyCheckIntervalMs should we randomly use? This helps avoid alignment to other events. + * @class + * @param {LatencyMonitorOptions} [options] */ constructor ({ latencyCheckIntervalMs, dataEmitIntervalMs, asyncTestFn, latencyRandomPercentage } = {}) { super() @@ -91,6 +96,7 @@ class LatencyMonitor extends EventEmitter { // See: http://stackoverflow.com/questions/6032429/chrome-timeouts-interval-suspended-in-background-tabs if (isBrowser()) { that._visibilityChangeEmitter = new VisibilityChangeEmitter() + that._visibilityChangeEmitter.on('visibilityChange', (pageInFocus) => { if (pageInFocus) { that._startTimers() diff --git a/src/connection-manager/visibility-change-emitter.js b/src/connection-manager/visibility-change-emitter.js index baece0ec17..c2204eabfc 100644 --- a/src/connection-manager/visibility-change-emitter.js +++ b/src/connection-manager/visibility-change-emitter.js @@ -4,13 +4,16 @@ * This code is based on `latency-monitor` (https://github.com/mlucool/latency-monitor) by `mlucool` (https://github.com/mlucool), available under Apache License 2.0 (https://github.com/mlucool/latency-monitor/blob/master/LICENSE) */ 'use strict' -const EventEmitter = require('events') + +const { EventEmitter } = require('events') 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 @@ -29,12 +32,12 @@ const debug = require('debug')('latency-monitor:VisibilityChangeEmitter') * }); * // To access the visibility state directly, call: * console.log('Am I focused now? ' + myVisibilityEmitter.isVisible()); - * - * @class VisibilityChangeEmitter */ -module.exports = class VisibilityChangeEmitter extends EventEmitter { +class VisibilityChangeEmitter extends EventEmitter { /** * Creates a VisibilityChangeEmitter + * + * @class */ constructor () { super() @@ -119,3 +122,5 @@ module.exports = class VisibilityChangeEmitter extends EventEmitter { this.emit('visibilityChange', visible) } } + +module.exports = VisibilityChangeEmitter diff --git a/src/content-routing.js b/src/content-routing.js index d7e160e79e..4f49a43db1 100644 --- a/src/content-routing.js +++ b/src/content-routing.js @@ -6,6 +6,11 @@ const { messages, codes } = require('./errors') const all = require('it-all') const pAny = require('p-any') +/** + * @typedef {import('peer-id')} PeerId + * @typedef {import('multiaddr')} multiaddr + */ + module.exports = (node) => { const routers = node._modules.contentRouting || [] const dht = node._dht @@ -24,7 +29,7 @@ module.exports = (node) => { * @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[] }>} + * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Array }>} */ async * findProviders (key, options) { if (!routers.length) { diff --git a/src/dialer/dial-request.js b/src/dialer/dial-request.js index dc427e1bbf..6caa89032b 100644 --- a/src/dialer/dial-request.js +++ b/src/dialer/dial-request.js @@ -9,6 +9,16 @@ log.error = debug('libp2p:dialer:request:error') const FIFO = require('p-fifo') const pAny = require('p-any') +/** + * @typedef {import('./')} Dialer + */ + +/** + * @typedef {Object} DialRequestOptions + * @property {Multiaddr[]} addrs + * @property {function(Multiaddr):Promise} dialAction + * @property {Dialer} dialer + */ class DialRequest { /** * Manages running the `dialAction` on multiple provided `addrs` in parallel @@ -17,10 +27,8 @@ class DialRequest { * started using `DialRequest.run(options)`. Once a single dial has succeeded, * all other dials in the request will be cancelled. * - * @param {object} options - * @param {Multiaddr[]} options.addrs - * @param {function(Multiaddr):Promise} options.dialAction - * @param {Dialer} options.dialer + * @class + * @param {DialRequestOptions} options */ constructor ({ addrs, @@ -34,8 +42,8 @@ class DialRequest { /** * @async - * @param {object} options - * @param {AbortSignal} options.signal - An AbortController signal + * @param {object} [options] + * @param {AbortSignal} [options.signal] - An AbortController signal * @returns {Connection} */ async run (options) { diff --git a/src/dialer/index.js b/src/dialer/index.js index 3ee3ada6c8..c12926b2bd 100644 --- a/src/dialer/index.js +++ b/src/dialer/index.js @@ -19,17 +19,40 @@ const { MAX_PER_PEER_DIALS } = require('../constants') +/** + * @typedef {import('peer-id')} PeerId + * @typedef {import('../peer-store')} PeerStore + * @typedef {import('../transport-manager')} TransportManager + * @typedef {import('./dial-request')} DialRequest + */ + +/** + * @typedef {Object} DialerProperties + * @property {PeerStore} peerStore + * @property {TransportManager} transportManager + * + * @typedef {Object} DialerOptions + * @param {(addresses: Array Array
} [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 + * + * @typedef DialTarget + * @property {string} id + * @property {Array} addrs + * + * @typedef PendingDial + * @property {DialRequest} dialRequest + * @property {TimeoutController} controller + * @property {Promise} promise + * @property {function():void} destroy + */ + class Dialer { /** * @class - * @param {object} options - * @param {TransportManager} options.transportManager - * @param {Peerstore} options.peerStore - * @param {(addresses: Array Array
} [options.addressSorter = publicAddressesFirst] - Sort the known addresses of a peer before trying to dial. - * @param {number} [options.concurrency = MAX_PARALLEL_DIALS] - Number of max concurrent dials. - * @param {number} [options.perPeerLimit = MAX_PER_PEER_DIALS] - Number of max concurrent dials per peer. - * @param {number} [options.timeout = DIAL_TIMEOUT] - How long a dial attempt is allowed to take. - * @param {object} [options.resolvers = {}] - multiaddr resolvers to use when dialing + * @param {DialerProperties & DialerOptions} options */ constructor ({ transportManager, @@ -73,7 +96,7 @@ class Dialer { * The dial to the first address that is successfully able to upgrade a connection * will be used. * - * @param {PeerId|Multiaddr|string} peer - The peer to dial + * @param {PeerId|multiaddr|string} peer - The peer to dial * @param {object} [options] * @param {AbortSignal} [options.signal] - An AbortController signal * @returns {Promise} @@ -102,19 +125,13 @@ class Dialer { } } - /** - * @typedef DialTarget - * @property {string} id - * @property {Multiaddr[]} addrs - */ - /** * Creates a DialTarget. The DialTarget is used to create and track * the DialRequest to a given peer. * If a multiaddr is received it should be the first address attempted. * * @private - * @param {PeerId|Multiaddr|string} peer - A PeerId or Multiaddr + * @param {PeerId|multiaddr|string} peer - A PeerId or Multiaddr * @returns {Promise} */ async _createDialTarget (peer) { @@ -145,14 +162,6 @@ class Dialer { } } - /** - * @typedef PendingDial - * @property {DialRequest} dialRequest - * @property {TimeoutController} controller - * @property {Promise} promise - * @property {function():void} destroy - */ - /** * Creates a PendingDial that wraps the underlying DialRequest * @@ -210,8 +219,8 @@ class Dialer { /** * Resolve multiaddr recursively. * - * @param {Multiaddr} ma - * @returns {Promise>} + * @param {multiaddr} ma + * @returns {Promise>} */ async _resolve (ma) { // TODO: recursive logic should live in multiaddr once dns4/dns6 support is in place @@ -239,8 +248,8 @@ class Dialer { /** * Resolve a given multiaddr. If this fails, an empty array will be returned * - * @param {Multiaddr} ma - * @returns {Promise>} + * @param {multiaddr} ma + * @returns {Promise>} */ async _resolveRecord (ma) { try { diff --git a/src/get-peer.js b/src/get-peer.js index bc36b04cc9..9ebd535698 100644 --- a/src/get-peer.js +++ b/src/get-peer.js @@ -6,12 +6,17 @@ const errCode = require('err-code') const { codes } = require('./errors') +/** + * @typedef {import('peer-id')} PeerId + * @typedef {import('multiaddr')} multiaddr + */ + /** * Converts the given `peer` to a `Peer` object. * If a multiaddr is received, the addressBook is updated. * - * @param {PeerId|Multiaddr|string} peer - * @returns {{ id: PeerId, multiaddrs: Array }} + * @param {PeerId|multiaddr|string} peer + * @returns {{ id: PeerId, multiaddrs: Array }} */ function getPeer (peer) { if (typeof peer === 'string') { diff --git a/src/identify/index.js b/src/identify/index.js index 351bfbe4c7..871020da64 100644 --- a/src/identify/index.js +++ b/src/identify/index.js @@ -29,50 +29,24 @@ const { const { codes } = require('../errors') -class IdentifyService { - /** - * Takes the `addr` and converts it to a Multiaddr if possible - * - * @param {Uint8Array | string} addr - * @returns {Multiaddr|null} - */ - static getCleanMultiaddr (addr) { - if (addr && addr.length > 0) { - try { - return multiaddr(addr) - } catch (_) { - return null - } - } - return null - } +/** + * @typedef {import('../')} Libp2p + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('../').DuplexIterable} DuplexIterable + */ +class IdentifyService { /** * @class - * @param {object} options + * @param {Object} options * @param {Libp2p} options.libp2p */ constructor ({ libp2p }) { - /** - * @property {PeerStore} - */ + this._libp2p = libp2p this.peerStore = libp2p.peerStore - - /** - * @property {ConnectionManager} - */ this.connectionManager = libp2p.connectionManager - - /** - * @property {PeerId} - */ this.peerId = libp2p.peerId - /** - * @property {AddressManager} - */ - this._libp2p = libp2p - this.handleMessage = this.handleMessage.bind(this) // When a new connection happens, trigger identify @@ -228,9 +202,9 @@ class IdentifyService { /** * A handler to register with Libp2p to process identify messages. * - * @param {object} options + * @param {Object} options * @param {string} options.protocol - * @param {*} options.stream + * @param {DuplexIterable} options.stream * @param {Connection} options.connection * @returns {Promise} */ @@ -250,8 +224,8 @@ class IdentifyService { * to the requesting peer over the given `connection` * * @private - * @param {object} options - * @param {*} options.stream + * @param {Object} options + * @param {DuplexIterable} options.stream * @param {Connection} options.connection */ async _handleIdentify ({ connection, stream }) { @@ -290,7 +264,7 @@ class IdentifyService { * * @private * @param {object} options - * @param {*} options.stream + * @param {DuplexIterable} options.stream * @param {Connection} options.connection */ async _handlePush ({ connection, stream }) { @@ -331,6 +305,23 @@ class IdentifyService { // Update the protocols this.peerStore.protoBook.set(id, message.protocols) } + + /** + * Takes the `addr` and converts it to a Multiaddr if possible + * + * @param {Uint8Array | string} addr + * @returns {multiaddr|null} + */ + static getCleanMultiaddr (addr) { + if (addr && addr.length > 0) { + try { + return multiaddr(addr) + } catch (_) { + return null + } + } + return null + } } module.exports.IdentifyService = IdentifyService diff --git a/src/index.js b/src/index.js index 1c25ef8600..68b92f6c68 100644 --- a/src/index.js +++ b/src/index.js @@ -35,16 +35,55 @@ const { } = require('./identify') /** + * @typedef {Object} PeerStoreOptions + * @property {boolean} persistence + * + * @typedef {Object} PeerDiscoveryOptions + * @property {boolean} autoDial + * + * @typedef {Object} RelayOptions + * @property {boolean} enabled + * @property {import('./circuit').RelayAdvertiseOptions} advertise + * @property {import('./circuit').HopOptions} hop + * @property {import('./circuit').AutoRelayOptions} autoRelay + * + * @typedef {Object} Libp2pConfig + * @property {Object} [dht] dht module options + * @property {PeerDiscoveryOptions} [peerDiscovery] + * @property {Object} [pubsub] pubsub module options + * @property {RelayOptions} [relay] + * @property {Object} [transport] transport options indexed by transport key + * + * @typedef {Object} Libp2pOptions + * @property {Array} modules libp2p modules to use + * @property {import('./address-manager').AddressManagerOptions} [addresses] + * @property {import('./connection-manager').ConnectionManagerOptions} [connectionManager] + * @property {import('./dialer').DialerOptions} [dialer] + * @property {import('./metrics').MetricsOptions} [metrics] + * @property {Object} [keychain] + * @property {import('./transport-manager').TransportManagerOptions} [transportManager] + * @property {PeerStoreOptions & import('./peer-store/persistent').PersistentPeerStoreOptions} [peerStore] + * @property {Libp2pConfig} [config] + * @property {PeerId} peerId + * + * @extends {EventEmitter} * @fires Libp2p#error Emitted when an error occurs * @fires Libp2p#peer:discovery Emitted when a peer is discovered */ class Libp2p extends EventEmitter { + /** + * Libp2p node. + * + * @class + * @param {Libp2pOptions} _options + */ constructor (_options) { super() // validateConfig will ensure the config is correct, // and add default values where appropriate this._options = validateConfig(_options) + /** @type {PeerId} */ this.peerId = this._options.peerId this.datastore = this._options.datastore @@ -592,11 +631,16 @@ class Libp2p extends EventEmitter { } } +/** + * @typedef {Object} CreateOptions + * @property {PeerId} peerId + */ + /** * Like `new Libp2p(options)` except it will create a `PeerId` * instance if one is not provided in options. * - * @param {object} options - Libp2p configuration options + * @param {Libp2pOptions & CreateOptions} [options] - Libp2p configuration options * @returns {Libp2p} */ Libp2p.create = async function create (options = {}) { @@ -610,4 +654,10 @@ Libp2p.create = async function create (options = {}) { return new Libp2p(options) } +/** + * @typedef {Object} DuplexIterable + * @property {(source: AsyncIterator<*>) => Promise} sink + * @property {AsyncIterator<*>} source + */ + module.exports = Libp2p diff --git a/src/insecure/plaintext.js b/src/insecure/plaintext.js index 83e1ba463b..2a6a3a4bcb 100644 --- a/src/insecure/plaintext.js +++ b/src/insecure/plaintext.js @@ -16,6 +16,17 @@ function lpEncodeExchange (exchange) { return lp.encode.single(pb) } +/** + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + */ + +/** + * Encrypt connection. + * + * @param {PeerId} localId + * @param {Connection} conn + * @param {PeerId} remoteId + */ async function encrypt (localId, conn, remoteId) { const shake = handshake(conn) diff --git a/src/metrics/index.js b/src/metrics/index.js index 9d0f436041..49827bdeb1 100644 --- a/src/metrics/index.js +++ b/src/metrics/index.js @@ -17,15 +17,21 @@ const directionToEvent = { out: 'dataSent' } +/** + * @typedef MetricsProperties + * @property {ConnectionManager} connectionManager + * + * @typedef MetricsOptions + * @property {number} [computeThrottleMaxQueueSize = defaultOptions.computeThrottleMaxQueueSize] + * @property {number} [computeThrottleTimeout = defaultOptions.computeThrottleTimeout] + * @property {Array} [movingAverageIntervals = defaultOptions.movingAverageIntervals] + * @property {number} [maxOldPeersRetention = defaultOptions.maxOldPeersRetention] + */ + class Metrics { /** - * - * @param {object} options - * @param {ConnectionManager} options.connectionManager - * @param {number} options.computeThrottleMaxQueueSize - * @param {number} options.computeThrottleTimeout - * @param {Array} options.movingAverageIntervals - * @param {number} options.maxOldPeersRetention + * @class + * @param {MetricsProperties & MetricsOptions} options */ constructor (options) { this._options = mergeOptions(defaultOptions, options) diff --git a/src/peer-routing.js b/src/peer-routing.js index e783c82f8b..c05fdebe7d 100644 --- a/src/peer-routing.js +++ b/src/peer-routing.js @@ -12,6 +12,11 @@ const { clearDelayedInterval } = require('set-delayed-interval') +/** + * @typedef {import('peer-id')} PeerId + * @typedef {import('multiaddr')} Multiaddr + */ + /** * Responsible for managing the usage of the available Peer Routing modules. */ diff --git a/src/peer-store/address-book.js b/src/peer-store/address-book.js index 07d8af59b2..3bd6995eeb 100644 --- a/src/peer-store/address-book.js +++ b/src/peer-store/address-book.js @@ -17,35 +17,36 @@ const { const Envelope = require('../record/envelope') /** - * The AddressBook is responsible for keeping the known multiaddrs - * of a peer. + * Address object + * + * @typedef {Object} Address + * @property {multiaddr} multiaddr peer multiaddr. + * @property {boolean} isCertified obtained from a signed peer record. */ -class AddressBook extends Book { - /** - * Address object - * - * @typedef {Object} Address - * @property {Multiaddr} multiaddr peer multiaddr. - * @property {boolean} isCertified obtained from a signed peer record. - */ - /** - * CertifiedRecord object - * - * @typedef {Object} CertifiedRecord - * @property {Uint8Array} raw raw envelope. - * @property {number} seqNumber seq counter. - */ +/** + * CertifiedRecord object + * + * @typedef {Object} CertifiedRecord + * @property {Uint8Array} raw raw envelope. + * @property {number} seqNumber seq counter. + */ - /** - * Entry object for the addressBook - * - * @typedef {Object} Entry - * @property {Array
} addresses peer Addresses. - * @property {CertifiedRecord} record certified peer record. - */ +/** + * Entry object for the addressBook + * + * @typedef {Object} Entry + * @property {Array
} addresses peer Addresses. + * @property {CertifiedRecord} record certified peer record. + */ +/** + * @extends {Book} + */ +class AddressBook extends Book { /** + * The AddressBook is responsible for keeping the known multiaddrs of a peer. + * * @class * @param {PeerStore} peerStore */ @@ -171,7 +172,7 @@ class AddressBook extends Book { * * @override * @param {PeerId} peerId - * @param {Array} multiaddrs + * @param {Array} multiaddrs * @returns {AddressBook} */ set (peerId, multiaddrs) { @@ -221,7 +222,7 @@ class AddressBook extends Book { * If the peer is not known, it is set with the given addresses. * * @param {PeerId} peerId - * @param {Array} multiaddrs + * @param {Array} multiaddrs * @returns {AddressBook} */ add (peerId, multiaddrs) { @@ -286,7 +287,7 @@ class AddressBook extends Book { * Transforms received multiaddrs into Address. * * @private - * @param {Array} multiaddrs + * @param {Array} multiaddrs * @param {boolean} [isCertified] * @returns {Array
} */ diff --git a/src/peer-store/book.js b/src/peer-store/book.js index f0a830f97a..e1893ce908 100644 --- a/src/peer-store/book.js +++ b/src/peer-store/book.js @@ -9,17 +9,16 @@ const { const passthrough = data => data -/** - * The Book is the skeleton for the PeerStore books. - */ class Book { /** + * The Book is the skeleton for the PeerStore books. + * * @class * @param {Object} properties * @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 {Function} [properties.eventTransformer] - Transformer function of the provided data for being emitted. + * @param {(data: *) => Array<*>} [properties.eventTransformer] - Transformer function of the provided data for being emitted. */ constructor ({ peerStore, eventName, eventProperty, eventTransformer = passthrough }) { this._ps = peerStore @@ -30,7 +29,7 @@ class Book { /** * Map known peers to their data. * - * @type {Map} + * @type {Map} */ this.data = new Map() } diff --git a/src/peer-store/index.js b/src/peer-store/index.js index 69a1f15a57..ab3f632782 100644 --- a/src/peer-store/index.js +++ b/src/peer-store/index.js @@ -18,7 +18,7 @@ const { } = require('../errors') /** - * Responsible for managing known peers, as well as their addresses, protocols and metadata. + * @extends {EventEmitter} * * @fires PeerStore#peer Emitted when a new peer is added. * @fires PeerStore#change:protocols Emitted when a known peer supports a different set of protocols. @@ -38,6 +38,8 @@ class PeerStore extends EventEmitter { */ /** + * Responsible for managing known peers, as well as their addresses, protocols and metadata. + * * @param {object} options * @param {PeerId} options.peerId * @class diff --git a/src/peer-store/key-book.js b/src/peer-store/key-book.js index 607d12795f..6a045ad58f 100644 --- a/src/peer-store/key-book.js +++ b/src/peer-store/key-book.js @@ -14,10 +14,12 @@ const { } = require('../errors') /** - * The KeyBook is responsible for keeping the known public keys of a peer. + * @extends {Book} */ class KeyBook extends Book { /** + * The KeyBook is responsible for keeping the known public keys of a peer. + * * @class * @param {PeerStore} peerStore */ diff --git a/src/peer-store/metadata-book.js b/src/peer-store/metadata-book.js index 490ef02b09..7a8b794cfe 100644 --- a/src/peer-store/metadata-book.js +++ b/src/peer-store/metadata-book.js @@ -15,13 +15,15 @@ const { } = require('../errors') /** - * The MetadataBook is responsible for keeping the known supported - * protocols of a peer. + * @extends {Book} * * @fires MetadataBook#change:metadata */ class MetadataBook extends Book { /** + * The MetadataBook is responsible for keeping the known supported + * protocols of a peer. + * * @class * @param {PeerStore} peerStore */ diff --git a/src/peer-store/persistent/index.js b/src/peer-store/persistent/index.js index 70a417f4f7..f23c23e193 100644 --- a/src/peer-store/persistent/index.js +++ b/src/peer-store/persistent/index.js @@ -21,16 +21,22 @@ const { const Addresses = require('./pb/address-book.proto') const Protocols = require('./pb/proto-book.proto') +/** + * @typedef {Object} PersistentPeerStoreProperties + * @property {PeerId} peerId + * @property {Datastore} datastore + * + * @typedef {Object} PersistentPeerStoreOptions + * @property {number} [threshold = 5] - Number of dirty peers allowed before commit data. + */ + /** * Responsible for managing the persistence of data in the PeerStore. */ class PersistentPeerStore extends PeerStore { /** * @class - * @param {Object} properties - * @param {PeerId} properties.peerId - * @param {Datastore} properties.datastore - Datastore to persist data. - * @param {number} [properties.threshold = 5] - Number of dirty peers allowed before commit data. + * @param {PersistentPeerStoreProperties & PersistentPeerStoreOptions} properties */ constructor ({ peerId, datastore, threshold = 5 }) { super({ peerId }) diff --git a/src/peer-store/proto-book.js b/src/peer-store/proto-book.js index a08f5a284d..009d0ba8cc 100644 --- a/src/peer-store/proto-book.js +++ b/src/peer-store/proto-book.js @@ -14,13 +14,15 @@ const { } = require('../errors') /** - * The ProtoBook is responsible for keeping the known supported - * protocols of a peer. + * @extends {Book} * * @fires ProtoBook#change:protocols */ class ProtoBook extends Book { /** + * The ProtoBook is responsible for keeping the known supported + * protocols of a peer. + * * @class * @param {PeerStore} peerStore */ diff --git a/src/ping/index.js b/src/ping/index.js index e882f81f4c..415f400036 100644 --- a/src/ping/index.js +++ b/src/ping/index.js @@ -12,6 +12,12 @@ const { collect, take } = require('streaming-iterables') const { PROTOCOL, PING_LENGTH } = require('./constants') +/** + * @typedef {import('../')} Libp2p + * @typedef {import('multiaddr')} multiaddr + * @typedef {import('peer-id')} PeerId + */ + /** * Ping a given peer and wait for its response, getting the operation latency. * diff --git a/src/pnet/index.js b/src/pnet/index.js index e5f82331a2..d49e13df79 100644 --- a/src/pnet/index.js +++ b/src/pnet/index.js @@ -20,11 +20,15 @@ const log = debug('libp2p:pnet') log.error = debug('libp2p:pnet:err') /** - * Takes a Private Shared Key (psk) and provides a `protect` method - * for wrapping existing connections in a private encryption stream + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('../').DuplexIterable} DuplexIterable */ + class Protector { /** + * Takes a Private Shared Key (psk) and provides a `protect` method + * for wrapping existing connections in a private encryption stream. + * * @param {Uint8Array} keyBuffer - The private shared key buffer * @class */ @@ -40,7 +44,7 @@ class Protector { * created with. * * @param {Connection} connection - The connection to protect - * @returns {*} A protected duplex iterable + * @returns {DuplexIterable} A protected duplex iterable */ async protect (connection) { if (!connection) { diff --git a/src/record/envelope/index.js b/src/record/envelope/index.js index 6a73914f2a..cee2e26b96 100644 --- a/src/record/envelope/index.js +++ b/src/record/envelope/index.js @@ -15,11 +15,14 @@ const { codes } = require('../../errors') const Protobuf = require('./envelope.proto') /** - * The Envelope is responsible for keeping an arbitrary signed record - * by a libp2p peer. + * @typedef {import('peer-id')} PeerId */ + class Envelope { /** + * The Envelope is responsible for keeping an arbitrary signed record + * by a libp2p peer. + * * @class * @param {object} params * @param {PeerId} params.peerId diff --git a/src/record/peer-record/index.js b/src/record/peer-record/index.js index 51c43a7970..faeac81d24 100644 --- a/src/record/peer-record/index.js +++ b/src/record/peer-record/index.js @@ -12,13 +12,20 @@ const { } = require('./consts') /** - * The PeerRecord is used for distributing peer routing records across the network. - * It contains the peer's reachable listen addresses. + * @typedef {import('peer-id')} PeerId + * @typedef {import('multiaddr')} multiaddr + */ + +/** + * @extends {Record} */ class PeerRecord extends Record { /** + * The PeerRecord is used for distributing peer routing records across the network. + * It contains the peer's reachable listen addresses. + * * @class - * @param {object} params + * @param {Object} params * @param {PeerId} params.peerId * @param {Array} params.multiaddrs - addresses of the associated peer. * @param {number} [params.seqNumber] - monotonically-increasing sequence counter that's used to order PeerRecords in time. diff --git a/src/record/utils.js b/src/record/utils.js index 65696156b8..0a92ade177 100644 --- a/src/record/utils.js +++ b/src/record/utils.js @@ -3,10 +3,14 @@ const Envelope = require('./envelope') const PeerRecord = require('./peer-record') +/** + * @typedef {import('../')} Libp2p + */ + /** * Create (or update if existing) self peer record and store it in the AddressBook. * - * @param {libp2p} libp2p + * @param {Libp2p} libp2p * @returns {Promise} */ async function updateSelfPeerRecord (libp2p) { diff --git a/src/registrar.js b/src/registrar.js index 5130a02fcb..4917aeb5b8 100644 --- a/src/registrar.js +++ b/src/registrar.js @@ -10,6 +10,14 @@ const { } = require('./errors') const Topology = require('libp2p-interfaces/src/topology') +/** + * @typedef {import('peer-id')} PeerId + * @typedef {import('./peer-store')} PeerStore + * @typedef {import('./connection-manager')} ConnectionManager + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('libp2p-interfaces/src/topology')} Topology + */ + /** * Responsible for notifying registered protocols of events in the network. */ @@ -17,7 +25,7 @@ class Registrar { /** * @param {Object} props * @param {PeerStore} props.peerStore - * @param {connectionManager} props.connectionManager + * @param {ConnectionManager} props.connectionManager * @class */ constructor ({ peerStore, connectionManager }) { diff --git a/src/transport-manager.js b/src/transport-manager.js index 7a47a9e90a..f6c62d143b 100644 --- a/src/transport-manager.js +++ b/src/transport-manager.js @@ -9,13 +9,22 @@ log.error = debug('libp2p:transports:error') const { updateSelfPeerRecord } = require('./record/utils') +/** + * @typedef {import('multiaddr')} multiaddr + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * + * @typedef {Object} TransportManagerProperties + * @property {import('./')} libp2p + * @property {import('./upgrader')} upgrader + * + * @typedef {Object} TransportManagerOptions + * @property {boolean} [faultTolerance = FAULT_TOLERANCE.FATAL_ALL] - Address listen error tolerance. + */ + class TransportManager { /** * @class - * @param {object} options - * @param {Libp2p} options.libp2p - The Libp2p instance. It will be passed to the transports. - * @param {Upgrader} options.upgrader - The upgrader to provide to the transports - * @param {boolean} [options.faultTolerance = FAULT_TOLERANCE.FATAL_ALL] - Address listen error tolerance. + * @param {TransportManagerProperties & TransportManagerOptions} options */ constructor ({ libp2p, upgrader, faultTolerance = FAULT_TOLERANCE.FATAL_ALL }) { this.libp2p = libp2p @@ -81,7 +90,7 @@ class TransportManager { /** * Dials the given Multiaddr over it's supported transport * - * @param {Multiaddr} ma + * @param {multiaddr} ma * @param {*} options * @returns {Promise} */ @@ -102,7 +111,7 @@ class TransportManager { /** * Returns all Multiaddr's the listeners are using * - * @returns {Multiaddr[]} + * @returns {Array} */ getAddrs () { let addrs = [] @@ -126,7 +135,7 @@ class TransportManager { /** * Finds a transport that matches the given Multiaddr * - * @param {Multiaddr} ma + * @param {multiaddr} ma * @returns {Transport|null} */ transportForMultiaddr (ma) { @@ -141,7 +150,7 @@ class TransportManager { * Starts listeners for each listen Multiaddr. * * @async - * @param {Array} addrs - addresses to attempt to listen on + * @param {Array} addrs - addresses to attempt to listen on */ async listen (addrs) { if (!addrs || addrs.length === 0) { diff --git a/src/upgrader.js b/src/upgrader.js index 92997eb15f..0a422b2e82 100644 --- a/src/upgrader.js +++ b/src/upgrader.js @@ -13,6 +13,10 @@ const mutableProxy = require('mutable-proxy') const { codes } = require('./errors') +/** + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + */ + /** * @typedef MultiaddrConnection * @property {Function} sink From 7e05c4a43be48b3a5046108afc5c12d532ccf5be Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 25 Nov 2020 17:58:52 +0100 Subject: [PATCH 02/18] chore: address review --- package.json | 2 +- src/address-manager/index.js | 12 ++++++++---- src/circuit/auto-relay.js | 4 ++-- src/circuit/transport.js | 15 ++++++++++----- src/connection-manager/index.js | 9 ++++++--- src/content-routing.js | 14 ++++++++++---- src/dialer/dial-request.js | 1 + src/dialer/index.js | 17 +++++++++-------- src/get-peer.js | 4 ++-- src/identify/index.js | 13 ++++++------- src/index.js | 18 ++++++++---------- src/insecure/plaintext.js | 2 +- src/metrics/index.js | 11 ++++++++--- src/metrics/stats.js | 6 +++--- src/peer-routing.js | 19 +++++++++++++++---- src/peer-store/address-book.js | 24 ++++++++++++++---------- src/peer-store/book.js | 14 ++++++++------ src/peer-store/index.js | 10 +++++++--- src/peer-store/metadata-book.js | 2 +- src/peer-store/proto-book.js | 6 +++--- src/ping/index.js | 4 ++-- src/pnet/index.js | 4 ++-- src/pubsub-adapter.js | 4 ++++ src/record/peer-record/index.js | 4 ++-- src/transport-manager.js | 10 +++++----- 25 files changed, 138 insertions(+), 91 deletions(-) diff --git a/package.json b/package.json index 34dcc4d260..3996c800c0 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "it-pipe": "^1.1.0", "it-protocol-buffers": "^0.2.0", "libp2p-crypto": "^0.18.0", - "libp2p-interfaces": "^0.7.2", + "libp2p-interfaces": "libp2p/js-libp2p-interfaces#chore/add-duplex-iterable-type-to-connection", "libp2p-utils": "^0.2.2", "mafmt": "^8.0.0", "merge-options": "^2.0.0", diff --git a/src/address-manager/index.js b/src/address-manager/index.js index 9a9bc0b0cb..d4811be72c 100644 --- a/src/address-manager/index.js +++ b/src/address-manager/index.js @@ -6,10 +6,14 @@ log.error = debug('libp2p:addresses:error') const multiaddr = require('multiaddr') +/** + * @typedef {import('multiaddr')} Multiaddr + */ + /** * @typedef {Object} AddressManagerOptions - * @property {Array} [listen = []] - list of multiaddrs string representation to listen. - * @property {Array} [announce = []] - list of multiaddrs string representation to announce. + * @property {string[]} [listen = []] - list of multiaddrs string representation to listen. + * @property {string[]} [announce = []] - list of multiaddrs string representation to announce. */ class AddressManager { /** @@ -29,7 +33,7 @@ class AddressManager { /** * Get peer listen multiaddrs. * - * @returns {Array} + * @returns {Multiaddr[]} */ getListenAddrs () { return Array.from(this.listen).map((a) => multiaddr(a)) @@ -38,7 +42,7 @@ class AddressManager { /** * Get peer announcing multiaddrs. * - * @returns {Array} + * @returns {Multiaddr[]} */ getAnnounceAddrs () { return Array.from(this.announce).map((a) => multiaddr(a)) diff --git a/src/circuit/auto-relay.js b/src/circuit/auto-relay.js index 3740bc34fe..7cca188735 100644 --- a/src/circuit/auto-relay.js +++ b/src/circuit/auto-relay.js @@ -69,7 +69,7 @@ class AutoRelay { * * @param {Object} props * @param {PeerId} props.peerId - * @param {Array} props.protocols + * @param {string[]} props.protocols * @returns {Promise} */ async _onProtocolChange ({ peerId, protocols }) { @@ -182,7 +182,7 @@ class AutoRelay { * 2. Dial and try to listen on the peers we know that support hop but are not connected. * 3. Search the network. * - * @param {Array} [peersToIgnore] + * @param {string[]} [peersToIgnore] * @returns {Promise} */ async _listenOnAvailableHopRelays (peersToIgnore = []) { diff --git a/src/circuit/transport.js b/src/circuit/transport.js index cc79870564..6ba27b2a93 100644 --- a/src/circuit/transport.js +++ b/src/circuit/transport.js @@ -18,14 +18,19 @@ const { handleCanHop, handleHop, hop } = require('./circuit/hop') const { handleStop } = require('./circuit/stop') const StreamHandler = require('./circuit/stream-handler') +/** + * @typedef {import('multiaddr')} Multiaddr + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + */ + class Circuit { /** * Creates an instance of the Circuit Transport. * * @class * @param {object} options - * @param {Libp2p} options.libp2p - * @param {Upgrader} options.upgrader + * @param {import('../')} options.libp2p + * @param {import('../upgrader')} options.upgrader */ constructor ({ libp2p, upgrader }) { this._dialer = libp2p.dialer @@ -101,7 +106,7 @@ class Circuit { /** * Dial a peer over a relay * - * @param {multiaddr} ma - the multiaddr of the peer to dial + * @param {Multiaddr} ma - the multiaddr of the peer to dial * @param {Object} options - dial options * @param {AbortSignal} [options.signal] - An optional abort signal * @returns {Connection} - the connection @@ -176,8 +181,8 @@ class Circuit { /** * Filter check for all Multiaddrs that this transport can dial on * - * @param {Array} multiaddrs - * @returns {Array} + * @param {Multiaddr[]} multiaddrs + * @returns {Multiaddr[]} */ filter (multiaddrs) { multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [multiaddrs] diff --git a/src/connection-manager/index.js b/src/connection-manager/index.js index 388c99409a..7b6ae5e414 100644 --- a/src/connection-manager/index.js +++ b/src/connection-manager/index.js @@ -51,7 +51,7 @@ const defaultOptions = { */ /** - * @extends {EventEmitter} + * @extends EventEmitter * * @fires ConnectionManager#peer:connect Emitted when a new peer is connected. * @fires ConnectionManager#peer:disconnect Emitted when a peer is disconnected. @@ -87,7 +87,7 @@ class ConnectionManager extends EventEmitter { /** * Map of connections per peer * - * @type {Map>} + * @type {Map} */ this.connections = new Map() @@ -168,6 +168,7 @@ class ConnectionManager extends EventEmitter { * * @param {PeerId} peerId * @param {number} value - A number between 0 and 1 + * @returns {void} */ setPeerValue (peerId, value) { if (value < 0 || value > 1) { @@ -201,6 +202,7 @@ class ConnectionManager extends EventEmitter { * Tracks the incoming connection and check the connection limit * * @param {Connection} connection + * @returns {void} */ onConnect (connection) { const peerId = connection.remotePeer @@ -227,6 +229,7 @@ class ConnectionManager extends EventEmitter { * Removes the connection from tracking * * @param {Connection} connection + * @returns {void} */ onDisconnect (connection) { const peerId = connection.remotePeer.toB58String() @@ -260,7 +263,7 @@ class ConnectionManager extends EventEmitter { * Get all open connections with a peer. * * @param {PeerId} peerId - * @returns {Array} + * @returns {Connection[]} */ getAll (peerId) { if (!PeerId.isPeerId(peerId)) { diff --git a/src/content-routing.js b/src/content-routing.js index 4f49a43db1..75131ba1fa 100644 --- a/src/content-routing.js +++ b/src/content-routing.js @@ -8,7 +8,13 @@ const pAny = require('p-any') /** * @typedef {import('peer-id')} PeerId - * @typedef {import('multiaddr')} multiaddr + * @typedef {import('multiaddr')} Multiaddr + */ + +/** + * @typedef {Object} GetData + * @property {PeerId} from + * @property {Uint8Array} val */ module.exports = (node) => { @@ -29,7 +35,7 @@ module.exports = (node) => { * @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: Array }>} + * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} */ async * findProviders (key, options) { if (!routers.length) { @@ -91,7 +97,7 @@ module.exports = (node) => { * @param {Uint8Array} key * @param {Object} [options] - get options * @param {number} [options.timeout] - optional timeout (default: 60000) - * @returns {Promise<{from: PeerId, val: Uint8Array}>} + * @returns {Promise} */ async get (key, options) { // eslint-disable-line require-await if (!node.isStarted() || !dht.isStarted) { @@ -108,7 +114,7 @@ module.exports = (node) => { * @param {number} nVals * @param {Object} [options] - get options * @param {number} [options.timeout] - optional timeout (default: 60000) - * @returns {Promise>} + * @returns {Promise} */ async getMany (key, nVals, options) { // eslint-disable-line require-await if (!node.isStarted() || !dht.isStarted) { diff --git a/src/dialer/dial-request.js b/src/dialer/dial-request.js index 6caa89032b..d91158ed49 100644 --- a/src/dialer/dial-request.js +++ b/src/dialer/dial-request.js @@ -11,6 +11,7 @@ const pAny = require('p-any') /** * @typedef {import('./')} Dialer + * @typedef {import('multiaddr')} Multiaddr */ /** diff --git a/src/dialer/index.js b/src/dialer/index.js index c12926b2bd..18be09c1a5 100644 --- a/src/dialer/index.js +++ b/src/dialer/index.js @@ -20,6 +20,7 @@ const { } = require('../constants') /** + * @typedef {import('multiaddr')} Multiaddr * @typedef {import('peer-id')} PeerId * @typedef {import('../peer-store')} PeerStore * @typedef {import('../transport-manager')} TransportManager @@ -32,7 +33,7 @@ const { * @property {TransportManager} transportManager * * @typedef {Object} DialerOptions - * @param {(addresses: Array Array
} [options.addressSorter = publicAddressesFirst] - Sort the known addresses of a peer before trying to dial. + * @param {(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. @@ -40,7 +41,7 @@ const { * * @typedef DialTarget * @property {string} id - * @property {Array} addrs + * @property {Multiaddr[]} addrs * * @typedef PendingDial * @property {DialRequest} dialRequest @@ -96,7 +97,7 @@ class Dialer { * The dial to the first address that is successfully able to upgrade a connection * will be used. * - * @param {PeerId|multiaddr|string} peer - The peer to dial + * @param {PeerId|Multiaddr|string} peer - The peer to dial * @param {object} [options] * @param {AbortSignal} [options.signal] - An AbortController signal * @returns {Promise} @@ -131,7 +132,7 @@ class Dialer { * If a multiaddr is received it should be the first address attempted. * * @private - * @param {PeerId|multiaddr|string} peer - A PeerId or Multiaddr + * @param {PeerId|Multiaddr|string} peer - A PeerId or Multiaddr * @returns {Promise} */ async _createDialTarget (peer) { @@ -219,8 +220,8 @@ class Dialer { /** * Resolve multiaddr recursively. * - * @param {multiaddr} ma - * @returns {Promise>} + * @param {Multiaddr} ma + * @returns {Promise} */ async _resolve (ma) { // TODO: recursive logic should live in multiaddr once dns4/dns6 support is in place @@ -248,8 +249,8 @@ class Dialer { /** * Resolve a given multiaddr. If this fails, an empty array will be returned * - * @param {multiaddr} ma - * @returns {Promise>} + * @param {Multiaddr} ma + * @returns {Promise} */ async _resolveRecord (ma) { try { diff --git a/src/get-peer.js b/src/get-peer.js index 9ebd535698..29422334eb 100644 --- a/src/get-peer.js +++ b/src/get-peer.js @@ -8,7 +8,7 @@ const { codes } = require('./errors') /** * @typedef {import('peer-id')} PeerId - * @typedef {import('multiaddr')} multiaddr + * @typedef {import('multiaddr')} Multiaddr */ /** @@ -16,7 +16,7 @@ const { codes } = require('./errors') * If a multiaddr is received, the addressBook is updated. * * @param {PeerId|multiaddr|string} peer - * @returns {{ id: PeerId, multiaddrs: Array }} + * @returns {{ id: PeerId, multiaddrs: Multiaddr[] }} */ function getPeer (peer) { if (typeof peer === 'string') { diff --git a/src/identify/index.js b/src/identify/index.js index 871020da64..7b1617e139 100644 --- a/src/identify/index.js +++ b/src/identify/index.js @@ -30,16 +30,15 @@ const { const { codes } = require('../errors') /** - * @typedef {import('../')} Libp2p * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection - * @typedef {import('../').DuplexIterable} DuplexIterable + * @typedef {import('libp2p-interfaces/src/connection/connection').DuplexIterableStream} DuplexIterableStream */ class IdentifyService { /** * @class * @param {Object} options - * @param {Libp2p} options.libp2p + * @param {import('../')} options.libp2p */ constructor ({ libp2p }) { this._libp2p = libp2p @@ -74,7 +73,7 @@ class IdentifyService { /** * Send an Identify Push update to the list of connections * - * @param {Array} connections + * @param {Connection[]} connections * @returns {Promise} */ async push (connections) { @@ -204,7 +203,7 @@ class IdentifyService { * * @param {Object} options * @param {string} options.protocol - * @param {DuplexIterable} options.stream + * @param {DuplexIterableStream} options.stream * @param {Connection} options.connection * @returns {Promise} */ @@ -225,7 +224,7 @@ class IdentifyService { * * @private * @param {Object} options - * @param {DuplexIterable} options.stream + * @param {DuplexIterableStream} options.stream * @param {Connection} options.connection */ async _handleIdentify ({ connection, stream }) { @@ -264,7 +263,7 @@ class IdentifyService { * * @private * @param {object} options - * @param {DuplexIterable} options.stream + * @param {DuplexIterableStream} options.stream * @param {Connection} options.connection */ async _handlePush ({ connection, stream }) { diff --git a/src/index.js b/src/index.js index 68b92f6c68..eca2206fa8 100644 --- a/src/index.js +++ b/src/index.js @@ -34,6 +34,10 @@ const { multicodecs: IDENTIFY_PROTOCOLS } = require('./identify') +/** + * @typedef {import('multiaddr')} Multiaddr + */ + /** * @typedef {Object} PeerStoreOptions * @property {boolean} persistence @@ -55,7 +59,7 @@ const { * @property {Object} [transport] transport options indexed by transport key * * @typedef {Object} Libp2pOptions - * @property {Array} modules libp2p modules to use + * @property {Object[]} modules libp2p modules to use * @property {import('./address-manager').AddressManagerOptions} [addresses] * @property {import('./connection-manager').ConnectionManagerOptions} [connectionManager] * @property {import('./dialer').DialerOptions} [dialer] @@ -399,7 +403,7 @@ class Libp2p extends EventEmitter { * by transports to listen with the announce addresses. * Duplicated addresses and noAnnounce addresses are filtered out. * - * @returns {Array} + * @returns {Multiaddr[]} */ get multiaddrs () { const announceAddrs = this.addressManager.getAnnounceAddrs() @@ -416,7 +420,7 @@ class Libp2p extends EventEmitter { /** * Disconnects all connections to the given `peer` * - * @param {PeerId|multiaddr|string} peer - the peer to close connections to + * @param {PeerId|Multiaddr|string} peer - the peer to close connections to * @returns {Promise} */ async hangUp (peer) { @@ -544,7 +548,7 @@ class Libp2p extends EventEmitter { * Known peers may be emitted. * * @private - * @param {{ id: PeerId, multiaddrs: Array, protocols: Array }} peer + * @param {{ id: PeerId, multiaddrs: Multiaddr[], protocols: string[] }} peer */ _onDiscoveryPeer (peer) { if (peer.id.toB58String() === this.peerId.toB58String()) { @@ -654,10 +658,4 @@ Libp2p.create = async function create (options = {}) { return new Libp2p(options) } -/** - * @typedef {Object} DuplexIterable - * @property {(source: AsyncIterator<*>) => Promise} sink - * @property {AsyncIterator<*>} source - */ - module.exports = Libp2p diff --git a/src/insecure/plaintext.js b/src/insecure/plaintext.js index 2a6a3a4bcb..0e9f8dd992 100644 --- a/src/insecure/plaintext.js +++ b/src/insecure/plaintext.js @@ -25,7 +25,7 @@ function lpEncodeExchange (exchange) { * * @param {PeerId} localId * @param {Connection} conn - * @param {PeerId} remoteId + * @param {PeerId} [remoteId] */ async function encrypt (localId, conn, remoteId) { const shake = handshake(conn) diff --git a/src/metrics/index.js b/src/metrics/index.js index 49827bdeb1..3d9593ce87 100644 --- a/src/metrics/index.js +++ b/src/metrics/index.js @@ -17,6 +17,10 @@ const directionToEvent = { out: 'dataSent' } +/** + * @typedef {import('peer-id')} PeerId + */ + /** * @typedef MetricsProperties * @property {ConnectionManager} connectionManager @@ -24,7 +28,7 @@ const directionToEvent = { * @typedef MetricsOptions * @property {number} [computeThrottleMaxQueueSize = defaultOptions.computeThrottleMaxQueueSize] * @property {number} [computeThrottleTimeout = defaultOptions.computeThrottleTimeout] - * @property {Array} [movingAverageIntervals = defaultOptions.movingAverageIntervals] + * @property {number[]} [movingAverageIntervals = defaultOptions.movingAverageIntervals] * @property {number} [maxOldPeersRetention = defaultOptions.maxOldPeersRetention] */ @@ -82,7 +86,7 @@ class Metrics { /** * Returns a list of `PeerId` strings currently being tracked * - * @returns {Array} + * @returns {string[]} */ get peers () { return Array.from(this._peerStats.keys()) @@ -103,7 +107,7 @@ class Metrics { /** * Returns a list of all protocol strings currently being tracked. * - * @returns {Array} + * @returns {string[]} */ get protocols () { return Array.from(this._protocolStats.keys()) @@ -182,6 +186,7 @@ class Metrics { * * @param {PeerId} placeholder - A peerId string * @param {PeerId} peerId + * @returns {void} */ updatePlaceholder (placeholder, peerId) { if (!this._running) return diff --git a/src/metrics/stats.js b/src/metrics/stats.js index 3517766309..d259376256 100644 --- a/src/metrics/stats.js +++ b/src/metrics/stats.js @@ -8,7 +8,7 @@ const retimer = require('retimer') /** * A queue based manager for stat processing * - * @param {Array} initialCounters + * @param {string[]} initialCounters * @param {any} options */ class Stats extends EventEmitter { @@ -77,7 +77,7 @@ class Stats extends EventEmitter { /** * Returns a clone of the internal movingAverages * - * @returns {Array} + * @returns {MovingAverage[]} */ get movingAverages () { return Object.assign({}, this._movingAverages) @@ -229,7 +229,7 @@ class Stats extends EventEmitter { * will be updated or initialized if they don't already exist. * * @private - * @param {Array} op + * @param {{string, number}[]} op * @throws {InvalidNumber} * @returns {void} */ diff --git a/src/peer-routing.js b/src/peer-routing.js index c05fdebe7d..841a3279c3 100644 --- a/src/peer-routing.js +++ b/src/peer-routing.js @@ -16,10 +16,6 @@ const { * @typedef {import('peer-id')} PeerId * @typedef {import('multiaddr')} Multiaddr */ - -/** - * Responsible for managing the usage of the available Peer Routing modules. - */ class PeerRouting { /** * @class @@ -73,6 +69,7 @@ class PeerRouting { clearDelayedInterval(this._timeoutId) } +<<<<<<< HEAD /** * Iterates over all peer routers in series to find the given peer. * @@ -92,6 +89,20 @@ class PeerRouting { // If we don't have a result, we need to provide an error to keep trying if (!result || Object.keys(result).length === 0) { throw errCode(new Error('not found'), 'NOT_FOUND') +======= + return { + /** + * Iterates over all peer routers in series to find the given peer. + * + * @param {string} id - The id of the peer to find + * @param {object} [options] + * @param {number} [options.timeout] - How long the query should run + * @returns {Promise<{ id: PeerId, multiaddrs: Multiaddr[] }>} + */ + findPeer: async (id, options) => { // eslint-disable-line require-await + if (!routers.length) { + throw errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE') +>>>>>>> chore: address review } return result diff --git a/src/peer-store/address-book.js b/src/peer-store/address-book.js index 3bd6995eeb..bbfc30c8b9 100644 --- a/src/peer-store/address-book.js +++ b/src/peer-store/address-book.js @@ -16,11 +16,15 @@ const { } = require('../errors') const Envelope = require('../record/envelope') +/** + * @typedef {import('multiaddr')} Multiaddr + */ + /** * Address object * * @typedef {Object} Address - * @property {multiaddr} multiaddr peer multiaddr. + * @property {Multiaddr} multiaddr peer multiaddr. * @property {boolean} isCertified obtained from a signed peer record. */ @@ -36,7 +40,7 @@ const Envelope = require('../record/envelope') * Entry object for the addressBook * * @typedef {Object} Entry - * @property {Array
} addresses peer Addresses. + * @property {Address[]} addresses peer Addresses. * @property {CertifiedRecord} record certified peer record. */ @@ -71,7 +75,7 @@ class AddressBook extends Book { /** * Map known peers to their known Address Entries. * - * @type {Map>} + * @type {Map} */ this.data = new Map() } @@ -172,7 +176,7 @@ class AddressBook extends Book { * * @override * @param {PeerId} peerId - * @param {Array} multiaddrs + * @param {Multiaddr[]} multiaddrs * @returns {AddressBook} */ set (peerId, multiaddrs) { @@ -222,7 +226,7 @@ class AddressBook extends Book { * If the peer is not known, it is set with the given addresses. * * @param {PeerId} peerId - * @param {Array} multiaddrs + * @param {Multiaddr[]} multiaddrs * @returns {AddressBook} */ add (peerId, multiaddrs) { @@ -271,7 +275,7 @@ class AddressBook extends Book { * * @override * @param {PeerId} peerId - * @returns {Array
|undefined} + * @returns {Address[]|undefined} */ get (peerId) { if (!PeerId.isPeerId(peerId)) { @@ -287,9 +291,9 @@ class AddressBook extends Book { * Transforms received multiaddrs into Address. * * @private - * @param {Array} multiaddrs + * @param {Multiaddr[]} multiaddrs * @param {boolean} [isCertified] - * @returns {Array
} + * @returns {Address[]} */ _toAddresses (multiaddrs, isCertified = false) { if (!multiaddrs) { @@ -320,8 +324,8 @@ class AddressBook extends Book { * Returns `undefined` if there are no known multiaddrs for the given peer. * * @param {PeerId} peerId - * @param {(addresses: Array Array
} [addressSorter] - * @returns {Array|undefined} + * @param {(addresses: Address[]) => Address[]} [addressSorter] + * @returns {Multiaddr[]|undefined} */ getMultiaddrsForPeer (peerId, addressSorter = (ms) => ms) { if (!PeerId.isPeerId(peerId)) { diff --git a/src/peer-store/book.js b/src/peer-store/book.js index e1893ce908..cbfafdd6b9 100644 --- a/src/peer-store/book.js +++ b/src/peer-store/book.js @@ -13,12 +13,14 @@ class Book { /** * The Book is the skeleton for the PeerStore books. * + * @template T + * * @class * @param {Object} properties * @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: *) => Array<*>} [properties.eventTransformer] - Transformer function of the provided data for being emitted. + * @param {(data: T) => T[]} [properties.eventTransformer] - Transformer function of the provided data for being emitted. */ constructor ({ peerStore, eventName, eventProperty, eventTransformer = passthrough }) { this._ps = peerStore @@ -29,7 +31,7 @@ class Book { /** * Map known peers to their data. * - * @type {Map} + * @type {Map|Data} data + * @param {T[]|T} data */ set (peerId, data) { throw errcode(new Error('set must be implemented by the subclass'), 'ERR_NOT_IMPLEMENTED') @@ -49,7 +51,7 @@ class Book { * * @private * @param {PeerId} peerId - peerId of the data to store - * @param {*} data - data to store. + * @param {T} data - data to store. * @param {Object} [options] - storing options. * @param {boolean} [options.emit = true] - emit the provided data. * @returns {void} @@ -69,7 +71,7 @@ class Book { * * @private * @param {PeerId} peerId - * @param {*} data + * @param {T} data */ _emit (peerId, data) { this._ps.emit(this.eventName, { @@ -83,7 +85,7 @@ class Book { * Returns `undefined` if there is no available data for the given peer. * * @param {PeerId} peerId - * @returns {Array|undefined} + * @returns {T[]|undefined} */ get (peerId) { if (!PeerId.isPeerId(peerId)) { diff --git a/src/peer-store/index.js b/src/peer-store/index.js index ab3f632782..3713d7d4d0 100644 --- a/src/peer-store/index.js +++ b/src/peer-store/index.js @@ -17,6 +17,10 @@ const { ERR_INVALID_PARAMETERS } = require('../errors') +/** + * @typedef {import('./address-book').Address} Address + */ + /** * @extends {EventEmitter} * @@ -32,9 +36,9 @@ class PeerStore extends EventEmitter { * * @typedef {Object} Peer * @property {PeerId} id peer's peer-id instance. - * @property {Array
} addresses peer's addresses containing its multiaddrs and metadata. - * @property {Array} protocols peer's supported protocols. - * @property {Map} metadata peer's metadata map. + * @property {Address[]} addresses peer's addresses containing its multiaddrs and metadata. + * @property {string[]} protocols peer's supported protocols. + * @property {Map} metadata peer's metadata map. */ /** diff --git a/src/peer-store/metadata-book.js b/src/peer-store/metadata-book.js index 7a8b794cfe..796c9ee8f9 100644 --- a/src/peer-store/metadata-book.js +++ b/src/peer-store/metadata-book.js @@ -53,7 +53,7 @@ class MetadataBook extends Book { * @param {PeerId} peerId * @param {string} key - metadata key * @param {Uint8Array} value - metadata value - * @returns {ProtoBook} + * @returns {MetadataBook} */ set (peerId, key, value) { if (!PeerId.isPeerId(peerId)) { diff --git a/src/peer-store/proto-book.js b/src/peer-store/proto-book.js index 009d0ba8cc..60b9c503f9 100644 --- a/src/peer-store/proto-book.js +++ b/src/peer-store/proto-book.js @@ -52,7 +52,7 @@ class ProtoBook extends Book { * * @override * @param {PeerId} peerId - * @param {Array} protocols + * @param {string[]} protocols * @returns {ProtoBook} */ set (peerId, protocols) { @@ -90,7 +90,7 @@ class ProtoBook extends Book { * If the peer was not known before, it will be added. * * @param {PeerId} peerId - * @param {Array} protocols + * @param {string[]} protocols * @returns {ProtoBook} */ add (peerId, protocols) { @@ -125,7 +125,7 @@ class ProtoBook extends Book { * If the protocols did not exist before, nothing will be done. * * @param {PeerId} peerId - * @param {Array} protocols + * @param {string[]} protocols * @returns {ProtoBook} */ remove (peerId, protocols) { diff --git a/src/ping/index.js b/src/ping/index.js index 415f400036..5ad54021cf 100644 --- a/src/ping/index.js +++ b/src/ping/index.js @@ -14,7 +14,7 @@ const { PROTOCOL, PING_LENGTH } = require('./constants') /** * @typedef {import('../')} Libp2p - * @typedef {import('multiaddr')} multiaddr + * @typedef {import('multiaddr')} Multiaddr * @typedef {import('peer-id')} PeerId */ @@ -22,7 +22,7 @@ const { PROTOCOL, PING_LENGTH } = require('./constants') * Ping a given peer and wait for its response, getting the operation latency. * * @param {Libp2p} node - * @param {PeerId|multiaddr} peer + * @param {PeerId|Multiaddr} peer * @returns {Promise} */ async function ping (node, peer) { diff --git a/src/pnet/index.js b/src/pnet/index.js index d49e13df79..d2b97b2cb7 100644 --- a/src/pnet/index.js +++ b/src/pnet/index.js @@ -21,7 +21,7 @@ log.error = debug('libp2p:pnet:err') /** * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection - * @typedef {import('../').DuplexIterable} DuplexIterable + * @typedef {import('libp2p-interfaces/src/connection/connection').DuplexIterableStream} DuplexIterableStream */ class Protector { @@ -44,7 +44,7 @@ class Protector { * created with. * * @param {Connection} connection - The connection to protect - * @returns {DuplexIterable} A protected duplex iterable + * @returns {DuplexIterableStream} A protected duplex iterable */ async protect (connection) { if (!connection) { diff --git a/src/pubsub-adapter.js b/src/pubsub-adapter.js index 1f42cc7d15..4f2134fe6c 100644 --- a/src/pubsub-adapter.js +++ b/src/pubsub-adapter.js @@ -1,5 +1,9 @@ 'use strict' +/** + * @typedef {import('libp2p-interfaces/src/pubsub').InMessage} InMessage + */ + // Pubsub adapter to keep API with handlers while not removed. module.exports = (PubsubRouter, libp2p, options) => { class Pubsub extends PubsubRouter { diff --git a/src/record/peer-record/index.js b/src/record/peer-record/index.js index faeac81d24..2fadc3b9aa 100644 --- a/src/record/peer-record/index.js +++ b/src/record/peer-record/index.js @@ -13,7 +13,7 @@ const { /** * @typedef {import('peer-id')} PeerId - * @typedef {import('multiaddr')} multiaddr + * @typedef {import('multiaddr')} Multiaddr */ /** @@ -27,7 +27,7 @@ class PeerRecord extends Record { * @class * @param {Object} params * @param {PeerId} params.peerId - * @param {Array} params.multiaddrs - addresses of the associated peer. + * @param {Multiaddr[]} params.multiaddrs - addresses of the associated peer. * @param {number} [params.seqNumber] - monotonically-increasing sequence counter that's used to order PeerRecords in time. */ constructor ({ peerId, multiaddrs = [], seqNumber = Date.now() }) { diff --git a/src/transport-manager.js b/src/transport-manager.js index f6c62d143b..06ab69b74b 100644 --- a/src/transport-manager.js +++ b/src/transport-manager.js @@ -10,7 +10,7 @@ log.error = debug('libp2p:transports:error') const { updateSelfPeerRecord } = require('./record/utils') /** - * @typedef {import('multiaddr')} multiaddr + * @typedef {import('multiaddr')} Multiaddr * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection * * @typedef {Object} TransportManagerProperties @@ -90,7 +90,7 @@ class TransportManager { /** * Dials the given Multiaddr over it's supported transport * - * @param {multiaddr} ma + * @param {Multiaddr} ma * @param {*} options * @returns {Promise} */ @@ -111,7 +111,7 @@ class TransportManager { /** * Returns all Multiaddr's the listeners are using * - * @returns {Array} + * @returns {Multiaddr[]} */ getAddrs () { let addrs = [] @@ -135,7 +135,7 @@ class TransportManager { /** * Finds a transport that matches the given Multiaddr * - * @param {multiaddr} ma + * @param {Multiaddr} ma * @returns {Transport|null} */ transportForMultiaddr (ma) { @@ -150,7 +150,7 @@ class TransportManager { * Starts listeners for each listen Multiaddr. * * @async - * @param {Array} addrs - addresses to attempt to listen on + * @param {Multiaddr[]} addrs - addresses to attempt to listen on */ async listen (addrs) { if (!addrs || addrs.length === 0) { From 28b9f8562c419d9ef5561b3671c66b99814b0582 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 26 Nov 2020 19:16:35 +0100 Subject: [PATCH 03/18] chore: add types checker script and more fixes on the jsdocs --- package.json | 12 ++++++++++- src/address-manager/index.js | 4 ---- src/circuit/auto-relay.js | 5 +++-- src/circuit/circuit/hop.js | 13 ++++++++---- src/circuit/circuit/stop.js | 17 ++++++++++------ src/circuit/circuit/stream-handler.js | 11 +++++----- src/circuit/circuit/utils.js | 4 ++++ src/circuit/index.js | 5 +++-- src/circuit/listener.js | 10 ++++----- src/connection-manager/index.js | 29 +++++++++++++++------------ src/content-routing.js | 3 ++- src/dialer/dial-request.js | 8 +++----- src/dialer/index.js | 13 +++++++----- src/get-peer.js | 3 +-- src/identify/index.js | 18 ++++++++--------- src/index.js | 27 ++++++++++++++----------- src/insecure/plaintext.js | 7 ++++--- src/keychain/index.js | 3 ++- src/peer-routing.js | 22 ++++---------------- src/peer-store/address-book.js | 14 +++++++------ src/peer-store/book.js | 12 ++++++++--- src/peer-store/index.js | 7 ++----- src/peer-store/key-book.js | 11 +++++++--- src/peer-store/metadata-book.js | 11 +++++++--- src/peer-store/persistent/index.js | 9 ++++++--- src/peer-store/proto-book.js | 15 ++++++++++---- src/ping/index.js | 13 +++++++----- src/pnet/crypto.js | 9 +++++---- src/pnet/index.js | 13 ++++++------ src/pnet/key-generator.js | 2 ++ src/pubsub-adapter.js | 5 +++-- src/record/envelope/index.js | 9 +++------ src/registrar.js | 10 +++++---- src/transport-manager.js | 14 +++++++------ src/types.ts | 18 +++++++++++++++++ src/upgrader.js | 16 ++++++++------- tsconfig.json | 9 +++++++++ 37 files changed, 246 insertions(+), 165 deletions(-) create mode 100644 src/types.ts create mode 100644 tsconfig.json diff --git a/package.json b/package.json index 3996c800c0..b7cd5777c4 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,15 @@ "description": "JavaScript implementation of libp2p, a modular peer to peer network stack", "leadMaintainer": "Jacob Heun ", "main": "src/index.js", + "types": "dist/src/index.d.ts", + "typesVersions": { + "*": { + "src/*": [ + "dist/src/*", + "dist/src/*/index" + ] + } + }, "files": [ "dist", "src" @@ -15,6 +24,7 @@ "test:node": "aegir test -t node -f \"./test/**/*.{node,spec}.js\"", "test:browser": "aegir test -t browser", "test:examples": "cd examples && npm run test:all", + "test:types": "aegir ts -p check", "release": "aegir release -t node -t browser", "release-minor": "aegir release --type minor -t node -t browser", "release-major": "aegir release --type major -t node -t browser", @@ -88,7 +98,7 @@ "devDependencies": { "@nodeutils/defaults-deep": "^1.1.0", "abortable-iterator": "^3.0.0", - "aegir": "^27.0.0", + "aegir": "^29.1.0", "chai-bytes": "^0.1.2", "chai-string": "^1.5.0", "delay": "^4.3.0", diff --git a/src/address-manager/index.js b/src/address-manager/index.js index d4811be72c..5c9874af33 100644 --- a/src/address-manager/index.js +++ b/src/address-manager/index.js @@ -1,9 +1,5 @@ 'use strict' -const debug = require('debug') -const log = debug('libp2p:addresses') -log.error = debug('libp2p:addresses:error') - const multiaddr = require('multiaddr') /** diff --git a/src/circuit/auto-relay.js b/src/circuit/auto-relay.js index 7cca188735..babf4ea75a 100644 --- a/src/circuit/auto-relay.js +++ b/src/circuit/auto-relay.js @@ -1,8 +1,9 @@ 'use strict' const debug = require('debug') -const log = debug('libp2p:auto-relay') -log.error = debug('libp2p:auto-relay:error') +const log = Object.assign(debug('libp2p:auto-relay'), { + error: debug('libp2p:auto-relay:err') +}) const uint8ArrayFromString = require('uint8arrays/from-string') const uint8ArrayToString = require('uint8arrays/to-string') diff --git a/src/circuit/circuit/hop.js b/src/circuit/circuit/hop.js index c653a7c9ae..7cd7ab2312 100644 --- a/src/circuit/circuit/hop.js +++ b/src/circuit/circuit/hop.js @@ -1,21 +1,26 @@ 'use strict' const debug = require('debug') -const log = debug('libp2p:circuit:hop') -log.error = debug('libp2p:circuit:hop:error') +const log = Object.assign(debug('libp2p:circuit:hop'), { + error: debug('libp2p:circuit:hop:err') +}) +const errCode = require('err-code') const PeerId = require('peer-id') const { validateAddrs } = require('./utils') const StreamHandler = require('./stream-handler') const { CircuitRelay: CircuitPB } = require('../protocol') -const pipe = require('it-pipe') -const errCode = require('err-code') +const { pipe } = require('it-pipe') const { codes: Errors } = require('../../errors') const { stop } = require('./stop') const multicodec = require('./../multicodec') +/** + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + */ + module.exports.handleHop = async function handleHop ({ connection, request, diff --git a/src/circuit/circuit/stop.js b/src/circuit/circuit/stop.js index 77eaa1fcc2..f9447b722d 100644 --- a/src/circuit/circuit/stop.js +++ b/src/circuit/circuit/stop.js @@ -1,23 +1,28 @@ 'use strict' +const debug = require('debug') +const log = Object.assign(debug('libp2p:circuit:stop'), { + error: debug('libp2p:circuit:stop:err') +}) + const { CircuitRelay: CircuitPB } = require('../protocol') const multicodec = require('../multicodec') const StreamHandler = require('./stream-handler') const { validateAddrs } = require('./utils') -const debug = require('debug') -const log = debug('libp2p:circuit:stop') -log.error = debug('libp2p:circuit:stop:error') +/** + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + */ /** * Handles incoming STOP requests * * @private - * @param {*} options + * @param {object} options * @param {Connection} options.connection * @param {*} options.request - The CircuitRelay protobuf request (unencoded) * @param {StreamHandler} options.streamHandler - * @returns {Promise<*>} Resolves a duplex iterable + * @returns {Promise<*>|void} Resolves a duplex iterable */ module.exports.handleStop = function handleStop ({ connection, @@ -44,7 +49,7 @@ module.exports.handleStop = function handleStop ({ * Creates a STOP request * * @private - * @param {*} options + * @param {object} options * @param {Connection} options.connection * @param {*} 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 8b8ecf89bc..fe0adba722 100644 --- a/src/circuit/circuit/stream-handler.js +++ b/src/circuit/circuit/stream-handler.js @@ -1,13 +1,14 @@ 'use strict' +const debug = require('debug') +const log = Object.assign(debug('libp2p:circuit:stream-handler'), { + error: debug('libp2p:circuit:stream-handler:err') +}) + const lp = require('it-length-prefixed') const handshake = require('it-handshake') const { CircuitRelay: CircuitPB } = require('../protocol') -const debug = require('debug') -const log = debug('libp2p:circuit:stream-handler') -log.error = debug('libp2p:circuit:stream-handler:error') - class StreamHandler { /** * Create a stream handler for connection @@ -27,7 +28,7 @@ class StreamHandler { * Read and decode message * * @async - * @returns {void} + * @returns {Promise} */ async read () { const msg = await this.decoder.next() diff --git a/src/circuit/circuit/utils.js b/src/circuit/circuit/utils.js index be7ab35a73..669c37adc3 100644 --- a/src/circuit/circuit/utils.js +++ b/src/circuit/circuit/utils.js @@ -3,6 +3,10 @@ const multiaddr = require('multiaddr') const { CircuitRelay } = require('../protocol') +/** + * @typedef {import('./stream-handler')} StreamHandler + */ + /** * Write a response * diff --git a/src/circuit/index.js b/src/circuit/index.js index 91cb685106..447d829ac5 100644 --- a/src/circuit/index.js +++ b/src/circuit/index.js @@ -1,8 +1,9 @@ 'use strict' const debug = require('debug') -const log = debug('libp2p:relay') -log.error = debug('libp2p:relay:error') +const log = Object.assign(debug('libp2p:relay'), { + error: debug('libp2p:relay:err') +}) const { setDelayedInterval, diff --git a/src/circuit/listener.js b/src/circuit/listener.js index 02e371fb8b..e591e43d11 100644 --- a/src/circuit/listener.js +++ b/src/circuit/listener.js @@ -1,14 +1,14 @@ 'use strict' -const EventEmitter = require('events') +const { EventEmitter } = require('events') const multiaddr = require('multiaddr') -const debug = require('debug') -const log = debug('libp2p:circuit:listener') -log.err = debug('libp2p:circuit:error:listener') +/** + * @typedef {import('multiaddr')} Multiaddr + */ /** - * @param {Libp2p} libp2p + * @param {import('../')} libp2p * @returns {Listener} a transport listener */ module.exports = (libp2p) => { diff --git a/src/connection-manager/index.js b/src/connection-manager/index.js index 7b6ae5e414..8259e56ba5 100644 --- a/src/connection-manager/index.js +++ b/src/connection-manager/index.js @@ -1,8 +1,9 @@ 'use strict' const debug = require('debug') -const log = debug('libp2p:connection-manager') -log.error = debug('libp2p:connection-manager:error') +const log = Object.assign(debug('libp2p:connection-manager'), { + error: debug('libp2p:connection-manager:err') +}) const errcode = require('err-code') const mergeOptions = require('merge-options') @@ -14,7 +15,7 @@ const { EventEmitter } = require('events') const PeerId = require('peer-id') const { - ERR_INVALID_PARAMETERS + codes: { ERR_INVALID_PARAMETERS } } = require('../errors') const defaultOptions = { @@ -187,15 +188,17 @@ class ConnectionManager extends EventEmitter { * @private */ _checkMetrics () { - const movingAverages = this._libp2p.metrics.global.movingAverages - const received = movingAverages.dataReceived[this._options.movingAverageInterval].movingAverage() - this._checkMaxLimit('maxReceivedData', received) - const sent = movingAverages.dataSent[this._options.movingAverageInterval].movingAverage() - this._checkMaxLimit('maxSentData', sent) - const total = received + sent - this._checkMaxLimit('maxData', total) - log('metrics update', total) - this._timer = retimer(this._checkMetrics, this._options.pollInterval) + if (this._libp2p.metrics) { + const movingAverages = this._libp2p.metrics.global.movingAverages + const received = movingAverages.dataReceived[this._options.movingAverageInterval].movingAverage() + this._checkMaxLimit('maxReceivedData', received) + const sent = movingAverages.dataSent[this._options.movingAverageInterval].movingAverage() + this._checkMaxLimit('maxSentData', sent) + const total = received + sent + this._checkMaxLimit('maxData', total) + log('metrics update', total) + this._timer = retimer(this._checkMetrics, this._options.pollInterval) + } } /** @@ -249,7 +252,7 @@ class ConnectionManager extends EventEmitter { * Get a connection with a peer. * * @param {PeerId} peerId - * @returns {Connection} + * @returns {Connection|null} */ get (peerId) { const connections = this.getAll(peerId) diff --git a/src/content-routing.js b/src/content-routing.js index 75131ba1fa..185865d8ae 100644 --- a/src/content-routing.js +++ b/src/content-routing.js @@ -9,6 +9,7 @@ const pAny = require('p-any') /** * @typedef {import('peer-id')} PeerId * @typedef {import('multiaddr')} Multiaddr + * @typedef {import('cids')} CID */ /** @@ -63,7 +64,7 @@ module.exports = (node) => { * 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 if (!routers.length) { diff --git a/src/dialer/dial-request.js b/src/dialer/dial-request.js index d91158ed49..f906c2ba81 100644 --- a/src/dialer/dial-request.js +++ b/src/dialer/dial-request.js @@ -1,15 +1,13 @@ 'use strict' +const errCode = require('err-code') const AbortController = require('abort-controller') const anySignal = require('any-signal') -const debug = require('debug') -const errCode = require('err-code') -const log = debug('libp2p:dialer:request') -log.error = debug('libp2p:dialer:request:error') const FIFO = require('p-fifo') const pAny = require('p-any') /** + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection * @typedef {import('./')} Dialer * @typedef {import('multiaddr')} Multiaddr */ @@ -45,7 +43,7 @@ class DialRequest { * @async * @param {object} [options] * @param {AbortSignal} [options.signal] - An AbortController signal - * @returns {Connection} + * @returns {Promise} */ async run (options) { const tokens = this.dialer.getTokens(this.addrs.length) diff --git a/src/dialer/index.js b/src/dialer/index.js index 18be09c1a5..4233e2d977 100644 --- a/src/dialer/index.js +++ b/src/dialer/index.js @@ -1,12 +1,13 @@ 'use strict' -const multiaddr = require('multiaddr') +const debug = require('debug') +const log = Object.assign(debug('libp2p:dialer'), { + error: debug('libp2p:dialer:err') +}) const errCode = require('err-code') +const multiaddr = require('multiaddr') const TimeoutController = require('timeout-abort-controller') const anySignal = require('any-signal') -const debug = require('debug') -const log = debug('libp2p:dialer') -log.error = debug('libp2p:dialer:error') const { DialRequest } = require('./dial-request') const { publicAddressesFirst } = require('libp2p-utils/src/address-sort') @@ -20,9 +21,11 @@ const { } = require('../constants') /** + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection * @typedef {import('multiaddr')} Multiaddr * @typedef {import('peer-id')} PeerId * @typedef {import('../peer-store')} PeerStore + * @typedef {import('../peer-store/address-book').Address} Address * @typedef {import('../transport-manager')} TransportManager * @typedef {import('./dial-request')} DialRequest */ @@ -172,7 +175,7 @@ class Dialer { * @param {AbortSignal} [options.signal] - An AbortController signal * @returns {PendingDial} */ - _createPendingDial (dialTarget, options) { + _createPendingDial (dialTarget, options = {}) { const dialAction = (addr, options) => { if (options.signal.aborted) throw errCode(new Error('already aborted'), codes.ERR_ALREADY_ABORTED) return this.transportManager.dial(addr, options) diff --git a/src/get-peer.js b/src/get-peer.js index 29422334eb..35e2f26429 100644 --- a/src/get-peer.js +++ b/src/get-peer.js @@ -7,7 +7,6 @@ const errCode = require('err-code') const { codes } = require('./errors') /** - * @typedef {import('peer-id')} PeerId * @typedef {import('multiaddr')} Multiaddr */ @@ -16,7 +15,7 @@ const { codes } = require('./errors') * If a multiaddr is received, the addressBook is updated. * * @param {PeerId|multiaddr|string} peer - * @returns {{ id: PeerId, multiaddrs: Multiaddr[] }} + * @returns {{ id: PeerId, multiaddrs: Multiaddr[]|undefined }} */ function getPeer (peer) { if (typeof peer === 'string') { diff --git a/src/identify/index.js b/src/identify/index.js index 7b1617e139..fe8b91b0a4 100644 --- a/src/identify/index.js +++ b/src/identify/index.js @@ -1,13 +1,13 @@ 'use strict' const debug = require('debug') -const log = debug('libp2p:identify') -log.error = debug('libp2p:identify:error') - +const log = Object.assign(debug('libp2p:identify'), { + error: debug('libp2p:identify:err') +}) const errCode = require('err-code') const pb = require('it-protocol-buffers') const lp = require('it-length-prefixed') -const pipe = require('it-pipe') +const { pipe } = require('it-pipe') const { collect, take, consume } = require('streaming-iterables') const uint8ArrayFromString = require('uint8arrays/from-string') @@ -50,9 +50,7 @@ class IdentifyService { // When a new connection happens, trigger identify this.connectionManager.on('peer:connect', (connection) => { - const peerId = connection.remotePeer - - this.identify(connection, peerId).catch(log.error) + this.identify(connection).catch(log.error) }) // When self multiaddrs change, trigger identify-push @@ -74,7 +72,7 @@ class IdentifyService { * Send an Identify Push update to the list of connections * * @param {Connection[]} connections - * @returns {Promise} + * @returns {Promise} */ async push (connections) { const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId) @@ -205,7 +203,7 @@ class IdentifyService { * @param {string} options.protocol * @param {DuplexIterableStream} options.stream * @param {Connection} options.connection - * @returns {Promise} + * @returns {Promise|undefined} */ handleMessage ({ connection, stream, protocol }) { switch (protocol) { @@ -226,6 +224,7 @@ class IdentifyService { * @param {Object} options * @param {DuplexIterableStream} options.stream * @param {Connection} options.connection + * @returns {Promise} */ async _handleIdentify ({ connection, stream }) { let publicKey = new Uint8Array(0) @@ -265,6 +264,7 @@ class IdentifyService { * @param {object} options * @param {DuplexIterableStream} options.stream * @param {Connection} options.connection + * @returns {Promise} */ async _handlePush ({ connection, stream }) { let message diff --git a/src/index.js b/src/index.js index eca2206fa8..d9440adf1e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,10 +1,11 @@ 'use strict' -const { EventEmitter } = require('events') const debug = require('debug') +const log = Object.assign(debug('libp2p'), { + error: debug('libp2p:err') +}) +const { EventEmitter } = require('events') const globalThis = require('ipfs-utils/src/globalthis') -const log = debug('libp2p') -log.error = debug('libp2p:error') const errCode = require('err-code') const PeerId = require('peer-id') @@ -36,6 +37,7 @@ const { /** * @typedef {import('multiaddr')} Multiaddr + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection */ /** @@ -131,6 +133,7 @@ class Libp2p extends EventEmitter { const keychainOpts = Keychain.generateOptions() + /** @type {Keychain} */ this.keychain = new Keychain(this._options.keychain.datastore, { passPhrase: this._options.keychain.pass, ...keychainOpts, @@ -285,7 +288,7 @@ class Libp2p extends EventEmitter { * Stop the libp2p node by closing its listeners and open connections * * @async - * @returns {void} + * @returns {Promise} */ async stop () { log('libp2p is stopping') @@ -331,7 +334,7 @@ class Libp2p extends EventEmitter { * Imports the private key as 'self', if needed. * * @async - * @returns {void} + * @returns {Promise} */ async loadKeychain () { try { @@ -360,12 +363,12 @@ class Libp2p extends EventEmitter { * peer will be added to the nodes `peerStore` * * @param {PeerId|Multiaddr|string} peer - The peer to dial - * @param {object} options + * @param {object} [options] * @param {AbortSignal} [options.signal] * @returns {Promise} */ dial (peer, options) { - return this.dialProtocol(peer, null, options) + return this.dialProtocol(peer, undefined, options) } /** @@ -375,8 +378,8 @@ class Libp2p extends EventEmitter { * * @async * @param {PeerId|Multiaddr|string} peer - The peer to dial - * @param {string[]|string} protocols - * @param {object} options + * @param {undefined|string[]|string} protocols + * @param {object} [options] * @param {AbortSignal} [options.signal] * @returns {Promise} */ @@ -644,10 +647,10 @@ class Libp2p extends EventEmitter { * Like `new Libp2p(options)` except it will create a `PeerId` * instance if one is not provided in options. * - * @param {Libp2pOptions & CreateOptions} [options] - Libp2p configuration options - * @returns {Libp2p} + * @param {Libp2pOptions & CreateOptions} options - Libp2p configuration options + * @returns {Promise} */ -Libp2p.create = async function create (options = {}) { +Libp2p.create = async function create (options) { if (options.peerId) { return new Libp2p(options) } diff --git a/src/insecure/plaintext.js b/src/insecure/plaintext.js index 0e9f8dd992..92010798c1 100644 --- a/src/insecure/plaintext.js +++ b/src/insecure/plaintext.js @@ -1,11 +1,12 @@ 'use strict' +const debug = require('debug') +const log = Object.assign(debug('libp2p:plaintext'), { + error: debug('libp2p:plaintext:err') +}) const handshake = require('it-handshake') const lp = require('it-length-prefixed') const PeerId = require('peer-id') -const debug = require('debug') -const log = debug('libp2p:plaintext') -log.error = debug('libp2p:plaintext:error') const { UnexpectedPeerError, InvalidCryptoExchangeError } = require('libp2p-interfaces/src/crypto/errors') const { Exchange, KeyType } = require('./proto') diff --git a/src/keychain/index.js b/src/keychain/index.js index c823eb3e46..10d402c669 100644 --- a/src/keychain/index.js +++ b/src/keychain/index.js @@ -101,7 +101,8 @@ class Keychain { * Creates a new instance of a key chain. * * @param {DS} store - where the key are. - * @param {object} options - ??? + * @param {object} options + * @class */ constructor (store, options) { if (!store) { diff --git a/src/peer-routing.js b/src/peer-routing.js index 841a3279c3..88a230196c 100644 --- a/src/peer-routing.js +++ b/src/peer-routing.js @@ -1,9 +1,10 @@ 'use strict' -const errCode = require('err-code') const debug = require('debug') -const log = debug('libp2p:peer-routing') -log.error = debug('libp2p:peer-routing:error') +const log = Object.assign(debug('libp2p:peer-routing'), { + error: debug('libp2p:peer-routing:err') +}) +const errCode = require('err-code') const all = require('it-all') const pAny = require('p-any') @@ -69,7 +70,6 @@ class PeerRouting { clearDelayedInterval(this._timeoutId) } -<<<<<<< HEAD /** * Iterates over all peer routers in series to find the given peer. * @@ -89,20 +89,6 @@ class PeerRouting { // If we don't have a result, we need to provide an error to keep trying if (!result || Object.keys(result).length === 0) { throw errCode(new Error('not found'), 'NOT_FOUND') -======= - return { - /** - * Iterates over all peer routers in series to find the given peer. - * - * @param {string} id - The id of the peer to find - * @param {object} [options] - * @param {number} [options.timeout] - How long the query should run - * @returns {Promise<{ id: PeerId, multiaddrs: Multiaddr[] }>} - */ - findPeer: async (id, options) => { // eslint-disable-line require-await - if (!routers.length) { - throw errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE') ->>>>>>> chore: address review } return result diff --git a/src/peer-store/address-book.js b/src/peer-store/address-book.js index bbfc30c8b9..5545997322 100644 --- a/src/peer-store/address-book.js +++ b/src/peer-store/address-book.js @@ -1,9 +1,10 @@ 'use strict' -const errcode = require('err-code') const debug = require('debug') -const log = debug('libp2p:peer-store:address-book') -log.error = debug('libp2p:peer-store:address-book:error') +const log = Object.assign(debug('libp2p:peer-store:address-book'), { + error: debug('libp2p:peer-store:address-book:err') +}) +const errcode = require('err-code') const multiaddr = require('multiaddr') const PeerId = require('peer-id') @@ -18,6 +19,7 @@ const Envelope = require('../record/envelope') /** * @typedef {import('multiaddr')} Multiaddr + * @typedef {import('./')} PeerStore */ /** @@ -75,7 +77,7 @@ class AddressBook extends Book { /** * Map known peers to their known Address Entries. * - * @type {Map} + * @type {Map} */ this.data = new Map() } @@ -110,7 +112,7 @@ class AddressBook extends Book { const peerId = peerRecord.peerId const id = peerId.toB58String() - const entry = this.data.get(id) || {} + const entry = this.data.get(id) || { record: undefined } const storedRecord = entry.record // ensure seq is greater than, or equal to, the last received @@ -156,7 +158,7 @@ class AddressBook extends Book { * Returns undefined if no record exists. * * @param {PeerId} peerId - * @returns {Promise} + * @returns {Promise|undefined} */ getPeerRecord (peerId) { const raw = this.getRawEnvelope(peerId) diff --git a/src/peer-store/book.js b/src/peer-store/book.js index cbfafdd6b9..447483d9e2 100644 --- a/src/peer-store/book.js +++ b/src/peer-store/book.js @@ -9,12 +9,17 @@ const { const passthrough = data => data +/** + * @typedef {import('./')} PeerStore + */ + +/** + * @template T + */ class Book { /** * The Book is the skeleton for the PeerStore books. * - * @template T - * * @class * @param {Object} properties * @param {PeerStore} properties.peerStore - PeerStore instance. @@ -31,7 +36,7 @@ class Book { /** * Map known peers to their data. * - * @type {Map} */ this.data = new Map() } @@ -94,6 +99,7 @@ class Book { const rec = this.data.get(peerId.toB58String()) + // @ts-ignore return rec ? [...rec] : undefined } diff --git a/src/peer-store/index.js b/src/peer-store/index.js index 3713d7d4d0..07762b8cbc 100644 --- a/src/peer-store/index.js +++ b/src/peer-store/index.js @@ -1,9 +1,6 @@ 'use strict' const errcode = require('err-code') -const debug = require('debug') -const log = debug('libp2p:peer-store') -log.error = debug('libp2p:peer-store:error') const { EventEmitter } = require('events') const PeerId = require('peer-id') @@ -14,7 +11,7 @@ const MetadataBook = require('./metadata-book') const ProtoBook = require('./proto-book') const { - ERR_INVALID_PARAMETERS + codes: { ERR_INVALID_PARAMETERS } } = require('../errors') /** @@ -127,7 +124,7 @@ class PeerStore extends EventEmitter { * Get the stored information of a given peer. * * @param {PeerId} peerId - * @returns {Peer} + * @returns {Peer|undefined} */ get (peerId) { if (!PeerId.isPeerId(peerId)) { diff --git a/src/peer-store/key-book.js b/src/peer-store/key-book.js index 6a045ad58f..1c22db63ef 100644 --- a/src/peer-store/key-book.js +++ b/src/peer-store/key-book.js @@ -1,9 +1,10 @@ 'use strict' -const errcode = require('err-code') const debug = require('debug') -const log = debug('libp2p:peer-store:key-book') -log.error = debug('libp2p:peer-store:key-book:error') +const log = Object.assign(debug('libp2p:peer-store:key-book'), { + error: debug('libp2p:peer-store:key-book:err') +}) +const errcode = require('err-code') const PeerId = require('peer-id') @@ -13,6 +14,10 @@ const { codes: { ERR_INVALID_PARAMETERS } } = require('../errors') +/** + * @typedef {import('./')} PeerStore + */ + /** * @extends {Book} */ diff --git a/src/peer-store/metadata-book.js b/src/peer-store/metadata-book.js index 796c9ee8f9..7d24312cf8 100644 --- a/src/peer-store/metadata-book.js +++ b/src/peer-store/metadata-book.js @@ -1,9 +1,10 @@ 'use strict' -const errcode = require('err-code') const debug = require('debug') -const log = debug('libp2p:peer-store:proto-book') -log.error = debug('libp2p:peer-store:proto-book:error') +const log = Object.assign(debug('libp2p:peer-store:proto-book'), { + error: debug('libp2p:peer-store:proto-book:err') +}) +const errcode = require('err-code') const uint8ArrayEquals = require('uint8arrays/equals') const PeerId = require('peer-id') @@ -14,6 +15,10 @@ const { codes: { ERR_INVALID_PARAMETERS } } = require('../errors') +/** + * @typedef {import('./')} PeerStore + */ + /** * @extends {Book} * diff --git a/src/peer-store/persistent/index.js b/src/peer-store/persistent/index.js index f23c23e193..ceb77a650c 100644 --- a/src/peer-store/persistent/index.js +++ b/src/peer-store/persistent/index.js @@ -1,9 +1,9 @@ 'use strict' const debug = require('debug') -const log = debug('libp2p:persistent-peer-store') -log.error = debug('libp2p:persistent-peer-store:error') - +const log = Object.assign(debug('libp2p:persistent-peer-store'), { + error: debug('libp2p:persistent-peer-store:err') +}) const { Key } = require('interface-datastore') const multiaddr = require('multiaddr') const PeerId = require('peer-id') @@ -346,6 +346,7 @@ class PersistentPeerStore extends PeerStore { case 'addrs': decoded = Addresses.decode(value) + // @ts-ignore this.addressBook._setData( peerId, { @@ -363,6 +364,7 @@ class PersistentPeerStore extends PeerStore { case 'keys': decoded = await PeerId.createFromPubKey(value) + // @ts-ignore this.keyBook._setData( decoded, decoded, @@ -378,6 +380,7 @@ class PersistentPeerStore extends PeerStore { case 'protos': decoded = Protocols.decode(value) + // @ts-ignore this.protoBook._setData( peerId, new Set(decoded.protocols), diff --git a/src/peer-store/proto-book.js b/src/peer-store/proto-book.js index 60b9c503f9..18529d7369 100644 --- a/src/peer-store/proto-book.js +++ b/src/peer-store/proto-book.js @@ -1,10 +1,10 @@ 'use strict' -const errcode = require('err-code') const debug = require('debug') -const log = debug('libp2p:peer-store:proto-book') -log.error = debug('libp2p:peer-store:proto-book:error') - +const log = Object.assign(debug('libp2p:peer-store:proto-book'), { + error: debug('libp2p:peer-store:proto-book:err') +}) +const errcode = require('err-code') const PeerId = require('peer-id') const Book = require('./book') @@ -13,6 +13,10 @@ const { codes: { ERR_INVALID_PARAMETERS } } = require('../errors') +/** + * @typedef {import('./')} PeerStore + */ + /** * @extends {Book} * @@ -79,6 +83,7 @@ class ProtoBook extends Book { return this } + // @ts-ignore this._setData(peerId, newSet) log(`stored provided protocols for ${id}`) @@ -114,6 +119,7 @@ class ProtoBook extends Book { return this } + // @ts-ignore this._setData(peerId, newSet) log(`added provided protocols for ${id}`) @@ -152,6 +158,7 @@ class ProtoBook extends Book { return this } + // @ts-ignore this._setData(peerId, newSet) log(`removed provided protocols for ${id}`) } diff --git a/src/ping/index.js b/src/ping/index.js index 5ad54021cf..a242f9fb1a 100644 --- a/src/ping/index.js +++ b/src/ping/index.js @@ -1,14 +1,16 @@ 'use strict' const debug = require('debug') -const log = debug('libp2p-ping') -log.error = debug('libp2p-ping:error') +const log = Object.assign(debug('libp2p:ping'), { + error: debug('libp2p:ping:err') +}) const errCode = require('err-code') const crypto = require('libp2p-crypto') -const pipe = require('it-pipe') +const { pipe } = require('it-pipe') const { toBuffer } = require('it-buffer') const { collect, take } = require('streaming-iterables') +const equals = require('uint8arrays/equals') const { PROTOCOL, PING_LENGTH } = require('./constants') @@ -26,11 +28,12 @@ const { PROTOCOL, PING_LENGTH } = require('./constants') * @returns {Promise} */ async function ping (node, peer) { + // @ts-ignore log('dialing %s to %s', PROTOCOL, peer.toB58String ? peer.toB58String() : peer) const { stream } = await node.dialProtocol(peer, PROTOCOL) - const start = new Date() + const start = new Date().getTime() const data = crypto.randomBytes(PING_LENGTH) const [result] = await pipe( @@ -42,7 +45,7 @@ async function ping (node, peer) { ) const end = Date.now() - if (!data.equals(result)) { + if (!equals(data, result)) { throw errCode(new Error('Received wrong ping ack'), 'ERR_WRONG_PING_ACK') } diff --git a/src/pnet/crypto.js b/src/pnet/crypto.js index ae824bfcfb..9cfcbc8e6f 100644 --- a/src/pnet/crypto.js +++ b/src/pnet/crypto.js @@ -1,16 +1,17 @@ 'use strict' const debug = require('debug') +const log = Object.assign(debug('libp2p:pnet'), { + trace: debug('libp2p:pnet:trace'), + error: debug('libp2p:pnet:err') +}) + const Errors = require('./errors') const xsalsa20 = require('xsalsa20') const KEY_LENGTH = require('./key-generator').KEY_LENGTH const uint8ArrayFromString = require('uint8arrays/from-string') const uint8ArrayToString = require('uint8arrays/to-string') -const log = debug('libp2p:pnet') -log.trace = debug('libp2p:pnet:trace') -log.error = debug('libp2p:pnet:err') - /** * Creates a stream iterable to encrypt messages in a private network * diff --git a/src/pnet/index.js b/src/pnet/index.js index d2b97b2cb7..74c99947e0 100644 --- a/src/pnet/index.js +++ b/src/pnet/index.js @@ -1,12 +1,16 @@ 'use strict' -const pipe = require('it-pipe') +const debug = require('debug') +const log = Object.assign(debug('libp2p:pnet'), { + error: debug('libp2p:pnet:err') +}) +const { pipe } = require('it-pipe') const errcode = require('err-code') const duplexPair = require('it-pair/duplex') const crypto = require('libp2p-crypto') const Errors = require('./errors') const { - ERR_INVALID_PARAMETERS + codes: { ERR_INVALID_PARAMETERS } } = require('../errors') const { createBoxStream, @@ -15,9 +19,6 @@ const { } = require('./crypto') const handshake = require('it-handshake') const { NONCE_LENGTH } = require('./key-generator') -const debug = require('debug') -const log = debug('libp2p:pnet') -log.error = debug('libp2p:pnet:err') /** * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection @@ -44,7 +45,7 @@ class Protector { * created with. * * @param {Connection} connection - The connection to protect - * @returns {DuplexIterableStream} A protected duplex iterable + * @returns {Promise} A protected duplex iterable */ async protect (connection) { if (!connection) { diff --git a/src/pnet/key-generator.js b/src/pnet/key-generator.js index b3676dcccf..d88f23d83c 100644 --- a/src/pnet/key-generator.js +++ b/src/pnet/key-generator.js @@ -22,6 +22,8 @@ module.exports = generate module.exports.NONCE_LENGTH = 24 module.exports.KEY_LENGTH = KEY_LENGTH +// @ts-ignore if (require.main === module) { + // @ts-ignore generate(process.stdout) } diff --git a/src/pubsub-adapter.js b/src/pubsub-adapter.js index 4f2134fe6c..4c8aed8f2a 100644 --- a/src/pubsub-adapter.js +++ b/src/pubsub-adapter.js @@ -2,6 +2,7 @@ /** * @typedef {import('libp2p-interfaces/src/pubsub').InMessage} InMessage + * @typedef {import('libp2p-interfaces/src/pubsub')} PubsubRouter */ // Pubsub adapter to keep API with handlers while not removed. @@ -12,7 +13,7 @@ module.exports = (PubsubRouter, libp2p, options) => { * * @override * @param {string} topic - * @param {function(msg: InMessage)} [handler] + * @param {(msg: InMessage) => void} [handler] * @returns {void} */ subscribe (topic, handler) { @@ -26,7 +27,7 @@ module.exports = (PubsubRouter, libp2p, options) => { * * @override * @param {string} topic - * @param {function(msg: InMessage)} [handler] + * @param {(msg: InMessage) => void} [handler] * @returns {void} */ unsubscribe (topic, handler) { diff --git a/src/record/envelope/index.js b/src/record/envelope/index.js index cee2e26b96..88a702afc5 100644 --- a/src/record/envelope/index.js +++ b/src/record/envelope/index.js @@ -1,8 +1,5 @@ 'use strict' -const debug = require('debug') -const log = debug('libp2p:envelope') -log.error = debug('libp2p:envelope:error') const errCode = require('err-code') const uint8arraysConcat = require('uint8arrays/concat') const uint8arraysFromString = require('uint8arrays/from-string') @@ -15,7 +12,7 @@ const { codes } = require('../../errors') const Protobuf = require('./envelope.proto') /** - * @typedef {import('peer-id')} PeerId + * @typedef {import('libp2p-interfaces/src/record')} Record */ class Envelope { @@ -145,7 +142,7 @@ Envelope.createFromProtobuf = async (data) => { * @async * @param {Record} record * @param {PeerId} peerId - * @returns {Envelope} + * @returns {Promise} */ Envelope.seal = async (record, peerId) => { const domain = record.domain @@ -169,7 +166,7 @@ Envelope.seal = async (record, peerId) => { * * @param {Uint8Array} data * @param {string} domain - * @returns {Envelope} + * @returns {Promise} */ Envelope.openAndCertify = async (data, domain) => { const envelope = await Envelope.createFromProtobuf(data) diff --git a/src/registrar.js b/src/registrar.js index 4917aeb5b8..70998c5d1c 100644 --- a/src/registrar.js +++ b/src/registrar.js @@ -1,12 +1,13 @@ 'use strict' const debug = require('debug') +const log = Object.assign(debug('libp2p:peer-store'), { + error: debug('libp2p:peer-store:err') +}) const errcode = require('err-code') -const log = debug('libp2p:peer-store') -log.error = debug('libp2p:peer-store:error') const { - ERR_INVALID_PARAMETERS + codes: { ERR_INVALID_PARAMETERS } } = require('./errors') const Topology = require('libp2p-interfaces/src/topology') @@ -73,11 +74,12 @@ class Registrar { */ register (topology) { if (!Topology.isTopology(topology)) { + log.error('topology must be an instance of interfaces/topology') throw errcode(new Error('topology must be an instance of interfaces/topology'), ERR_INVALID_PARAMETERS) } // Create topology - const id = (parseInt(Math.random() * 1e9)).toString(36) + Date.now() + const id = (Math.random() * 1e9).toString(36) + Date.now() this.topologies.set(id, topology) diff --git a/src/transport-manager.js b/src/transport-manager.js index 06ab69b74b..d9aef5335c 100644 --- a/src/transport-manager.js +++ b/src/transport-manager.js @@ -1,11 +1,13 @@ 'use strict' +const debug = require('debug') +const log = Object.assign(debug('libp2p:transports'), { + error: debug('libp2p:transports:err') +}) + const pSettle = require('p-settle') const { codes } = require('./errors') const errCode = require('err-code') -const debug = require('debug') -const log = debug('libp2p:transports') -log.error = debug('libp2p:transports:error') const { updateSelfPeerRecord } = require('./record/utils') @@ -18,7 +20,7 @@ const { updateSelfPeerRecord } = require('./record/utils') * @property {import('./upgrader')} upgrader * * @typedef {Object} TransportManagerOptions - * @property {boolean} [faultTolerance = FAULT_TOLERANCE.FATAL_ALL] - Address listen error tolerance. + * @property {number} [faultTolerance = FAULT_TOLERANCE.FATAL_ALL] - Address listen error tolerance. */ class TransportManager { @@ -126,7 +128,7 @@ class TransportManager { /** * Returns all the transports instances. * - * @returns {Iterator} + * @returns {IterableIterator} */ getTransports () { return this._transports.values() @@ -166,7 +168,7 @@ class TransportManager { // For each supported multiaddr, create a listener for (const addr of supportedAddrs) { log('creating listener for %s on %s', key, addr) - const listener = transport.createListener({}, this.onConnection) + const listener = transport.createListener({}) this._listeners.get(key).push(listener) // Track listen/close events diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000000..7f0ad3680c --- /dev/null +++ b/src/types.ts @@ -0,0 +1,18 @@ + +// Insecure Message types +export enum KeyType { + RSA = 0, + Ed25519 = 1, + Secp256k1 = 2, + ECDSA = 3 +} + +export type MessagePublicKey = { + Type: KeyType + Data: Uint8Array +} + +export type MessageExchange = { + id: Uint8Array + pubKey: MessagePublicKey +} diff --git a/src/upgrader.js b/src/upgrader.js index 0a422b2e82..ca798deaa7 100644 --- a/src/upgrader.js +++ b/src/upgrader.js @@ -1,20 +1,22 @@ 'use strict' const debug = require('debug') -const log = debug('libp2p:upgrader') -log.error = debug('libp2p:upgrader:error') +const log = Object.assign(debug('libp2p:upgrader'), { + error: debug('libp2p:upgrader:err') +}) +const errCode = require('err-code') const Multistream = require('multistream-select') const { Connection } = require('libp2p-interfaces/src/connection') const ConnectionStatus = require('libp2p-interfaces/src/connection/status') const PeerId = require('peer-id') const pipe = require('it-pipe') -const errCode = require('err-code') const mutableProxy = require('mutable-proxy') const { codes } = require('./errors') /** * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('multiaddr')} Multiaddr */ /** @@ -36,11 +38,11 @@ class Upgrader { /** * @param {object} options * @param {PeerId} options.localPeer - * @param {Metrics} options.metrics + * @param {import('./metrics')} [options.metrics] * @param {Map} options.cryptos * @param {Map} options.muxers - * @param {function(Connection)} options.onConnection - Called when a connection is upgraded - * @param {function(Connection)} options.onConnectionEnd + * @param {(Connection) => void} options.onConnection - Called when a connection is upgraded + * @param {(Connection) => void} options.onConnectionEnd */ constructor ({ localPeer, @@ -78,7 +80,7 @@ class Upgrader { if (this.metrics) { ({ setTarget: setPeer, proxy: proxyPeer } = mutableProxy()) - const idString = (parseInt(Math.random() * 1e9)).toString(36) + Date.now() + const idString = (Math.random() * 1e9).toString(36) + Date.now() setPeer({ toB58String: () => idString }) maConn = this.metrics.trackStream({ stream: maConn, remotePeer: proxyPeer }) } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..5b9a618c43 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ] +} \ No newline at end of file From 4b309ada54ef86aae43ab7bd6788df4da931d947 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Tue, 1 Dec 2020 22:47:59 +0100 Subject: [PATCH 04/18] chore: use new libp2p interface --- .travis.yml | 1 + package.json | 4 +- src/circuit/auto-relay.js | 3 + src/circuit/circuit/hop.js | 37 ++++++++-- src/circuit/circuit/stop.js | 2 +- src/circuit/circuit/stream-handler.js | 8 +- src/circuit/circuit/utils.js | 3 +- src/circuit/listener.js | 42 +++++------ src/circuit/protocol/index.js | 2 + src/circuit/transport.js | 17 +++-- src/circuit/utils.js | 2 + src/connection-manager/index.js | 5 +- src/connection-manager/latency-monitor.js | 1 + .../visibility-change-emitter.js | 1 + src/dialer/dial-request.js | 5 +- src/dialer/index.js | 16 ++-- src/identify/consts.js | 1 + src/identify/index.js | 19 +++-- src/index.js | 21 ++++-- src/keychain/cms.js | 1 + src/keychain/index.js | 1 + src/keychain/util.js | 1 + src/metrics/index.js | 10 ++- src/metrics/old-peers.js | 3 +- src/metrics/stats.js | 24 +++--- src/peer-routing.js | 2 +- src/peer-store/address-book.js | 48 ++++++------ src/peer-store/book.js | 6 +- src/peer-store/index.js | 2 +- src/peer-store/key-book.js | 4 +- src/peer-store/metadata-book.js | 6 +- src/peer-store/persistent/index.js | 2 +- src/pnet/index.js | 7 +- src/pubsub-adapter.js | 73 ++++++++++--------- src/record/envelope/envelope.proto.js | 7 +- src/record/envelope/index.js | 10 +-- src/record/peer-record/index.js | 6 +- src/record/peer-record/peer-record.proto.js | 7 +- src/registrar.js | 2 +- src/transport-manager.js | 2 + src/types.ts | 65 +++++++++++++++++ src/upgrader.js | 65 +++++++++-------- test/dialing/dial-request.spec.js | 2 +- test/identify/index.spec.js | 3 +- test/upgrading/upgrader.spec.js | 22 ------ tsconfig.json | 16 +++- 46 files changed, 355 insertions(+), 232 deletions(-) diff --git a/.travis.yml b/.travis.yml index 47f1fcb07a..b4bbfc1855 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,7 @@ jobs: # Remove pull libs once ping is async - npx aegir dep-check -- -i pull-handshake -i pull-stream - npm run lint + - npm run test:types - stage: test name: chrome diff --git a/package.json b/package.json index b7cd5777c4..8a3465f3bc 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "events": "^3.1.0", "hashlru": "^2.3.0", "interface-datastore": "^2.0.0", - "ipfs-utils": "^2.2.0", + "ipfs-utils": "^5.0.1", "it-all": "^1.0.1", "it-buffer": "^0.1.2", "it-handshake": "^1.0.1", @@ -71,7 +71,7 @@ "it-pipe": "^1.1.0", "it-protocol-buffers": "^0.2.0", "libp2p-crypto": "^0.18.0", - "libp2p-interfaces": "libp2p/js-libp2p-interfaces#chore/add-duplex-iterable-type-to-connection", + "libp2p-interfaces": "libp2p/js-libp2p-interfaces#feat/add-types", "libp2p-utils": "^0.2.2", "mafmt": "^8.0.0", "merge-options": "^2.0.0", diff --git a/src/circuit/auto-relay.js b/src/circuit/auto-relay.js index babf4ea75a..122ac979fb 100644 --- a/src/circuit/auto-relay.js +++ b/src/circuit/auto-relay.js @@ -90,6 +90,9 @@ class AutoRelay { // If protocol, check if can hop, store info in the metadataBook and listen on it try { const connection = this._connectionManager.get(peerId) + if (!connection) { + return + } // Do not hop on a relayed connection if (connection.remoteAddr.protoCodes().includes(CIRCUIT_PROTO_CODE)) { diff --git a/src/circuit/circuit/hop.js b/src/circuit/circuit/hop.js index 7cd7ab2312..59de474fe7 100644 --- a/src/circuit/circuit/hop.js +++ b/src/circuit/circuit/hop.js @@ -21,7 +21,19 @@ const multicodec = require('./../multicodec') * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection */ -module.exports.handleHop = async function handleHop ({ +/** + * @typedef {Object} HopRequest + * @property {Connection} connection + * @property {any} request + * @property {any} streamHandler + * @property {import('../transport')} circuit + */ + +/** + * @param {HopRequest} options + * @returns {Promise} + */ +async function handleHop ({ connection, request, streamHandler, @@ -56,6 +68,9 @@ module.exports.handleHop = async function handleHop ({ } // TODO: Handle being an active relay + if (!destinationConnection) { + return + } // Handle the incoming HOP request by performing a STOP request const stopRequest = { @@ -68,8 +83,7 @@ module.exports.handleHop = async function handleHop ({ try { destinationStream = await stop({ connection: destinationConnection, - request: stopRequest, - circuit + request: stopRequest }) } catch (err) { return log.error(err) @@ -96,10 +110,10 @@ module.exports.handleHop = async function handleHop ({ * * @param {object} options * @param {Connection} options.connection - Connection to the relay - * @param {*} options.request + * @param {CircuitPB} options.request * @returns {Promise} */ -module.exports.hop = async function hop ({ +async function hop ({ connection, request }) { @@ -128,7 +142,7 @@ module.exports.hop = async function hop ({ * @param {Connection} options.connection - Connection to the relay * @returns {Promise} */ -module.exports.canHop = async function canHop ({ +async function canHop ({ connection }) { // Create a new stream to the relay @@ -155,10 +169,10 @@ module.exports.canHop = async function canHop ({ * @param {Object} options * @param {Connection} options.connection * @param {StreamHandler} options.streamHandler - * @param {Circuit} options.circuit + * @param {import('../transport')} options.circuit * @private */ -module.exports.handleCanHop = function handleCanHop ({ +function handleCanHop ({ connection, streamHandler, circuit @@ -170,3 +184,10 @@ module.exports.handleCanHop = function handleCanHop ({ code: canHop ? CircuitPB.Status.SUCCESS : CircuitPB.Status.HOP_CANT_SPEAK_RELAY }) } + +module.exports = { + handleHop, + hop, + canHop, + handleCanHop +} diff --git a/src/circuit/circuit/stop.js b/src/circuit/circuit/stop.js index f9447b722d..9f47bd67e3 100644 --- a/src/circuit/circuit/stop.js +++ b/src/circuit/circuit/stop.js @@ -51,7 +51,7 @@ module.exports.handleStop = function handleStop ({ * @private * @param {object} options * @param {Connection} options.connection - * @param {*} options.request - The CircuitRelay protobuf request (unencoded) + * @param {CircuitPB} 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 fe0adba722..b320706d0c 100644 --- a/src/circuit/circuit/stream-handler.js +++ b/src/circuit/circuit/stream-handler.js @@ -13,9 +13,10 @@ class StreamHandler { /** * Create a stream handler for connection * + * @class * @param {object} options - * @param {*} options.stream - A duplex iterable - * @param {number} options.maxLength - max bytes length of message + * @param {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} options.stream - A duplex iterable + * @param {number} [options.maxLength = 4096] - max bytes length of message */ constructor ({ stream, maxLength = 4096 }) { this.stream = stream @@ -28,7 +29,7 @@ class StreamHandler { * Read and decode message * * @async - * @returns {Promise} + * @returns {Promise} */ async read () { const msg = await this.decoder.next() @@ -50,6 +51,7 @@ class StreamHandler { */ write (msg) { log('write message type %s', msg.type) + // @ts-ignore this.shake.write(lp.encode.single(CircuitPB.encode(msg))) } diff --git a/src/circuit/circuit/utils.js b/src/circuit/circuit/utils.js index 669c37adc3..65c5afe47d 100644 --- a/src/circuit/circuit/utils.js +++ b/src/circuit/circuit/utils.js @@ -5,13 +5,14 @@ const { CircuitRelay } = require('../protocol') /** * @typedef {import('./stream-handler')} StreamHandler + * @typedef {import('../../types').CircuitStatus} CircuitStatus */ /** * Write a response * * @param {StreamHandler} streamHandler - * @param {CircuitRelay.Status} status + * @param {CircuitStatus} status */ function writeResponse (streamHandler, status) { streamHandler.write({ diff --git a/src/circuit/listener.js b/src/circuit/listener.js index e591e43d11..d19cca5e46 100644 --- a/src/circuit/listener.js +++ b/src/circuit/listener.js @@ -5,6 +5,7 @@ const multiaddr = require('multiaddr') /** * @typedef {import('multiaddr')} Multiaddr + * @typedef {import('libp2p-interfaces/src/transport/types').Listener} Listener */ /** @@ -12,26 +13,15 @@ const multiaddr = require('multiaddr') * @returns {Listener} a transport listener */ module.exports = (libp2p) => { - const listener = new EventEmitter() const listeningAddrs = new Map() - // Remove listeningAddrs when a peer disconnects - libp2p.connectionManager.on('peer:disconnect', (connection) => { - const deleted = listeningAddrs.delete(connection.remotePeer.toB58String()) - - if (deleted) { - // Announce listen addresses change - listener.emit('close') - } - }) - /** * Add swarm handler and listen for incoming connections * * @param {Multiaddr} addr - * @returns {void} + * @returns {Promise} */ - listener.listen = async (addr) => { + async function listen (addr) { const addrString = String(addr).split('/p2p-circuit').find(a => a !== '') const relayConn = await libp2p.dial(multiaddr(addrString)) @@ -41,13 +31,6 @@ module.exports = (libp2p) => { listener.emit('listening') } - /** - * TODO: Remove the peers from our topology - * - * @returns {void} - */ - listener.close = () => {} - /** * Get fixed up multiaddrs * @@ -64,7 +47,7 @@ module.exports = (libp2p) => { * * @returns {Multiaddr[]} */ - listener.getAddrs = () => { + function getAddrs () { const addrs = [] for (const addr of listeningAddrs.values()) { addrs.push(addr) @@ -72,5 +55,22 @@ module.exports = (libp2p) => { return addrs } + /** @type Listener */ + const listener = Object.assign(new EventEmitter(), { + close: () => Promise.resolve(), + listen, + getAddrs + }) + + // Remove listeningAddrs when a peer disconnects + libp2p.connectionManager.on('peer:disconnect', (connection) => { + const deleted = listeningAddrs.delete(connection.remotePeer.toB58String()) + + if (deleted) { + // Announce listen addresses change + listener.emit('close') + } + }) + return listener } diff --git a/src/circuit/protocol/index.js b/src/circuit/protocol/index.js index f217cb4262..a9d3e31a6f 100644 --- a/src/circuit/protocol/index.js +++ b/src/circuit/protocol/index.js @@ -1,5 +1,7 @@ 'use strict' const protobuf = require('protons') + +/** @type {{CircuitRelay: import('../../types').CircuitMessageProto}} */ module.exports = protobuf(` message CircuitRelay { diff --git a/src/circuit/transport.js b/src/circuit/transport.js index 6ba27b2a93..2f2de306b9 100644 --- a/src/circuit/transport.js +++ b/src/circuit/transport.js @@ -1,8 +1,9 @@ 'use strict' const debug = require('debug') -const log = debug('libp2p:circuit') -log.error = debug('libp2p:circuit:error') +const log = Object.assign(debug('libp2p:circuit'), { + error: debug('libp2p:circuit:err') +}) const mafmt = require('mafmt') const multiaddr = require('multiaddr') @@ -76,8 +77,7 @@ class Circuit { virtualConnection = await handleStop({ connection, request, - streamHandler, - circuit + streamHandler }) break } @@ -94,7 +94,7 @@ class Circuit { remoteAddr, localAddr }) - const type = CircuitPB.Type === CircuitPB.Type.HOP ? 'relay' : 'inbound' + const type = request.Type === CircuitPB.Type.HOP ? 'relay' : 'inbound' log('new %s connection %s', type, maConn.remoteAddr) const conn = await this._upgrader.upgradeInbound(maConn) @@ -109,7 +109,7 @@ class Circuit { * @param {Multiaddr} ma - the multiaddr of the peer to dial * @param {Object} options - dial options * @param {AbortSignal} [options.signal] - An optional abort signal - * @returns {Connection} - the connection + * @returns {Promise} - the connection */ async dial (ma, options) { // Check the multiaddr to see if it contains a relay and a destination peer @@ -129,6 +129,7 @@ class Circuit { try { const virtualConnection = await hop({ connection: relayConnection, + // @ts-ignore circuit: this, request: { type: CircuitPB.Type.HOP, @@ -164,7 +165,7 @@ class Circuit { * * @param {any} options * @param {Function} handler - * @returns {listener} + * @returns {import('libp2p-interfaces/src/transport/types').Listener} */ createListener (options, handler) { if (typeof options === 'function') { @@ -175,7 +176,7 @@ class Circuit { // Called on successful HOP and STOP requests this.handler = handler - return createListener(this._libp2p, options) + return createListener(this._libp2p) } /** diff --git a/src/circuit/utils.js b/src/circuit/utils.js index 18b61eafbb..f75e13386a 100644 --- a/src/circuit/utils.js +++ b/src/circuit/utils.js @@ -3,6 +3,8 @@ const CID = require('cids') const multihashing = require('multihashing-async') +const TextEncoder = require('ipfs-utils/src/text-encoder') + /** * Convert a namespace string into a cid. * diff --git a/src/connection-manager/index.js b/src/connection-manager/index.js index 8259e56ba5..4ebbd8371e 100644 --- a/src/connection-manager/index.js +++ b/src/connection-manager/index.js @@ -175,10 +175,7 @@ class ConnectionManager extends EventEmitter { if (value < 0 || value > 1) { throw new Error('value should be a number between 0 and 1') } - if (peerId.toB58String) { - peerId = peerId.toB58String() - } - this._peerValues.set(peerId, value) + this._peerValues.set(peerId.toB58String(), value) } /** diff --git a/src/connection-manager/latency-monitor.js b/src/connection-manager/latency-monitor.js index 6eefa40e60..c9301ee142 100644 --- a/src/connection-manager/latency-monitor.js +++ b/src/connection-manager/latency-monitor.js @@ -1,3 +1,4 @@ +// @ts-nocheck 'use strict' /** diff --git a/src/connection-manager/visibility-change-emitter.js b/src/connection-manager/visibility-change-emitter.js index c2204eabfc..b69ba78f15 100644 --- a/src/connection-manager/visibility-change-emitter.js +++ b/src/connection-manager/visibility-change-emitter.js @@ -1,3 +1,4 @@ +// @ts-nocheck /* global document */ /** diff --git a/src/dialer/dial-request.js b/src/dialer/dial-request.js index f906c2ba81..bac571c1f3 100644 --- a/src/dialer/dial-request.js +++ b/src/dialer/dial-request.js @@ -18,6 +18,7 @@ const pAny = require('p-any') * @property {function(Multiaddr):Promise} dialAction * @property {Dialer} dialer */ + class DialRequest { /** * Manages running the `dialAction` on multiple provided `addrs` in parallel @@ -54,6 +55,7 @@ class DialRequest { const tokenHolder = new FIFO() tokens.forEach(token => tokenHolder.push(token)) + // @ts-ignore const dialAbortControllers = this.addrs.map(() => new AbortController()) let completedDials = 0 @@ -63,6 +65,7 @@ class DialRequest { let conn try { const signal = dialAbortControllers[i].signal + // @ts-ignore conn = await this.dialAction(addr, { ...options, signal: anySignal([signal, options.signal]) }) // Remove the successful AbortController so it is not aborted dialAbortControllers.splice(i, 1) @@ -85,4 +88,4 @@ class DialRequest { } } -module.exports.DialRequest = DialRequest +module.exports = DialRequest diff --git a/src/dialer/index.js b/src/dialer/index.js index 4233e2d977..c334d449dc 100644 --- a/src/dialer/index.js +++ b/src/dialer/index.js @@ -9,7 +9,7 @@ const multiaddr = require('multiaddr') const TimeoutController = require('timeout-abort-controller') const anySignal = require('any-signal') -const { DialRequest } = require('./dial-request') +const DialRequest = require('./dial-request') const { publicAddressesFirst } = require('libp2p-utils/src/address-sort') const getPeer = require('../get-peer') @@ -27,7 +27,6 @@ const { * @typedef {import('../peer-store')} PeerStore * @typedef {import('../peer-store/address-book').Address} Address * @typedef {import('../transport-manager')} TransportManager - * @typedef {import('./dial-request')} DialRequest */ /** @@ -241,12 +240,13 @@ class Dialer { return this._resolve(nm) })) - return recursiveMultiaddrs.flat().reduce((array, newM) => { - if (!array.find(m => m.equals(newM))) { - array.push(newM) - } - return array - }, []) // Unique addresses + return recursiveMultiaddrs.flat() + .reduce((/** @type {Multiaddr[]} */ array, /** @type {Multiaddr} */ newM) => { + if (!array.find(m => m.equals(newM))) { + array.push(newM) + } + return array + }, []) // Unique addresses } /** diff --git a/src/identify/consts.js b/src/identify/consts.js index 58ec077faa..9e15ef9f8e 100644 --- a/src/identify/consts.js +++ b/src/identify/consts.js @@ -1,5 +1,6 @@ 'use strict' +// @ts-ignore const libp2pVersion = require('../../package.json').version module.exports.PROTOCOL_VERSION = 'ipfs/0.1.0' diff --git a/src/identify/index.js b/src/identify/index.js index fe8b91b0a4..6a21342993 100644 --- a/src/identify/index.js +++ b/src/identify/index.js @@ -31,7 +31,7 @@ const { codes } = require('../errors') /** * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection - * @typedef {import('libp2p-interfaces/src/connection/connection').DuplexIterableStream} DuplexIterableStream + * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream */ class IdentifyService { @@ -200,9 +200,9 @@ class IdentifyService { * A handler to register with Libp2p to process identify messages. * * @param {Object} options - * @param {string} options.protocol - * @param {DuplexIterableStream} options.stream * @param {Connection} options.connection + * @param {MuxedStream} options.stream + * @param {string} options.protocol * @returns {Promise|undefined} */ handleMessage ({ connection, stream, protocol }) { @@ -222,7 +222,7 @@ class IdentifyService { * * @private * @param {Object} options - * @param {DuplexIterableStream} options.stream + * @param {MuxedStream} options.stream * @param {Connection} options.connection * @returns {Promise} */ @@ -262,7 +262,7 @@ class IdentifyService { * * @private * @param {object} options - * @param {DuplexIterableStream} options.stream + * @param {MuxedStream} options.stream * @param {Connection} options.connection * @returns {Promise} */ @@ -323,14 +323,17 @@ class IdentifyService { } } -module.exports.IdentifyService = IdentifyService /** * The protocols the IdentifyService supports * * @property multicodecs */ -module.exports.multicodecs = { +const multicodecs = { IDENTIFY: MULTICODEC_IDENTIFY, IDENTIFY_PUSH: MULTICODEC_IDENTIFY_PUSH } -module.exports.Message = Message + +IdentifyService.multicodecs = multicodecs +IdentifyService.Messsage = Message + +module.exports = IdentifyService diff --git a/src/index.js b/src/index.js index d9440adf1e..386f016145 100644 --- a/src/index.js +++ b/src/index.js @@ -30,10 +30,8 @@ const PubsubAdapter = require('./pubsub-adapter') const PersistentPeerStore = require('./peer-store/persistent') const Registrar = require('./registrar') const ping = require('./ping') -const { - IdentifyService, - multicodecs: IDENTIFY_PROTOCOLS -} = require('./identify') +const IdentifyService = require('./identify') +const IDENTIFY_PROTOCOLS = IdentifyService.multicodecs /** * @typedef {import('multiaddr')} Multiaddr @@ -193,6 +191,7 @@ class Libp2p extends EventEmitter { }) if (this._config.relay.enabled) { + // @ts-ignore this.transportManager.add(Circuit.prototype[Symbol.toStringTag], Circuit) this.relay = new Relay(this) } @@ -206,6 +205,7 @@ class Libp2p extends EventEmitter { // Add the identify service since we can multiplex this.identifyService = new IdentifyService({ libp2p: this }) + // @ts-ignore this.handle(Object.values(IDENTIFY_PROTOCOLS), this.identifyService.handleMessage) } @@ -254,13 +254,16 @@ class Libp2p extends EventEmitter { * * @param {string} eventName * @param {...any} args - * @returns {void} + * @returns {boolean} */ emit (eventName, ...args) { + // TODO: do we still need this? + // @ts-ignore if (eventName === 'error' && !this._events.error) { - log.error(...args) + log.error(args) + return false } else { - super.emit(eventName, ...args) + return super.emit(eventName, ...args) } } @@ -463,7 +466,7 @@ class Libp2p extends EventEmitter { * Registers the `handler` for each protocol * * @param {string[]|string} protocols - * @param {function({ connection:*, stream:*, protocol:string })} handler + * @param {({ connection: Connection, stream: any, protocol: string }) => void} handler */ handle (protocols, handler) { protocols = Array.isArray(protocols) ? protocols : [protocols] @@ -629,7 +632,9 @@ class Libp2p extends EventEmitter { // Transport modules with discovery for (const Transport of this.transportManager.getTransports()) { + // @ts-ignore if (Transport.discovery) { + // @ts-ignore setupService(Transport.discovery) } } diff --git a/src/keychain/cms.js b/src/keychain/cms.js index 60bfd323f7..c808ed697c 100644 --- a/src/keychain/cms.js +++ b/src/keychain/cms.js @@ -1,3 +1,4 @@ +// @ts-nocheck 'use strict' require('node-forge/lib/pkcs7') diff --git a/src/keychain/index.js b/src/keychain/index.js index 10d402c669..440a2913a5 100644 --- a/src/keychain/index.js +++ b/src/keychain/index.js @@ -1,3 +1,4 @@ +// @ts-nocheck /* eslint max-nested-callbacks: ["error", 5] */ 'use strict' diff --git a/src/keychain/util.js b/src/keychain/util.js index 56386fe488..6a332c9ceb 100644 --- a/src/keychain/util.js +++ b/src/keychain/util.js @@ -1,3 +1,4 @@ +// @ts-nocheck 'use strict' require('node-forge/lib/x509') diff --git a/src/metrics/index.js b/src/metrics/index.js index 3d9593ce87..8d94861d81 100644 --- a/src/metrics/index.js +++ b/src/metrics/index.js @@ -1,7 +1,8 @@ +// @ts-nocheck 'use strict' const mergeOptions = require('merge-options') -const pipe = require('it-pipe') +const { pipe } = require('it-pipe') const { tap } = require('streaming-iterables') const oldPeerLRU = require('./old-peers') const { METRICS: defaultOptions } = require('../constants') @@ -19,11 +20,12 @@ const directionToEvent = { /** * @typedef {import('peer-id')} PeerId + * @typedef {import('libp2p-interfaces/src/transport/types').MultiaddrConnection} MultiaddrConnection */ /** * @typedef MetricsProperties - * @property {ConnectionManager} connectionManager + * @property {import('../connection-manager')} connectionManager * * @typedef MetricsOptions * @property {number} [computeThrottleMaxQueueSize = defaultOptions.computeThrottleMaxQueueSize] @@ -216,10 +218,10 @@ class Metrics { * with the placeholder string returned from here, and the known `PeerId`. * * @param {Object} options - * @param {{ sink: function(*), source: function() }} options.stream - A duplex iterable stream + * @param {MultiaddrConnection} options.stream - A duplex iterable stream * @param {PeerId} [options.remotePeer] - The id of the remote peer that's connected * @param {string} [options.protocol] - The protocol the stream is running - * @returns {string} The peerId string or placeholder string + * @returns {MultiaddrConnection} The peerId string or placeholder string */ trackStream ({ stream, remotePeer, protocol }) { const metrics = this diff --git a/src/metrics/old-peers.js b/src/metrics/old-peers.js index 08d317dc09..1f38ba6e24 100644 --- a/src/metrics/old-peers.js +++ b/src/metrics/old-peers.js @@ -6,9 +6,10 @@ const LRU = require('hashlru') * Creates and returns a Least Recently Used Cache * * @param {number} maxSize - * @returns {LRUCache} + * @returns {any} */ module.exports = (maxSize) => { + // @ts-ignore const patched = LRU(maxSize) patched.delete = patched.remove return patched diff --git a/src/metrics/stats.js b/src/metrics/stats.js index d259376256..00470b000e 100644 --- a/src/metrics/stats.js +++ b/src/metrics/stats.js @@ -1,17 +1,19 @@ +// @ts-nocheck 'use strict' -const EventEmitter = require('events') +const { EventEmitter } = require('events') const Big = require('bignumber.js') const MovingAverage = require('moving-average') const retimer = require('retimer') -/** - * A queue based manager for stat processing - * - * @param {string[]} initialCounters - * @param {any} options - */ class Stats extends EventEmitter { + /** + * A queue based manager for stat processing + * + * @class + * @param {string[]} initialCounters + * @param {any} options + */ constructor (initialCounters, options) { super() @@ -21,6 +23,8 @@ class Stats extends EventEmitter { this._frequencyLastTime = Date.now() this._frequencyAccumulators = {} + + /** @type {{}} */ this._movingAverages = {} this._update = this._update.bind(this) @@ -68,7 +72,7 @@ class Stats extends EventEmitter { /** * Returns a clone of the current stats. * - * @returns {Map} + * @returns {Object} */ get snapshot () { return Object.assign({}, this._stats) @@ -77,7 +81,7 @@ class Stats extends EventEmitter { /** * Returns a clone of the internal movingAverages * - * @returns {MovingAverage[]} + * @returns {MovingAverage} */ get movingAverages () { return Object.assign({}, this._movingAverages) @@ -238,7 +242,7 @@ class Stats extends EventEmitter { const inc = op[1] if (typeof inc !== 'number') { - throw new Error('invalid increment number:', inc) + throw new Error(`invalid increment number: ${inc}`) } let n diff --git a/src/peer-routing.js b/src/peer-routing.js index 88a230196c..26fe9625b4 100644 --- a/src/peer-routing.js +++ b/src/peer-routing.js @@ -20,7 +20,7 @@ const { class PeerRouting { /** * @class - * @param {Libp2p} libp2p + * @param {import('./')} libp2p */ constructor (libp2p) { this._peerId = libp2p.peerId diff --git a/src/peer-store/address-book.js b/src/peer-store/address-book.js index 5545997322..a42a6b8538 100644 --- a/src/peer-store/address-book.js +++ b/src/peer-store/address-book.js @@ -124,6 +124,7 @@ class AddressBook extends Book { // Replace unsigned addresses by the new ones from the record // TODO: Once we have ttls for the addresses, we should merge these in. + // @ts-ignore this._setData(peerId, { addresses, record: { @@ -188,22 +189,22 @@ class AddressBook extends Book { } const addresses = this._toAddresses(multiaddrs) - const id = peerId.toB58String() - const entry = this.data.get(id) || {} - const rec = entry.addresses // Not replace multiaddrs if (!addresses.length) { return this } + const id = peerId.toB58String() + const entry = this.data.get(id) + // Already knows the peer - if (rec && rec.length === addresses.length) { - const intersection = rec.filter((addr) => addresses.some((newAddr) => addr.multiaddr.equals(newAddr.multiaddr))) + if (entry && entry.addresses && entry.addresses.length === addresses.length) { + const intersection = entry.addresses.filter((addr) => addresses.some((newAddr) => addr.multiaddr.equals(newAddr.multiaddr))) // Are new addresses equal to the old ones? // If yes, no changes needed! - if (intersection.length === rec.length) { + if (intersection.length === entry.addresses.length) { log(`the addresses provided to store are equal to the already stored for ${id}`) return this } @@ -211,12 +212,12 @@ class AddressBook extends Book { this._setData(peerId, { addresses, - record: entry.record + record: entry && entry.record }) log(`stored provided multiaddrs for ${id}`) // Notify the existance of a new peer - if (!rec) { + if (!(entry && entry.addresses)) { this._ps.emit('peer', peerId) } @@ -240,32 +241,33 @@ class AddressBook extends Book { const addresses = this._toAddresses(multiaddrs) const id = peerId.toB58String() - const entry = this.data.get(id) || {} - const rec = entry.addresses || [] + const entry = this.data.get(id) - // Add recorded uniquely to the new array (Union) - rec.forEach((addr) => { - if (!addresses.find(r => r.multiaddr.equals(addr.multiaddr))) { - addresses.push(addr) - } - }) + if (entry && entry.addresses) { + // Add recorded uniquely to the new array (Union) + entry.addresses.forEach((addr) => { + if (!addresses.find(r => r.multiaddr.equals(addr.multiaddr))) { + addresses.push(addr) + } + }) - // If the recorded length is equal to the new after the unique union - // The content is the same, no need to update. - if (rec && rec.length === addresses.length) { - log(`the addresses provided to store are already stored for ${id}`) - return this + // If the recorded length is equal to the new after the unique union + // The content is the same, no need to update. + if (entry.addresses.length === addresses.length) { + log(`the addresses provided to store are already stored for ${id}`) + return this + } } this._setData(peerId, { addresses, - record: entry.record + record: entry && entry.record }) log(`added provided multiaddrs for ${id}`) // Notify the existance of a new peer - if (!entry.addresses) { + if (!(entry && entry.addresses)) { this._ps.emit('peer', peerId) } diff --git a/src/peer-store/book.js b/src/peer-store/book.js index 447483d9e2..becd30b774 100644 --- a/src/peer-store/book.js +++ b/src/peer-store/book.js @@ -54,7 +54,7 @@ class Book { /** * Set data into the datastructure, persistence and emit it using the provided transformers. * - * @private + * @protected * @param {PeerId} peerId - peerId of the data to store * @param {T} data - data to store. * @param {Object} [options] - storing options. @@ -74,9 +74,9 @@ class Book { /** * Emit data. * - * @private + * @protected * @param {PeerId} peerId - * @param {T} data + * @param {any} [data] */ _emit (peerId, data) { this._ps.emit(this.eventName, { diff --git a/src/peer-store/index.js b/src/peer-store/index.js index 07762b8cbc..b3df1bbb94 100644 --- a/src/peer-store/index.js +++ b/src/peer-store/index.js @@ -35,7 +35,7 @@ class PeerStore extends EventEmitter { * @property {PeerId} id peer's peer-id instance. * @property {Address[]} addresses peer's addresses containing its multiaddrs and metadata. * @property {string[]} protocols peer's supported protocols. - * @property {Map} metadata peer's metadata map. + * @property {Map|undefined} metadata peer's metadata map. */ /** diff --git a/src/peer-store/key-book.js b/src/peer-store/key-book.js index 1c22db63ef..2326b3e966 100644 --- a/src/peer-store/key-book.js +++ b/src/peer-store/key-book.js @@ -49,7 +49,7 @@ class KeyBook extends Book { * * @override * @param {PeerId} peerId - * @param {RsaPublicKey|Ed25519PublicKey|Secp256k1PublicKey} publicKey + * @param {any} publicKey * @returns {KeyBook} */ set (peerId, publicKey) { @@ -79,7 +79,7 @@ class KeyBook extends Book { * * @override * @param {PeerId} peerId - * @returns {RsaPublicKey|Ed25519PublicKey|Secp256k1PublicKey} + * @returns {any} */ get (peerId) { if (!PeerId.isPeerId(peerId)) { diff --git a/src/peer-store/metadata-book.js b/src/peer-store/metadata-book.js index 7d24312cf8..38504fc0ea 100644 --- a/src/peer-store/metadata-book.js +++ b/src/peer-store/metadata-book.js @@ -60,6 +60,7 @@ class MetadataBook extends Book { * @param {Uint8Array} value - metadata value * @returns {MetadataBook} */ + // @ts-ignore set (peerId, key, value) { if (!PeerId.isPeerId(peerId)) { log.error('peerId must be an instance of peer-id to store data') @@ -102,8 +103,9 @@ class MetadataBook extends Book { * Get the known data of a provided peer. * * @param {PeerId} peerId - * @returns {Map} + * @returns {Map|undefined} */ + // @ts-ignore get (peerId) { if (!PeerId.isPeerId(peerId)) { throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS) @@ -117,7 +119,7 @@ class MetadataBook extends Book { * * @param {PeerId} peerId * @param {string} key - * @returns {Uint8Array} + * @returns {Uint8Array | undefined} */ getValue (peerId, key) { if (!PeerId.isPeerId(peerId)) { diff --git a/src/peer-store/persistent/index.js b/src/peer-store/persistent/index.js index ceb77a650c..e004f86a52 100644 --- a/src/peer-store/persistent/index.js +++ b/src/peer-store/persistent/index.js @@ -24,7 +24,7 @@ const Protocols = require('./pb/proto-book.proto') /** * @typedef {Object} PersistentPeerStoreProperties * @property {PeerId} peerId - * @property {Datastore} datastore + * @property {any} datastore * * @typedef {Object} PersistentPeerStoreOptions * @property {number} [threshold = 5] - Number of dirty peers allowed before commit data. diff --git a/src/pnet/index.js b/src/pnet/index.js index 74c99947e0..194a5005ec 100644 --- a/src/pnet/index.js +++ b/src/pnet/index.js @@ -21,8 +21,7 @@ const handshake = require('it-handshake') const { NONCE_LENGTH } = require('./key-generator') /** - * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection - * @typedef {import('libp2p-interfaces/src/connection/connection').DuplexIterableStream} DuplexIterableStream + * @typedef {import('libp2p-interfaces/src/transport/types').MultiaddrConnection} MultiaddrConnection */ class Protector { @@ -44,8 +43,8 @@ class Protector { * between its two peers from the PSK the Protector instance was * created with. * - * @param {Connection} connection - The connection to protect - * @returns {Promise} A protected duplex iterable + * @param {MultiaddrConnection} connection - The connection to protect + * @returns {Promise} A protected duplex iterable */ async protect (connection) { if (!connection) { diff --git a/src/pubsub-adapter.js b/src/pubsub-adapter.js index 4c8aed8f2a..7d7af8df2f 100644 --- a/src/pubsub-adapter.js +++ b/src/pubsub-adapter.js @@ -6,42 +6,49 @@ */ // Pubsub adapter to keep API with handlers while not removed. -module.exports = (PubsubRouter, libp2p, options) => { - class Pubsub extends PubsubRouter { - /** - * Subscribes to a given topic. - * - * @override - * @param {string} topic - * @param {(msg: InMessage) => void} [handler] - * @returns {void} - */ - subscribe (topic, handler) { - // Bind provided handler - handler && this.on(topic, handler) - super.subscribe(topic) +function pubsubAdapter (PubsubRouter, libp2p, options) { + const pubsub = new PubsubRouter(libp2p, options) + pubsub._subscribeAdapter = pubsub.subscribe + pubsub._unsubscribeAdapter = pubsub.unsubscribe + + /** + * Subscribes to a given topic. + * + * @override + * @param {string} topic + * @param {(msg: InMessage) => void} [handler] + * @returns {void} + */ + function subscribe (topic, handler) { + // Bind provided handler + handler && pubsub.on(topic, handler) + pubsub._subscribeAdapter(topic) + } + + /** + * Unsubscribe from the given topic. + * + * @override + * @param {string} topic + * @param {(msg: InMessage) => void} [handler] + * @returns {void} + */ + function unsubscribe (topic, handler) { + if (!handler) { + pubsub.removeAllListeners(topic) + } else { + pubsub.removeListener(topic, handler) } - /** - * Unsubscribe from the given topic. - * - * @override - * @param {string} topic - * @param {(msg: InMessage) => void} [handler] - * @returns {void} - */ - unsubscribe (topic, handler) { - if (!handler) { - this.removeAllListeners(topic) - } else { - this.removeListener(topic, handler) - } - - if (this.listenerCount(topic) === 0) { - super.unsubscribe(topic) - } + if (pubsub.listenerCount(topic) === 0) { + pubsub._unsubscribeAdapter(topic) } } - return new Pubsub(libp2p, options) + pubsub.subscribe = subscribe + pubsub.unsubscribe = unsubscribe + + return pubsub } + +module.exports = pubsubAdapter diff --git a/src/record/envelope/envelope.proto.js b/src/record/envelope/envelope.proto.js index ca0074961a..c8907debda 100644 --- a/src/record/envelope/envelope.proto.js +++ b/src/record/envelope/envelope.proto.js @@ -2,7 +2,8 @@ const protons = require('protons') -const message = ` +/** @type {{Envelope: import('../../types').MessageProto}} */ +module.exports = protons(` message Envelope { // public_key is the public key of the keypair the enclosed payload was // signed with. @@ -20,6 +21,4 @@ message Envelope { // additional security. bytes signature = 5; } -` - -module.exports = protons(message).Envelope +`) diff --git a/src/record/envelope/index.js b/src/record/envelope/index.js index 88a702afc5..3a791bedc7 100644 --- a/src/record/envelope/index.js +++ b/src/record/envelope/index.js @@ -49,7 +49,7 @@ class Envelope { const publicKey = cryptoKeys.marshalPublicKey(this.peerId.pubKey) - this._marshal = Protobuf.encode({ + this._marshal = Protobuf.Envelope.encode({ public_key: publicKey, payload_type: this.payloadType, payload: this.payload, @@ -102,14 +102,14 @@ const formatSignaturePayload = (domain, payloadType, payload) => { // - The length of the payload field in bytes // - The value of the payload field - domain = uint8arraysFromString(domain) - const domainLength = varint.encode(domain.byteLength) + const domainUint8Array = uint8arraysFromString(domain) + const domainLength = varint.encode(domainUint8Array.byteLength) const payloadTypeLength = varint.encode(payloadType.length) const payloadLength = varint.encode(payload.length) return uint8arraysConcat([ new Uint8Array(domainLength), - domain, + domainUint8Array, new Uint8Array(payloadTypeLength), payloadType, new Uint8Array(payloadLength), @@ -124,7 +124,7 @@ const formatSignaturePayload = (domain, payloadType, payload) => { * @returns {Promise} */ Envelope.createFromProtobuf = async (data) => { - const envelopeData = Protobuf.decode(data) + const envelopeData = Protobuf.Envelope.decode(data) const peerId = await PeerId.createFromPubKey(envelopeData.public_key) return new Envelope({ diff --git a/src/record/peer-record/index.js b/src/record/peer-record/index.js index 2fadc3b9aa..7bde8081d5 100644 --- a/src/record/peer-record/index.js +++ b/src/record/peer-record/index.js @@ -51,7 +51,7 @@ class PeerRecord extends Record { return this._marshal } - this._marshal = Protobuf.encode({ + this._marshal = Protobuf.PeerRecord.encode({ peer_id: this.peerId.toBytes(), seq: this.seqNumber, addresses: this.multiaddrs.map((m) => ({ @@ -65,7 +65,7 @@ class PeerRecord extends Record { /** * Returns true if `this` record equals the `other`. * - * @param {Record} other + * @param {PeerRecord} other * @returns {boolean} */ equals (other) { @@ -96,7 +96,7 @@ class PeerRecord extends Record { */ PeerRecord.createFromProtobuf = (buf) => { // Decode - const peerRecord = Protobuf.decode(buf) + const peerRecord = Protobuf.PeerRecord.decode(buf) const peerId = PeerId.createFromBytes(peerRecord.peer_id) const multiaddrs = (peerRecord.addresses || []).map((a) => multiaddr(a.multiaddr)) diff --git a/src/record/peer-record/peer-record.proto.js b/src/record/peer-record/peer-record.proto.js index 9da916ca87..0ebb3b90d0 100644 --- a/src/record/peer-record/peer-record.proto.js +++ b/src/record/peer-record/peer-record.proto.js @@ -7,7 +7,8 @@ const protons = require('protons') // is expected to expand to include other information in the future. // PeerRecords are designed to be serialized to bytes and placed inside of // SignedEnvelopes before sharing with other peers. -const message = ` +/** @type {{PeerRecord: import('../../types').MessageProto}} */ +module.exports = protons(` message PeerRecord { // AddressInfo is a wrapper around a binary multiaddr. It is defined as a // separate message to allow us to add per-address metadata in the future. @@ -24,6 +25,4 @@ message PeerRecord { // addresses is a list of public listen addresses for the peer. repeated AddressInfo addresses = 3; } -` - -module.exports = protons(message).PeerRecord +`) diff --git a/src/registrar.js b/src/registrar.js index 70998c5d1c..367f110c80 100644 --- a/src/registrar.js +++ b/src/registrar.js @@ -60,7 +60,7 @@ class Registrar { * Get a connection with a peer. * * @param {PeerId} peerId - * @returns {Connection} + * @returns {Connection | null} */ getConnection (peerId) { return this.connectionManager.get(peerId) diff --git a/src/transport-manager.js b/src/transport-manager.js index d9aef5335c..f204222b7b 100644 --- a/src/transport-manager.js +++ b/src/transport-manager.js @@ -14,6 +14,7 @@ const { updateSelfPeerRecord } = require('./record/utils') /** * @typedef {import('multiaddr')} Multiaddr * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('libp2p-interfaces/src/transport/types').Transport} Transport * * @typedef {Object} TransportManagerProperties * @property {import('./')} libp2p @@ -53,6 +54,7 @@ class TransportManager { throw errCode(new Error('There is already a transport with this key'), codes.ERR_DUPLICATE_TRANSPORT) } + // @ts-ignore const transport = new Transport({ ...transportOptions, libp2p: this.libp2p, diff --git a/src/types.ts b/src/types.ts index 7f0ad3680c..9a97803d15 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,3 +16,68 @@ export type MessageExchange = { id: Uint8Array pubKey: MessagePublicKey } + +// Protobufs +export type MessageProto = { + encode(value: any): Uint8Array + decode(bytes: Uint8Array): any +} + +export type SUCCESS = 100; +export type HOP_SRC_ADDR_TOO_LONG = 220; +export type HOP_DST_ADDR_TOO_LONG = 221; +export type HOP_SRC_MULTIADDR_INVALID = 250; +export type HOP_DST_MULTIADDR_INVALID = 251; +export type HOP_NO_CONN_TO_DST = 260; +export type HOP_CANT_DIAL_DST = 261; +export type HOP_CANT_OPEN_DST_STREAM = 262; +export type HOP_CANT_SPEAK_RELAY = 270; +export type HOP_CANT_RELAY_TO_SELF = 280; +export type STOP_SRC_ADDR_TOO_LONG = 320; +export type STOP_DST_ADDR_TOO_LONG = 321; +export type STOP_SRC_MULTIADDR_INVALID = 350; +export type STOP_DST_MULTIADDR_INVALID = 351; +export type STOP_RELAY_REFUSED = 390; +export type MALFORMED_MESSAGE = 400; + +export type CircuitStatus = SUCCESS | HOP_SRC_ADDR_TOO_LONG | HOP_DST_ADDR_TOO_LONG + | HOP_SRC_MULTIADDR_INVALID | HOP_DST_MULTIADDR_INVALID | HOP_NO_CONN_TO_DST + | HOP_CANT_DIAL_DST | HOP_CANT_OPEN_DST_STREAM | HOP_CANT_SPEAK_RELAY | HOP_CANT_RELAY_TO_SELF + | STOP_SRC_ADDR_TOO_LONG | STOP_DST_ADDR_TOO_LONG | STOP_SRC_MULTIADDR_INVALID + | STOP_DST_MULTIADDR_INVALID | STOP_RELAY_REFUSED | MALFORMED_MESSAGE + +export type HOP = 1; +export type STOP = 2; +export type STATUS = 3; +export type CAN_HOP = 4; + +export type CircuitType = HOP | STOP | STATUS | CAN_HOP + +export type CircuitMessageProto = { + encode(value: any): Uint8Array + decode(bytes: Uint8Array): any + Status: { + SUCCESS: SUCCESS, + HOP_SRC_ADDR_TOO_LONG: HOP_SRC_ADDR_TOO_LONG, + HOP_DST_ADDR_TOO_LONG: HOP_DST_ADDR_TOO_LONG, + HOP_SRC_MULTIADDR_INVALID: HOP_SRC_MULTIADDR_INVALID, + HOP_DST_MULTIADDR_INVALID: HOP_DST_MULTIADDR_INVALID, + HOP_NO_CONN_TO_DST: HOP_NO_CONN_TO_DST, + HOP_CANT_DIAL_DST: HOP_CANT_DIAL_DST, + HOP_CANT_OPEN_DST_STREAM: HOP_CANT_OPEN_DST_STREAM, + HOP_CANT_SPEAK_RELAY: HOP_CANT_SPEAK_RELAY, + HOP_CANT_RELAY_TO_SELF: HOP_CANT_RELAY_TO_SELF, + STOP_SRC_ADDR_TOO_LONG: STOP_SRC_ADDR_TOO_LONG, + STOP_DST_ADDR_TOO_LONG: STOP_DST_ADDR_TOO_LONG, + STOP_SRC_MULTIADDR_INVALID: STOP_SRC_MULTIADDR_INVALID, + STOP_DST_MULTIADDR_INVALID: STOP_DST_MULTIADDR_INVALID, + STOP_RELAY_REFUSED: STOP_RELAY_REFUSED, + MALFORMED_MESSAGE: MALFORMED_MESSAGE + }, + Type: { + HOP: HOP, + STOP: STOP, + STATUS: STATUS, + CAN_HOP: CAN_HOP + } +} diff --git a/src/upgrader.js b/src/upgrader.js index ca798deaa7..9ef25a4780 100644 --- a/src/upgrader.js +++ b/src/upgrader.js @@ -9,27 +9,23 @@ const Multistream = require('multistream-select') const { Connection } = require('libp2p-interfaces/src/connection') const ConnectionStatus = require('libp2p-interfaces/src/connection/status') const PeerId = require('peer-id') -const pipe = require('it-pipe') +const { pipe } = require('it-pipe') const mutableProxy = require('mutable-proxy') const { codes } = require('./errors') /** * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('libp2p-interfaces/src/transport/types').MultiaddrConnection} MultiaddrConnection + * @typedef {import('libp2p-interfaces/src/stream-muxer/types').Muxer} Muxer + * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream + * @typedef {import('libp2p-interfaces/src/crypto/types').Crypto} Crypto * @typedef {import('multiaddr')} Multiaddr */ -/** - * @typedef MultiaddrConnection - * @property {Function} sink - * @property {AsyncIterator} source - * @property {*} conn - * @property {Multiaddr} remoteAddr - */ - /** * @typedef CryptoResult - * @property {*} conn A duplex iterable + * @property {MultiaddrConnection} conn A duplex iterable * @property {PeerId} remotePeer * @property {string} protocol */ @@ -39,23 +35,23 @@ class Upgrader { * @param {object} options * @param {PeerId} options.localPeer * @param {import('./metrics')} [options.metrics] - * @param {Map} options.cryptos - * @param {Map} options.muxers + * @param {Map} [options.cryptos] + * @param {Map} [options.muxers] * @param {(Connection) => void} options.onConnection - Called when a connection is upgraded * @param {(Connection) => void} options.onConnectionEnd */ constructor ({ localPeer, metrics, - cryptos, - muxers, + cryptos = new Map(), + muxers = new Map(), onConnectionEnd = () => {}, onConnection = () => {} }) { this.localPeer = localPeer this.metrics = metrics - this.cryptos = cryptos || new Map() - this.muxers = muxers || new Map() + this.cryptos = cryptos + this.muxers = muxers this.protector = null this.protocols = new Map() this.onConnection = onConnection @@ -138,12 +134,7 @@ class Upgrader { * @returns {Promise} */ async upgradeOutbound (maConn) { - let remotePeerId - try { - remotePeerId = PeerId.createFromB58String(maConn.remoteAddr.getPeerId()) - } catch (err) { - log.error('multiaddr did not contain a valid peer id', err) - } + const remotePeerId = PeerId.createFromB58String(maConn.remoteAddr.getPeerId()) let encryptedConn let remotePeer @@ -155,7 +146,7 @@ class Upgrader { if (this.metrics) { ({ setTarget: setPeer, proxy: proxyPeer } = mutableProxy()) - const idString = (parseInt(Math.random() * 1e9)).toString(36) + Date.now() + const idString = (Math.random() * 1e9).toString(36) + Date.now() setPeer({ toB58String: () => idString }) maConn = this.metrics.trackStream({ stream: maConn, remotePeer: proxyPeer }) } @@ -213,8 +204,8 @@ class Upgrader { * @param {string} options.cryptoProtocol - The crypto protocol that was negotiated * @param {string} options.direction - One of ['inbound', 'outbound'] * @param {MultiaddrConnection} options.maConn - The transport layer connection - * @param {*} options.upgradedConn - A duplex connection returned from multiplexer and/or crypto selection - * @param {Muxer} options.Muxer - The muxer to be used for muxing + * @param {MuxedStream | MultiaddrConnection} options.upgradedConn - A duplex connection returned from multiplexer and/or crypto selection + * @param {Muxer} [options.Muxer] - The muxer to be used for muxing * @param {PeerId} options.remotePeer - The peer the connection is with * @returns {Connection} */ @@ -233,6 +224,7 @@ class Upgrader { if (Muxer) { // Create the muxer + // @ts-ignore muxer = new Muxer({ // Run anytime a remote stream is created onStream: async muxedStream => { @@ -306,6 +298,7 @@ class Upgrader { remotePeer: remotePeer, stat: { direction, + // @ts-ignore timeline: maConn.timeline, multiplexer: Muxer && Muxer.multicodec, encryption: cryptoProtocol @@ -332,7 +325,7 @@ class Upgrader { * @private * @param {object} options * @param {Connection} options.connection - The connection the stream belongs to - * @param {Stream} options.stream + * @param {MuxedStream} options.stream * @param {string} options.protocol */ _onStream ({ connection, stream, protocol }) { @@ -348,7 +341,7 @@ class Upgrader { * @param {PeerId} localPeer - The initiators PeerId * @param {*} connection * @param {Map} cryptos - * @returns {CryptoResult} An encrypted connection, remote peer `PeerId` and the protocol of the `Crypto` used + * @returns {Promise} An encrypted connection, remote peer `PeerId` and the protocol of the `Crypto` used */ async _encryptInbound (localPeer, connection, cryptos) { const mss = new Multistream.Listener(connection) @@ -360,6 +353,10 @@ class Upgrader { const crypto = cryptos.get(protocol) log('encrypting inbound connection...') + if (!crypto) { + throw new Error(`no crypto module found for ${protocol}`) + } + return { ...await crypto.secureInbound(localPeer, stream), protocol @@ -379,7 +376,7 @@ class Upgrader { * @param {*} connection * @param {PeerId} remotePeerId * @param {Map} cryptos - * @returns {CryptoResult} An encrypted connection, remote peer `PeerId` and the protocol of the `Crypto` used + * @returns {Promise} An encrypted connection, remote peer `PeerId` and the protocol of the `Crypto` used */ async _encryptOutbound (localPeer, connection, remotePeerId, cryptos) { const mss = new Multistream.Dialer(connection) @@ -391,6 +388,10 @@ class Upgrader { const crypto = cryptos.get(protocol) log('encrypting outbound connection to %j', remotePeerId) + if (!crypto) { + throw new Error(`no crypto module found for ${protocol}`) + } + return { ...await crypto.secureOutbound(localPeer, stream, remotePeerId), protocol @@ -406,9 +407,9 @@ class Upgrader { * * @private * @async - * @param {*} connection - A basic duplex connection to multiplex + * @param {MultiaddrConnection} connection - A basic duplex connection to multiplex * @param {Map} muxers - The muxers to attempt multiplexing with - * @returns {*} A muxed connection + * @returns {Promise<{ stream: MuxedStream, Muxer?: Muxer}>} A muxed connection */ async _multiplexOutbound (connection, muxers) { const dialer = new Multistream.Dialer(connection) @@ -430,9 +431,9 @@ class Upgrader { * * @private * @async - * @param {*} connection - A basic duplex connection to multiplex + * @param {MultiaddrConnection} connection - A basic duplex connection to multiplex * @param {Map} muxers - The muxers to attempt multiplexing with - * @returns {*} A muxed connection + * @returns {Promise<{ stream: MuxedStream, Muxer?: Muxer}>} A muxed connection */ async _multiplexInbound (connection, muxers) { const listener = new Multistream.Listener(connection) diff --git a/test/dialing/dial-request.spec.js b/test/dialing/dial-request.spec.js index 4ca25e9d28..fd56620a00 100644 --- a/test/dialing/dial-request.spec.js +++ b/test/dialing/dial-request.spec.js @@ -10,7 +10,7 @@ const AggregateError = require('aggregate-error') const pDefer = require('p-defer') const delay = require('delay') -const { DialRequest } = require('../../src/dialer/dial-request') +const DialRequest = require('../../src/dialer/dial-request') const createMockConnection = require('../utils/mockConnection') const error = new Error('dial failes') diff --git a/test/identify/index.spec.js b/test/identify/index.spec.js index 749f491484..cccd071871 100644 --- a/test/identify/index.spec.js +++ b/test/identify/index.spec.js @@ -12,7 +12,8 @@ const pWaitFor = require('p-wait-for') const unit8ArrayToString = require('uint8arrays/to-string') const { codes: Errors } = require('../../src/errors') -const { IdentifyService, multicodecs } = require('../../src/identify') +const IdentifyService = require('../../src/identify') +const multicodecs = IdentifyService.multicodecs const Peers = require('../fixtures/peers') const Libp2p = require('../../src') const Envelope = require('../../src/record/envelope') diff --git a/test/upgrading/upgrader.spec.js b/test/upgrading/upgrader.spec.js index 7282dcd1c2..96df354952 100644 --- a/test/upgrading/upgrader.spec.js +++ b/test/upgrading/upgrader.spec.js @@ -56,28 +56,6 @@ describe('Upgrader', () => { sinon.restore() }) - it('should ignore a missing remote peer id', async () => { - const { inbound, outbound } = mockMultiaddrConnPair({ addrs, remotePeer }) - - const muxers = new Map([[Muxer.multicodec, Muxer]]) - sinon.stub(localUpgrader, 'muxers').value(muxers) - sinon.stub(remoteUpgrader, 'muxers').value(muxers) - - const cryptos = new Map([[Crypto.protocol, Crypto]]) - sinon.stub(localUpgrader, 'cryptos').value(cryptos) - sinon.stub(remoteUpgrader, 'cryptos').value(cryptos) - - // Remove the peer id from the remote address - outbound.remoteAddr = outbound.remoteAddr.decapsulateCode(421) - - const connections = await Promise.all([ - localUpgrader.upgradeOutbound(outbound), - remoteUpgrader.upgradeInbound(inbound) - ]) - - expect(connections).to.have.length(2) - }) - it('should upgrade with valid muxers and crypto', async () => { const { inbound, outbound } = mockMultiaddrConnPair({ addrs, remotePeer }) diff --git a/tsconfig.json b/tsconfig.json index 5b9a618c43..48a9c8e8b8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,21 @@ { "extends": "./node_modules/aegir/src/config/tsconfig.aegir.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": false, + "noImplicitAny": false, + "noImplicitThis": true, + "noFallthroughCasesInSwitch": true, + "noUnusedLocals": true, + "noUnusedParameters": false, + "strictFunctionTypes": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "strictBindCallApply": true, + "strict": true, + "alwaysStrict": true, + "stripInternal": true }, "include": [ "src" From 149c19a886f0874e0bc07f4a92634f15579f7f6e Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 2 Dec 2020 17:27:59 +0100 Subject: [PATCH 05/18] chore: minor fixes and github ci --- .github/workflows/main.yml | 67 ++++++++++++++++++++++++++++++++++++++ .travis.yml | 59 --------------------------------- package.json | 4 +-- src/transport-manager.js | 1 - src/upgrader.js | 6 ++-- tsconfig.json | 16 +-------- 6 files changed, 72 insertions(+), 81 deletions(-) create mode 100644 .github/workflows/main.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000000..8681fdae91 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,67 @@ +name: ci +on: + push: + branches: + - master + pull_request: + branches: + - '**' + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: yarn + - run: yarn lint + - run: yarn build + - uses: gozala/typescript-error-reporter-action@v1.0.4 + - run: yarn aegir dep-check -- -i aegir + - uses: ipfs/aegir/actions/bundle-size@master + name: size + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + test-node: + needs: check + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + node: [12, 14] + fail-fast: true + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node }} + - run: yarn + - run: npx nyc --reporter=lcov npm run test:node -- --bail + - uses: codecov/codecov-action@v1 + test-chrome: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: yarn + - run: yarn aegir test -t browser -t webworker + test-firefox: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: yarn + - run: yarn aegir test -t browser -t webworker -- --browsers FirefoxHeadless + test-electron-main: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: yarn + - run: npx xvfb-maybe yarn aegir test -t electron-main --bail + test-electron-renderer: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: yarn + - run: npx xvfb-maybe yarn aegir test -t electron-renderer --bail \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b4bbfc1855..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,59 +0,0 @@ -language: node_js -cache: npm -stages: - - check - - test - - cov - -node_js: - - 'lts/*' - - '14' - -os: - - linux - - osx - -script: npx nyc -s npm run test:node -- --bail -after_success: npx nyc report --reporter=text-lcov > coverage.lcov && npx codecov - -jobs: - include: - - stage: check - script: - - npx aegir build --bundlesize - # Remove pull libs once ping is async - - npx aegir dep-check -- -i pull-handshake -i pull-stream - - npm run lint - - npm run test:types - - - stage: test - name: chrome - addons: - chrome: stable - script: - - npx aegir test -t browser -t webworker - - - stage: test - name: firefox - addons: - firefox: latest - script: - - npx aegir test -t browser -t webworker -- --browsers FirefoxHeadless - - - stage: test - name: interop - script: - - cd node_modules/interop-libp2p - - npm install - - LIBP2P_JS=${TRAVIS_BUILD_DIR}/src/index.js npx aegir test -t node --bail - - - stage: test - if: type = pull_request - name: example - auto-relay - script: - - cd examples - - npm install - - npm run test -- auto-relay - -notifications: - email: false \ No newline at end of file diff --git a/package.json b/package.json index 8a3465f3bc..b66585d5de 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "it-pipe": "^1.1.0", "it-protocol-buffers": "^0.2.0", "libp2p-crypto": "^0.18.0", - "libp2p-interfaces": "libp2p/js-libp2p-interfaces#feat/add-types", + "libp2p-interfaces": "libp2p/js-libp2p-interfaces#feat/add-types-with-post-install", "libp2p-utils": "^0.2.2", "mafmt": "^8.0.0", "merge-options": "^2.0.0", @@ -98,7 +98,7 @@ "devDependencies": { "@nodeutils/defaults-deep": "^1.1.0", "abortable-iterator": "^3.0.0", - "aegir": "^29.1.0", + "aegir": "^29.2.0", "chai-bytes": "^0.1.2", "chai-string": "^1.5.0", "delay": "^4.3.0", diff --git a/src/transport-manager.js b/src/transport-manager.js index f204222b7b..258a8a86b8 100644 --- a/src/transport-manager.js +++ b/src/transport-manager.js @@ -54,7 +54,6 @@ class TransportManager { throw errCode(new Error('There is already a transport with this key'), codes.ERR_DUPLICATE_TRANSPORT) } - // @ts-ignore const transport = new Transport({ ...transportOptions, libp2p: this.libp2p, diff --git a/src/upgrader.js b/src/upgrader.js index 9ef25a4780..8d00cb5210 100644 --- a/src/upgrader.js +++ b/src/upgrader.js @@ -7,7 +7,6 @@ const log = Object.assign(debug('libp2p:upgrader'), { const errCode = require('err-code') const Multistream = require('multistream-select') const { Connection } = require('libp2p-interfaces/src/connection') -const ConnectionStatus = require('libp2p-interfaces/src/connection/status') const PeerId = require('peer-id') const { pipe } = require('it-pipe') const mutableProxy = require('mutable-proxy') @@ -223,8 +222,7 @@ class Upgrader { let connection if (Muxer) { - // Create the muxer - // @ts-ignore + // @ts-ignore Create the muxer muxer = new Muxer({ // Run anytime a remote stream is created onStream: async muxedStream => { @@ -270,7 +268,7 @@ class Upgrader { // Wait for close to finish before notifying of the closure (async () => { try { - if (connection.stat.status === ConnectionStatus.OPEN) { + if (connection.stat.status === 'open') { await connection.close() } } catch (err) { diff --git a/tsconfig.json b/tsconfig.json index 48a9c8e8b8..5b9a618c43 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,7 @@ { "extends": "./node_modules/aegir/src/config/tsconfig.aegir.json", "compilerOptions": { - "outDir": "dist", - "forceConsistentCasingInFileNames": true, - "noImplicitReturns": false, - "noImplicitAny": false, - "noImplicitThis": true, - "noFallthroughCasesInSwitch": true, - "noUnusedLocals": true, - "noUnusedParameters": false, - "strictFunctionTypes": true, - "strictNullChecks": true, - "strictPropertyInitialization": true, - "strictBindCallApply": true, - "strict": true, - "alwaysStrict": true, - "stripInternal": true + "outDir": "dist" }, "include": [ "src" From d3d6b3566a2aa8bfdb85cf67a3ea4ff813eddca3 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 2 Dec 2020 21:39:17 +0100 Subject: [PATCH 06/18] chore: fix remaining ts ignores --- package.json | 1 - src/circuit/circuit/stop.js | 7 ++++--- src/circuit/circuit/stream-handler.js | 4 ++-- src/circuit/transport.js | 2 -- src/dialer/dial-request.js | 11 ++++++----- src/get-peer.js | 2 +- src/identify/consts.js | 2 +- src/index.js | 18 ++++++++++-------- src/insecure/plaintext.js | 8 ++++---- src/metrics/old-peers.js | 2 +- src/metrics/stats.js | 1 - src/peer-store/address-book.js | 11 ----------- src/peer-store/book.js | 2 +- src/peer-store/key-book.js | 5 +++-- src/peer-store/metadata-book.js | 3 +-- src/peer-store/persistent/index.js | 6 +++--- src/peer-store/proto-book.js | 3 --- src/ping/index.js | 2 +- src/pnet/key-generator.js | 2 +- src/types.ts | 10 ---------- src/upgrader.js | 3 +-- 21 files changed, 40 insertions(+), 65 deletions(-) diff --git a/package.json b/package.json index b66585d5de..487a1d119c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "test:node": "aegir test -t node -f \"./test/**/*.{node,spec}.js\"", "test:browser": "aegir test -t browser", "test:examples": "cd examples && npm run test:all", - "test:types": "aegir ts -p check", "release": "aegir release -t node -t browser", "release-minor": "aegir release --type minor -t node -t browser", "release-major": "aegir release --type major -t node -t browser", diff --git a/src/circuit/circuit/stop.js b/src/circuit/circuit/stop.js index 9f47bd67e3..16192ad563 100644 --- a/src/circuit/circuit/stop.js +++ b/src/circuit/circuit/stop.js @@ -12,6 +12,7 @@ const { validateAddrs } = require('./utils') /** * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream */ /** @@ -20,9 +21,9 @@ const { validateAddrs } = require('./utils') * @private * @param {object} options * @param {Connection} options.connection - * @param {*} options.request - The CircuitRelay protobuf request (unencoded) + * @param {CircuitPB} options.request - The CircuitRelay protobuf request (unencoded) * @param {StreamHandler} options.streamHandler - * @returns {Promise<*>|void} Resolves a duplex iterable + * @returns {Promise|void} Resolves a duplex iterable */ module.exports.handleStop = function handleStop ({ connection, @@ -52,7 +53,7 @@ module.exports.handleStop = function handleStop ({ * @param {object} options * @param {Connection} options.connection * @param {CircuitPB} options.request - The CircuitRelay protobuf request (unencoded) - * @returns {Promise<*>} Resolves a duplex iterable + * @returns {Promise} Resolves a duplex iterable */ module.exports.stop = async function stop ({ connection, diff --git a/src/circuit/circuit/stream-handler.js b/src/circuit/circuit/stream-handler.js index b320706d0c..b63dcbff4e 100644 --- a/src/circuit/circuit/stream-handler.js +++ b/src/circuit/circuit/stream-handler.js @@ -47,11 +47,11 @@ class StreamHandler { /** * Encode and write array of buffers * - * @param {*} msg - An unencoded CircuitRelay protobuf message + * @param {CircuitPB} msg - An unencoded CircuitRelay protobuf message */ write (msg) { log('write message type %s', msg.type) - // @ts-ignore + // @ts-ignore lp.encode expects type type 'Buffer | BufferList', not 'Uint8Array' this.shake.write(lp.encode.single(CircuitPB.encode(msg))) } diff --git a/src/circuit/transport.js b/src/circuit/transport.js index 2f2de306b9..4eea061043 100644 --- a/src/circuit/transport.js +++ b/src/circuit/transport.js @@ -129,8 +129,6 @@ class Circuit { try { const virtualConnection = await hop({ connection: relayConnection, - // @ts-ignore - circuit: this, request: { type: CircuitPB.Type.HOP, srcPeer: { diff --git a/src/dialer/dial-request.js b/src/dialer/dial-request.js index bac571c1f3..62bab31be6 100644 --- a/src/dialer/dial-request.js +++ b/src/dialer/dial-request.js @@ -1,7 +1,7 @@ 'use strict' const errCode = require('err-code') -const AbortController = require('abort-controller') +const AbortController = require('abort-controller').default const anySignal = require('any-signal') const FIFO = require('p-fifo') const pAny = require('p-any') @@ -13,9 +13,12 @@ const pAny = require('p-any') */ /** + * @typedef {Object} DialOptions + * @property {AbortSignal} signal + * * @typedef {Object} DialRequestOptions * @property {Multiaddr[]} addrs - * @property {function(Multiaddr):Promise} dialAction + * @property {(m: Multiaddr, options: DialOptions) => Promise} dialAction * @property {Dialer} dialer */ @@ -46,7 +49,7 @@ class DialRequest { * @param {AbortSignal} [options.signal] - An AbortController signal * @returns {Promise} */ - async run (options) { + async run (options = {}) { const tokens = this.dialer.getTokens(this.addrs.length) // If no tokens are available, throw if (tokens.length < 1) { @@ -55,7 +58,6 @@ class DialRequest { const tokenHolder = new FIFO() tokens.forEach(token => tokenHolder.push(token)) - // @ts-ignore const dialAbortControllers = this.addrs.map(() => new AbortController()) let completedDials = 0 @@ -65,7 +67,6 @@ class DialRequest { let conn try { const signal = dialAbortControllers[i].signal - // @ts-ignore conn = await this.dialAction(addr, { ...options, signal: anySignal([signal, options.signal]) }) // Remove the successful AbortController so it is not aborted dialAbortControllers.splice(i, 1) diff --git a/src/get-peer.js b/src/get-peer.js index 35e2f26429..807c333384 100644 --- a/src/get-peer.js +++ b/src/get-peer.js @@ -14,7 +14,7 @@ const { codes } = require('./errors') * Converts the given `peer` to a `Peer` object. * If a multiaddr is received, the addressBook is updated. * - * @param {PeerId|multiaddr|string} peer + * @param {PeerId|Multiaddr|string} peer * @returns {{ id: PeerId, multiaddrs: Multiaddr[]|undefined }} */ function getPeer (peer) { diff --git a/src/identify/consts.js b/src/identify/consts.js index 9e15ef9f8e..1f697e5dc5 100644 --- a/src/identify/consts.js +++ b/src/identify/consts.js @@ -1,6 +1,6 @@ 'use strict' -// @ts-ignore +// @ts-ignore file not listed within the file list of projects const libp2pVersion = require('../../package.json').version module.exports.PROTOCOL_VERSION = 'ipfs/0.1.0' diff --git a/src/index.js b/src/index.js index 386f016145..175dd724a7 100644 --- a/src/index.js +++ b/src/index.js @@ -36,6 +36,8 @@ 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/pubsub')} Pubsub */ /** @@ -52,9 +54,9 @@ const IDENTIFY_PROTOCOLS = IdentifyService.multicodecs * @property {import('./circuit').AutoRelayOptions} autoRelay * * @typedef {Object} Libp2pConfig - * @property {Object} [dht] dht module options + * @property {any} [dht] dht module options * @property {PeerDiscoveryOptions} [peerDiscovery] - * @property {Object} [pubsub] pubsub module options + * @property {Pubsub} [pubsub] pubsub module options * @property {RelayOptions} [relay] * @property {Object} [transport] transport options indexed by transport key * @@ -191,7 +193,7 @@ class Libp2p extends EventEmitter { }) if (this._config.relay.enabled) { - // @ts-ignore + // @ts-ignore Circuit prototype this.transportManager.add(Circuit.prototype[Symbol.toStringTag], Circuit) this.relay = new Relay(this) } @@ -205,7 +207,6 @@ class Libp2p extends EventEmitter { // Add the identify service since we can multiplex this.identifyService = new IdentifyService({ libp2p: this }) - // @ts-ignore this.handle(Object.values(IDENTIFY_PROTOCOLS), this.identifyService.handleMessage) } @@ -234,6 +235,7 @@ class Libp2p extends EventEmitter { if (this._modules.pubsub) { const Pubsub = this._modules.pubsub // using pubsub adapter with *DEPRECATED* handlers functionality + /** @type {Pubsub} */ this.pubsub = PubsubAdapter(Pubsub, this, this._config.pubsub) } @@ -258,7 +260,7 @@ class Libp2p extends EventEmitter { */ emit (eventName, ...args) { // TODO: do we still need this? - // @ts-ignore + // @ts-ignore _events does not exist in libp2p if (eventName === 'error' && !this._events.error) { log.error(args) return false @@ -466,7 +468,7 @@ class Libp2p extends EventEmitter { * Registers the `handler` for each protocol * * @param {string[]|string} protocols - * @param {({ connection: Connection, stream: any, protocol: string }) => void} handler + * @param {({ connection: Connection, stream: MuxedStream, protocol: string }) => void} handler */ handle (protocols, handler) { protocols = Array.isArray(protocols) ? protocols : [protocols] @@ -632,9 +634,9 @@ class Libp2p extends EventEmitter { // Transport modules with discovery for (const Transport of this.transportManager.getTransports()) { - // @ts-ignore + // @ts-ignore Transport interface does not include discovery if (Transport.discovery) { - // @ts-ignore + // @ts-ignore Transport interface does not include discovery setupService(Transport.discovery) } } diff --git a/src/insecure/plaintext.js b/src/insecure/plaintext.js index 92010798c1..07efe9f758 100644 --- a/src/insecure/plaintext.js +++ b/src/insecure/plaintext.js @@ -12,15 +12,15 @@ const { UnexpectedPeerError, InvalidCryptoExchangeError } = require('libp2p-inte const { Exchange, KeyType } = require('./proto') const protocol = '/plaintext/2.0.0' +/** + * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + */ + function lpEncodeExchange (exchange) { const pb = Exchange.encode(exchange) return lp.encode.single(pb) } -/** - * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection - */ - /** * Encrypt connection. * diff --git a/src/metrics/old-peers.js b/src/metrics/old-peers.js index 1f38ba6e24..753bdf5fa1 100644 --- a/src/metrics/old-peers.js +++ b/src/metrics/old-peers.js @@ -9,7 +9,7 @@ const LRU = require('hashlru') * @returns {any} */ module.exports = (maxSize) => { - // @ts-ignore + // @ts-ignore LRU expression is not callable const patched = LRU(maxSize) patched.delete = patched.remove return patched diff --git a/src/metrics/stats.js b/src/metrics/stats.js index 00470b000e..e35ab311fc 100644 --- a/src/metrics/stats.js +++ b/src/metrics/stats.js @@ -24,7 +24,6 @@ class Stats extends EventEmitter { this._frequencyLastTime = Date.now() this._frequencyAccumulators = {} - /** @type {{}} */ this._movingAverages = {} this._update = this._update.bind(this) diff --git a/src/peer-store/address-book.js b/src/peer-store/address-book.js index a42a6b8538..516d908f6b 100644 --- a/src/peer-store/address-book.js +++ b/src/peer-store/address-book.js @@ -23,23 +23,13 @@ const Envelope = require('../record/envelope') */ /** - * Address object - * * @typedef {Object} Address * @property {Multiaddr} multiaddr peer multiaddr. * @property {boolean} isCertified obtained from a signed peer record. - */ - -/** - * CertifiedRecord object * * @typedef {Object} CertifiedRecord * @property {Uint8Array} raw raw envelope. * @property {number} seqNumber seq counter. - */ - -/** - * Entry object for the addressBook * * @typedef {Object} Entry * @property {Address[]} addresses peer Addresses. @@ -124,7 +114,6 @@ class AddressBook extends Book { // Replace unsigned addresses by the new ones from the record // TODO: Once we have ttls for the addresses, we should merge these in. - // @ts-ignore this._setData(peerId, { addresses, record: { diff --git a/src/peer-store/book.js b/src/peer-store/book.js index becd30b774..42bb749f01 100644 --- a/src/peer-store/book.js +++ b/src/peer-store/book.js @@ -90,7 +90,7 @@ class Book { * Returns `undefined` if there is no available data for the given peer. * * @param {PeerId} peerId - * @returns {T[]|undefined} + * @returns {T[]|T|undefined} */ get (peerId) { if (!PeerId.isPeerId(peerId)) { diff --git a/src/peer-store/key-book.js b/src/peer-store/key-book.js index 2326b3e966..356c81866e 100644 --- a/src/peer-store/key-book.js +++ b/src/peer-store/key-book.js @@ -16,6 +16,7 @@ const { /** * @typedef {import('./')} PeerStore + * @typedef {import('libp2p-crypto').PublicKey} PublicKey */ /** @@ -49,7 +50,7 @@ class KeyBook extends Book { * * @override * @param {PeerId} peerId - * @param {any} publicKey + * @param {PublicKey} publicKey * @returns {KeyBook} */ set (peerId, publicKey) { @@ -79,7 +80,7 @@ class KeyBook extends Book { * * @override * @param {PeerId} peerId - * @returns {any} + * @returns {PublicKey | undefined} */ get (peerId) { if (!PeerId.isPeerId(peerId)) { diff --git a/src/peer-store/metadata-book.js b/src/peer-store/metadata-book.js index 38504fc0ea..d497bb2f04 100644 --- a/src/peer-store/metadata-book.js +++ b/src/peer-store/metadata-book.js @@ -60,7 +60,7 @@ class MetadataBook extends Book { * @param {Uint8Array} value - metadata value * @returns {MetadataBook} */ - // @ts-ignore + // @ts-ignore override with more then the parameters expected in Book set (peerId, key, value) { if (!PeerId.isPeerId(peerId)) { log.error('peerId must be an instance of peer-id to store data') @@ -105,7 +105,6 @@ class MetadataBook extends Book { * @param {PeerId} peerId * @returns {Map|undefined} */ - // @ts-ignore get (peerId) { if (!PeerId.isPeerId(peerId)) { throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS) diff --git a/src/peer-store/persistent/index.js b/src/peer-store/persistent/index.js index e004f86a52..bbab49657e 100644 --- a/src/peer-store/persistent/index.js +++ b/src/peer-store/persistent/index.js @@ -346,7 +346,7 @@ class PersistentPeerStore extends PeerStore { case 'addrs': decoded = Addresses.decode(value) - // @ts-ignore + // @ts-ignore protected function this.addressBook._setData( peerId, { @@ -364,7 +364,7 @@ class PersistentPeerStore extends PeerStore { case 'keys': decoded = await PeerId.createFromPubKey(value) - // @ts-ignore + // @ts-ignore protected function this.keyBook._setData( decoded, decoded, @@ -380,7 +380,7 @@ class PersistentPeerStore extends PeerStore { case 'protos': decoded = Protocols.decode(value) - // @ts-ignore + // @ts-ignore protected function this.protoBook._setData( peerId, new Set(decoded.protocols), diff --git a/src/peer-store/proto-book.js b/src/peer-store/proto-book.js index 18529d7369..5c17b1371a 100644 --- a/src/peer-store/proto-book.js +++ b/src/peer-store/proto-book.js @@ -83,7 +83,6 @@ class ProtoBook extends Book { return this } - // @ts-ignore this._setData(peerId, newSet) log(`stored provided protocols for ${id}`) @@ -119,7 +118,6 @@ class ProtoBook extends Book { return this } - // @ts-ignore this._setData(peerId, newSet) log(`added provided protocols for ${id}`) @@ -158,7 +156,6 @@ class ProtoBook extends Book { return this } - // @ts-ignore this._setData(peerId, newSet) log(`removed provided protocols for ${id}`) } diff --git a/src/ping/index.js b/src/ping/index.js index a242f9fb1a..53e3f67930 100644 --- a/src/ping/index.js +++ b/src/ping/index.js @@ -28,7 +28,7 @@ const { PROTOCOL, PING_LENGTH } = require('./constants') * @returns {Promise} */ async function ping (node, peer) { - // @ts-ignore + // @ts-ignore multiaddr might not have toB58String log('dialing %s to %s', PROTOCOL, peer.toB58String ? peer.toB58String() : peer) const { stream } = await node.dialProtocol(peer, PROTOCOL) diff --git a/src/pnet/key-generator.js b/src/pnet/key-generator.js index d88f23d83c..8a7a1ef5a2 100644 --- a/src/pnet/key-generator.js +++ b/src/pnet/key-generator.js @@ -22,7 +22,7 @@ module.exports = generate module.exports.NONCE_LENGTH = 24 module.exports.KEY_LENGTH = KEY_LENGTH -// @ts-ignore +// @ts-ignore This condition will always return 'false' since the types 'Module | undefined' if (require.main === module) { // @ts-ignore generate(process.stdout) diff --git a/src/types.ts b/src/types.ts index 9a97803d15..fe58c0e5bf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -7,16 +7,6 @@ export enum KeyType { ECDSA = 3 } -export type MessagePublicKey = { - Type: KeyType - Data: Uint8Array -} - -export type MessageExchange = { - id: Uint8Array - pubKey: MessagePublicKey -} - // Protobufs export type MessageProto = { encode(value: any): Uint8Array diff --git a/src/upgrader.js b/src/upgrader.js index 8d00cb5210..d11c22b1f0 100644 --- a/src/upgrader.js +++ b/src/upgrader.js @@ -14,7 +14,6 @@ const mutableProxy = require('mutable-proxy') const { codes } = require('./errors') /** - * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection * @typedef {import('libp2p-interfaces/src/transport/types').MultiaddrConnection} MultiaddrConnection * @typedef {import('libp2p-interfaces/src/stream-muxer/types').Muxer} Muxer * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream @@ -222,7 +221,7 @@ class Upgrader { let connection if (Muxer) { - // @ts-ignore Create the muxer + // Create the muxer muxer = new Muxer({ // Run anytime a remote stream is created onStream: async muxedStream => { From 89fd524d159b4c2fd8633650bf2b6bb28f1ec03e Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 2 Dec 2020 21:43:04 +0100 Subject: [PATCH 07/18] chore: reset cache ci... --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 487a1d119c..85853dc9cd 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "it-pipe": "^1.1.0", "it-protocol-buffers": "^0.2.0", "libp2p-crypto": "^0.18.0", - "libp2p-interfaces": "libp2p/js-libp2p-interfaces#feat/add-types-with-post-install", + "libp2p-interfaces": "^0.7.2", "libp2p-utils": "^0.2.2", "mafmt": "^8.0.0", "merge-options": "^2.0.0", From 2109ef03cda56505e498223fe7415165474918d8 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 2 Dec 2020 21:43:58 +0100 Subject: [PATCH 08/18] chore: remove interfaces dep for ci cache --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 85853dc9cd..261406cef2 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,6 @@ "it-pipe": "^1.1.0", "it-protocol-buffers": "^0.2.0", "libp2p-crypto": "^0.18.0", - "libp2p-interfaces": "^0.7.2", "libp2p-utils": "^0.2.2", "mafmt": "^8.0.0", "merge-options": "^2.0.0", From 32dd055a46281c51046bb8f0022e4405622d5753 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 2 Dec 2020 21:47:41 +0100 Subject: [PATCH 09/18] chore: reset cache ci... --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 261406cef2..487a1d119c 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "it-pipe": "^1.1.0", "it-protocol-buffers": "^0.2.0", "libp2p-crypto": "^0.18.0", + "libp2p-interfaces": "libp2p/js-libp2p-interfaces#feat/add-types-with-post-install", "libp2p-utils": "^0.2.2", "mafmt": "^8.0.0", "merge-options": "^2.0.0", From a5f5160b26458f503494533f194656ae74efabe4 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 3 Dec 2020 11:41:09 +0100 Subject: [PATCH 10/18] chore: update record, transport and stream muxer per latest interface changes --- .github/workflows/main.yml | 26 ++++++-------------------- src/record/envelope/index.js | 2 +- src/record/peer-record/index.js | 11 ++++++----- src/transport-manager.js | 4 +++- src/upgrader.js | 13 +++++++------ test/record/envelope.spec.js | 6 +++--- 6 files changed, 26 insertions(+), 36 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8681fdae91..8ac4800718 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,9 +14,9 @@ jobs: - uses: actions/checkout@v2 - run: yarn - run: yarn lint + # - uses: gozala/typescript-error-reporter-action@v1.0.4 - run: yarn build - - uses: gozala/typescript-error-reporter-action@v1.0.4 - - run: yarn aegir dep-check -- -i aegir + - run: yarn aegir dep-check - uses: ipfs/aegir/actions/bundle-size@master name: size with: @@ -26,7 +26,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest] + os: [windows-latest, ubuntu-latest, macos-latest] node: [12, 14] fail-fast: true steps: @@ -35,7 +35,7 @@ jobs: with: node-version: ${{ matrix.node }} - run: yarn - - run: npx nyc --reporter=lcov npm run test:node -- --bail + - run: npx nyc --reporter=lcov aegir test -t node -- --bail - uses: codecov/codecov-action@v1 test-chrome: needs: check @@ -43,25 +43,11 @@ jobs: steps: - uses: actions/checkout@v2 - run: yarn - - run: yarn aegir test -t browser -t webworker + - run: npx aegir test -t browser -t webworker --bail test-firefox: needs: check runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: yarn - - run: yarn aegir test -t browser -t webworker -- --browsers FirefoxHeadless - test-electron-main: - needs: check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - run: yarn - - run: npx xvfb-maybe yarn aegir test -t electron-main --bail - test-electron-renderer: - needs: check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - run: yarn - - run: npx xvfb-maybe yarn aegir test -t electron-renderer --bail \ No newline at end of file + - run: npx aegir test -t browser -t webworker --bail -- --browsers FirefoxHeadless \ No newline at end of file diff --git a/src/record/envelope/index.js b/src/record/envelope/index.js index 3a791bedc7..46f9c3ccf6 100644 --- a/src/record/envelope/index.js +++ b/src/record/envelope/index.js @@ -12,7 +12,7 @@ const { codes } = require('../../errors') const Protobuf = require('./envelope.proto') /** - * @typedef {import('libp2p-interfaces/src/record')} Record + * @typedef {import('libp2p-interfaces/src/record/types').Record} Record */ class Envelope { diff --git a/src/record/peer-record/index.js b/src/record/peer-record/index.js index 7bde8081d5..334e717ed3 100644 --- a/src/record/peer-record/index.js +++ b/src/record/peer-record/index.js @@ -2,7 +2,6 @@ const multiaddr = require('multiaddr') const PeerId = require('peer-id') -const Record = require('libp2p-interfaces/src/record') const arrayEquals = require('libp2p-utils/src/array-equals') const Protobuf = require('./peer-record.proto') @@ -14,12 +13,13 @@ const { /** * @typedef {import('peer-id')} PeerId * @typedef {import('multiaddr')} Multiaddr + * @typedef {import('libp2p-interfaces/src/record/types').Record} Record */ /** - * @extends {Record} + * @implements {Record} */ -class PeerRecord extends Record { +class PeerRecord { /** * The PeerRecord is used for distributing peer routing records across the network. * It contains the peer's reachable listen addresses. @@ -31,7 +31,8 @@ class PeerRecord extends Record { * @param {number} [params.seqNumber] - monotonically-increasing sequence counter that's used to order PeerRecords in time. */ constructor ({ peerId, multiaddrs = [], seqNumber = Date.now() }) { - super(ENVELOPE_DOMAIN_PEER_RECORD, ENVELOPE_PAYLOAD_TYPE_PEER_RECORD) + this.domain = ENVELOPE_DOMAIN_PEER_RECORD + this.codec = ENVELOPE_PAYLOAD_TYPE_PEER_RECORD this.peerId = peerId this.multiaddrs = multiaddrs @@ -66,7 +67,7 @@ class PeerRecord extends Record { * Returns true if `this` record equals the `other`. * * @param {PeerRecord} other - * @returns {boolean} + * @returns {other is Record} */ equals (other) { // Validate PeerId diff --git a/src/transport-manager.js b/src/transport-manager.js index 258a8a86b8..6d1326833f 100644 --- a/src/transport-manager.js +++ b/src/transport-manager.js @@ -14,6 +14,7 @@ const { updateSelfPeerRecord } = require('./record/utils') /** * @typedef {import('multiaddr')} Multiaddr * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection + * @typedef {import('libp2p-interfaces/src/transport/types').TransportFactory} TransportFactory * @typedef {import('libp2p-interfaces/src/transport/types').Transport} Transport * * @typedef {Object} TransportManagerProperties @@ -32,6 +33,7 @@ class TransportManager { constructor ({ libp2p, upgrader, faultTolerance = FAULT_TOLERANCE.FATAL_ALL }) { this.libp2p = libp2p this.upgrader = upgrader + /** @type {Map} */ this._transports = new Map() this._listeners = new Map() this.faultTolerance = faultTolerance @@ -41,7 +43,7 @@ class TransportManager { * Adds a `Transport` to the manager * * @param {string} key - * @param {Transport} Transport + * @param {TransportFactory} Transport * @param {*} transportOptions - Additional options to pass to the transport * @returns {void} */ diff --git a/src/upgrader.js b/src/upgrader.js index d11c22b1f0..14d0a4e82d 100644 --- a/src/upgrader.js +++ b/src/upgrader.js @@ -15,6 +15,7 @@ const { codes } = require('./errors') /** * @typedef {import('libp2p-interfaces/src/transport/types').MultiaddrConnection} MultiaddrConnection + * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxerFactory} MuxerFactory * @typedef {import('libp2p-interfaces/src/stream-muxer/types').Muxer} Muxer * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream * @typedef {import('libp2p-interfaces/src/crypto/types').Crypto} Crypto @@ -34,7 +35,7 @@ class Upgrader { * @param {PeerId} options.localPeer * @param {import('./metrics')} [options.metrics] * @param {Map} [options.cryptos] - * @param {Map} [options.muxers] + * @param {Map} [options.muxers] * @param {(Connection) => void} options.onConnection - Called when a connection is upgraded * @param {(Connection) => void} options.onConnectionEnd */ @@ -203,7 +204,7 @@ class Upgrader { * @param {string} options.direction - One of ['inbound', 'outbound'] * @param {MultiaddrConnection} options.maConn - The transport layer connection * @param {MuxedStream | MultiaddrConnection} options.upgradedConn - A duplex connection returned from multiplexer and/or crypto selection - * @param {Muxer} [options.Muxer] - The muxer to be used for muxing + * @param {MuxerFactory} [options.Muxer] - The muxer to be used for muxing * @param {PeerId} options.remotePeer - The peer the connection is with * @returns {Connection} */ @@ -405,8 +406,8 @@ class Upgrader { * @private * @async * @param {MultiaddrConnection} connection - A basic duplex connection to multiplex - * @param {Map} muxers - The muxers to attempt multiplexing with - * @returns {Promise<{ stream: MuxedStream, Muxer?: Muxer}>} A muxed connection + * @param {Map} muxers - The muxers to attempt multiplexing with + * @returns {Promise<{ stream: MuxedStream, Muxer?: MuxerFactory}>} A muxed connection */ async _multiplexOutbound (connection, muxers) { const dialer = new Multistream.Dialer(connection) @@ -429,8 +430,8 @@ class Upgrader { * @private * @async * @param {MultiaddrConnection} connection - A basic duplex connection to multiplex - * @param {Map} muxers - The muxers to attempt multiplexing with - * @returns {Promise<{ stream: MuxedStream, Muxer?: Muxer}>} A muxed connection + * @param {Map} muxers - The muxers to attempt multiplexing with + * @returns {Promise<{ stream: MuxedStream, Muxer?: MuxerFactory}>} A muxed connection */ async _multiplexInbound (connection, muxers) { const listener = new Multistream.Listener(connection) diff --git a/test/record/envelope.spec.js b/test/record/envelope.spec.js index ca7408f26f..d95a925ecb 100644 --- a/test/record/envelope.spec.js +++ b/test/record/envelope.spec.js @@ -6,7 +6,6 @@ chai.use(require('chai-bytes')) const uint8arrayFromString = require('uint8arrays/from-string') const uint8arrayEquals = require('uint8arrays/equals') const Envelope = require('../../src/record/envelope') -const Record = require('libp2p-interfaces/src/record') const { codes: ErrorCodes } = require('../../src/errors') const peerUtils = require('../utils/creators/peer') @@ -14,9 +13,10 @@ const peerUtils = require('../utils/creators/peer') const domain = 'libp2p-testing' const codec = uint8arrayFromString('/libp2p/testdata') -class TestRecord extends Record { +class TestRecord { constructor (data) { - super(domain, codec) + this.domain = domain + this.codec = codec this.data = data } From 77a02573e0e58c2c0a9921db61601c18866619f4 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 3 Dec 2020 12:03:41 +0100 Subject: [PATCH 11/18] chore: add interop and examples in github actions --- .github/workflows/main.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8ac4800718..8641a8a52d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -50,4 +50,18 @@ jobs: steps: - uses: actions/checkout@v2 - run: yarn - - run: npx aegir test -t browser -t webworker --bail -- --browsers FirefoxHeadless \ No newline at end of file + - run: npx aegir test -t browser -t webworker --bail -- --browsers FirefoxHeadless + test-interop: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: yarn + - run: cd node_modules/interop-libp2p && yarn && LIBP2P_JS=${GITHUB_WORKSPACE}/src/index.js npx aegir test -t node --bail + test-auto-relay-example: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: yarn + - run: cd examples && yarn && npm run test -- auto-relay \ No newline at end of file From 55910c87975ca145baa0bfc4593931239aff3d44 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 3 Dec 2020 16:46:36 +0100 Subject: [PATCH 12/18] chore: minor changes from lodestar testing --- src/content-routing.js | 211 +++++++++++++++++++++-------------------- src/index.js | 4 +- src/peer-store/book.js | 13 +-- 3 files changed, 116 insertions(+), 112 deletions(-) diff --git a/src/content-routing.js b/src/content-routing.js index 185865d8ae..d2989d817c 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 (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 + }) + ) - // If we have the dht, make it first - if (dht) { - routers.unshift(dht) + for (const peer of result) { + yield peer + } } - 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) + /** + * 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 175dd724a7..f7daaa4c4e 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 42bb749f01..48855c157b 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 13/18] 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 f7daaa4c4e..8c04e4d835 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 14/18] 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 8641a8a52d..ade1dcbcc0 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 16192ad563..827d68d3ad 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 b63dcbff4e..d94576c5ce 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 4ebbd8371e..4add4840e1 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 d2989d817c..cba4a38bce 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 53e3f67930..eb8d7b96e9 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 15/18] 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 59de474fe7..3c1730cedc 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 827d68d3ad..2e41e48c8d 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 d94576c5ce..5be2c6edf5 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 4eea061043..650bb97d2b 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 b69ba78f15..ebe5e7d076 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 c334d449dc..09ae2627ad 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 8c04e4d835..7e62040316 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 c808ed697c..3ba99cfb5b 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 516d908f6b..74b6049a5c 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 fe58c0e5bf..3e87d7c803 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 From 9966c6ceb2d5970f2ef90012a7d6ea1a3272dd76 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 10 Dec 2020 11:25:48 +0100 Subject: [PATCH 16/18] chore: apply suggestions from code review Co-authored-by: Irakli Gozalishvili --- src/circuit/circuit/hop.js | 8 ++++---- src/circuit/circuit/stop.js | 6 +++--- src/index.js | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/circuit/circuit/hop.js b/src/circuit/circuit/hop.js index 3c1730cedc..8e23e6a894 100644 --- a/src/circuit/circuit/hop.js +++ b/src/circuit/circuit/hop.js @@ -18,16 +18,16 @@ const { stop } = require('./stop') const multicodec = require('./../multicodec') /** - * @typedef {import('../../types').CircuitRequest} Request + * @typedef {import('../../types').CircuitRequest} CircuitRequest * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection - * @typedef {import('./stream-handler')} StreamHandlerT + * @typedef {import('./stream-handler')} StreamHandlerT * @typedef {import('../transport')} Transport */ /** * @typedef {Object} HopRequest * @property {Connection} connection - * @property {Request} request + * @property {CircuitRequest} request * @property {StreamHandlerT} streamHandler * @property {Transport} circuit */ @@ -113,7 +113,7 @@ async function handleHop ({ * * @param {object} options * @param {Connection} options.connection - Connection to the relay - * @param {Request} options.request + * @param {CircuitRequest} options.request * @returns {Promise} */ async function hop ({ diff --git a/src/circuit/circuit/stop.js b/src/circuit/circuit/stop.js index 2e41e48c8d..46a9f8af20 100644 --- a/src/circuit/circuit/stop.js +++ b/src/circuit/circuit/stop.js @@ -13,7 +13,7 @@ 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('../../types').CircuitRequest} CircuitRequest * @typedef {import('./stream-handler')} StreamHandlerT */ @@ -23,7 +23,7 @@ const { validateAddrs } = require('./utils') * @private * @param {Object} options * @param {Connection} options.connection - * @param {Request} options.request - The CircuitRelay protobuf request (unencoded) + * @param {CircuitRequest} options.request - The CircuitRelay protobuf request (unencoded) * @param {StreamHandlerT} options.streamHandler * @returns {Promise|void} Resolves a duplex iterable */ @@ -54,7 +54,7 @@ module.exports.handleStop = function handleStop ({ * @private * @param {Object} options * @param {Connection} options.connection - * @param {Request} options.request - The CircuitRelay protobuf request (unencoded) + * @param {CircuitRequest} options.request - The CircuitRelay protobuf request (unencoded) * @returns {Promise} Resolves a duplex iterable */ module.exports.stop = async function stop ({ diff --git a/src/index.js b/src/index.js index 7e62040316..9ad8986c02 100644 --- a/src/index.js +++ b/src/index.js @@ -95,6 +95,9 @@ class Libp2p extends EventEmitter { super() // validateConfig will ensure the config is correct, // and add default values where appropriate + /** + * @private + */ this._options = validateConfig(_options) /** @type {PeerId} */ @@ -394,7 +397,7 @@ class Libp2p extends EventEmitter { * * @async * @param {PeerId|Multiaddr|string} peer - The peer to dial - * @param {null|string[]|string} protocols + * @param {string[]|string} protocols * @param {object} [options] * @param {AbortSignal} [options.signal] * @returns {Promise} From aa98bc2f0e03b6e1c03815e78be1f709a9fda6a6 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 10 Dec 2020 11:50:22 +0100 Subject: [PATCH 17/18] chore: address other review comments --- src/circuit/circuit/stop.js | 2 +- src/circuit/transport.js | 4 +++- src/index.js | 3 --- src/record/peer-record/index.js | 8 ++++++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/circuit/circuit/stop.js b/src/circuit/circuit/stop.js index 46a9f8af20..111b811dc2 100644 --- a/src/circuit/circuit/stop.js +++ b/src/circuit/circuit/stop.js @@ -14,7 +14,7 @@ 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} CircuitRequest - * @typedef {import('./stream-handler')} StreamHandlerT + * @typedef {import('./stream-handler')} StreamHandlerT */ /** diff --git a/src/circuit/transport.js b/src/circuit/transport.js index 650bb97d2b..fc2ddad4f0 100644 --- a/src/circuit/transport.js +++ b/src/circuit/transport.js @@ -24,6 +24,7 @@ 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 + * @typedef {import('../types').CircuitRequest} CircuitRequest */ class Circuit { @@ -53,6 +54,7 @@ class Circuit { * @param {MuxedStream} props.stream */ async _onProtocol ({ connection, stream }) { + /** @type {import('./circuit/stream-handler')} */ const streamHandler = new StreamHandler({ stream }) const request = await streamHandler.read() @@ -101,7 +103,7 @@ class Circuit { remoteAddr, localAddr }) - const type = request.Type === CircuitPB.Type.HOP ? 'relay' : 'inbound' + const type = request.type === CircuitPB.Type.HOP ? 'relay' : 'inbound' log('new %s connection %s', type, maConn.remoteAddr) const conn = await this._upgrader.upgradeInbound(maConn) diff --git a/src/index.js b/src/index.js index 9ad8986c02..c22b022d39 100644 --- a/src/index.js +++ b/src/index.js @@ -95,9 +95,6 @@ class Libp2p extends EventEmitter { super() // validateConfig will ensure the config is correct, // and add default values where appropriate - /** - * @private - */ this._options = validateConfig(_options) /** @type {PeerId} */ diff --git a/src/record/peer-record/index.js b/src/record/peer-record/index.js index 334e717ed3..32d018abc5 100644 --- a/src/record/peer-record/index.js +++ b/src/record/peer-record/index.js @@ -66,10 +66,14 @@ class PeerRecord { /** * Returns true if `this` record equals the `other`. * - * @param {PeerRecord} other - * @returns {other is Record} + * @param {unknown} other + * @returns {boolean} */ equals (other) { + if (!(other instanceof PeerRecord)) { + return false + } + // Validate PeerId if (!this.peerId.equals(other.peerId)) { return false From 222bb7bc881005711d1117117c33210b288a1f2e Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 3 Dec 2020 16:47:31 +0100 Subject: [PATCH 18/18] chore: add typedefs peerstore book template --- src/peer-store/address-book.js | 30 +++++++--------------------- src/peer-store/book.js | 24 ++++++++++++---------- src/peer-store/key-book.js | 22 +++------------------ src/peer-store/metadata-book.js | 35 ++++++++++++++------------------- src/peer-store/proto-book.js | 18 +++++++++++++++-- 5 files changed, 55 insertions(+), 74 deletions(-) diff --git a/src/peer-store/address-book.js b/src/peer-store/address-book.js index 74b6049a5c..ebbd260c42 100644 --- a/src/peer-store/address-book.js +++ b/src/peer-store/address-book.js @@ -33,11 +33,11 @@ const Envelope = require('../record/envelope') * * @typedef {Object} Entry * @property {Address[]} addresses peer Addresses. - * @property {CertifiedRecord} record certified peer record. + * @property {CertifiedRecord} [record] certified peer record. */ /** - * @extends {Book} + * @extends {Book} */ class AddressBook extends Book { /** @@ -56,12 +56,13 @@ class AddressBook extends Book { peerStore, eventName: 'change:multiaddrs', eventProperty: 'multiaddrs', - eventTransformer: (data) => { - if (!data.addresses) { + eventTransformer: (entry) => { + if (!entry || !entry.addresses) { return [] } - return data.addresses.map((address) => address.multiaddr) - } + return entry.addresses.map((address) => address.multiaddr) + }, + getTransformer: (entry) => entry && entry.addresses ? [...entry.addresses] : undefined }) /** @@ -263,23 +264,6 @@ class AddressBook extends Book { return this } - /** - * Get the known data of a provided peer. - * - * @override - * @param {PeerId} peerId - * @returns {Address[]|undefined} - */ - get (peerId) { - if (!PeerId.isPeerId(peerId)) { - throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS) - } - - const entry = this.data.get(peerId.toB58String()) - - return entry && entry.addresses ? [...entry.addresses] : undefined - } - /** * Transforms received multiaddrs into Address. * diff --git a/src/peer-store/book.js b/src/peer-store/book.js index 48855c157b..727e74a8bd 100644 --- a/src/peer-store/book.js +++ b/src/peer-store/book.js @@ -13,6 +13,9 @@ const passthrough = data => data * @typedef {import('./')} PeerStore */ +/** + * @template Data, GetData, EventData + */ class Book { /** * The Book is the skeleton for the PeerStore books. @@ -22,18 +25,20 @@ 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: any) => any[]} [properties.eventTransformer] - Transformer function of the provided data for being emitted. + * @param {(data: Data | undefined) => EventData | undefined} [properties.eventTransformer] - Transformer function of the provided data for being emitted. + * @param {(data: Data | undefined) => GetData | undefined} [properties.getTransformer] - Transformer function of the provided data for being returned on get. */ - constructor ({ peerStore, eventName, eventProperty, eventTransformer = passthrough }) { + constructor ({ peerStore, eventName, eventProperty, eventTransformer = passthrough, getTransformer = passthrough }) { this._ps = peerStore this.eventName = eventName this.eventProperty = eventProperty this.eventTransformer = eventTransformer + this.getTransformer = getTransformer /** * Map known peers to their data. * - * @type {Map} + * @type {Map} */ this.data = new Map() } @@ -42,7 +47,7 @@ class Book { * Set known data of a provided peer. * * @param {PeerId} peerId - * @param {any[]|any} data + * @param {unknown} data */ set (peerId, data) { throw errcode(new Error('set must be implemented by the subclass'), 'ERR_NOT_IMPLEMENTED') @@ -53,7 +58,7 @@ class Book { * * @protected * @param {PeerId} peerId - peerId of the data to store - * @param {any} data - data to store. + * @param {Data} data - data to store. * @param {Object} [options] - storing options. * @param {boolean} [options.emit = true] - emit the provided data. * @returns {void} @@ -73,7 +78,7 @@ class Book { * * @protected * @param {PeerId} peerId - * @param {any} [data] + * @param {Data | undefined} [data] */ _emit (peerId, data) { this._ps.emit(this.eventName, { @@ -87,7 +92,7 @@ class Book { * Returns `undefined` if there is no available data for the given peer. * * @param {PeerId} peerId - * @returns {any[]|any|undefined} + * @returns {GetData | undefined} */ get (peerId) { if (!PeerId.isPeerId(peerId)) { @@ -96,8 +101,7 @@ class Book { const rec = this.data.get(peerId.toB58String()) - // @ts-ignore - return rec ? [...rec] : undefined + return this.getTransformer(rec) } /** @@ -115,7 +119,7 @@ class Book { return false } - this._emit(peerId, []) + this._emit(peerId, undefined) return true } diff --git a/src/peer-store/key-book.js b/src/peer-store/key-book.js index 356c81866e..ba92b87afb 100644 --- a/src/peer-store/key-book.js +++ b/src/peer-store/key-book.js @@ -20,7 +20,7 @@ const { */ /** - * @extends {Book} + * @extends {Book} */ class KeyBook extends Book { /** @@ -34,7 +34,8 @@ class KeyBook extends Book { peerStore, eventName: 'change:pubkey', eventProperty: 'pubkey', - eventTransformer: (data) => data.pubKey + eventTransformer: (data) => data && data.pubKey, + getTransformer: (data) => data && data.pubKey }) /** @@ -74,23 +75,6 @@ class KeyBook extends Book { return this } - - /** - * Get Public key of the given PeerId, if stored. - * - * @override - * @param {PeerId} peerId - * @returns {PublicKey | undefined} - */ - get (peerId) { - if (!PeerId.isPeerId(peerId)) { - throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS) - } - - const rec = this.data.get(peerId.toB58String()) - - return rec ? rec.pubKey : undefined - } } module.exports = KeyBook diff --git a/src/peer-store/metadata-book.js b/src/peer-store/metadata-book.js index d497bb2f04..4008ed5434 100644 --- a/src/peer-store/metadata-book.js +++ b/src/peer-store/metadata-book.js @@ -10,17 +10,23 @@ const uint8ArrayEquals = require('uint8arrays/equals') const PeerId = require('peer-id') const Book = require('./book') - const { codes: { ERR_INVALID_PARAMETERS } } = require('../errors') +const eventName = 'change:metadata' +const eventProperty = 'metadata' + /** * @typedef {import('./')} PeerStore */ /** - * @extends {Book} + * @typedef {Map} Metadata + */ + +/** + * @extends {Book} * * @fires MetadataBook#change:metadata */ @@ -39,14 +45,14 @@ class MetadataBook extends Book { */ super({ peerStore, - eventName: 'change:metadata', - eventProperty: 'metadata' + eventName, + eventProperty }) /** * Map known peers to their known protocols. * - * @type {Map>} + * @type {Map} */ this.data = new Map() } @@ -99,20 +105,6 @@ class MetadataBook extends Book { emit && this._emit(peerId, key) } - /** - * Get the known data of a provided peer. - * - * @param {PeerId} peerId - * @returns {Map|undefined} - */ - get (peerId) { - if (!PeerId.isPeerId(peerId)) { - throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS) - } - - return this.data.get(peerId.toB58String()) - } - /** * Get specific metadata value, if it exists * @@ -167,7 +159,10 @@ class MetadataBook extends Book { return false } - this._emit(peerId, key) + this._ps.emit(eventName, { + peerId, + [eventProperty]: key + }) return true } diff --git a/src/peer-store/proto-book.js b/src/peer-store/proto-book.js index 5c17b1371a..f02ba94ef4 100644 --- a/src/peer-store/proto-book.js +++ b/src/peer-store/proto-book.js @@ -17,8 +17,21 @@ const { * @typedef {import('./')} PeerStore */ +// @extends {Book} + +/** + * @param {Set | undefined} set + * @returns {string[] | undefined} + */ +const transformSetToArray = (set) => { + if (!set) { + return undefined + } + return Array.from(set) +} + /** - * @extends {Book} + * @extends {Book, string[], string[]>} * * @fires ProtoBook#change:protocols */ @@ -39,7 +52,8 @@ class ProtoBook extends Book { peerStore, eventName: 'change:protocols', eventProperty: 'protocols', - eventTransformer: (data) => Array.from(data) + eventTransformer: (data) => transformSetToArray(data) || [], + getTransformer: (data) => transformSetToArray(data) }) /**