UNPKG

@waku/core

Version:

TypeScript implementation of the Waku v2 protocol

140 lines 5.21 kB
import { Logger } from "@waku/utils"; import { ConnectionLimiter } from "./connection_limiter.js"; import { Dialer } from "./dialer.js"; import { DiscoveryDialer } from "./discovery_dialer.js"; import { KeepAliveManager } from "./keep_alive_manager.js"; import { NetworkMonitor } from "./network_monitor.js"; import { ShardReader } from "./shard_reader.js"; import { getPeerPing, mapToPeerId, mapToPeerIdOrMultiaddr } from "./utils.js"; const log = new Logger("connection-manager"); const DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED = 3; const DEFAULT_PING_KEEP_ALIVE_SEC = 5 * 60; const DEFAULT_RELAY_KEEP_ALIVE_SEC = 5 * 60; const DEFAULT_ENABLE_AUTO_RECOVERY = true; const DEFAULT_MAX_CONNECTIONS = 10; const DEFAULT_MAX_DIALING_PEERS = 3; const DEFAULT_FAILED_DIAL_COOLDOWN_SEC = 60; const DEFAULT_DIAL_COOLDOWN_SEC = 10; export class ConnectionManager { keepAliveManager; discoveryDialer; dialer; shardReader; networkMonitor; connectionLimiter; options; libp2p; constructor(options) { this.libp2p = options.libp2p; this.options = { maxBootstrapPeers: DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED, maxConnections: DEFAULT_MAX_CONNECTIONS, pingKeepAlive: DEFAULT_PING_KEEP_ALIVE_SEC, relayKeepAlive: DEFAULT_RELAY_KEEP_ALIVE_SEC, enableAutoRecovery: DEFAULT_ENABLE_AUTO_RECOVERY, maxDialingPeers: DEFAULT_MAX_DIALING_PEERS, failedDialCooldown: DEFAULT_FAILED_DIAL_COOLDOWN_SEC, dialCooldown: DEFAULT_DIAL_COOLDOWN_SEC, ...options.config }; this.keepAliveManager = new KeepAliveManager({ relay: options.relay, libp2p: options.libp2p, options: { pingKeepAlive: this.options.pingKeepAlive, relayKeepAlive: this.options.relayKeepAlive } }); this.shardReader = new ShardReader({ libp2p: options.libp2p, networkConfig: options.networkConfig }); this.dialer = new Dialer({ libp2p: options.libp2p, shardReader: this.shardReader, options: this.options }); this.discoveryDialer = new DiscoveryDialer({ libp2p: options.libp2p, dialer: this.dialer }); this.networkMonitor = new NetworkMonitor({ libp2p: options.libp2p, events: options.events }); this.connectionLimiter = new ConnectionLimiter({ libp2p: options.libp2p, events: options.events, networkMonitor: this.networkMonitor, dialer: this.dialer, options: this.options }); } start() { this.dialer.start(); this.networkMonitor.start(); this.discoveryDialer.start(); this.keepAliveManager.start(); this.connectionLimiter.start(); } stop() { this.dialer.stop(); this.networkMonitor.stop(); this.discoveryDialer.stop(); this.keepAliveManager.stop(); this.connectionLimiter.stop(); } isConnected() { return this.networkMonitor.isConnected(); } async dial(peer, protocolCodecs) { const ma = mapToPeerIdOrMultiaddr(peer); log.info(`Dialing peer ${ma.toString()} with protocols ${protocolCodecs}`); // must use libp2p directly instead of dialer because we need to dial the peer right away const stream = await this.libp2p.dialProtocol(ma, protocolCodecs); log.info(`Dialed peer ${ma.toString()} with protocols ${protocolCodecs}`); return stream; } async hangUp(peer) { const peerId = mapToPeerId(peer); try { log.info(`Dropping connection with peer ${peerId.toString()}`); await this.libp2p.hangUp(peerId); log.info(`Dropped connection with peer ${peerId.toString()}`); return true; } catch (error) { log.error(`Error dropping connection with peer ${peerId.toString()} - ${error}`); return false; } } async getConnectedPeers(codec) { const peerIDs = this.libp2p.getPeers(); log.info(`Getting connected peers for codec ${codec}`); if (peerIDs.length === 0) { log.info(`No connected peers`); return []; } const peers = await Promise.all(peerIDs.map(async (id) => { try { return await this.libp2p.peerStore.get(id); } catch (e) { return null; } })); const result = peers .filter((p) => !!p) .filter((p) => (codec ? p.protocols.includes(codec) : true)) .sort((left, right) => getPeerPing(left) - getPeerPing(right)); log.info(`Found ${result.length} connected peers for codec ${codec}`); return result; } async hasShardInfo(peerId) { return this.shardReader.hasShardInfo(peerId); } async isPeerOnTopic(peerId, pubsubTopic) { return this.shardReader.isPeerOnTopic(peerId, pubsubTopic); } } //# sourceMappingURL=connection_manager.js.map