UNPKG

@waku/core

Version:

TypeScript implementation of the Waku v2 protocol

105 lines (87 loc) 2.91 kB
import { Libp2p, Peer, PeerId, PeerInfo } from "@libp2p/interface"; import { Multiaddr } from "@multiformats/multiaddr"; import { Libp2pEventHandler } from "@waku/interfaces"; import { Logger } from "@waku/utils"; import { Dialer } from "./dialer.js"; type DiscoveryDialerConstructorOptions = { libp2p: Libp2p; dialer: Dialer; }; interface IDiscoveryDialer { start(): void; stop(): void; } const log = new Logger("discovery-dialer"); /** * This class is responsible for dialing peers that are discovered by the libp2p node. * Managing limits for the peers is out of scope for this class. * Dialing after discovery is needed to identify the peer and get all other information: metadata, protocols, etc. */ export class DiscoveryDialer implements IDiscoveryDialer { private readonly libp2p: Libp2p; private readonly dialer: Dialer; public constructor(options: DiscoveryDialerConstructorOptions) { this.libp2p = options.libp2p; this.dialer = options.dialer; this.onPeerDiscovery = this.onPeerDiscovery.bind(this); } public start(): void { this.libp2p.addEventListener( "peer:discovery", this.onPeerDiscovery as Libp2pEventHandler<PeerInfo> ); } public stop(): void { this.libp2p.removeEventListener( "peer:discovery", this.onPeerDiscovery as Libp2pEventHandler<PeerInfo> ); } private async onPeerDiscovery(event: CustomEvent<PeerInfo>): Promise<void> { const peerId = event.detail.id; log.info(`Discovered new peer: ${peerId}`); try { await this.updatePeerStore(peerId, event.detail.multiaddrs); await this.dialer.dial(peerId); } catch (error) { log.error(`Error dialing peer ${peerId}`, error); } } private async updatePeerStore( peerId: PeerId, multiaddrs: Multiaddr[] ): Promise<void> { try { log.info(`Updating peer store for ${peerId}`); const peer = await this.getPeer(peerId); if (!peer) { log.info(`Peer ${peerId} not found in store, saving`); await this.libp2p.peerStore.save(peerId, { multiaddrs: multiaddrs }); return; } const hasSameAddr = multiaddrs.every((addr) => peer.addresses.some((a) => a.multiaddr.equals(addr)) ); if (hasSameAddr) { log.info(`Peer ${peerId} has same addresses in peer store, skipping`); return; } log.info(`Merging peer ${peerId} addresses in peer store`); await this.libp2p.peerStore.merge(peerId, { multiaddrs: multiaddrs }); } catch (error) { log.error(`Error updating peer store for ${peerId}`, error); } } private async getPeer(peerId: PeerId): Promise<Peer | undefined> { try { return await this.libp2p.peerStore.get(peerId); } catch (error) { log.error(`Error getting peer info for ${peerId}`, error); return undefined; } } }