feat: replace `waitForRemotePeers()` with `waku.waitForPeer()` method (#2161)

* fix comment of default number of peers

* export default number of peers from base protocol sdk

* rename to light_push, move class to separate file

* move waitForRemotePeer to sdk package

* add todo to move waitForGossipSubPeerInMesh into @waku/relay

* clean up waitForRemotePeer, split metadata await from event and optimise, decouple from protocol implementations

* simplify and rename ILightPush interface

* use only connected peers in light push based on connections instead of peer renewal mechanism

* improve readability of result processing in light push

* fix check & update tests

* address tests, add new test cases, fix racing condition in StreamManager

* use libp2p.getPeers

* feat: confirm metadata and protocols needed in waitForRemotePeer

* rely on passed protocols and fallback to mounted

* add I prefix to Waku interface

* implement waku.connect method

* add docs to IWaku interface

* remove export and usage of waitForRemotePeer

* move wait for remote peer related to Realy out of @waku/sdk

* change tests to use new API

* fix linting

* update size limit

* rename .connect to .waitForPeer

* export waitForRemotePeer and mark as deprecated

* feat: add mocha tests to @waku/sdk and cover waitForRemotePeer (#2163)

* feat: add mocha tests to @waku/sdk and cover waitForRemotePeer

* add waitForRemote UTs

* remove junk

* feat: expose peerId and protocols from WakuNode (#2166)

* chore: expose peerId and protocols from WakuNode

* remove unused method

* move to private method

* rename to waitForPeers

* up test
This commit is contained in:
Sasha 2024-10-09 00:43:34 +02:00 committed by GitHub
parent d37e0245cf
commit 75fcca4cd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 713 additions and 193 deletions

View File

@ -9,7 +9,7 @@ module.exports = [
path: ["packages/sdk/bundle/index.js", "packages/core/bundle/index.js"],
import: {
"packages/sdk/bundle/index.js":
"{ createLightNode, waitForRemotePeer, createEncoder, createDecoder, bytesToUtf8, utf8ToBytes, Decoder, Encoder, DecodedMessage, WakuNode }",
"{ createLightNode, createEncoder, createDecoder, bytesToUtf8, utf8ToBytes, Decoder, Encoder, DecodedMessage, WakuNode }",
},
},
{

13
package-lock.json generated
View File

@ -39370,7 +39370,8 @@
"@waku/utils": "0.0.20",
"chai": "^4.3.10",
"debug": "^4.3.4",
"fast-check": "^3.19.0"
"fast-check": "^3.19.0",
"p-event": "^6.0.1"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.7",
@ -39409,19 +39410,23 @@
"@waku/message-hash": "0.1.16",
"@waku/proto": "^0.0.8",
"@waku/utils": "0.0.20",
"libp2p": "^1.8.1",
"p-event": "^6.0.1"
"libp2p": "^1.8.1"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5",
"@types/chai": "^4.3.11",
"@types/mocha": "^10.0.6",
"@waku/build-utils": "*",
"chai": "^4.3.10",
"cspell": "^8.6.1",
"interface-datastore": "^8.2.10",
"mocha": "^10.3.0",
"npm-run-all": "^4.1.5",
"rollup": "^4.12.0"
"rollup": "^4.12.0",
"sinon": "^18.0.0"
},
"engines": {
"node": ">=20"

View File

@ -16,6 +16,7 @@ export interface IRelayAPI {
readonly pubsubTopics: Set<PubsubTopic>;
readonly gossipSub: GossipSub;
start: () => Promise<void>;
waitForPeers: () => Promise<void>;
getMeshPeers: (topic?: TopicStr) => PeerIdStr[];
}

View File

@ -10,36 +10,127 @@ import { Protocols } from "./protocols.js";
import type { IRelay } from "./relay.js";
import type { IStore } from "./store.js";
export interface Waku {
export interface IWaku {
libp2p: Libp2p;
relay?: IRelay;
store?: IStore;
filter?: IFilter;
lightPush?: ILightPush;
health: IHealthManager;
connectionManager: IConnectionManager;
/**
* Returns a unique identifier for a node on the network.
*
* @example
* ```typescript
* console.log(waku.peerId); // 12D3KooWNmk9yXHfHJ4rUduRqD1TCTHkNFMPF9WP2dqWpZDL4aUb
* ```
*/
peerId: PeerId;
/**
* Returns a list of supported protocols.
*
* @example
* ```typescript
* console.log(waku.protocols); // ['/ipfs/id/1.0.0', '/ipfs/ping/1.0.0', '/vac/waku/filter-push/2.0.0-beta1', '/vac/waku/metadata/1.0.0']
* ```
*/
protocols: string[];
/**
* Dials to the provided peer
*
* @param {PeerId | MultiaddrInput} peer information to use for dialing
* @param {Protocols[]} [protocols] array of Waku protocols to be used for dialing. If no provided - will be derived from mounted protocols.
*
* @returns {Promise<Stream>} `Promise` that will resolve to a `Stream` to a dialed peer
*
* @example
* ```typescript
* await waku.dial(remotePeerId, [Protocols.LightPush]);
*
* waku.isConnected() === true;
* ```
*/
dial(peer: PeerId | MultiaddrInput, protocols?: Protocols[]): Promise<Stream>;
/**
* Starts all services and components related to functionality of Waku node.
*
* @returns {Promise<boolean>} `Promise` that will resolve when started.
*
* @example
* ```typescript
* await waku.start();
*
* waku.isStarted() === true;
* ```
*/
start(): Promise<void>;
/**
* Stops all recurring processes and services that are needed for functionality of Waku node.
*
* @returns {Promise<boolean>} `Promise` that resolves when stopped.
*
* @example
* ```typescript
* await waku.stop();
*
* waku.isStarted === false;
* ```
*/
stop(): Promise<void>;
/**
* Resolves when Waku successfully gains connection to a remote peers that fits provided requirements.
* Must be used after attempting to connect to nodes, using {@link IWaku.dial} or
* if was bootstrapped by using {@link IPeerExchange} or {@link DnsDiscoveryComponents}.
*
* @param {Protocols[]} [protocols] Protocols that need to be enabled by remote peers
* @param {number} [timeoutMs] Timeout value in milliseconds after which promise rejects
*
* @returns {Promise<void>} `Promise` that **resolves** if all desired protocols are fulfilled by
* at least one remote peer, **rejects** if the timeoutMs is reached
* @throws If passing a protocol that is not mounted or Waku node is not started
*
* @example
* ```typescript
* try {
* // let's wait for at least one LightPush node and timeout in 1 second
* await waku.waitForPeers([Protocols.LightPush], 1000);
* } catch(e) {
* waku.isConnected() === false;
* console.error("Failed to connect due to", e);
* }
*
* waku.isConnected() === true;
* ```
*/
waitForPeers(protocols?: Protocols[], timeoutMs?: number): Promise<void>;
/**
* @returns {boolean} `true` if the node was started and `false` otherwise
*/
isStarted(): boolean;
/**
* @returns {boolean} `true` if the node has working connection and `false` otherwise
*/
isConnected(): boolean;
health: IHealthManager;
}
export interface LightNode extends Waku {
export interface LightNode extends IWaku {
relay: undefined;
store: IStore;
filter: IFilter;
lightPush: ILightPush;
}
export interface RelayNode extends Waku {
export interface RelayNode extends IWaku {
relay: IRelay;
store: undefined;
filter: undefined;

View File

@ -58,7 +58,8 @@
"@waku/utils": "0.0.20",
"chai": "^4.3.10",
"debug": "^4.3.4",
"fast-check": "^3.19.0"
"fast-check": "^3.19.0",
"p-event": "^6.0.1"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.7",

View File

@ -26,6 +26,7 @@ import {
import { isWireSizeUnderCap, toAsyncIterator } from "@waku/utils";
import { pushOrInitMapSet } from "@waku/utils";
import { Logger } from "@waku/utils";
import { pEvent } from "p-event";
import { RelayCodecs } from "./constants.js";
import { messageValidator } from "./message_validator.js";
@ -94,6 +95,22 @@ class Relay implements IRelay {
this.subscribeToAllTopics();
}
/**
* Wait for at least one peer with the given protocol to be connected and in the gossipsub
* mesh for all pubsubTopics.
*/
public async waitForPeers(): Promise<void> {
let peers = this.getMeshPeers();
const pubsubTopics = this.pubsubTopics;
for (const topic of pubsubTopics) {
while (peers.length == 0) {
await pEvent(this.gossipSub, "gossipsub:heartbeat");
peers = this.getMeshPeers(topic);
}
}
}
/**
* Send Waku message.
*/

View File

@ -0,0 +1,6 @@
{
"reporterEnabled": "spec, allure-mocha",
"allureMochaReporter": {
"outputDir": "allure-results"
}
}

26
packages/sdk/.mocharc.cjs Normal file
View File

@ -0,0 +1,26 @@
const config = {
extension: ['ts'],
spec: 'src/**/*.spec.ts',
require: ['ts-node/register', 'isomorphic-fetch'],
loader: 'ts-node/esm',
nodeOptions: [
'experimental-specifier-resolution=node',
'loader=ts-node/esm'
],
exit: true
};
if (process.env.CI) {
console.log("Running tests in parallel");
config.parallel = true;
config.jobs = 6;
console.log("Activating allure reporting");
config.reporter = 'mocha-multi-reporters';
config.reporterOptions = {
configFile: '.mocha.reporters.json'
};
} else {
console.log("Running tests serially. To enable parallel execution update mocha config");
}
module.exports = config;

View File

@ -50,6 +50,9 @@
"check:lint": "eslint src *.js",
"check:spelling": "cspell \"{README.md,src/**/*.ts}\"",
"check:tsc": "tsc -p tsconfig.dev.json",
"test": "NODE_ENV=test run-s test:*",
"test:node": "NODE_ENV=test TS_NODE_PROJECT=./tsconfig.dev.json mocha",
"watch:test": "mocha --watch",
"prepublish": "npm run build",
"reset-hard": "git clean -dfx -e .idea && git reset --hard && npm i && npm run build"
},
@ -70,15 +73,19 @@
"@waku/proto": "^0.0.8",
"@waku/utils": "0.0.20",
"@waku/message-hash": "0.1.16",
"libp2p": "^1.8.1",
"p-event": "^6.0.1"
"libp2p": "^1.8.1"
},
"devDependencies": {
"@types/mocha": "^10.0.6",
"@types/chai": "^4.3.11",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5",
"@waku/build-utils": "*",
"mocha": "^10.3.0",
"sinon": "^18.0.0",
"chai": "^4.3.10",
"cspell": "^8.6.1",
"interface-datastore": "^8.2.10",
"npm-run-all": "^4.1.5",

View File

@ -1,6 +1,6 @@
import { type LightNode } from "@waku/interfaces";
import { CreateWakuNodeOptions, WakuNode } from "../waku.js";
import { CreateWakuNodeOptions, WakuNode } from "../waku/index.js";
import { createLibp2pAndUpdateOptions } from "./libp2p.js";

View File

@ -21,7 +21,7 @@ import {
CreateWakuNodeOptions,
DefaultPingMaxInboundStreams,
DefaultUserAgent
} from "../waku.js";
} from "../waku/index.js";
import { defaultPeerDiscoveries } from "./discovery.js";

View File

@ -7,7 +7,7 @@ export {
export { utf8ToBytes, bytesToUtf8 } from "@waku/utils/bytes";
export * from "./waku.js";
export * from "./waku/index.js";
export {
createLightNode,
@ -18,8 +18,6 @@ export { wakuLightPush } from "./protocols/light_push/index.js";
export { wakuFilter } from "./protocols/filter/index.js";
export { wakuStore } from "./protocols/store/index.js";
export { waitForRemotePeer } from "./wait_for_remote_peer.js";
export * as waku from "@waku/core";
export * as utils from "@waku/utils";
export * from "@waku/interfaces";

View File

@ -0,0 +1,2 @@
export * from "./waku.js";
export { waitForRemotePeer } from "./wait_for_remote_peer.js";

View File

@ -0,0 +1,399 @@
import type { Connection, Peer, PeerStore } from "@libp2p/interface";
import { FilterCodecs, LightPushCodec, StoreCodec } from "@waku/core";
import { IRelay, Protocols } from "@waku/interfaces";
import { expect } from "chai";
import sinon from "sinon";
import { waitForRemotePeer } from "./wait_for_remote_peer.js";
import { WakuNode } from "./waku.js";
describe("waitForRemotePeer", () => {
let eventTarget = new EventTarget();
beforeEach(() => {
eventTarget = new EventTarget();
});
it("should reject if WakuNode is not started", async () => {
const wakuMock = mockWakuNode({
connections: [{}]
});
let err: Error | undefined = undefined;
try {
await waitForRemotePeer(wakuMock);
} catch (e) {
err = e as Error;
}
expect(err).not.to.be.undefined;
expect(err!.message).to.be.eq("Waku node is not started");
});
it("should reject if Relay is requested but not mounted", async () => {
const wakuMock = mockWakuNode({ isStarted: true });
wakuMock.relay = undefined;
let err: Error | undefined = undefined;
try {
await waitForRemotePeer(wakuMock, [Protocols.Relay]);
} catch (e) {
err = e as Error;
}
expect(err).not.to.be.undefined;
expect(err!.message).to.be.eq(
"Cannot wait for Relay peer: protocol not mounted"
);
});
it("should reject if LightPush is requested but not mounted", async () => {
const wakuMock = mockWakuNode({ isStarted: true });
wakuMock.lightPush = undefined;
let err: Error | undefined = undefined;
try {
await waitForRemotePeer(wakuMock, [Protocols.LightPush]);
} catch (e) {
err = e as Error;
}
expect(err).not.to.be.undefined;
expect(err!.message).to.be.eq(
"Cannot wait for LightPush peer: protocol not mounted"
);
});
it("should reject if Store is requested but not mounted", async () => {
const wakuMock = mockWakuNode({ isStarted: true });
wakuMock.store = undefined;
let err: Error | undefined = undefined;
try {
await waitForRemotePeer(wakuMock, [Protocols.Store]);
} catch (e) {
err = e as Error;
}
expect(err).not.to.be.undefined;
expect(err!.message).to.be.eq(
"Cannot wait for Store peer: protocol not mounted"
);
});
it("should reject if Filter is requested but not mounted", async () => {
const wakuMock = mockWakuNode({ isStarted: true });
wakuMock.filter = undefined;
let err: Error | undefined = undefined;
try {
await waitForRemotePeer(wakuMock, [Protocols.Filter]);
} catch (e) {
err = e as Error;
}
expect(err).not.to.be.undefined;
expect(err!.message).to.be.eq(
"Cannot wait for Filter peer: protocol not mounted"
);
});
it("should reject on timeout if it was set", async () => {
const addEventListenerSpy = sinon.spy(eventTarget.addEventListener);
eventTarget.addEventListener = addEventListenerSpy;
const wakuMock = mockWakuNode({ isStarted: true, eventTarget });
// let's wait for LightPush in that test
wakuMock.lightPush = {} as any;
let err: Error | undefined = undefined;
try {
await waitForRemotePeer(wakuMock, [Protocols.LightPush], 10);
} catch (e) {
err = e as Error;
}
expect(addEventListenerSpy.calledOnceWith("peer:identify")).to.be.true;
expect(err).not.to.be.undefined;
expect(err!.message).to.be.eq("Timed out waiting for a remote peer.");
});
it("should check connected peers if present and suitable", async () => {
const addEventListenerSpy = sinon.spy(eventTarget.addEventListener);
eventTarget.addEventListener = addEventListenerSpy;
const wakuNode = mockWakuNode({
isStarted: true,
eventTarget,
connections: [{}],
peers: [
mockPeer("1", []),
mockPeer("1.1", ["random"]),
mockPeer("2", ["random", LightPushCodec])
],
metadataService: mockMetadataService("resolve")
});
let err: Error | undefined;
try {
await waitForRemotePeer(wakuNode, [Protocols.LightPush]);
} catch (e) {
err = e as Error;
}
expect(err).to.be.undefined;
expect(addEventListenerSpy.notCalled).to.be.true;
});
it("should wait for LightPush peer to be connected", async () => {
const addEventListenerSpy = sinon.spy(
(_type: string, _cb: (e: any) => void) => {
_cb({ detail: { protocols: [LightPushCodec] } });
}
);
eventTarget.addEventListener = addEventListenerSpy;
// check without metadata service
let wakuNode = mockWakuNode({
isStarted: true,
eventTarget,
connections: [{}],
peers: [
mockPeer("1", []),
mockPeer("1.1", ["random"]),
mockPeer("2", ["random"])
]
});
let err: Error | undefined;
try {
await waitForRemotePeer(wakuNode, [Protocols.LightPush]);
} catch (e) {
err = e as Error;
}
expect(addEventListenerSpy.calledOnceWith("peer:identify")).to.be.true;
expect(err).to.be.undefined;
// check with metadata serivice
wakuNode = mockWakuNode({
isStarted: true,
eventTarget,
connections: [{}],
peers: [
mockPeer("1", []),
mockPeer("1.1", ["random"]),
mockPeer("2", ["random"])
],
metadataService: mockMetadataService("resolve")
});
try {
await waitForRemotePeer(wakuNode, [Protocols.LightPush]);
} catch (e) {
err = e as Error;
}
expect(addEventListenerSpy.calledTwice).to.be.true;
expect(addEventListenerSpy.lastCall.calledWith("peer:identify")).to.be.true;
expect(err).to.be.undefined;
});
it("should wait for Filter peer to be connected", async () => {
const addEventListenerSpy = sinon.spy(
(_type: string, _cb: (e: any) => void) => {
_cb({ detail: { protocols: [FilterCodecs.SUBSCRIBE] } });
}
);
eventTarget.addEventListener = addEventListenerSpy;
// check without metadata service
let wakuNode = mockWakuNode({
isStarted: true,
eventTarget,
connections: [{}],
peers: [
mockPeer("1", []),
mockPeer("1.1", ["random"]),
mockPeer("2", ["random"])
]
});
let err: Error | undefined;
try {
await waitForRemotePeer(wakuNode, [Protocols.Filter]);
} catch (e) {
err = e as Error;
}
expect(addEventListenerSpy.calledOnceWith("peer:identify")).to.be.true;
expect(err).to.be.undefined;
// check with metadata serivice
wakuNode = mockWakuNode({
isStarted: true,
eventTarget,
connections: [{}],
peers: [
mockPeer("1", []),
mockPeer("1.1", ["random"]),
mockPeer("2", ["random"])
],
metadataService: mockMetadataService("resolve")
});
try {
await waitForRemotePeer(wakuNode, [Protocols.Filter]);
} catch (e) {
err = e as Error;
}
expect(addEventListenerSpy.calledTwice).to.be.true;
expect(addEventListenerSpy.lastCall.calledWith("peer:identify")).to.be.true;
expect(err).to.be.undefined;
});
it("should wait for Store peer to be connected", async () => {
const addEventListenerSpy = sinon.spy(
(_type: string, _cb: (e: any) => void) => {
_cb({ detail: { protocols: [StoreCodec] } });
}
);
eventTarget.addEventListener = addEventListenerSpy;
// check without metadata service
let wakuNode = mockWakuNode({
isStarted: true,
eventTarget,
connections: [{}],
peers: [
mockPeer("1", []),
mockPeer("1.1", ["random"]),
mockPeer("2", ["random"])
]
});
let err: Error | undefined;
try {
await waitForRemotePeer(wakuNode, [Protocols.Store]);
} catch (e) {
err = e as Error;
}
expect(addEventListenerSpy.calledOnceWith("peer:identify")).to.be.true;
expect(err).to.be.undefined;
// check with metadata serivice
wakuNode = mockWakuNode({
isStarted: true,
eventTarget,
connections: [{}],
peers: [
mockPeer("1", []),
mockPeer("1.1", ["random"]),
mockPeer("2", ["random"])
],
metadataService: mockMetadataService("resolve")
});
try {
await waitForRemotePeer(wakuNode, [Protocols.Store]);
} catch (e) {
err = e as Error;
}
expect(addEventListenerSpy.calledTwice).to.be.true;
expect(addEventListenerSpy.lastCall.calledWith("peer:identify")).to.be.true;
expect(err).to.be.undefined;
});
it("should call waitForPeer on Relay", async () => {
const waitForRelaySpy = sinon.spy();
const wakuNode = mockWakuNode({
isStarted: true,
eventTarget,
connections: [{}],
peers: [
mockPeer("1", []),
mockPeer("1.1", ["random"]),
mockPeer("2", ["random"])
]
});
wakuNode.relay = { waitForPeers: waitForRelaySpy } as unknown as IRelay;
let err: Error | undefined;
try {
await waitForRemotePeer(wakuNode, [Protocols.Relay]);
} catch (e) {
err = e as Error;
}
expect(waitForRelaySpy.calledOnceWith()).to.be.true;
expect(err).to.be.undefined;
});
});
type MockWakuOptions = {
isStarted?: boolean;
connections?: any[];
peers?: Peer[];
metadataService?: any;
eventTarget?: EventTarget;
};
function mockWakuNode(options: MockWakuOptions = {}): WakuNode {
return {
filter: {},
lightPush: {},
relay: {},
store: {},
libp2p: {
peerStore: mockPeerStore(options?.peers || []),
services: {
metadata: options.metadataService
},
addEventListener: options?.eventTarget
? options.eventTarget.addEventListener.bind(options.eventTarget)
: undefined,
removeEventListener: options?.eventTarget
? options.eventTarget.removeEventListener.bind(options.eventTarget)
: undefined,
getConnections() {
return (options.connections || []) as Connection[];
},
getPeers() {
return (options?.peers || []).map((p) => p.id);
}
},
isStarted() {
return options?.isStarted || false;
}
} as WakuNode;
}
function mockMetadataService(mode: "resolve" | "reject"): any {
return {
confirmOrAttemptHandshake: () => {
return Promise.resolve(
mode === "resolve" ? { error: null } : { error: {} }
);
}
};
}
function mockPeerStore(peers: any[]): PeerStore {
return {
get(peerId) {
return Promise.resolve(peers.find((p) => p.id === peerId));
}
} as PeerStore;
}
function mockPeer(id: string, protocols: string[]): Peer {
return {
id,
protocols
} as unknown as Peer;
}

View File

@ -1,13 +1,14 @@
import type { IdentifyResult } from "@libp2p/interface";
import { FilterCodecs, LightPushCodec, StoreCodec } from "@waku/core";
import type { IRelay, Libp2p, Waku } from "@waku/interfaces";
import type { IWaku, Libp2p } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import { Logger } from "@waku/utils";
import { pEvent } from "p-event";
const log = new Logger("wait-for-remote-peer");
/**
* @deprecated Since @waku/sdk 0.29.0. Will be removed from 0.31.0
*
* Wait for a remote peer to be ready given the passed protocols.
* Must be used after attempting to connect to nodes, using
* {@link @waku/sdk!WakuNode.dial} or a bootstrap method with
@ -27,7 +28,7 @@ const log = new Logger("wait-for-remote-peer");
* @default Wait for remote peers with protocols enabled locally and no time out is applied.
*/
export async function waitForRemotePeer(
waku: Waku,
waku: IWaku,
protocols?: Protocols[],
timeoutMs?: number
): Promise<void> {
@ -41,6 +42,7 @@ export async function waitForRemotePeer(
if (connections.length > 0 && !protocols.includes(Protocols.Relay)) {
const success = await waitForMetadata(waku, protocols);
if (success) {
return;
}
@ -52,7 +54,7 @@ export async function waitForRemotePeer(
if (!waku.relay) {
throw Error("Cannot wait for Relay peer: protocol not mounted");
}
promises.push(waitForGossipSubPeerInMesh(waku.relay));
promises.push(waku.relay.waitForPeers());
}
if (protocols.includes(Protocols.Store)) {
@ -136,7 +138,7 @@ async function waitForConnectedPeer(
* Waits for the metadata from the remote peer.
*/
async function waitForMetadata(
waku: Waku,
waku: IWaku,
protocols: Protocols[]
): Promise<boolean> {
const connectedPeers = waku.libp2p.getPeers();
@ -189,25 +191,10 @@ async function waitForMetadata(
return false;
}
// TODO: move to @waku/relay and use in `node.connect()` API https://github.com/waku-org/js-waku/issues/1761
/**
* Wait for at least one peer with the given protocol to be connected and in the gossipsub
* mesh for all pubsubTopics.
*/
async function waitForGossipSubPeerInMesh(waku: IRelay): Promise<void> {
let peers = waku.getMeshPeers();
const pubsubTopics = waku.pubsubTopics;
for (const topic of pubsubTopics) {
while (peers.length == 0) {
await pEvent(waku.gossipSub, "gossipsub:heartbeat");
peers = waku.getMeshPeers(topic);
}
}
}
const awaitTimeout = (ms: number, rejectReason: string): Promise<void> =>
new Promise((_resolve, reject) => setTimeout(() => reject(rejectReason), ms));
new Promise((_resolve, reject) =>
setTimeout(() => reject(Error(rejectReason)), ms)
);
async function rejectOnTimeout<T>(
promise: Promise<T>,
@ -217,7 +204,7 @@ async function rejectOnTimeout<T>(
await Promise.race([promise, awaitTimeout(timeoutMs, rejectReason)]);
}
function getEnabledProtocols(waku: Waku): Protocols[] {
function getEnabledProtocols(waku: IWaku): Protocols[] {
const protocols = [];
if (waku.relay) {

View File

@ -8,18 +8,20 @@ import type {
ILightPush,
IRelay,
IStore,
IWaku,
Libp2p,
ProtocolCreateOptions,
PubsubTopic,
Waku
PubsubTopic
} from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import { Logger } from "@waku/utils";
import { wakuFilter } from "./protocols/filter/index.js";
import { wakuLightPush } from "./protocols/light_push/index.js";
import { wakuStore } from "./protocols/store/index.js";
import { ReliabilityMonitorManager } from "./reliability_monitor/index.js";
import { wakuFilter } from "../protocols/filter/index.js";
import { wakuLightPush } from "../protocols/light_push/index.js";
import { wakuStore } from "../protocols/store/index.js";
import { ReliabilityMonitorManager } from "../reliability_monitor/index.js";
import { waitForRemotePeer } from "./wait_for_remote_peer.js";
export const DefaultPingKeepAliveValueSecs = 5 * 60;
export const DefaultRelayKeepAliveValueSecs = 5 * 60;
@ -59,7 +61,7 @@ type ProtocolsEnabled = {
store?: boolean;
};
export class WakuNode implements Waku {
export class WakuNode implements IWaku {
public libp2p: Libp2p;
public relay?: IRelay;
public store?: IStore;
@ -126,18 +128,20 @@ export class WakuNode implements Waku {
);
}
/**
* Dials to the provided peer.
*
* @param peer The peer to dial
* @param protocols Waku protocols we expect from the peer; Defaults to mounted protocols
*/
public get peerId(): PeerId {
return this.libp2p.peerId;
}
public get protocols(): string[] {
return this.libp2p.getProtocols();
}
public async dial(
peer: PeerId | MultiaddrInput,
protocols?: Protocols[]
): Promise<Stream> {
const _protocols = protocols ?? [];
const peerId = mapToPeerIdOrMultiaddr(peer);
const peerId = this.mapToPeerIdOrMultiaddr(peer);
if (typeof protocols === "undefined") {
this.relay && _protocols.push(Protocols.Relay);
@ -201,6 +205,13 @@ export class WakuNode implements Waku {
await this.libp2p.stop();
}
public async waitForPeers(
protocols?: Protocols[],
timeoutMs?: number
): Promise<void> {
return waitForRemotePeer(this, protocols, timeoutMs);
}
public isStarted(): boolean {
return this.libp2p.status == "started";
}
@ -209,23 +220,9 @@ export class WakuNode implements Waku {
return this.connectionManager.isConnected();
}
/**
* Return the local multiaddr with peer id on which libp2p is listening.
*
* @throws if libp2p is not listening on localhost.
*/
public getLocalMultiaddrWithID(): string {
const localMultiaddr = this.libp2p
.getMultiaddrs()
.find((addr) => addr.toString().match(/127\.0\.0\.1/));
if (!localMultiaddr || localMultiaddr.toString() === "") {
throw "Not listening on localhost";
}
return localMultiaddr + "/p2p/" + this.libp2p.peerId.toString();
private mapToPeerIdOrMultiaddr(
peerId: PeerId | MultiaddrInput
): PeerId | Multiaddr {
return isPeerId(peerId) ? peerId : multiaddr(peerId);
}
}
function mapToPeerIdOrMultiaddr(
peerId: PeerId | MultiaddrInput
): PeerId | Multiaddr {
return isPeerId(peerId) ? peerId : multiaddr(peerId);
}

View File

@ -4,7 +4,7 @@ import {
Protocols
} from "@waku/interfaces";
import { createRelayNode } from "@waku/relay";
import { createLightNode, waitForRemotePeer, WakuNode } from "@waku/sdk";
import { createLightNode, WakuNode } from "@waku/sdk";
import {
derivePubsubTopicsFromNetworkConfig,
Logger,
@ -63,7 +63,7 @@ export async function runNodes<T>(
if (waku) {
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, protocols);
await waku.waitForPeers(protocols);
await nwaku.ensureSubscriptions(pubsubTopics);
return [nwaku, waku as T];
} else {

View File

@ -1,12 +1,12 @@
import {
DefaultNetworkConfig,
IWaku,
LightNode,
NetworkConfig,
ProtocolCreateOptions,
Protocols,
Waku
Protocols
} from "@waku/interfaces";
import { createLightNode, waitForRemotePeer } from "@waku/sdk";
import { createLightNode } from "@waku/sdk";
import { derivePubsubTopicsFromNetworkConfig } from "@waku/utils";
import { Context } from "mocha";
import pRetry from "p-retry";
@ -52,7 +52,7 @@ export async function runMultipleNodes(
for (const node of serviceNodes.nodes) {
await waku.dial(await node.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
await node.ensureSubscriptions(
derivePubsubTopicsFromNetworkConfig(networkConfig)
);
@ -73,7 +73,7 @@ export async function runMultipleNodes(
export async function teardownNodesWithRedundancy(
serviceNodes: ServiceNodesFleet,
wakuNodes: Waku | Waku[]
wakuNodes: IWaku | IWaku[]
): Promise<void> {
const wNodes = Array.isArray(wakuNodes) ? wakuNodes : [wakuNodes];

View File

@ -1,4 +1,4 @@
import { Waku } from "@waku/interfaces";
import { IWaku } from "@waku/interfaces";
import { Logger } from "@waku/utils";
import pRetry from "p-retry";
@ -8,7 +8,7 @@ const log = new Logger("test:teardown");
export async function tearDownNodes(
nwakuNodes: ServiceNode | ServiceNode[],
wakuNodes: Waku | Waku[]
wakuNodes: IWaku | IWaku[]
): Promise<void> {
const nNodes = Array.isArray(nwakuNodes) ? nwakuNodes : [nwakuNodes];
const wNodes = Array.isArray(wakuNodes) ? wakuNodes : [wakuNodes];

View File

@ -2,7 +2,6 @@ import { EnrDecoder } from "@waku/enr";
import type { RelayNode } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import { createRelayNode } from "@waku/relay";
import { waitForRemotePeer } from "@waku/sdk";
import { expect } from "chai";
import {
@ -41,7 +40,7 @@ describe("ENR Interop: ServiceNode", function () {
});
await waku.start();
await waku.dial(multiAddrWithId);
await waitForRemotePeer(waku, [Protocols.Relay]);
await waku.waitForPeers([Protocols.Relay]);
const nwakuInfo = await nwaku.info();
const nimPeerId = await nwaku.getPeerId();
@ -75,7 +74,7 @@ describe("ENR Interop: ServiceNode", function () {
});
await waku.start();
await waku.dial(multiAddrWithId);
await waitForRemotePeer(waku, [Protocols.Relay]);
await waku.waitForPeers([Protocols.Relay]);
const nwakuInfo = await nwaku.info();
const nimPeerId = await nwaku.getPeerId();
@ -110,7 +109,7 @@ describe("ENR Interop: ServiceNode", function () {
});
await waku.start();
await waku.dial(multiAddrWithId);
await waitForRemotePeer(waku, [Protocols.Relay]);
await waku.waitForPeers([Protocols.Relay]);
const nwakuInfo = await nwaku.info();
const nimPeerId = await nwaku.getPeerId();

View File

@ -14,7 +14,7 @@ import {
createDecoder as createSymDecoder,
createEncoder as createSymEncoder
} from "@waku/message-encryption/symmetric";
import { createLightNode, waitForRemotePeer } from "@waku/sdk";
import { createLightNode } from "@waku/sdk";
import { contentTopicToPubsubTopic, Logger } from "@waku/utils";
import { bytesToUtf8, utf8ToBytes } from "@waku/utils/bytes";
import { expect } from "chai";
@ -110,7 +110,7 @@ describe("Waku Message Ephemeral field", function () {
await waku.start();
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
});
it("Ephemeral messages are not stored", async function () {
@ -157,7 +157,7 @@ describe("Waku Message Ephemeral field", function () {
log.info("Waku nodes connected to nwaku");
await waitForRemotePeer(waku1, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
log.info("Sending messages using light push");
await Promise.all([
@ -166,7 +166,7 @@ describe("Waku Message Ephemeral field", function () {
waku1.lightPush.send(ClearEncoder, clearMsg)
]);
await waitForRemotePeer(waku2, [Protocols.Store]);
await waku2.waitForPeers([Protocols.Store]);
const messages: DecodedMessage[] = [];

View File

@ -1,5 +1,5 @@
import { LightNode, Protocols } from "@waku/interfaces";
import { utf8ToBytes, waitForRemotePeer } from "@waku/sdk";
import { utf8ToBytes } from "@waku/sdk";
import { expect } from "chai";
import {
@ -236,7 +236,7 @@ const runTests = (strictCheckNodes: boolean): void => {
// Redo the connection and create a new subscription
for (const node of this.serviceNodes) {
await waku.dial(await node.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
}
await waku.filter.subscribe(
@ -276,7 +276,7 @@ const runTests = (strictCheckNodes: boolean): void => {
// Restart nwaku node
await teardownNodesWithRedundancy(serviceNodes, []);
await serviceNodes.start();
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
await waku.lightPush.send(TestEncoder, { payload: utf8ToBytes("M2") });

View File

@ -6,7 +6,6 @@ import type {
SingleShardInfo
} from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import { waitForRemotePeer } from "@waku/sdk";
import {
contentTopicToPubsubTopic,
contentTopicToShardIndex,
@ -117,7 +116,7 @@ describe("Waku Filter V2: Multiple PubsubTopics", function () {
clusterId: 3
});
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
await nwaku2.ensureSubscriptions([customPubsubTopic2]);
@ -270,7 +269,7 @@ describe("Waku Filter V2 (Autosharding): Multiple PubsubTopics", function () {
contentTopic: [customContentTopic2]
});
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
await nwaku2.ensureSubscriptionsAutosharding([customContentTopic2]);
@ -409,7 +408,7 @@ describe("Waku Filter V2 (Named sharding): Multiple PubsubTopics", function () {
clusterId: 3
});
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
await nwaku2.ensureSubscriptions([customPubsubTopic2]);

View File

@ -1,5 +1,5 @@
import { LightNode, Protocols } from "@waku/interfaces";
import { utf8ToBytes, waitForRemotePeer } from "@waku/sdk";
import { utf8ToBytes } from "@waku/sdk";
import { expect } from "chai";
import {
@ -215,7 +215,7 @@ describe("Waku Filter V2: FilterPush", function () {
// Redo the connection and create a new subscription
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
await waku.filter.subscribe([TestDecoder], messageCollector.callback);
@ -242,7 +242,7 @@ describe("Waku Filter V2: FilterPush", function () {
// Restart nwaku node
await tearDownNodes(nwaku, []);
await nwaku.start();
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
await waku.lightPush.send(TestEncoder, { payload: utf8ToBytes("M2") });

View File

@ -7,7 +7,7 @@ import {
getPublicKey,
symmetric
} from "@waku/message-encryption";
import { utf8ToBytes, waitForRemotePeer } from "@waku/sdk";
import { utf8ToBytes } from "@waku/sdk";
import { expect } from "chai";
import type { Context } from "mocha";
@ -445,7 +445,7 @@ describe("Waku Filter V2: Subscribe: Single Service Node", function () {
// Set up and start a new nwaku node
[nwaku2, waku2] = await runNodes(ctx, TestShardInfo);
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
await nwaku2.ensureSubscriptions([TestPubsubTopic]);
// Send a message using the new subscription

View File

@ -2,13 +2,13 @@ import { createDecoder, createEncoder } from "@waku/core";
import {
DefaultNetworkConfig,
ISubscription,
IWaku,
LightNode,
NetworkConfig,
ProtocolCreateOptions,
Protocols,
Waku
Protocols
} from "@waku/interfaces";
import { createLightNode, waitForRemotePeer } from "@waku/sdk";
import { createLightNode } from "@waku/sdk";
import {
contentTopicToPubsubTopic,
derivePubsubTopicsFromNetworkConfig,
@ -107,7 +107,7 @@ export async function runMultipleNodes(
for (const node of serviceNodes.nodes) {
await waku.dial(await node.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
await waku.waitForPeers([Protocols.Filter, Protocols.LightPush]);
await node.ensureSubscriptions(pubsubTopics);
const wakuConnections = waku.libp2p.getConnections();
@ -126,7 +126,7 @@ export async function runMultipleNodes(
export async function teardownNodesWithRedundancy(
serviceNodes: ServiceNodesFleet,
wakuNodes: Waku | Waku[]
wakuNodes: IWaku | IWaku[]
): Promise<void> {
const wNodes = Array.isArray(wakuNodes) ? wakuNodes : [wakuNodes];

View File

@ -9,8 +9,7 @@ import {
Protocols,
ShardInfo,
Tags,
utf8ToBytes,
waitForRemotePeer
utf8ToBytes
} from "@waku/sdk";
import {
encodeRelayShard,
@ -70,7 +69,7 @@ describe("getConnectedPeersForProtocolAndShard", function () {
waku = await createLightNode({ networkConfig: shardInfo });
await waku.start();
await waku.libp2p.dialProtocol(serviceNodeMa, LightPushCodec);
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const peers = await getConnectedPeersForProtocolAndShard(
waku.libp2p.getConnections(),
waku.libp2p.peerStore,
@ -120,7 +119,7 @@ describe("getConnectedPeersForProtocolAndShard", function () {
await waku.libp2p.dialProtocol(serviceNode1Ma, LightPushCodec);
await waku.libp2p.dialProtocol(serviceNode2Ma, LightPushCodec);
await waku.start();
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const peers = await getConnectedPeersForProtocolAndShard(
waku.libp2p.getConnections(),
@ -173,7 +172,7 @@ describe("getConnectedPeersForProtocolAndShard", function () {
await waku.libp2p.dialProtocol(serviceNode2Ma, LightPushCodec);
await waku.start();
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const peers = await getConnectedPeersForProtocolAndShard(
waku.libp2p.getConnections(),
@ -226,7 +225,7 @@ describe("getConnectedPeersForProtocolAndShard", function () {
await delay(500);
await waku.libp2p.dialProtocol(serviceNodeMa2, LightPushCodec);
await waku.start();
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const peers = await getConnectedPeersForProtocolAndShard(
waku.libp2p.getConnections(),
@ -260,7 +259,7 @@ describe("getConnectedPeersForProtocolAndShard", function () {
waku = await createLightNode({ networkConfig: shardInfo });
await waku.start();
await waku.libp2p.dialProtocol(serviceNodeMa, LightPushCodec);
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const peers = await getConnectedPeersForProtocolAndShard(
waku.libp2p.getConnections(),
waku.libp2p.peerStore,
@ -313,7 +312,7 @@ describe("getConnectedPeersForProtocolAndShard", function () {
await waku.libp2p.dialProtocol(serviceNode2Ma, LightPushCodec);
await waku.start();
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const peers = await getConnectedPeersForProtocolAndShard(
waku.libp2p.getConnections(),
@ -367,7 +366,7 @@ describe("getConnectedPeersForProtocolAndShard", function () {
await waku.libp2p.dialProtocol(serviceNode2Ma, LightPushCodec);
await waku.start();
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const peers = await getConnectedPeersForProtocolAndShard(
waku.libp2p.getConnections(),
@ -421,7 +420,7 @@ describe("getConnectedPeersForProtocolAndShard", function () {
await delay(500);
await waku.libp2p.dialProtocol(serviceNodeMa2, LightPushCodec);
await waku.start();
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const peers = await getConnectedPeersForProtocolAndShard(
waku.libp2p.getConnections(),

View File

@ -1,4 +1,4 @@
import { HealthStatus, LightNode, Protocols, Waku } from "@waku/interfaces";
import { HealthStatus, IWaku, LightNode, Protocols } from "@waku/interfaces";
import { createLightNode } from "@waku/sdk";
import { shardInfoToPubsubTopics } from "@waku/utils";
import { expect } from "chai";
@ -87,7 +87,7 @@ function getExpectedProtocolStatus(peerCount: number): HealthStatus {
}
async function getPeerCounBasedOnConnections(
waku: Waku,
waku: IWaku,
codec: string
): Promise<number> {
const peerIDs = waku.libp2p

View File

@ -8,7 +8,6 @@ import {
ShardInfo,
SingleShardInfo
} from "@waku/interfaces";
import { waitForRemotePeer } from "@waku/sdk";
import {
contentTopicToPubsubTopic,
contentTopicToShardIndex,
@ -133,7 +132,7 @@ describe("Waku Light Push : Multiple PubsubTopics", function () {
singleShardInfoToPubsubTopic(singleShardInfo2)
]);
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const messageCollector2 = new MessageCollector(nwaku2);
@ -275,7 +274,7 @@ describe("Waku Light Push (Autosharding): Multiple PubsubTopics", function () {
});
await nwaku2.ensureSubscriptionsAutosharding([customContentTopic2]);
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const messageCollector2 = new MessageCollector(nwaku2);
@ -426,7 +425,7 @@ describe("Waku Light Push (named sharding): Multiple PubsubTopics", function ()
await nwaku2.ensureSubscriptions([autoshardingPubsubTopic2]);
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const messageCollector2 = new MessageCollector(nwaku2);

View File

@ -3,7 +3,7 @@ import type { PeerInfo } from "@libp2p/interface";
import { CustomEvent } from "@libp2p/interface";
import { multiaddr } from "@multiformats/multiaddr";
import type { Multiaddr } from "@multiformats/multiaddr";
import type { Waku } from "@waku/interfaces";
import type { IWaku } from "@waku/interfaces";
import { createLightNode } from "@waku/sdk";
import { expect } from "chai";
import Sinon, { SinonSpy, SinonStub } from "sinon";
@ -18,7 +18,7 @@ import {
} from "../src/index.js";
describe("multiaddr: dialing", function () {
let waku: Waku;
let waku: IWaku;
let nwaku: ServiceNode;
let dialPeerSpy: SinonSpy;
let isPeerTopicConfigured: SinonStub;

View File

@ -2,7 +2,6 @@ import type { PeerId } from "@libp2p/interface";
import { DecodedMessage } from "@waku/core";
import { Protocols, RelayNode } from "@waku/interfaces";
import { createRelayNode } from "@waku/relay";
import { waitForRemotePeer } from "@waku/sdk";
import { bytesToUtf8, utf8ToBytes } from "@waku/utils/bytes";
import { expect } from "chai";
@ -109,7 +108,7 @@ describe("Waku Relay, Interop", function () {
const nwakuMultiaddr = await nwaku.getMultiaddrWithId();
await waku2.dial(nwakuMultiaddr);
await waitForRemotePeer(waku2, [Protocols.Relay]);
await waku2.waitForPeers([Protocols.Relay]);
await delay(2000);
// Check that the two JS peers are NOT directly connected

View File

@ -7,7 +7,6 @@ import {
} from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import { createRelayNode } from "@waku/relay";
import { waitForRemotePeer } from "@waku/sdk";
import {
contentTopicToPubsubTopic,
pubsubTopicToSingleShardInfo,
@ -115,9 +114,9 @@ describe("Waku Relay, multiple pubsub topics", function () {
]);
await Promise.all([
waitForRemotePeer(waku1, [Protocols.Relay]),
waitForRemotePeer(waku2, [Protocols.Relay]),
waitForRemotePeer(waku3, [Protocols.Relay])
waku1.waitForPeers([Protocols.Relay]),
waku2.waitForPeers([Protocols.Relay]),
waku2.waitForPeers([Protocols.Relay])
]);
await waku1.relay.subscribeWithUnsubscribe(
@ -222,9 +221,9 @@ describe("Waku Relay, multiple pubsub topics", function () {
]);
await Promise.all([
waitForRemotePeer(waku1, [Protocols.Relay]),
waitForRemotePeer(waku2, [Protocols.Relay]),
waitForRemotePeer(waku3, [Protocols.Relay])
waku1.waitForPeers([Protocols.Relay]),
waku2.waitForPeers([Protocols.Relay]),
waku3.waitForPeers([Protocols.Relay])
]);
await waku1.relay.subscribeWithUnsubscribe(
@ -290,8 +289,8 @@ describe("Waku Relay, multiple pubsub topics", function () {
]);
await Promise.all([
waitForRemotePeer(waku1, [Protocols.Relay]),
waitForRemotePeer(waku2, [Protocols.Relay])
waku1.waitForPeers([Protocols.Relay]),
waku2.waitForPeers([Protocols.Relay])
]);
const messageText = "Communicating using a custom pubsub topic";
@ -420,9 +419,9 @@ describe("Waku Relay (Autosharding), multiple pubsub topics", function () {
]);
await Promise.all([
waitForRemotePeer(waku1, [Protocols.Relay]),
waitForRemotePeer(waku2, [Protocols.Relay]),
waitForRemotePeer(waku3, [Protocols.Relay])
waku1.waitForPeers([Protocols.Relay]),
waku2.waitForPeers([Protocols.Relay]),
waku3.waitForPeers([Protocols.Relay])
]);
await waku1.relay.subscribeWithUnsubscribe(
@ -536,9 +535,9 @@ describe("Waku Relay (Autosharding), multiple pubsub topics", function () {
]);
await Promise.all([
waitForRemotePeer(waku1, [Protocols.Relay]),
waitForRemotePeer(waku2, [Protocols.Relay]),
waitForRemotePeer(waku3, [Protocols.Relay])
waku1.waitForPeers([Protocols.Relay]),
waku2.waitForPeers([Protocols.Relay]),
waku3.waitForPeers([Protocols.Relay])
]);
await waku1.relay.subscribeWithUnsubscribe(
@ -631,8 +630,8 @@ describe("Waku Relay (Autosharding), multiple pubsub topics", function () {
]);
await Promise.all([
waitForRemotePeer(waku1, [Protocols.Relay]),
waitForRemotePeer(waku2, [Protocols.Relay])
waku1.waitForPeers([Protocols.Relay]),
waku2.waitForPeers([Protocols.Relay])
]);
const messageText = "Communicating using a custom pubsub topic";

View File

@ -6,7 +6,6 @@ import {
ShardInfo
} from "@waku/interfaces";
import { createRelayNode } from "@waku/relay";
import { waitForRemotePeer } from "@waku/sdk";
import { contentTopicToPubsubTopic, Logger } from "@waku/utils";
import { Context } from "mocha";
@ -46,7 +45,7 @@ export async function waitForAllRemotePeers(
): Promise<void> {
log.info("Wait for mutual pubsub subscription");
await Promise.all(
nodes.map((node): Promise<void> => waitForRemotePeer(node, RELAY_PROTOCOLS))
nodes.map((node): Promise<void> => node.waitForPeers(RELAY_PROTOCOLS))
);
}

View File

@ -1,10 +1,5 @@
import { LightNode, ProtocolError, Protocols } from "@waku/interfaces";
import {
createEncoder,
createLightNode,
utf8ToBytes,
waitForRemotePeer
} from "@waku/sdk";
import { createEncoder, createLightNode, utf8ToBytes } from "@waku/sdk";
import {
contentTopicToPubsubTopic,
contentTopicToShardIndex
@ -61,7 +56,7 @@ describe("Autosharding: Running Nodes", function () {
}
});
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const encoder = createEncoder({
contentTopic: ContentTopic,
@ -103,7 +98,7 @@ describe("Autosharding: Running Nodes", function () {
}
});
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const encoder = createEncoder({
contentTopic: ContentTopic,
@ -160,7 +155,7 @@ describe("Autosharding: Running Nodes", function () {
});
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const encoder = createEncoder({
contentTopic: ContentTopic,
@ -223,7 +218,7 @@ describe("Autosharding: Running Nodes", function () {
}
});
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const encoder1 = createEncoder({
contentTopic: ContentTopic,

View File

@ -5,12 +5,7 @@ import {
ShardInfo,
SingleShardInfo
} from "@waku/interfaces";
import {
createEncoder,
createLightNode,
utf8ToBytes,
waitForRemotePeer
} from "@waku/sdk";
import { createEncoder, createLightNode, utf8ToBytes } from "@waku/sdk";
import {
shardInfoToPubsubTopics,
singleShardInfosToShardInfo,
@ -62,7 +57,7 @@ describe("Static Sharding: Running Nodes", function () {
networkConfig: shardInfo
});
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const encoder = createEncoder({
contentTopic: ContentTopic,
@ -102,7 +97,7 @@ describe("Static Sharding: Running Nodes", function () {
networkConfig: shardInfo
});
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const encoder = createEncoder({
contentTopic: ContentTopic,
@ -151,7 +146,7 @@ describe("Static Sharding: Running Nodes", function () {
networkConfig: shardInfo
});
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const encoder = createEncoder({
contentTopic: ContentTopic,
@ -217,7 +212,7 @@ describe("Static Sharding: Running Nodes", function () {
networkConfig: shardInfoBothShards
});
await waku.dial(await nwaku.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.LightPush]);
await waku.waitForPeers([Protocols.LightPush]);
const encoder1 = createEncoder({
contentTopic: ContentTopic,

View File

@ -14,7 +14,6 @@ import {
createDecoder as createSymDecoder,
createEncoder as createSymEncoder
} from "@waku/message-encryption/symmetric";
import { waitForRemotePeer } from "@waku/sdk";
import { bytesToUtf8, utf8ToBytes } from "@waku/utils/bytes";
import { expect } from "chai";
import { equals } from "uint8arrays/equals";
@ -292,7 +291,7 @@ describe("Waku Store, general", function () {
waku.lightPush.send(TestEncoder, clearMsg)
]);
await waitForRemotePeer(waku2, [Protocols.Store]);
await waku2.waitForPeers([Protocols.Store]);
const messages: DecodedMessage[] = [];
log.info("Retrieve messages from store");

View File

@ -1,6 +1,6 @@
import { createDecoder } from "@waku/core";
import type { ContentTopicInfo, IMessage, LightNode } from "@waku/interfaces";
import { createLightNode, Protocols, waitForRemotePeer } from "@waku/sdk";
import { createLightNode, Protocols } from "@waku/sdk";
import {
contentTopicToPubsubTopic,
pubsubTopicToSingleShardInfo
@ -130,7 +130,7 @@ describe("Waku Store, custom pubsub topic", function () {
);
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Store]);
await waku.waitForPeers([Protocols.Store]);
let customMessages: IMessage[] = [];
let testMessages: IMessage[] = [];
@ -263,7 +263,7 @@ describe("Waku Store (Autosharding), custom pubsub topic", function () {
await waku.dial(await nwaku.getMultiaddrWithId());
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Store]);
await waku.waitForPeers([Protocols.Store]);
let customMessages: IMessage[] = [];
let testMessages: IMessage[] = [];
@ -389,7 +389,7 @@ describe("Waku Store (named sharding), custom pubsub topic", function () {
);
await waku.dial(await nwaku2.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Store]);
await waku.waitForPeers([Protocols.Store]);
let customMessages: IMessage[] = [];
let testMessages: IMessage[] = [];

View File

@ -11,7 +11,7 @@ import {
ShardInfo,
type SingleShardInfo
} from "@waku/interfaces";
import { createLightNode, waitForRemotePeer } from "@waku/sdk";
import { createLightNode } from "@waku/sdk";
import { Logger, singleShardInfoToPubsubTopic } from "@waku/utils";
import { expect } from "chai";
import { Context } from "mocha";
@ -111,7 +111,7 @@ export async function startAndConnectLightNode(
});
await waku.start();
await waku.dial(await instance.getMultiaddrWithId());
await waitForRemotePeer(waku, [Protocols.Store]);
await waku.waitForPeers([Protocols.Store]);
const wakuConnections = waku.libp2p.getConnections();

View File

@ -1,7 +1,7 @@
import type { LightNode, RelayNode } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import { createRelayNode } from "@waku/relay";
import { createLightNode, waitForRemotePeer } from "@waku/sdk";
import { createLightNode } from "@waku/sdk";
import { expect } from "chai";
import {
@ -60,7 +60,7 @@ describe("Wait for remote peer", function () {
});
await waku1.start();
const waitPromise = waitForRemotePeer(waku1, [Protocols.Relay]);
const waitPromise = waku1.waitForPeers([Protocols.Relay]);
await delay(1000);
await waku1.dial(multiAddrWithId);
await waitPromise;
@ -80,12 +80,14 @@ describe("Wait for remote peer", function () {
})
.then((waku1) => waku1.start().then(() => waku1))
.then((waku1) => {
waitForRemotePeer(waku1, [Protocols.Relay], 200).then(
waku1.waitForPeers([Protocols.Relay], 200).then(
() => {
throw "Promise expected to reject on time out";
},
(reason) => {
expect(reason).to.eq("Timed out waiting for a remote peer.");
expect(reason?.message).to.eq(
"Timed out waiting for a remote peer."
);
done();
}
);
@ -111,7 +113,7 @@ describe("Wait for remote peer", function () {
await waku2.start();
await waku2.dial(multiAddrWithId);
await delay(1000);
await waitForRemotePeer(waku2, [Protocols.Store]);
await waku2.waitForPeers([Protocols.Store]);
const peers = (await waku2.store.protocol.connectedPeers()).map((peer) =>
peer.id.toString()
@ -138,7 +140,7 @@ describe("Wait for remote peer", function () {
networkConfig: DefaultTestShardInfo
});
await waku2.start();
const waitPromise = waitForRemotePeer(waku2, [Protocols.Store], 2000);
const waitPromise = waku2.waitForPeers([Protocols.Store], 2000);
await delay(1000);
await waku2.dial(multiAddrWithId);
await waitPromise;
@ -170,7 +172,7 @@ describe("Wait for remote peer", function () {
});
await waku2.start();
await waku2.dial(multiAddrWithId);
await waitForRemotePeer(waku2, [Protocols.LightPush]);
await waku2.waitForPeers([Protocols.LightPush]);
const peers = (await waku2.lightPush.protocol.connectedPeers()).map(
(peer) => peer.id.toString()
@ -199,7 +201,7 @@ describe("Wait for remote peer", function () {
});
await waku2.start();
await waku2.dial(multiAddrWithId);
await waitForRemotePeer(waku2, [Protocols.Filter]);
await waku2.waitForPeers([Protocols.Filter]);
const peers = (await waku2.filter.protocol.connectedPeers()).map((peer) =>
peer.id.toString()
@ -228,7 +230,7 @@ describe("Wait for remote peer", function () {
});
await waku2.start();
await waku2.dial(multiAddrWithId);
await waitForRemotePeer(waku2, [
await waku2.waitForPeers([
Protocols.Filter,
Protocols.Store,
Protocols.LightPush

View File

@ -1,7 +1,7 @@
import { bootstrap } from "@libp2p/bootstrap";
import type { PeerId } from "@libp2p/interface";
import { DecodedMessage } from "@waku/core";
import type { LightNode, RelayNode, Waku } from "@waku/interfaces";
import type { IWaku, LightNode, RelayNode } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import { generateSymmetricKey } from "@waku/message-encryption";
import {
@ -12,8 +12,7 @@ import { createRelayNode } from "@waku/relay";
import {
createLightNode,
createEncoder as createPlainEncoder,
DefaultUserAgent,
waitForRemotePeer
DefaultUserAgent
} from "@waku/sdk";
import { bytesToUtf8, utf8ToBytes } from "@waku/utils/bytes";
import { expect } from "chai";
@ -59,7 +58,7 @@ describe("Waku Dial [node only]", function () {
});
await waku.start();
await waku.dial(multiAddrWithId);
await waitForRemotePeer(waku, [
await waku.waitForPeers([
Protocols.Store,
Protocols.Filter,
Protocols.LightPush
@ -190,8 +189,8 @@ describe("Decryption Keys", function () {
await waku1.dial(waku2.libp2p.peerId);
await Promise.all([
waitForRemotePeer(waku1, [Protocols.Relay]),
waitForRemotePeer(waku2, [Protocols.Relay])
waku1.waitForPeers([Protocols.Relay]),
waku1.waitForPeers([Protocols.Relay])
]);
});
@ -239,8 +238,8 @@ describe("Decryption Keys", function () {
});
describe("User Agent", function () {
let waku1: Waku;
let waku2: Waku;
let waku1: IWaku;
let waku2: IWaku;
afterEachCustom(this, async () => {
await tearDownNodes([], [waku1, waku2]);
@ -268,7 +267,7 @@ describe("User Agent", function () {
multiaddrs: waku2.libp2p.getMultiaddrs()
});
await waku1.dial(waku2.libp2p.peerId);
await waitForRemotePeer(waku1);
await waku1.waitForPeers();
const [waku1PeerInfo, waku2PeerInfo] = await Promise.all([
waku2.libp2p.peerStore.get(waku1.libp2p.peerId),