diff --git a/CHANGELOG.md b/CHANGELOG.md index a8f415ae9d..51600c43a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,12 +12,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Simple connection management that selects the most recent connection for store, light push and filter requests. +- `createLightNode` to create a Waku node for resource restricted environment with Light Push, Filter and Relay. +- `createPrivacyNode` to create a Waku node for privacy preserving usage with Relay only. ### Changed - **breaking**: `DecryptionParams` may be passed when using `queryHistory` instead of just keys. - Examples have been moved to https://github.com/waku-org/js-waku-examples. - `Waku` is now defined as an interface with `WakuNode` an implementation of it. +- `createWaku` is deprecated in favour of `createLightNode` and `createPrivacyNode`. +- `waitForRemotePeer` can throw, default behaviour has changed. ### Fixed diff --git a/package-lock.json b/package-lock.json index 6e01acfe5c..4a99a45e9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@libp2p/interface-peer-id": "^1.0.2", "@libp2p/interface-peer-info": "^1.0.1", "@libp2p/interface-peer-store": "^1.0.0", + "@libp2p/interface-pubsub": "^2.0.1", "@libp2p/interfaces": "^3.0.2", "@libp2p/mplex": "^5.1.1", "@libp2p/peer-id": "^1.1.10", diff --git a/package.json b/package.json index 626ff428c3..2fc3f7f4cf 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "@libp2p/interface-peer-id": "^1.0.2", "@libp2p/interface-peer-info": "^1.0.1", "@libp2p/interface-peer-store": "^1.0.0", + "@libp2p/interface-pubsub": "^2.0.1", "@libp2p/interfaces": "^3.0.2", "@libp2p/mplex": "^5.1.1", "@libp2p/peer-id": "^1.1.10", diff --git a/src/lib/create_waku.ts b/src/lib/create_waku.ts index d68f9b5cf8..c6b776292f 100644 --- a/src/lib/create_waku.ts +++ b/src/lib/create_waku.ts @@ -6,7 +6,7 @@ import { all as filterAll } from "@libp2p/websockets/filters"; import { createLibp2p, Libp2pOptions } from "libp2p"; import type { Libp2p } from "libp2p"; -import type { Waku } from "./interfaces"; +import type { Waku, WakuLight, WakuPrivacy } from "./interfaces"; import { PeerDiscoveryStaticPeers } from "./peer_discovery_static_list"; import { getPredefinedBootstrapNodes } from "./predefined_bootstrap_nodes"; import { WakuNode, WakuOptions } from "./waku"; @@ -50,6 +50,60 @@ export interface CreateOptions { defaultBootstrap?: boolean; } +/** + * Create a Waku node that uses Waku Light Push, Filter and Store to send and + * receive messages, enabling low resource consumption. + * **Note: This is NOT compatible with nwaku** + * Ref: https://github.com/status-im/nwaku/issues/1085 + */ +export async function createLightNode( + options?: CreateOptions & WakuOptions +): Promise { + const libp2pOptions = options?.libp2p ?? {}; + const peerDiscovery = libp2pOptions.peerDiscovery ?? []; + if (options?.defaultBootstrap) { + peerDiscovery.push(defaultPeerDiscovery()); + Object.assign(libp2pOptions, { peerDiscovery }); + } + + const libp2p = await defaultLibp2p(undefined, libp2pOptions); + + const wakuStore = new WakuStore(libp2p, options); + const wakuLightPush = new WakuLightPush(libp2p, options); + const wakuFilter = new WakuFilter(libp2p, options); + + return new WakuNode( + options ?? {}, + libp2p, + wakuStore, + wakuLightPush, + wakuFilter + ) as WakuLight; +} + +/** + * Create a Waku node that uses Waku Relay to send and receive messages, + * enabling some privacy preserving properties. + */ +export async function createPrivacyNode( + options?: CreateOptions & WakuOptions +): Promise { + const libp2pOptions = options?.libp2p ?? {}; + const peerDiscovery = libp2pOptions.peerDiscovery ?? []; + if (options?.defaultBootstrap) { + peerDiscovery.push(defaultPeerDiscovery()); + Object.assign(libp2pOptions, { peerDiscovery }); + } + + const libp2p = await defaultLibp2p(new WakuRelay(options), libp2pOptions); + + return new WakuNode(options ?? {}, libp2p) as WakuPrivacy; +} + +/** + * @deprecated use { @link createLightNode } (only compatible with nwaku v0.12), + * { @link createPrivacyNode } or { @link Waku.constructor } instead; + */ export async function createWaku( options?: CreateOptions & WakuOptions ): Promise { @@ -80,7 +134,7 @@ export function defaultPeerDiscovery(): PeerDiscovery { } export async function defaultLibp2p( - wakuRelay: WakuRelay, + wakuRelay?: WakuRelay, options?: Partial ): Promise { const libp2pOpts = Object.assign( @@ -89,7 +143,7 @@ export async function defaultLibp2p( streamMuxers: [new Mplex()], connectionEncryption: [new Noise()], }, - { pubsub: wakuRelay }, + wakuRelay ? { pubsub: wakuRelay } : {}, options ?? {} ); diff --git a/src/lib/interfaces.ts b/src/lib/interfaces.ts index 204d29a6c6..8b2c93606d 100644 --- a/src/lib/interfaces.ts +++ b/src/lib/interfaces.ts @@ -12,10 +12,10 @@ import type { WakuStore } from "./waku_store"; export interface Waku { libp2p: Libp2p; - relay: WakuRelay; - store: WakuStore; - filter: WakuFilter; - lightPush: WakuLightPush; + relay?: WakuRelay; + store?: WakuStore; + filter?: WakuFilter; + lightPush?: WakuLightPush; dial(peer: PeerId | Multiaddr, protocols?: Protocols[]): Promise; @@ -37,3 +37,17 @@ export interface Waku { deleteDecryptionKey(key: Uint8Array | string): void; } + +export interface WakuLight extends Waku { + relay: undefined; + store: WakuStore; + filter: WakuFilter; + lightPush: WakuLightPush; +} + +export interface WakuPrivacy extends Waku { + relay: WakuRelay; + store: undefined; + filter: undefined; + lightPush: undefined; +} diff --git a/src/lib/wait_for_remote_peer.node.spec.ts b/src/lib/wait_for_remote_peer.node.spec.ts index 3185c5011e..67793a890b 100644 --- a/src/lib/wait_for_remote_peer.node.spec.ts +++ b/src/lib/wait_for_remote_peer.node.spec.ts @@ -3,13 +3,14 @@ import { expect } from "chai"; import { makeLogFileName, NOISE_KEY_1, Nwaku } from "../test_utils"; import { delay } from "../test_utils/delay"; -import { createWaku } from "./create_waku"; -import type { Waku } from "./interfaces"; +import { createLightNode, createPrivacyNode } from "./create_waku"; +import type { WakuLight, WakuPrivacy } from "./interfaces"; import { waitForRemotePeer } from "./wait_for_remote_peer"; import { Protocols } from "./waku"; describe("Wait for remote peer", function () { - let waku: Waku; + let waku1: WakuPrivacy; + let waku2: WakuLight; let nwaku: Nwaku | undefined; afterEach(async function () { @@ -17,7 +18,8 @@ describe("Wait for remote peer", function () { nwaku.stop(); nwaku = undefined; } - !!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e)); + waku1?.stop().catch((e) => console.log("Waku failed to stop", e)); + waku2?.stop().catch((e) => console.log("Waku failed to stop", e)); }); it("Relay - dialed first", async function () { @@ -31,14 +33,14 @@ describe("Wait for remote peer", function () { }); const multiAddrWithId = await nwaku.getMultiaddrWithId(); - waku = await createWaku({ + waku1 = await createPrivacyNode({ staticNoiseKey: NOISE_KEY_1, }); - await waku.start(); - await waku.dial(multiAddrWithId); + await waku1.start(); + await waku1.dial(multiAddrWithId); await delay(1000); - await waitForRemotePeer(waku, [Protocols.Relay]); - const peers = waku.relay.getMeshPeers(); + await waitForRemotePeer(waku1, [Protocols.Relay]); + const peers = waku1.relay.getMeshPeers(); const nimPeerId = multiAddrWithId.getPeerId(); expect(nimPeerId).to.not.be.undefined; @@ -56,17 +58,17 @@ describe("Wait for remote peer", function () { }); const multiAddrWithId = await nwaku.getMultiaddrWithId(); - waku = await createWaku({ + waku1 = await createPrivacyNode({ staticNoiseKey: NOISE_KEY_1, }); - await waku.start(); + await waku1.start(); - const waitPromise = waitForRemotePeer(waku, [Protocols.Relay]); + const waitPromise = waitForRemotePeer(waku1, [Protocols.Relay]); await delay(1000); - await waku.dial(multiAddrWithId); + await waku1.dial(multiAddrWithId); await waitPromise; - const peers = waku.relay.getMeshPeers(); + const peers = waku1.relay.getMeshPeers(); const nimPeerId = multiAddrWithId.getPeerId(); expect(nimPeerId).to.not.be.undefined; @@ -75,12 +77,12 @@ describe("Wait for remote peer", function () { it("Relay - times out", function (done) { this.timeout(5000); - createWaku({ + createPrivacyNode({ staticNoiseKey: NOISE_KEY_1, }) - .then((waku) => waku.start().then(() => waku)) - .then((waku) => { - waitForRemotePeer(waku, [Protocols.Relay], 200).then( + .then((waku1) => waku1.start().then(() => waku1)) + .then((waku1) => { + waitForRemotePeer(waku1, [Protocols.Relay], 200).then( () => { throw "Promise expected to reject on time out"; }, @@ -104,15 +106,15 @@ describe("Wait for remote peer", function () { }); const multiAddrWithId = await nwaku.getMultiaddrWithId(); - waku = await createWaku({ + waku2 = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); - await waku.start(); - await waku.dial(multiAddrWithId); + await waku2.start(); + await waku2.dial(multiAddrWithId); await delay(1000); - await waitForRemotePeer(waku, [Protocols.Store]); + await waitForRemotePeer(waku2, [Protocols.Store]); - const peers = (await waku.store.peers()).map((peer) => peer.id.toString()); + const peers = (await waku2.store.peers()).map((peer) => peer.id.toString()); const nimPeerId = multiAddrWithId.getPeerId(); expect(nimPeerId).to.not.be.undefined; @@ -131,16 +133,16 @@ describe("Wait for remote peer", function () { }); const multiAddrWithId = await nwaku.getMultiaddrWithId(); - waku = await createWaku({ + waku2 = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); - await waku.start(); - const waitPromise = waitForRemotePeer(waku, [Protocols.Store], 2000); + await waku2.start(); + const waitPromise = waitForRemotePeer(waku2, [Protocols.Store], 2000); await delay(1000); - await waku.dial(multiAddrWithId); + await waku2.dial(multiAddrWithId); await waitPromise; - const peers = (await waku.store.peers()).map((peer) => peer.id.toString()); + const peers = (await waku2.store.peers()).map((peer) => peer.id.toString()); const nimPeerId = multiAddrWithId.getPeerId(); @@ -159,14 +161,14 @@ describe("Wait for remote peer", function () { }); const multiAddrWithId = await nwaku.getMultiaddrWithId(); - waku = await createWaku({ + waku2 = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); - await waku.start(); - await waku.dial(multiAddrWithId); - await waitForRemotePeer(waku, [Protocols.LightPush]); + await waku2.start(); + await waku2.dial(multiAddrWithId); + await waitForRemotePeer(waku2, [Protocols.LightPush]); - const peers = (await waku.lightPush.peers()).map((peer) => + const peers = (await waku2.lightPush.peers()).map((peer) => peer.id.toString() ); @@ -187,14 +189,79 @@ describe("Wait for remote peer", function () { }); const multiAddrWithId = await nwaku.getMultiaddrWithId(); - waku = await createWaku({ + waku2 = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); - await waku.start(); - await waku.dial(multiAddrWithId); - await waitForRemotePeer(waku, [Protocols.Filter]); + await waku2.start(); + await waku2.dial(multiAddrWithId); + await waitForRemotePeer(waku2, [Protocols.Filter]); - const peers = (await waku.filter.peers()).map((peer) => peer.id.toString()); + const peers = (await waku2.filter.peers()).map((peer) => + peer.id.toString() + ); + + const nimPeerId = multiAddrWithId.getPeerId(); + + expect(nimPeerId).to.not.be.undefined; + expect(peers.includes(nimPeerId as string)).to.be.true; + }); + + it("Light Node - default protocols", async function () { + this.timeout(20_000); + nwaku = new Nwaku(makeLogFileName(this)); + await nwaku.start({ + filter: true, + lightpush: true, + relay: false, + store: true, + persistMessages: true, + }); + const multiAddrWithId = await nwaku.getMultiaddrWithId(); + + waku2 = await createLightNode({ + staticNoiseKey: NOISE_KEY_1, + }); + await waku2.start(); + await waku2.dial(multiAddrWithId); + await waitForRemotePeer(waku2); + + const filterPeers = (await waku2.filter.peers()).map((peer) => + peer.id.toString() + ); + const storePeers = (await waku2.store.peers()).map((peer) => + peer.id.toString() + ); + const lightPushPeers = (await waku2.lightPush.peers()).map((peer) => + peer.id.toString() + ); + + const nimPeerId = multiAddrWithId.getPeerId(); + + expect(nimPeerId).to.not.be.undefined; + expect(filterPeers.includes(nimPeerId as string)).to.be.true; + expect(storePeers.includes(nimPeerId as string)).to.be.true; + expect(lightPushPeers.includes(nimPeerId as string)).to.be.true; + }); + + it("Privacy Node - default protocol", async function () { + this.timeout(20_000); + nwaku = new Nwaku(makeLogFileName(this)); + await nwaku.start({ + filter: false, + lightpush: false, + relay: true, + store: false, + }); + const multiAddrWithId = await nwaku.getMultiaddrWithId(); + + waku1 = await createPrivacyNode({ + staticNoiseKey: NOISE_KEY_1, + }); + await waku1.start(); + await waku1.dial(multiAddrWithId); + await waitForRemotePeer(waku1); + + const peers = await waku1.relay.getMeshPeers(); const nimPeerId = multiAddrWithId.getPeerId(); diff --git a/src/lib/wait_for_remote_peer.ts b/src/lib/wait_for_remote_peer.ts index 004db2a76c..e68f2d7c86 100644 --- a/src/lib/wait_for_remote_peer.ts +++ b/src/lib/wait_for_remote_peer.ts @@ -36,33 +36,41 @@ interface WakuGossipSubProtocol extends GossipSub { * * @returns A promise that **resolves** if all desired protocols are fulfilled by * remote nodes, **rejects** if the timeoutMs is reached. - * - * @default Remote peer must have Waku Relay enabled and no time out is applied. + * @throws If passing a protocol that is not mounted + * @default Wait for remote peers with protocols enabled locally and no time out is applied. */ export async function waitForRemotePeer( waku: Waku, protocols?: Protocols[], timeoutMs?: number ): Promise { - protocols = protocols ?? [Protocols.Relay]; + protocols = protocols ?? getEnabledProtocols(waku); if (!waku.isStarted()) return Promise.reject("Waku node is not started"); const promises = []; if (protocols.includes(Protocols.Relay)) { + if (!waku.relay) + throw new Error("Cannot wait for Relay peer: protocol not mounted"); promises.push(waitForGossipSubPeerInMesh(waku.relay)); } if (protocols.includes(Protocols.Store)) { + if (!waku.store) + throw new Error("Cannot wait for Store peer: protocol not mounted"); promises.push(waitForConnectedPeer(waku.store, Object.values(StoreCodecs))); } if (protocols.includes(Protocols.LightPush)) { + if (!waku.lightPush) + throw new Error("Cannot wait for LightPush peer: protocol not mounted"); promises.push(waitForConnectedPeer(waku.lightPush, [LightPushCodec])); } if (protocols.includes(Protocols.Filter)) { + if (!waku.filter) + throw new Error("Cannot wait for Filter peer: protocol not mounted"); promises.push(waitForConnectedPeer(waku.filter, [FilterCodec])); } @@ -131,3 +139,25 @@ async function rejectOnTimeout( ): Promise { await Promise.race([promise, awaitTimeout(timeoutMs, rejectReason)]); } + +function getEnabledProtocols(waku: Waku): Protocols[] { + const protocols = []; + + if (waku.relay) { + protocols.push(Protocols.Relay); + } + + if (waku.filter) { + protocols.push(Protocols.Filter); + } + + if (waku.store) { + protocols.push(Protocols.Store); + } + + if (waku.lightPush) { + protocols.push(Protocols.LightPush); + } + + return protocols; +} diff --git a/src/lib/waku.node.spec.ts b/src/lib/waku.node.spec.ts index a0a9c62d8f..9913cfc3fb 100644 --- a/src/lib/waku.node.spec.ts +++ b/src/lib/waku.node.spec.ts @@ -8,9 +8,9 @@ import { Nwaku, } from "../test_utils/"; -import { createWaku } from "./create_waku"; +import { createLightNode, createPrivacyNode } from "./create_waku"; import { generateSymmetricKey } from "./crypto"; -import type { Waku } from "./interfaces"; +import type { Waku, WakuLight, WakuPrivacy } from "./interfaces"; import { PeerDiscoveryStaticPeers } from "./peer_discovery_static_list"; import { waitForRemotePeer } from "./wait_for_remote_peer"; import { Protocols } from "./waku"; @@ -31,15 +31,20 @@ describe("Waku Dial [node only]", function () { it("connects to nwaku", async function () { this.timeout(20_000); nwaku = new Nwaku(makeLogFileName(this)); - await nwaku.start(); + await nwaku.start({ + filter: true, + store: true, + lightpush: true, + persistMessages: true, + }); const multiAddrWithId = await nwaku.getMultiaddrWithId(); - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); await waku.start(); await waku.dial(multiAddrWithId); - await waitForRemotePeer(waku, [Protocols.Relay]); + await waitForRemotePeer(waku); const nimPeerId = await nwaku.getPeerId(); expect(await waku.libp2p.peerStore.has(nimPeerId)).to.be.true; @@ -47,7 +52,7 @@ describe("Waku Dial [node only]", function () { }); describe("Bootstrap", function () { - let waku: Waku; + let waku: WakuLight; let nwaku: Nwaku; afterEach(async function () { @@ -61,7 +66,7 @@ describe("Waku Dial [node only]", function () { nwaku = new Nwaku(makeLogFileName(this)); await nwaku.start(); const multiAddrWithId = await nwaku.getMultiaddrWithId(); - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, libp2p: { peerDiscovery: [new PeerDiscoveryStaticPeers([multiAddrWithId])], @@ -87,7 +92,7 @@ describe("Waku Dial [node only]", function () { nwaku = new Nwaku(makeLogFileName(this)); await nwaku.start(); - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, libp2p: { peerDiscovery: [ @@ -119,15 +124,15 @@ describe("Decryption Keys", () => { } }); - let waku1: Waku; - let waku2: Waku; + let waku1: WakuPrivacy; + let waku2: WakuPrivacy; beforeEach(async function () { this.timeout(5000); [waku1, waku2] = await Promise.all([ - createWaku({ staticNoiseKey: NOISE_KEY_1 }).then((waku) => + createPrivacyNode({ staticNoiseKey: NOISE_KEY_1 }).then((waku) => waku.start().then(() => waku) ), - createWaku({ + createPrivacyNode({ staticNoiseKey: NOISE_KEY_2, libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }, }).then((waku) => waku.start().then(() => waku)), diff --git a/src/lib/waku.ts b/src/lib/waku.ts index b12080cc59..aa65878f16 100644 --- a/src/lib/waku.ts +++ b/src/lib/waku.ts @@ -1,5 +1,6 @@ import type { Stream } from "@libp2p/interface-connection"; import type { PeerId } from "@libp2p/interface-peer-id"; +import type { PubSub } from "@libp2p/interface-pubsub"; import { peerIdFromString } from "@libp2p/peer-id"; import type { Multiaddr } from "@multiformats/multiaddr"; import { multiaddr } from "@multiformats/multiaddr"; @@ -12,6 +13,7 @@ import { LightPushCodec, WakuLightPush } from "./waku_light_push"; import { DecryptionMethod, WakuMessage } from "./waku_message"; import { WakuRelay } from "./waku_relay"; import { RelayCodecs, RelayPingContentTopic } from "./waku_relay/constants"; +import * as relayConstants from "./waku_relay/constants"; import { StoreCodecs, WakuStore } from "./waku_store"; export const DefaultPingKeepAliveValueSecs = 0; @@ -46,10 +48,10 @@ export interface WakuOptions { export class WakuNode implements Waku { public libp2p: Libp2p; - public relay: WakuRelay; - public store: WakuStore; - public filter: WakuFilter; - public lightPush: WakuLightPush; + public relay?: WakuRelay; + public store?: WakuStore; + public filter?: WakuFilter; + public lightPush?: WakuLightPush; private pingKeepAliveTimers: { [peer: string]: ReturnType; @@ -61,22 +63,27 @@ export class WakuNode implements Waku { constructor( options: WakuOptions, libp2p: Libp2p, - store: WakuStore, - lightPush: WakuLightPush, - filter: WakuFilter + store?: WakuStore, + lightPush?: WakuLightPush, + filter?: WakuFilter ) { this.libp2p = libp2p; - this.relay = libp2p.pubsub as unknown as WakuRelay; this.store = store; this.filter = filter; this.lightPush = lightPush; + + if (isWakuRelay(libp2p.pubsub)) { + this.relay = libp2p.pubsub; + } + this.pingKeepAliveTimers = {}; this.relayKeepAliveTimers = {}; const pingKeepAlive = options.pingKeepAlive || DefaultPingKeepAliveValueSecs; - const relayKeepAlive = - options.relayKeepAlive || DefaultRelayKeepAliveValueSecs; + const relayKeepAlive = this.relay + ? options.relayKeepAlive || DefaultRelayKeepAliveValueSecs + : 0; libp2p.connectionManager.addEventListener("peer:connect", (evt) => { this.startKeepAlive(evt.detail.remotePeer, pingKeepAlive, relayKeepAlive); @@ -180,9 +187,9 @@ export class WakuNode implements Waku { key: Uint8Array | string, options?: { method?: DecryptionMethod; contentTopics?: string[] } ): void { - this.relay.addDecryptionKey(key, options); - this.store.addDecryptionKey(key, options); - this.filter.addDecryptionKey(key, options); + if (this.relay) this.relay.addDecryptionKey(key, options); + if (this.store) this.store.addDecryptionKey(key, options); + if (this.filter) this.filter.addDecryptionKey(key, options); } /** @@ -192,9 +199,9 @@ export class WakuNode implements Waku { * Strings must be in hex format. */ deleteDecryptionKey(key: Uint8Array | string): void { - this.relay.deleteDecryptionKey(key); - this.store.deleteDecryptionKey(key); - this.filter.deleteDecryptionKey(key); + if (this.relay) this.relay.deleteDecryptionKey(key); + if (this.store) this.store.deleteDecryptionKey(key); + if (this.filter) this.filter.deleteDecryptionKey(key); } /** @@ -230,11 +237,12 @@ export class WakuNode implements Waku { }, pingPeriodSecs * 1000); } - if (relayPeriodSecs !== 0) { + const relay = this.relay; + if (relay && relayPeriodSecs !== 0) { this.relayKeepAliveTimers[peerIdStr] = setInterval(() => { log("Sending Waku Relay ping message"); WakuMessage.fromBytes(new Uint8Array(), RelayPingContentTopic).then( - (wakuMsg) => this.relay.send(wakuMsg) + (wakuMsg) => relay.send(wakuMsg) ); }, relayPeriodSecs * 1000); } @@ -266,3 +274,16 @@ export class WakuNode implements Waku { this.relayKeepAliveTimers = {}; } } + +function isWakuRelay(pubsub: PubSub): pubsub is WakuRelay { + if (pubsub) { + try { + return pubsub.multicodecs.includes( + relayConstants.RelayCodecs[relayConstants.RelayCodecs.length - 1] + ); + // Exception is expected if `libp2p` was not instantiated with pubsub + // eslint-disable-next-line no-empty + } catch (e) {} + } + return false; +} diff --git a/src/lib/waku_filter/index.node.spec.ts b/src/lib/waku_filter/index.node.spec.ts index bd91ae783f..6c3ca82cda 100644 --- a/src/lib/waku_filter/index.node.spec.ts +++ b/src/lib/waku_filter/index.node.spec.ts @@ -3,8 +3,8 @@ import debug from "debug"; import { makeLogFileName, NOISE_KEY_1, Nwaku } from "../../test_utils"; import { delay } from "../../test_utils/delay"; -import { createWaku } from "../create_waku"; -import type { Waku } from "../interfaces"; +import { createLightNode } from "../create_waku"; +import type { WakuLight } from "../interfaces"; import { waitForRemotePeer } from "../wait_for_remote_peer"; import { Protocols } from "../waku"; import { WakuMessage } from "../waku_message"; @@ -14,7 +14,7 @@ const log = debug("waku:test"); const TestContentTopic = "/test/1/waku-filter"; describe("Waku Filter", () => { - let waku: Waku; + let waku: WakuLight; let nwaku: Nwaku; afterEach(async function () { @@ -26,7 +26,7 @@ describe("Waku Filter", () => { this.timeout(15000); nwaku = new Nwaku(makeLogFileName(this)); await nwaku.start({ filter: true, lightpush: true }); - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }, }); @@ -47,7 +47,7 @@ describe("Waku Filter", () => { expect(msg.payloadAsUtf8).to.eq(messageText); }; await waku.filter.subscribe(callback, [TestContentTopic]); - // As the filter protocol does not cater for a ack of subscription + // As the filter protocol does not cater for an ack of subscription // we cannot know whether the subscription happened. Something we want to // correct in future versions of the protocol. await delay(200); diff --git a/src/lib/waku_light_push/index.node.spec.ts b/src/lib/waku_light_push/index.node.spec.ts index 1f0dbdb7e7..5be99d1d0d 100644 --- a/src/lib/waku_light_push/index.node.spec.ts +++ b/src/lib/waku_light_push/index.node.spec.ts @@ -3,8 +3,8 @@ import debug from "debug"; import { makeLogFileName, NOISE_KEY_1, Nwaku } from "../../test_utils"; import { delay } from "../../test_utils/delay"; -import { createWaku } from "../create_waku"; -import type { Waku } from "../interfaces"; +import { createLightNode } from "../create_waku"; +import type { WakuLight } from "../interfaces"; import { waitForRemotePeer } from "../wait_for_remote_peer"; import { Protocols } from "../waku"; import { WakuMessage } from "../waku_message"; @@ -14,7 +14,7 @@ const log = debug("waku:test:lightpush"); const TestContentTopic = "/test/1/waku-light-push/utf8"; describe("Waku Light Push [node only]", () => { - let waku: Waku; + let waku: WakuLight; let nwaku: Nwaku; afterEach(async function () { @@ -28,7 +28,7 @@ describe("Waku Light Push [node only]", () => { nwaku = new Nwaku(makeLogFileName(this)); await nwaku.start({ lightpush: true }); - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); await waku.start(); @@ -64,7 +64,7 @@ describe("Waku Light Push [node only]", () => { nwaku = new Nwaku(makeLogFileName(this)); await nwaku.start({ lightpush: true, topics: customPubSubTopic }); - waku = await createWaku({ + waku = await createLightNode({ pubSubTopic: customPubSubTopic, staticNoiseKey: NOISE_KEY_1, }); diff --git a/src/lib/waku_message/index.node.spec.ts b/src/lib/waku_message/index.node.spec.ts index 7e7841352e..6fb5f705db 100644 --- a/src/lib/waku_message/index.node.spec.ts +++ b/src/lib/waku_message/index.node.spec.ts @@ -8,13 +8,13 @@ import { WakuRelayMessage, } from "../../test_utils"; import { delay } from "../../test_utils/delay"; -import { createWaku } from "../create_waku"; +import { createPrivacyNode } from "../create_waku"; import { generatePrivateKey, generateSymmetricKey, getPublicKey, } from "../crypto"; -import type { Waku } from "../interfaces"; +import type { WakuPrivacy } from "../interfaces"; import { bytesToHex, bytesToUtf8, hexToBytes, utf8ToBytes } from "../utils"; import { waitForRemotePeer } from "../wait_for_remote_peer"; import { Protocols } from "../waku"; @@ -27,12 +27,12 @@ const TestContentTopic = "/test/1/waku-message/utf8"; describe("Waku Message [node only]", function () { describe("Interop: nwaku", function () { - let waku: Waku; + let waku: WakuPrivacy; let nwaku: Nwaku; beforeEach(async function () { this.timeout(30_000); - waku = await createWaku({ + waku = await createPrivacyNode({ staticNoiseKey: NOISE_KEY_1, }); await waku.start(); diff --git a/src/lib/waku_relay/index.node.spec.ts b/src/lib/waku_relay/index.node.spec.ts index a089792e21..905a7a33c0 100644 --- a/src/lib/waku_relay/index.node.spec.ts +++ b/src/lib/waku_relay/index.node.spec.ts @@ -11,13 +11,13 @@ import { } from "../../test_utils"; import { delay } from "../../test_utils/delay"; import { DefaultPubSubTopic } from "../constants"; -import { createWaku } from "../create_waku"; +import { createPrivacyNode } from "../create_waku"; import { generatePrivateKey, generateSymmetricKey, getPublicKey, } from "../crypto"; -import type { Waku } from "../interfaces"; +import type { WakuPrivacy } from "../interfaces"; import { waitForRemotePeer } from "../wait_for_remote_peer"; import { Protocols } from "../waku"; import { DecryptionMethod, WakuMessage } from "../waku_message"; @@ -36,17 +36,17 @@ describe("Waku Relay [node only]", () => { } }); - let waku1: Waku; - let waku2: Waku; + let waku1: WakuPrivacy; + let waku2: WakuPrivacy; beforeEach(async function () { this.timeout(10000); log("Starting JS Waku instances"); [waku1, waku2] = await Promise.all([ - createWaku({ staticNoiseKey: NOISE_KEY_1 }).then((waku) => + createPrivacyNode({ staticNoiseKey: NOISE_KEY_1 }).then((waku) => waku.start().then(() => waku) ), - createWaku({ + createPrivacyNode({ staticNoiseKey: NOISE_KEY_2, libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }, }).then((waku) => waku.start().then(() => waku)), @@ -259,9 +259,9 @@ describe("Waku Relay [node only]", () => { }); describe("Custom pubsub topic", () => { - let waku1: Waku; - let waku2: Waku; - let waku3: Waku; + let waku1: WakuPrivacy; + let waku2: WakuPrivacy; + let waku3: WakuPrivacy; afterEach(async function () { !!waku1 && waku1.stop().catch((e) => console.log("Waku failed to stop", e)); @@ -279,16 +279,16 @@ describe("Waku Relay [node only]", () => { // 1 and 2 uses a custom pubsub // 3 uses the default pubsub [waku1, waku2, waku3] = await Promise.all([ - createWaku({ + createPrivacyNode({ pubSubTopic: pubSubTopic, staticNoiseKey: NOISE_KEY_1, }).then((waku) => waku.start().then(() => waku)), - createWaku({ + createPrivacyNode({ pubSubTopic: pubSubTopic, staticNoiseKey: NOISE_KEY_2, libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }, }).then((waku) => waku.start().then(() => waku)), - createWaku({ + createPrivacyNode({ staticNoiseKey: NOISE_KEY_3, }).then((waku) => waku.start().then(() => waku)), ]); @@ -338,12 +338,12 @@ describe("Waku Relay [node only]", () => { }); describe("Interop: nwaku", function () { - let waku: Waku; + let waku: WakuPrivacy; let nwaku: Nwaku; beforeEach(async function () { this.timeout(30_000); - waku = await createWaku({ + waku = await createPrivacyNode({ staticNoiseKey: NOISE_KEY_1, }); await waku.start(); @@ -423,8 +423,8 @@ describe("Waku Relay [node only]", () => { }); describe.skip("Two nodes connected to nwaku", function () { - let waku1: Waku; - let waku2: Waku; + let waku1: WakuPrivacy; + let waku2: WakuPrivacy; let nwaku: Nwaku; afterEach(async function () { @@ -438,10 +438,10 @@ describe("Waku Relay [node only]", () => { it("Js publishes, other Js receives", async function () { this.timeout(60_000); [waku1, waku2] = await Promise.all([ - createWaku({ + createPrivacyNode({ staticNoiseKey: NOISE_KEY_1, }).then((waku) => waku.start().then(() => waku)), - createWaku({ + createPrivacyNode({ staticNoiseKey: NOISE_KEY_2, }).then((waku) => waku.start().then(() => waku)), ]); diff --git a/src/lib/waku_relay/index.ts b/src/lib/waku_relay/index.ts index 9be2757349..b53cf9519e 100644 --- a/src/lib/waku_relay/index.ts +++ b/src/lib/waku_relay/index.ts @@ -229,3 +229,5 @@ export class WakuRelay extends GossipSub { return super.getMeshPeers(topic ?? this.pubSubTopic); } } + +WakuRelay.multicodec = constants.RelayCodecs[constants.RelayCodecs.length - 1]; diff --git a/src/lib/waku_store/index.node.spec.ts b/src/lib/waku_store/index.node.spec.ts index a3f17f620b..323dd221ef 100644 --- a/src/lib/waku_store/index.node.spec.ts +++ b/src/lib/waku_store/index.node.spec.ts @@ -7,13 +7,13 @@ import { NOISE_KEY_2, Nwaku, } from "../../test_utils"; -import { createWaku } from "../create_waku"; +import { createLightNode } from "../create_waku"; import { generatePrivateKey, generateSymmetricKey, getPublicKey, } from "../crypto"; -import type { Waku } from "../interfaces"; +import type { WakuLight } from "../interfaces"; import { waitForRemotePeer } from "../wait_for_remote_peer"; import { Protocols } from "../waku"; import { DecryptionMethod, WakuMessage } from "../waku_message"; @@ -25,7 +25,7 @@ const log = debug("waku:test:store"); const TestContentTopic = "/test/1/waku-store/utf8"; describe("Waku Store", () => { - let waku: Waku; + let waku: WakuLight; let nwaku: Nwaku; afterEach(async function () { @@ -49,7 +49,7 @@ describe("Waku Store", () => { ).to.be.true; } - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); await waku.start(); @@ -82,7 +82,7 @@ describe("Waku Store", () => { ).to.be.true; } - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); await waku.start(); @@ -122,7 +122,7 @@ describe("Waku Store", () => { ).to.be.true; } - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); await waku.start(); @@ -159,7 +159,7 @@ describe("Waku Store", () => { ).to.be.true; } - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); await waku.start(); @@ -202,7 +202,7 @@ describe("Waku Store", () => { ).to.be.true; } - waku = await createWaku({ + waku = await createLightNode({ pubSubTopic: customPubSubTopic, staticNoiseKey: NOISE_KEY_1, }); @@ -269,10 +269,10 @@ describe("Waku Store", () => { log("Messages have been encrypted"); const [waku1, waku2, nimWakuMultiaddr] = await Promise.all([ - createWaku({ + createLightNode({ staticNoiseKey: NOISE_KEY_1, }).then((waku) => waku.start().then(() => waku)), - createWaku({ + createLightNode({ staticNoiseKey: NOISE_KEY_2, }).then((waku) => waku.start().then(() => waku)), nwaku.getMultiaddrWithId(), @@ -371,10 +371,10 @@ describe("Waku Store", () => { log("Messages have been encrypted"); const [waku1, waku2, nimWakuMultiaddr] = await Promise.all([ - createWaku({ + createLightNode({ staticNoiseKey: NOISE_KEY_1, }).then((waku) => waku.start().then(() => waku)), - createWaku({ + createLightNode({ staticNoiseKey: NOISE_KEY_2, }).then((waku) => waku.start().then(() => waku)), nwaku.getMultiaddrWithId(), @@ -458,7 +458,7 @@ describe("Waku Store", () => { ).to.be.true; } - waku = await createWaku({ + waku = await createLightNode({ staticNoiseKey: NOISE_KEY_1, }); await waku.start();