diff --git a/packages/interfaces/src/protocols.ts b/packages/interfaces/src/protocols.ts index 741f52056a..f80ad0806e 100644 --- a/packages/interfaces/src/protocols.ts +++ b/packages/interfaces/src/protocols.ts @@ -89,6 +89,17 @@ export type CreateNodeOptions = { */ defaultBootstrap?: boolean; + /** + * Enable or disable specific discovery methods. + * + * @default { peerExchange: true, dns: true, localPeerCache: true } + */ + discovery?: { + peerExchange: boolean; + dns: boolean; + localPeerCache: boolean; + }; + /** * List of peers to use to bootstrap the node. Ignored if defaultBootstrap is set to true. */ diff --git a/packages/sdk/src/create/discovery.spec.ts b/packages/sdk/src/create/discovery.spec.ts new file mode 100644 index 0000000000..40ce90ba94 --- /dev/null +++ b/packages/sdk/src/create/discovery.spec.ts @@ -0,0 +1,58 @@ +import { PubsubTopic } from "@waku/interfaces"; +import { expect } from "chai"; + +import { getPeerDiscoveries } from "./discovery.js"; + +describe("Default Peer Discoveries", () => { + const pubsubTopics: PubsubTopic[] = []; + + it("should have no discoveries enabled by default", () => { + const discoveries = getPeerDiscoveries(pubsubTopics); + expect(discoveries.length).to.equal(0); + }); + + it("should enable all discoveries when explicitly set", () => { + const discoveries = getPeerDiscoveries(pubsubTopics, { + dns: true, + peerExchange: true, + localPeerCache: true + }); + expect(discoveries.length).to.equal(3); + }); + + it("should enable only peerExchange and localPeerCache when dns is disabled", () => { + const discoveries = getPeerDiscoveries(pubsubTopics, { + dns: false, + peerExchange: true, + localPeerCache: true + }); + expect(discoveries.length).to.equal(2); + }); + + it("should enable only dns and localPeerCache when peerExchange is disabled", () => { + const discoveries = getPeerDiscoveries(pubsubTopics, { + dns: true, + peerExchange: false, + localPeerCache: true + }); + expect(discoveries.length).to.equal(2); + }); + + it("should enable only dns and peerExchange when localPeerCache is disabled", () => { + const discoveries = getPeerDiscoveries(pubsubTopics, { + dns: true, + peerExchange: true, + localPeerCache: false + }); + expect(discoveries.length).to.equal(2); + }); + + it("should enable only localPeerCache when dns and peerExchange are disabled", () => { + const discoveries = getPeerDiscoveries(pubsubTopics, { + dns: false, + peerExchange: false, + localPeerCache: true + }); + expect(discoveries.length).to.equal(1); + }); +}); diff --git a/packages/sdk/src/create/discovery.ts b/packages/sdk/src/create/discovery.ts index 341cff0e4e..c18cc1ec0b 100644 --- a/packages/sdk/src/create/discovery.ts +++ b/packages/sdk/src/create/discovery.ts @@ -5,18 +5,31 @@ import { wakuLocalPeerCacheDiscovery, wakuPeerExchangeDiscovery } from "@waku/discovery"; -import { type Libp2pComponents, PubsubTopic } from "@waku/interfaces"; +import { + CreateNodeOptions, + type Libp2pComponents, + PubsubTopic +} from "@waku/interfaces"; -export function defaultPeerDiscoveries( - pubsubTopics: PubsubTopic[] +export function getPeerDiscoveries( + pubsubTopics: PubsubTopic[], + enabled?: CreateNodeOptions["discovery"] ): ((components: Libp2pComponents) => PeerDiscovery)[] { const dnsEnrTrees = [enrTree["SANDBOX"]]; - const discoveries = [ - wakuDnsDiscovery(dnsEnrTrees), - wakuLocalPeerCacheDiscovery(), - wakuPeerExchangeDiscovery(pubsubTopics) - ]; + const discoveries: ((components: Libp2pComponents) => PeerDiscovery)[] = []; + + if (enabled?.dns) { + discoveries.push(wakuDnsDiscovery(dnsEnrTrees)); + } + + if (enabled?.localPeerCache) { + discoveries.push(wakuLocalPeerCacheDiscovery()); + } + + if (enabled?.peerExchange) { + discoveries.push(wakuPeerExchangeDiscovery(pubsubTopics)); + } return discoveries; } diff --git a/packages/sdk/src/create/libp2p.ts b/packages/sdk/src/create/libp2p.ts index 1b4afce675..868cc3f3d0 100644 --- a/packages/sdk/src/create/libp2p.ts +++ b/packages/sdk/src/create/libp2p.ts @@ -20,7 +20,7 @@ import { createLibp2p } from "libp2p"; import { isTestEnvironment } from "../env.js"; -import { defaultPeerDiscoveries } from "./discovery.js"; +import { getPeerDiscoveries } from "./discovery.js"; type MetadataService = { metadata?: (components: Libp2pComponents) => IMetadata; @@ -77,6 +77,12 @@ export async function defaultLibp2p( }) as any as Libp2p; // TODO: make libp2p include it; } +const DEFAULT_DISCOVERIES_ENABLED = { + dns: true, + peerExchange: true, + localPeerCache: true +}; + export async function createLibp2pAndUpdateOptions( options: CreateNodeOptions ): Promise<{ libp2p: Libp2p; pubsubTopics: PubsubTopic[] }> { @@ -90,7 +96,14 @@ export async function createLibp2pAndUpdateOptions( const peerDiscovery = libp2pOptions.peerDiscovery ?? []; if (options?.defaultBootstrap) { - peerDiscovery.push(...defaultPeerDiscoveries(pubsubTopics)); + peerDiscovery.push( + ...getPeerDiscoveries(pubsubTopics, { + ...DEFAULT_DISCOVERIES_ENABLED, + ...options.discovery + }) + ); + } else { + peerDiscovery.push(...getPeerDiscoveries(pubsubTopics, options.discovery)); } if (options?.bootstrapPeers) { diff --git a/packages/tests/src/lib/runNodes.ts b/packages/tests/src/lib/runNodes.ts index bba48f343a..0c3b6fc6e0 100644 --- a/packages/tests/src/lib/runNodes.ts +++ b/packages/tests/src/lib/runNodes.ts @@ -15,6 +15,12 @@ import { ServiceNode } from "./service_node.js"; export const log = new Logger("test:runNodes"); +export const DEFAULT_DISCOVERIES_ENABLED = { + dns: true, + peerExchange: true, + localPeerCache: true +}; + type RunNodesOptions = { context: Context; networkConfig: NetworkConfig; @@ -46,7 +52,8 @@ export async function runNodes( staticNoiseKey: NOISE_KEY_1, libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }, networkConfig: shardInfo, - lightPush: { numPeersToUse: 2 } + lightPush: { numPeersToUse: 2 }, + discovery: DEFAULT_DISCOVERIES_ENABLED }; log.info("Starting js waku node with :", JSON.stringify(waku_options)); diff --git a/packages/tests/src/utils/nodes.ts b/packages/tests/src/utils/nodes.ts index 497c6b9684..dc56d4adf0 100644 --- a/packages/tests/src/utils/nodes.ts +++ b/packages/tests/src/utils/nodes.ts @@ -13,6 +13,7 @@ import pRetry from "p-retry"; import { NOISE_KEY_1 } from "../constants.js"; import { ServiceNodesFleet } from "../lib/index.js"; +import { DEFAULT_DISCOVERIES_ENABLED } from "../lib/runNodes.js"; import { Args } from "../types.js"; import { waitForConnections } from "./waitForConnections.js"; @@ -41,7 +42,8 @@ export async function runMultipleNodes( addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }, networkConfig, - lightPush: { numPeersToUse: numServiceNodes } + lightPush: { numPeersToUse: numServiceNodes }, + discovery: DEFAULT_DISCOVERIES_ENABLED }; const waku = await createLightNode(wakuOptions);