@waku/core
Version:
TypeScript implementation of the Waku v2 protocol
140 lines • 5.21 kB
JavaScript
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