fix: improve node bootstrapping (#2121)

* fix: improve node bootstrapping

* implement dns discovery on failed dials

* update const to match RFC

* up
This commit is contained in:
Sasha 2024-09-06 01:10:54 +02:00 committed by GitHub
parent f4b6bb04b3
commit 0263cb80c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 44 additions and 13 deletions

View File

@ -2,6 +2,8 @@ import type { Peer, PeerId, PeerInfo, PeerStore } from "@libp2p/interface";
import { CustomEvent, TypedEventEmitter } from "@libp2p/interface"; import { CustomEvent, TypedEventEmitter } from "@libp2p/interface";
import { import {
ConnectionManagerOptions, ConnectionManagerOptions,
DiscoveryTrigger,
DNS_DISCOVERY_TAG,
EConnectionStateEvents, EConnectionStateEvents,
EPeersByDiscoveryEvents, EPeersByDiscoveryEvents,
IConnectionManager, IConnectionManager,
@ -292,6 +294,9 @@ export class ConnectionManager
this.dialErrorsForPeer.delete(peerId.toString()); this.dialErrorsForPeer.delete(peerId.toString());
await this.libp2p.peerStore.delete(peerId); await this.libp2p.peerStore.delete(peerId);
// if it was last available peer - attempt DNS discovery
await this.attemptDnsDiscovery();
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Error deleting undialable peer ${peerId.toString()} from peer store - ${error}` `Error deleting undialable peer ${peerId.toString()} from peer store - ${error}`
@ -300,6 +305,27 @@ export class ConnectionManager
} }
} }
private async attemptDnsDiscovery(): Promise<void> {
if (this.libp2p.getConnections().length > 0) return;
if ((await this.libp2p.peerStore.all()).length > 0) return;
log.info("Attempting to trigger DNS discovery.");
const dnsDiscovery = Object.values(this.libp2p.components.components).find(
(v: unknown) => {
if (v && v.toString) {
return v.toString().includes(DNS_DISCOVERY_TAG);
}
return false;
}
) as DiscoveryTrigger;
if (!dnsDiscovery) return;
await dnsDiscovery.findPeers();
}
private processDialQueue(): void { private processDialQueue(): void {
if ( if (
this.pendingPeerDialQueue.length > 0 && this.pendingPeerDialQueue.length > 0 &&

View File

@ -15,7 +15,7 @@ export const DEFAULT_BOOTSTRAP_TAG_VALUE = 50;
export const DEFAULT_BOOTSTRAP_TAG_TTL = 100_000_000; export const DEFAULT_BOOTSTRAP_TAG_TTL = 100_000_000;
export const DEFAULT_NODE_REQUIREMENTS: Partial<NodeCapabilityCount> = { export const DEFAULT_NODE_REQUIREMENTS: Partial<NodeCapabilityCount> = {
store: 2, store: 1,
filter: 1, filter: 2,
lightPush: 1 lightPush: 2
}; };

View File

@ -7,11 +7,13 @@ import {
import { peerDiscoverySymbol as symbol } from "@libp2p/interface"; import { peerDiscoverySymbol as symbol } from "@libp2p/interface";
import type { PeerInfo } from "@libp2p/interface"; import type { PeerInfo } from "@libp2p/interface";
import type { import type {
DiscoveryTrigger,
DnsDiscOptions, DnsDiscOptions,
DnsDiscoveryComponents, DnsDiscoveryComponents,
IEnr, IEnr,
NodeCapabilityCount NodeCapabilityCount
} from "@waku/interfaces"; } from "@waku/interfaces";
import { DNS_DISCOVERY_TAG } from "@waku/interfaces";
import { encodeRelayShard, Logger } from "@waku/utils"; import { encodeRelayShard, Logger } from "@waku/utils";
import { import {
@ -29,7 +31,7 @@ const log = new Logger("peer-discovery-dns");
*/ */
export class PeerDiscoveryDns export class PeerDiscoveryDns
extends TypedEventEmitter<PeerDiscoveryEvents> extends TypedEventEmitter<PeerDiscoveryEvents>
implements PeerDiscovery implements PeerDiscovery, DiscoveryTrigger
{ {
private nextPeer: (() => AsyncGenerator<IEnr>) | undefined; private nextPeer: (() => AsyncGenerator<IEnr>) | undefined;
private _started: boolean; private _started: boolean;
@ -56,8 +58,11 @@ export class PeerDiscoveryDns
log.info("Starting peer discovery via dns"); log.info("Starting peer discovery via dns");
this._started = true; this._started = true;
await this.findPeers();
}
if (this.nextPeer === undefined) { public async findPeers(): Promise<void> {
if (!this.nextPeer) {
let { enrUrls } = this._options; let { enrUrls } = this._options;
if (!Array.isArray(enrUrls)) enrUrls = [enrUrls]; if (!Array.isArray(enrUrls)) enrUrls = [enrUrls];
@ -134,7 +139,7 @@ export class PeerDiscoveryDns
} }
public get [Symbol.toStringTag](): string { public get [Symbol.toStringTag](): string {
return "@waku/bootstrap"; return DNS_DISCOVERY_TAG;
} }
} }

View File

@ -1,5 +1,7 @@
import { PeerStore } from "@libp2p/interface"; import { PeerStore } from "@libp2p/interface";
export const DNS_DISCOVERY_TAG = "@waku/bootstrap";
export type SearchContext = { export type SearchContext = {
domain: string; domain: string;
publicKey: string; publicKey: string;
@ -45,3 +47,7 @@ export interface DnsDiscOptions {
*/ */
tagTTL?: number; tagTTL?: number;
} }
export interface DiscoveryTrigger {
findPeers: () => Promise<void>;
}

View File

@ -7,19 +7,13 @@ import {
} from "@waku/discovery"; } from "@waku/discovery";
import { type Libp2pComponents, PubsubTopic } from "@waku/interfaces"; import { type Libp2pComponents, PubsubTopic } from "@waku/interfaces";
const DEFAULT_NODE_REQUIREMENTS = {
lightPush: 1,
filter: 1,
store: 1
};
export function defaultPeerDiscoveries( export function defaultPeerDiscoveries(
pubsubTopics: PubsubTopic[] pubsubTopics: PubsubTopic[]
): ((components: Libp2pComponents) => PeerDiscovery)[] { ): ((components: Libp2pComponents) => PeerDiscovery)[] {
const dnsEnrTrees = [enrTree["SANDBOX"], enrTree["TEST"]]; const dnsEnrTrees = [enrTree["SANDBOX"], enrTree["TEST"]];
const discoveries = [ const discoveries = [
wakuDnsDiscovery(dnsEnrTrees, DEFAULT_NODE_REQUIREMENTS), wakuDnsDiscovery(dnsEnrTrees),
wakuLocalPeerCacheDiscovery(), wakuLocalPeerCacheDiscovery(),
wakuPeerExchangeDiscovery(pubsubTopics) wakuPeerExchangeDiscovery(pubsubTopics)
]; ];