From ec02351e65d0627872e6a53894c060a593b9e66e Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Fri, 23 Sep 2022 09:33:42 +0100 Subject: [PATCH] fix: when creating dial targets, encapsulate PeerIds last (#1389) It turns out because `Multiaddr.encapsulate` stringifies the `Multiaddr` it's a [suprisingly expensive operation](https://github.com/multiformats/js-multiaddr/pull/275#issuecomment-1254981709) so here we switch the order of our `Multiaddr` pipeline around so we filter undialable addresses (e.g. unsupported transports etc) before encapsulating the `PeerId` onto a `Multiaddr` we'd then just ignore. --- src/connection-manager/dialer/index.ts | 29 +++++++++++++------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/connection-manager/dialer/index.ts b/src/connection-manager/dialer/index.ts index 7a731c945b..fd2a6ba8d7 100644 --- a/src/connection-manager/dialer/index.ts +++ b/src/connection-manager/dialer/index.ts @@ -232,15 +232,23 @@ export class DefaultDialer implements Startable, Dialer { * Multiaddrs not supported by the available transports will be filtered out. */ async _createDialTarget (peer: PeerId, options: AbortOptions): Promise { - const knownAddrs = await pipe( + const _resolve = this._resolve.bind(this) + + const addrs = await pipe( await this.components.getPeerStore().addressBook.get(peer), (source) => filter(source, async (address) => { return !(await this.components.getConnectionGater().denyDialMultiaddr(peer, address.multiaddr)) }), + // Sort addresses so, for example, we try certified public address first (source) => sort(source, this.addressSorter), - (source) => map(source, (address) => { - const ma = address.multiaddr - + async function * resolve (source) { + for await (const a of source) { + yield * await _resolve(a.multiaddr, options) + } + }, + // Multiaddrs not supported by the available transports will be filtered out. + (source) => filter(source, (ma) => Boolean(this.components.getTransportManager().transportForMultiaddr(ma))), + (source) => map(source, (ma) => { if (peer.toString() === ma.getPeerId()) { return ma } @@ -250,23 +258,14 @@ export class DefaultDialer implements Startable, Dialer { async (source) => await all(source) ) - const addrs: Multiaddr[] = [] - for (const a of knownAddrs) { - const resolvedAddrs = await this._resolve(a, options) - resolvedAddrs.forEach(ra => addrs.push(ra)) - } - - // Multiaddrs not supported by the available transports will be filtered out. - const supportedAddrs = addrs.filter(a => this.components.getTransportManager().transportForMultiaddr(a)) - - if (supportedAddrs.length > this.maxAddrsToDial) { + if (addrs.length > this.maxAddrsToDial) { await this.components.getPeerStore().delete(peer) throw errCode(new Error('dial with more addresses than allowed'), codes.ERR_TOO_MANY_ADDRESSES) } return { id: peer.toString(), - addrs: supportedAddrs + addrs } }