mirror of
https://github.com/logos-messaging/js-waku.git
synced 2026-01-07 16:23:09 +00:00
merge master
This commit is contained in:
commit
2ff19c7901
66
package-lock.json
generated
66
package-lock.json
generated
@ -2280,13 +2280,6 @@
|
|||||||
"uint8arrays": "^4.0.6"
|
"uint8arrays": "^4.0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@libp2p/interface-compliance-tests/node_modules/diff": {
|
|
||||||
"version": "5.1.0",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.3.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@libp2p/interface-compliance-tests/node_modules/p-limit": {
|
"node_modules/@libp2p/interface-compliance-tests/node_modules/p-limit": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -2300,32 +2293,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@libp2p/interface-compliance-tests/node_modules/sinon": {
|
|
||||||
"version": "16.0.0",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"@sinonjs/commons": "^3.0.0",
|
|
||||||
"@sinonjs/fake-timers": "^10.3.0",
|
|
||||||
"@sinonjs/samsam": "^8.0.0",
|
|
||||||
"diff": "^5.1.0",
|
|
||||||
"nise": "^5.1.4",
|
|
||||||
"supports-color": "^7.2.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/sinon"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@libp2p/interface-compliance-tests/node_modules/supports-color": {
|
|
||||||
"version": "7.2.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"has-flag": "^4.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@libp2p/interface-compliance-tests/node_modules/yocto-queue": {
|
"node_modules/@libp2p/interface-compliance-tests/node_modules/yocto-queue": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -23246,8 +23213,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sinon": {
|
"node_modules/sinon": {
|
||||||
"version": "15.2.0",
|
"version": "16.0.0",
|
||||||
"license": "BSD-3-Clause",
|
"resolved": "https://registry.npmjs.org/sinon/-/sinon-16.0.0.tgz",
|
||||||
|
"integrity": "sha512-B8AaZZm9CT5pqe4l4uWJztfD/mOTa7dL8Qo0W4+s+t74xECOgSZDDQCBjNgIK3+n4kyxQrSTv2V5ul8K25qkiQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sinonjs/commons": "^3.0.0",
|
"@sinonjs/commons": "^3.0.0",
|
||||||
"@sinonjs/fake-timers": "^10.3.0",
|
"@sinonjs/fake-timers": "^10.3.0",
|
||||||
@ -26152,7 +26120,7 @@
|
|||||||
"p-retry": "^6.0.0",
|
"p-retry": "^6.0.0",
|
||||||
"p-timeout": "^6.1.0",
|
"p-timeout": "^6.1.0",
|
||||||
"portfinder": "^1.0.32",
|
"portfinder": "^1.0.32",
|
||||||
"sinon": "^15.2.0",
|
"sinon": "^16.0.0",
|
||||||
"tail": "^2.2.6"
|
"tail": "^2.2.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -27622,32 +27590,12 @@
|
|||||||
"uint8arrays": "^4.0.6"
|
"uint8arrays": "^4.0.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"diff": {
|
|
||||||
"version": "5.1.0"
|
|
||||||
},
|
|
||||||
"p-limit": {
|
"p-limit": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"requires": {
|
"requires": {
|
||||||
"yocto-queue": "^1.0.0"
|
"yocto-queue": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sinon": {
|
|
||||||
"version": "16.0.0",
|
|
||||||
"requires": {
|
|
||||||
"@sinonjs/commons": "^3.0.0",
|
|
||||||
"@sinonjs/fake-timers": "^10.3.0",
|
|
||||||
"@sinonjs/samsam": "^8.0.0",
|
|
||||||
"diff": "^5.1.0",
|
|
||||||
"nise": "^5.1.4",
|
|
||||||
"supports-color": "^7.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "7.2.0",
|
|
||||||
"requires": {
|
|
||||||
"has-flag": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yocto-queue": {
|
"yocto-queue": {
|
||||||
"version": "1.0.0"
|
"version": "1.0.0"
|
||||||
}
|
}
|
||||||
@ -29380,7 +29328,7 @@
|
|||||||
"p-retry": "^6.0.0",
|
"p-retry": "^6.0.0",
|
||||||
"p-timeout": "^6.1.0",
|
"p-timeout": "^6.1.0",
|
||||||
"portfinder": "^1.0.32",
|
"portfinder": "^1.0.32",
|
||||||
"sinon": "^15.2.0",
|
"sinon": "^16.0.0",
|
||||||
"tail": "^2.2.6"
|
"tail": "^2.2.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -40512,7 +40460,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sinon": {
|
"sinon": {
|
||||||
"version": "15.2.0",
|
"version": "16.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sinon/-/sinon-16.0.0.tgz",
|
||||||
|
"integrity": "sha512-B8AaZZm9CT5pqe4l4uWJztfD/mOTa7dL8Qo0W4+s+t74xECOgSZDDQCBjNgIK3+n4kyxQrSTv2V5ul8K25qkiQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sinonjs/commons": "^3.0.0",
|
"@sinonjs/commons": "^3.0.0",
|
||||||
"@sinonjs/fake-timers": "^10.3.0",
|
"@sinonjs/fake-timers": "^10.3.0",
|
||||||
|
|||||||
@ -63,7 +63,7 @@
|
|||||||
"p-retry": "^6.0.0",
|
"p-retry": "^6.0.0",
|
||||||
"p-timeout": "^6.1.0",
|
"p-timeout": "^6.1.0",
|
||||||
"portfinder": "^1.0.32",
|
"portfinder": "^1.0.32",
|
||||||
"sinon": "^15.2.0",
|
"sinon": "^16.0.0",
|
||||||
"tail": "^2.2.6"
|
"tail": "^2.2.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@ -18,11 +18,7 @@ export class MessageCollector {
|
|||||||
list: Array<MessageRpcResponse | DecodedMessage> = [];
|
list: Array<MessageRpcResponse | DecodedMessage> = [];
|
||||||
callback: (msg: DecodedMessage) => void = () => {};
|
callback: (msg: DecodedMessage) => void = () => {};
|
||||||
|
|
||||||
constructor(
|
constructor(private nwaku?: NimGoNode) {
|
||||||
private contentTopic: string,
|
|
||||||
private nwaku?: NimGoNode,
|
|
||||||
private pubSubTopic = DefaultPubSubTopic
|
|
||||||
) {
|
|
||||||
if (!this.nwaku) {
|
if (!this.nwaku) {
|
||||||
this.callback = (msg: DecodedMessage): void => {
|
this.callback = (msg: DecodedMessage): void => {
|
||||||
log("Got a message");
|
log("Got a message");
|
||||||
@ -39,6 +35,12 @@ export class MessageCollector {
|
|||||||
return this.list[index];
|
return this.list[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasMessage(topic: string, text: string): boolean {
|
||||||
|
return this.list.some(
|
||||||
|
(message) => message.contentTopic === topic && message.payload === text
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Type guard to determine if a message is of type MessageRpcResponse
|
// Type guard to determine if a message is of type MessageRpcResponse
|
||||||
isMessageRpcResponse(
|
isMessageRpcResponse(
|
||||||
message: MessageRpcResponse | DecodedMessage
|
message: MessageRpcResponse | DecodedMessage
|
||||||
@ -51,14 +53,21 @@ export class MessageCollector {
|
|||||||
|
|
||||||
async waitForMessages(
|
async waitForMessages(
|
||||||
numMessages: number,
|
numMessages: number,
|
||||||
timeoutDuration: number = 400
|
options?: {
|
||||||
|
pubSubTopic?: string;
|
||||||
|
timeoutDuration?: number;
|
||||||
|
exact?: boolean;
|
||||||
|
}
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
const pubSubTopic = options?.pubSubTopic || DefaultPubSubTopic;
|
||||||
|
const timeoutDuration = options?.timeoutDuration || 400;
|
||||||
|
const exact = options?.exact || false;
|
||||||
|
|
||||||
while (this.count < numMessages) {
|
while (this.count < numMessages) {
|
||||||
if (this.nwaku) {
|
if (this.nwaku) {
|
||||||
try {
|
try {
|
||||||
this.list = await this.nwaku.messages(this.pubSubTopic);
|
this.list = await this.nwaku.messages(pubSubTopic);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log(`Can't retrieve messages because of ${error}`);
|
log(`Can't retrieve messages because of ${error}`);
|
||||||
await delay(10);
|
await delay(10);
|
||||||
@ -72,7 +81,16 @@ export class MessageCollector {
|
|||||||
await delay(10);
|
await delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
if (exact) {
|
||||||
|
if (this.count == numMessages) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
log(`Was expecting exactly ${numMessages} messages`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verifies a received message against expected values.
|
// Verifies a received message against expected values.
|
||||||
@ -96,10 +114,8 @@ export class MessageCollector {
|
|||||||
|
|
||||||
const message = this.getMessage(index);
|
const message = this.getMessage(index);
|
||||||
expect(message.contentTopic).to.eq(
|
expect(message.contentTopic).to.eq(
|
||||||
options.expectedContentTopic || this.contentTopic,
|
options.expectedContentTopic,
|
||||||
`Message content topic mismatch. Expected: ${
|
`Message content topic mismatch. Expected: ${options.expectedContentTopic}. Got: ${message.contentTopic}`
|
||||||
options.expectedContentTopic || this.contentTopic
|
|
||||||
}. Got: ${message.contentTopic}`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(message.version).to.eq(
|
expect(message.version).to.eq(
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export interface Args {
|
|||||||
peerExchange?: boolean;
|
peerExchange?: boolean;
|
||||||
discv5Discovery?: boolean;
|
discv5Discovery?: boolean;
|
||||||
storeMessageDbUrl?: string;
|
storeMessageDbUrl?: string;
|
||||||
topic?: string;
|
topic?: Array<string>;
|
||||||
rpcPrivate?: boolean;
|
rpcPrivate?: boolean;
|
||||||
websocketSupport?: boolean;
|
websocketSupport?: boolean;
|
||||||
tcpPort?: number;
|
tcpPort?: number;
|
||||||
|
|||||||
@ -149,10 +149,12 @@ describe("ConnectionManager", function () {
|
|||||||
let waku: LightNode;
|
let waku: LightNode;
|
||||||
|
|
||||||
this.beforeEach(async function () {
|
this.beforeEach(async function () {
|
||||||
|
this.timeout(15000);
|
||||||
waku = await createLightNode();
|
waku = await createLightNode();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
|
this.timeout(15000);
|
||||||
await waku.stop();
|
await waku.stop();
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
});
|
});
|
||||||
|
|||||||
149
packages/tests/tests/filter/multiple_pubsub.node.spec.ts
Normal file
149
packages/tests/tests/filter/multiple_pubsub.node.spec.ts
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import {
|
||||||
|
createDecoder,
|
||||||
|
createEncoder,
|
||||||
|
DefaultPubSubTopic,
|
||||||
|
waitForRemotePeer
|
||||||
|
} from "@waku/core";
|
||||||
|
import type { IFilterSubscription, LightNode } from "@waku/interfaces";
|
||||||
|
import { Protocols } from "@waku/interfaces";
|
||||||
|
import { utf8ToBytes } from "@waku/utils/bytes";
|
||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import {
|
||||||
|
makeLogFileName,
|
||||||
|
MessageCollector,
|
||||||
|
NimGoNode,
|
||||||
|
tearDownNodes
|
||||||
|
} from "../../src/index.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
runNodes,
|
||||||
|
TestContentTopic,
|
||||||
|
TestDecoder,
|
||||||
|
TestEncoder
|
||||||
|
} from "./utils.js";
|
||||||
|
|
||||||
|
describe("Waku Filter V2: Multiple PubSubtopics", function () {
|
||||||
|
// Set the timeout for all tests in this suite. Can be overwritten at test level
|
||||||
|
this.timeout(30000);
|
||||||
|
let waku: LightNode;
|
||||||
|
let nwaku: NimGoNode;
|
||||||
|
let nwaku2: NimGoNode;
|
||||||
|
let subscription: IFilterSubscription;
|
||||||
|
let messageCollector: MessageCollector;
|
||||||
|
const customPubSubTopic = "/waku/2/custom-dapp/proto";
|
||||||
|
const customContentTopic = "/test/2/waku-filter";
|
||||||
|
const newEncoder = createEncoder({
|
||||||
|
pubSubTopic: customPubSubTopic,
|
||||||
|
contentTopic: customContentTopic
|
||||||
|
});
|
||||||
|
const newDecoder = createDecoder(customContentTopic, customPubSubTopic);
|
||||||
|
|
||||||
|
this.beforeEach(async function () {
|
||||||
|
this.timeout(15000);
|
||||||
|
[nwaku, waku] = await runNodes(this, [
|
||||||
|
customPubSubTopic,
|
||||||
|
DefaultPubSubTopic
|
||||||
|
]);
|
||||||
|
subscription = await waku.filter.createSubscription(customPubSubTopic);
|
||||||
|
messageCollector = new MessageCollector();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.afterEach(async function () {
|
||||||
|
this.timeout(15000);
|
||||||
|
await tearDownNodes([nwaku, nwaku2], [waku]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Subscribe and receive messages on custom pubsubtopic", async function () {
|
||||||
|
await subscription.subscribe([newDecoder], messageCollector.callback);
|
||||||
|
await waku.lightPush.send(newEncoder, { payload: utf8ToBytes("M1") });
|
||||||
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
|
expectedContentTopic: customContentTopic,
|
||||||
|
expectedPubSubTopic: customPubSubTopic,
|
||||||
|
expectedMessageText: "M1"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Subscribe and receive messages on 2 different pubsubtopics", async function () {
|
||||||
|
await subscription.subscribe([newDecoder], messageCollector.callback);
|
||||||
|
|
||||||
|
// Subscribe from the same lightnode to the 2nd pubSubtopic
|
||||||
|
const subscription2 =
|
||||||
|
await waku.filter.createSubscription(DefaultPubSubTopic);
|
||||||
|
|
||||||
|
const messageCollector2 = new MessageCollector();
|
||||||
|
|
||||||
|
await subscription2.subscribe([TestDecoder], messageCollector2.callback);
|
||||||
|
|
||||||
|
await waku.lightPush.send(newEncoder, { payload: utf8ToBytes("M1") });
|
||||||
|
await waku.lightPush.send(TestEncoder, { payload: utf8ToBytes("M2") });
|
||||||
|
|
||||||
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
|
expect(await messageCollector2.waitForMessages(1)).to.eq(true);
|
||||||
|
|
||||||
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
|
expectedContentTopic: customContentTopic,
|
||||||
|
expectedPubSubTopic: customPubSubTopic,
|
||||||
|
expectedMessageText: "M1"
|
||||||
|
});
|
||||||
|
|
||||||
|
messageCollector2.verifyReceivedMessage(0, {
|
||||||
|
expectedContentTopic: TestContentTopic,
|
||||||
|
expectedPubSubTopic: DefaultPubSubTopic,
|
||||||
|
expectedMessageText: "M2"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Subscribe and receive messages from 2 nwaku nodes each with different pubsubtopics", async function () {
|
||||||
|
await subscription.subscribe([newDecoder], messageCollector.callback);
|
||||||
|
|
||||||
|
// Set up and start a new nwaku node with Default PubSubtopic
|
||||||
|
nwaku2 = new NimGoNode(makeLogFileName(this) + "2");
|
||||||
|
await nwaku2.start({
|
||||||
|
filter: true,
|
||||||
|
lightpush: true,
|
||||||
|
relay: true,
|
||||||
|
topic: [DefaultPubSubTopic]
|
||||||
|
});
|
||||||
|
await waku.dial(await nwaku2.getMultiaddrWithId());
|
||||||
|
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
|
||||||
|
|
||||||
|
// Subscribe from the same lightnode to the new nwaku on the new pubSubtopic
|
||||||
|
const subscription2 = await waku.filter.createSubscription(
|
||||||
|
DefaultPubSubTopic,
|
||||||
|
await nwaku2.getPeerId()
|
||||||
|
);
|
||||||
|
await nwaku.ensureSubscriptions([DefaultPubSubTopic]);
|
||||||
|
|
||||||
|
const messageCollector2 = new MessageCollector();
|
||||||
|
|
||||||
|
await subscription2.subscribe([TestDecoder], messageCollector2.callback);
|
||||||
|
|
||||||
|
// Making sure that messages are send and reveiced for both subscriptions
|
||||||
|
// While loop is done because of https://github.com/waku-org/js-waku/issues/1606
|
||||||
|
while (
|
||||||
|
!(await messageCollector.waitForMessages(1, {
|
||||||
|
pubSubTopic: customPubSubTopic
|
||||||
|
})) ||
|
||||||
|
!(await messageCollector2.waitForMessages(1, {
|
||||||
|
pubSubTopic: DefaultPubSubTopic
|
||||||
|
}))
|
||||||
|
) {
|
||||||
|
await waku.lightPush.send(newEncoder, { payload: utf8ToBytes("M1") });
|
||||||
|
await waku.lightPush.send(TestEncoder, { payload: utf8ToBytes("M2") });
|
||||||
|
}
|
||||||
|
|
||||||
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
|
expectedContentTopic: customContentTopic,
|
||||||
|
expectedPubSubTopic: customPubSubTopic,
|
||||||
|
expectedMessageText: "M1"
|
||||||
|
});
|
||||||
|
|
||||||
|
messageCollector2.verifyReceivedMessage(0, {
|
||||||
|
expectedContentTopic: TestContentTopic,
|
||||||
|
expectedPubSubTopic: DefaultPubSubTopic,
|
||||||
|
expectedMessageText: "M2"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { DefaultPubSubTopic } from "@waku/core";
|
||||||
import type { IFilterSubscription, LightNode } from "@waku/interfaces";
|
import type { IFilterSubscription, LightNode } from "@waku/interfaces";
|
||||||
import { utf8ToBytes } from "@waku/utils/bytes";
|
import { utf8ToBytes } from "@waku/utils/bytes";
|
||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
@ -22,9 +23,9 @@ describe("Waku Filter V2: Ping", function () {
|
|||||||
|
|
||||||
this.beforeEach(async function () {
|
this.beforeEach(async function () {
|
||||||
this.timeout(15000);
|
this.timeout(15000);
|
||||||
[nwaku, waku] = await runNodes(this);
|
[nwaku, waku] = await runNodes(this, [DefaultPubSubTopic]);
|
||||||
subscription = await waku.filter.createSubscription();
|
subscription = await waku.filter.createSubscription();
|
||||||
messageCollector = new MessageCollector(TestContentTopic);
|
messageCollector = new MessageCollector();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.afterEach(async function () {
|
this.afterEach(async function () {
|
||||||
|
|||||||
@ -31,9 +31,9 @@ describe("Waku Filter V2: FilterPush", function () {
|
|||||||
|
|
||||||
this.beforeEach(async function () {
|
this.beforeEach(async function () {
|
||||||
this.timeout(15000);
|
this.timeout(15000);
|
||||||
[nwaku, waku] = await runNodes(this);
|
[nwaku, waku] = await runNodes(this, [DefaultPubSubTopic]);
|
||||||
subscription = await waku.filter.createSubscription();
|
subscription = await waku.filter.createSubscription();
|
||||||
messageCollector = new MessageCollector(TestContentTopic);
|
messageCollector = new MessageCollector();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.afterEach(async function () {
|
this.afterEach(async function () {
|
||||||
@ -50,7 +50,8 @@ describe("Waku Filter V2: FilterPush", function () {
|
|||||||
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: testItem.value
|
expectedMessageText: testItem.value,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -72,7 +73,8 @@ describe("Waku Filter V2: FilterPush", function () {
|
|||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText,
|
expectedMessageText: messageText,
|
||||||
checkTimestamp: false
|
checkTimestamp: false,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if the timestamp matches
|
// Check if the timestamp matches
|
||||||
@ -218,7 +220,8 @@ describe("Waku Filter V2: FilterPush", function () {
|
|||||||
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -246,10 +249,12 @@ describe("Waku Filter V2: FilterPush", function () {
|
|||||||
// Confirm both messages were received.
|
// Confirm both messages were received.
|
||||||
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: "M1"
|
expectedMessageText: "M1",
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
messageCollector.verifyReceivedMessage(1, {
|
messageCollector.verifyReceivedMessage(1, {
|
||||||
expectedMessageText: "M2"
|
expectedMessageText: "M2",
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -269,10 +274,12 @@ describe("Waku Filter V2: FilterPush", function () {
|
|||||||
// Confirm both messages were received.
|
// Confirm both messages were received.
|
||||||
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: "M1"
|
expectedMessageText: "M1",
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
messageCollector.verifyReceivedMessage(1, {
|
messageCollector.verifyReceivedMessage(1, {
|
||||||
expectedMessageText: "M2"
|
expectedMessageText: "M2",
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -39,9 +39,9 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
|
|
||||||
this.beforeEach(async function () {
|
this.beforeEach(async function () {
|
||||||
this.timeout(15000);
|
this.timeout(15000);
|
||||||
[nwaku, waku] = await runNodes(this);
|
[nwaku, waku] = await runNodes(this, [DefaultPubSubTopic]);
|
||||||
subscription = await waku.filter.createSubscription();
|
subscription = await waku.filter.createSubscription();
|
||||||
messageCollector = new MessageCollector(TestContentTopic);
|
messageCollector = new MessageCollector();
|
||||||
|
|
||||||
// Nwaku subscribe to the default pubsub topic
|
// Nwaku subscribe to the default pubsub topic
|
||||||
await nwaku.ensureSubscriptions();
|
await nwaku.ensureSubscriptions();
|
||||||
@ -59,7 +59,8 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
expect((await nwaku.messages()).length).to.eq(1);
|
expect((await nwaku.messages()).length).to.eq(1);
|
||||||
});
|
});
|
||||||
@ -79,7 +80,8 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
expect((await nwaku.messages()).length).to.eq(1);
|
expect((await nwaku.messages()).length).to.eq(1);
|
||||||
});
|
});
|
||||||
@ -91,7 +93,8 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send another message on the same topic.
|
// Send another message on the same topic.
|
||||||
@ -103,7 +106,8 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
// Verify that the second message was successfully received.
|
// Verify that the second message was successfully received.
|
||||||
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(1, {
|
messageCollector.verifyReceivedMessage(1, {
|
||||||
expectedMessageText: newMessageText
|
expectedMessageText: newMessageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
expect((await nwaku.messages()).length).to.eq(2);
|
expect((await nwaku.messages()).length).to.eq(2);
|
||||||
});
|
});
|
||||||
@ -114,7 +118,8 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
await waku.lightPush.send(TestEncoder, messagePayload);
|
await waku.lightPush.send(TestEncoder, messagePayload);
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
|
|
||||||
// Modify subscription to include a new content topic and send a message.
|
// Modify subscription to include a new content topic and send a message.
|
||||||
@ -137,7 +142,8 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
await waku.lightPush.send(TestEncoder, newMessagePayload);
|
await waku.lightPush.send(TestEncoder, newMessagePayload);
|
||||||
expect(await messageCollector.waitForMessages(3)).to.eq(true);
|
expect(await messageCollector.waitForMessages(3)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(2, {
|
messageCollector.verifyReceivedMessage(2, {
|
||||||
expectedMessageText: newMessageText
|
expectedMessageText: newMessageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
expect((await nwaku.messages()).length).to.eq(3);
|
expect((await nwaku.messages()).length).to.eq(3);
|
||||||
});
|
});
|
||||||
@ -259,10 +265,12 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
// Confirm both messages were received.
|
// Confirm both messages were received.
|
||||||
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: "M1"
|
expectedMessageText: "M1",
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
messageCollector.verifyReceivedMessage(1, {
|
messageCollector.verifyReceivedMessage(1, {
|
||||||
expectedMessageText: "M2"
|
expectedMessageText: "M2",
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -299,7 +307,8 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
// Check if both messages were received
|
// Check if both messages were received
|
||||||
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: "M1"
|
expectedMessageText: "M1",
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
messageCollector.verifyReceivedMessage(1, {
|
messageCollector.verifyReceivedMessage(1, {
|
||||||
expectedContentTopic: newContentTopic,
|
expectedContentTopic: newContentTopic,
|
||||||
@ -307,38 +316,32 @@ describe("Waku Filter V2: Subscribe", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// this test fail 50% of times with messageCount being 1. Seems like a message is lost somehow
|
it("Subscribe and receive messages from multiple nwaku nodes", async function () {
|
||||||
it.skip("Subscribe and receive messages from multiple nwaku nodes", async function () {
|
|
||||||
await subscription.subscribe([TestDecoder], messageCollector.callback);
|
await subscription.subscribe([TestDecoder], messageCollector.callback);
|
||||||
await waku.lightPush.send(TestEncoder, { payload: utf8ToBytes("M1") });
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
|
||||||
|
|
||||||
// Set up and start a new nwaku node
|
// Set up and start a new nwaku node
|
||||||
nwaku2 = new NimGoNode(makeLogFileName(this) + "2");
|
nwaku2 = new NimGoNode(makeLogFileName(this) + "2");
|
||||||
await nwaku2.start({ filter: true, lightpush: true, relay: true });
|
await nwaku2.start({ filter: true, lightpush: true, relay: true });
|
||||||
|
|
||||||
await waku.dial(await nwaku2.getMultiaddrWithId());
|
await waku.dial(await nwaku2.getMultiaddrWithId());
|
||||||
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
|
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
|
||||||
const subscription2 = await waku.filter.createSubscription(
|
const subscription2 = await waku.filter.createSubscription(
|
||||||
DefaultPubSubTopic,
|
DefaultPubSubTopic,
|
||||||
await nwaku2.getPeerId()
|
await nwaku2.getPeerId()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send a message using the new subscription
|
// Send a message using the new subscription
|
||||||
const newContentTopic = "/test/2/waku-filter";
|
const newContentTopic = "/test/2/waku-filter";
|
||||||
const newEncoder = createEncoder({ contentTopic: newContentTopic });
|
const newEncoder = createEncoder({ contentTopic: newContentTopic });
|
||||||
const newDecoder = createDecoder(newContentTopic);
|
const newDecoder = createDecoder(newContentTopic);
|
||||||
await subscription2.subscribe([newDecoder], messageCollector.callback);
|
await subscription2.subscribe([newDecoder], messageCollector.callback);
|
||||||
await waku.lightPush.send(newEncoder, { payload: utf8ToBytes("M2") });
|
|
||||||
|
// Making sure that messages are send and reveiced for both subscriptions
|
||||||
|
while (!(await messageCollector.waitForMessages(2))) {
|
||||||
|
await waku.lightPush.send(TestEncoder, { payload: utf8ToBytes("M1") });
|
||||||
|
await waku.lightPush.send(newEncoder, { payload: utf8ToBytes("M2") });
|
||||||
|
}
|
||||||
|
|
||||||
// Check if both messages were received
|
// Check if both messages were received
|
||||||
expect(await messageCollector.waitForMessages(2)).to.eq(true);
|
expect(messageCollector.hasMessage(TestContentTopic, "M1")).to.be.true;
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
expect(messageCollector.hasMessage(newContentTopic, "M2")).to.be.true;
|
||||||
expectedMessageText: "M1"
|
|
||||||
});
|
|
||||||
messageCollector.verifyReceivedMessage(1, {
|
|
||||||
expectedContentTopic: newContentTopic,
|
|
||||||
expectedMessageText: "M2"
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { createDecoder, createEncoder } from "@waku/core";
|
import { createDecoder, createEncoder, DefaultPubSubTopic } from "@waku/core";
|
||||||
import type { IFilterSubscription, LightNode } from "@waku/interfaces";
|
import type { IFilterSubscription, LightNode } from "@waku/interfaces";
|
||||||
import { utf8ToBytes } from "@waku/utils/bytes";
|
import { utf8ToBytes } from "@waku/utils/bytes";
|
||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
@ -25,9 +25,9 @@ describe("Waku Filter V2: Unsubscribe", function () {
|
|||||||
|
|
||||||
this.beforeEach(async function () {
|
this.beforeEach(async function () {
|
||||||
this.timeout(15000);
|
this.timeout(15000);
|
||||||
[nwaku, waku] = await runNodes(this);
|
[nwaku, waku] = await runNodes(this, [DefaultPubSubTopic]);
|
||||||
subscription = await waku.filter.createSubscription();
|
subscription = await waku.filter.createSubscription();
|
||||||
messageCollector = new MessageCollector(TestContentTopic);
|
messageCollector = new MessageCollector();
|
||||||
|
|
||||||
// Nwaku subscribe to the default pubsub topic
|
// Nwaku subscribe to the default pubsub topic
|
||||||
await nwaku.ensureSubscriptions();
|
await nwaku.ensureSubscriptions();
|
||||||
@ -50,7 +50,8 @@ describe("Waku Filter V2: Unsubscribe", function () {
|
|||||||
|
|
||||||
// Check that from 2 messages send only the 1st was received
|
// Check that from 2 messages send only the 1st was received
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
expect(messageCollector.count).to.eq(1);
|
expect(messageCollector.count).to.eq(1);
|
||||||
expect((await nwaku.messages()).length).to.eq(2);
|
expect((await nwaku.messages()).length).to.eq(2);
|
||||||
|
|||||||
@ -64,14 +64,25 @@ export async function validatePingError(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function runNodes(
|
export async function runNodes(
|
||||||
currentTest: Context
|
context: Context,
|
||||||
|
pubSubTopics: string[]
|
||||||
): Promise<[NimGoNode, LightNode]> {
|
): Promise<[NimGoNode, LightNode]> {
|
||||||
const nwaku = new NimGoNode(makeLogFileName(currentTest));
|
const nwaku = new NimGoNode(makeLogFileName(context));
|
||||||
await nwaku.startWithRetries({ filter: true, lightpush: true, relay: true });
|
|
||||||
|
await nwaku.startWithRetries(
|
||||||
|
{
|
||||||
|
filter: true,
|
||||||
|
lightpush: true,
|
||||||
|
relay: true,
|
||||||
|
topic: pubSubTopics
|
||||||
|
},
|
||||||
|
{ retries: 3 }
|
||||||
|
);
|
||||||
|
|
||||||
let waku: LightNode | undefined;
|
let waku: LightNode | undefined;
|
||||||
try {
|
try {
|
||||||
waku = await createLightNode({
|
waku = await createLightNode({
|
||||||
|
pubSubTopics: pubSubTopics,
|
||||||
staticNoiseKey: NOISE_KEY_1,
|
staticNoiseKey: NOISE_KEY_1,
|
||||||
libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }
|
libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }
|
||||||
});
|
});
|
||||||
@ -83,6 +94,7 @@ export async function runNodes(
|
|||||||
if (waku) {
|
if (waku) {
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
await waku.dial(await nwaku.getMultiaddrWithId());
|
||||||
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
|
await waitForRemotePeer(waku, [Protocols.Filter, Protocols.LightPush]);
|
||||||
|
await nwaku.ensureSubscriptions(pubSubTopics);
|
||||||
return [nwaku, waku];
|
return [nwaku, waku];
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Failed to initialize waku");
|
throw new Error("Failed to initialize waku");
|
||||||
|
|||||||
@ -1,53 +0,0 @@
|
|||||||
import { createEncoder } from "@waku/core";
|
|
||||||
import { LightNode } from "@waku/interfaces";
|
|
||||||
import { utf8ToBytes } from "@waku/utils/bytes";
|
|
||||||
import { expect } from "chai";
|
|
||||||
|
|
||||||
import { MessageCollector, NimGoNode, tearDownNodes } from "../../src/index.js";
|
|
||||||
|
|
||||||
import { messageText, runNodes, TestContentTopic } from "./utils.js";
|
|
||||||
|
|
||||||
describe("Waku Light Push [node only] - custom pubsub topic", function () {
|
|
||||||
this.timeout(15000);
|
|
||||||
let waku: LightNode;
|
|
||||||
let nwaku: NimGoNode;
|
|
||||||
let messageCollector: MessageCollector;
|
|
||||||
const customPubSubTopic = "/waku/2/custom-dapp/proto";
|
|
||||||
|
|
||||||
beforeEach(async function () {
|
|
||||||
[nwaku, waku] = await runNodes(this, customPubSubTopic);
|
|
||||||
messageCollector = new MessageCollector(
|
|
||||||
TestContentTopic,
|
|
||||||
nwaku,
|
|
||||||
customPubSubTopic
|
|
||||||
);
|
|
||||||
|
|
||||||
await nwaku.ensureSubscriptions([customPubSubTopic]);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.afterEach(async function () {
|
|
||||||
this.timeout(15000);
|
|
||||||
await tearDownNodes([nwaku], [waku]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Push message", async function () {
|
|
||||||
const nimPeerId = await nwaku.getPeerId();
|
|
||||||
|
|
||||||
const testEncoder = createEncoder({
|
|
||||||
contentTopic: TestContentTopic,
|
|
||||||
pubSubTopic: customPubSubTopic
|
|
||||||
});
|
|
||||||
|
|
||||||
const pushResponse = await waku.lightPush.send(testEncoder, {
|
|
||||||
payload: utf8ToBytes(messageText)
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(pushResponse.recipients[0].toString()).to.eq(nimPeerId.toString());
|
|
||||||
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
|
||||||
expectedMessageText: messageText,
|
|
||||||
expectedContentTopic: TestContentTopic
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -19,7 +19,7 @@ import {
|
|||||||
TestEncoder
|
TestEncoder
|
||||||
} from "./utils.js";
|
} from "./utils.js";
|
||||||
|
|
||||||
describe("Waku Light Push [node only]", function () {
|
describe("Waku Light Push", function () {
|
||||||
// Set the timeout for all tests in this suite. Can be overwritten at test level
|
// Set the timeout for all tests in this suite. Can be overwritten at test level
|
||||||
this.timeout(15000);
|
this.timeout(15000);
|
||||||
let waku: LightNode;
|
let waku: LightNode;
|
||||||
@ -28,12 +28,8 @@ describe("Waku Light Push [node only]", function () {
|
|||||||
|
|
||||||
this.beforeEach(async function () {
|
this.beforeEach(async function () {
|
||||||
this.timeout(15000);
|
this.timeout(15000);
|
||||||
[nwaku, waku] = await runNodes(this);
|
[nwaku, waku] = await runNodes(this, [DefaultPubSubTopic]);
|
||||||
messageCollector = new MessageCollector(
|
messageCollector = new MessageCollector(nwaku);
|
||||||
TestContentTopic,
|
|
||||||
nwaku,
|
|
||||||
DefaultPubSubTopic
|
|
||||||
);
|
|
||||||
|
|
||||||
await nwaku.ensureSubscriptions();
|
await nwaku.ensureSubscriptions();
|
||||||
});
|
});
|
||||||
@ -52,7 +48,8 @@ describe("Waku Light Push [node only]", function () {
|
|||||||
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: testItem.value
|
expectedMessageText: testItem.value,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -71,7 +68,8 @@ describe("Waku Light Push [node only]", function () {
|
|||||||
|
|
||||||
for (let i = 0; i < 30; i++) {
|
for (let i = 0; i < 30; i++) {
|
||||||
messageCollector.verifyReceivedMessage(i, {
|
messageCollector.verifyReceivedMessage(i, {
|
||||||
expectedMessageText: generateMessageText(i)
|
expectedMessageText: generateMessageText(i),
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -85,7 +83,8 @@ describe("Waku Light Push [node only]", function () {
|
|||||||
expect(pushResponse.recipients.length).to.eq(1);
|
expect(pushResponse.recipients.length).to.eq(1);
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: undefined
|
expectedMessageText: undefined,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
expect(pushResponse.recipients.length).to.eq(0);
|
expect(pushResponse.recipients.length).to.eq(0);
|
||||||
@ -139,7 +138,8 @@ describe("Waku Light Push [node only]", function () {
|
|||||||
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -158,7 +158,8 @@ describe("Waku Light Push [node only]", function () {
|
|||||||
expect(pushResponse.recipients.length).to.eq(1);
|
expect(pushResponse.recipients.length).to.eq(1);
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
expect(pushResponse.recipients.length).to.eq(0);
|
expect(pushResponse.recipients.length).to.eq(0);
|
||||||
@ -187,7 +188,8 @@ describe("Waku Light Push [node only]", function () {
|
|||||||
|
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -207,7 +209,8 @@ describe("Waku Light Push [node only]", function () {
|
|||||||
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
expect(await messageCollector.waitForMessages(1)).to.eq(true);
|
||||||
messageCollector.verifyReceivedMessage(0, {
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
expectedMessageText: messageText,
|
expectedMessageText: messageText,
|
||||||
expectedTimestamp: customTimeNanos
|
expectedTimestamp: customTimeNanos,
|
||||||
|
expectedContentTopic: TestContentTopic
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
155
packages/tests/tests/light-push/multiple_pubsub.node.spec.ts
Normal file
155
packages/tests/tests/light-push/multiple_pubsub.node.spec.ts
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
import type { PeerId } from "@libp2p/interface/peer-id";
|
||||||
|
import {
|
||||||
|
createEncoder,
|
||||||
|
DefaultPubSubTopic,
|
||||||
|
waitForRemotePeer
|
||||||
|
} from "@waku/core";
|
||||||
|
import { LightNode, Protocols, SendResult } from "@waku/interfaces";
|
||||||
|
import { utf8ToBytes } from "@waku/utils/bytes";
|
||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import {
|
||||||
|
makeLogFileName,
|
||||||
|
MessageCollector,
|
||||||
|
NimGoNode,
|
||||||
|
tearDownNodes
|
||||||
|
} from "../../src/index.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
messageText,
|
||||||
|
runNodes,
|
||||||
|
TestContentTopic,
|
||||||
|
TestEncoder
|
||||||
|
} from "./utils.js";
|
||||||
|
|
||||||
|
describe("Waku Light Push : Multiple PubSubtopics", function () {
|
||||||
|
this.timeout(30000);
|
||||||
|
let waku: LightNode;
|
||||||
|
let nwaku: NimGoNode;
|
||||||
|
let nwaku2: NimGoNode;
|
||||||
|
let messageCollector: MessageCollector;
|
||||||
|
const customPubSubTopic = "/waku/2/custom-dapp/proto";
|
||||||
|
const customContentTopic = "/test/2/waku-light-push/utf8";
|
||||||
|
const customEncoder = createEncoder({
|
||||||
|
contentTopic: customContentTopic,
|
||||||
|
pubSubTopic: customPubSubTopic
|
||||||
|
});
|
||||||
|
let nimPeerId: PeerId;
|
||||||
|
|
||||||
|
this.beforeEach(async function () {
|
||||||
|
this.timeout(15000);
|
||||||
|
[nwaku, waku] = await runNodes(this, [
|
||||||
|
customPubSubTopic,
|
||||||
|
DefaultPubSubTopic
|
||||||
|
]);
|
||||||
|
messageCollector = new MessageCollector(nwaku);
|
||||||
|
nimPeerId = await nwaku.getPeerId();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.afterEach(async function () {
|
||||||
|
this.timeout(15000);
|
||||||
|
await tearDownNodes([nwaku, nwaku2], [waku]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Push message on custom pubSubTopic", async function () {
|
||||||
|
const pushResponse = await waku.lightPush.send(customEncoder, {
|
||||||
|
payload: utf8ToBytes(messageText)
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(pushResponse.recipients[0].toString()).to.eq(nimPeerId.toString());
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await messageCollector.waitForMessages(1, {
|
||||||
|
pubSubTopic: customPubSubTopic
|
||||||
|
})
|
||||||
|
).to.eq(true);
|
||||||
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
|
expectedMessageText: messageText,
|
||||||
|
expectedContentTopic: customContentTopic
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Subscribe and receive messages on 2 different pubsubtopics", async function () {
|
||||||
|
const pushResponse1 = await waku.lightPush.send(customEncoder, {
|
||||||
|
payload: utf8ToBytes("M1")
|
||||||
|
});
|
||||||
|
const pushResponse2 = await waku.lightPush.send(TestEncoder, {
|
||||||
|
payload: utf8ToBytes("M2")
|
||||||
|
});
|
||||||
|
expect(pushResponse1.recipients[0].toString()).to.eq(nimPeerId.toString());
|
||||||
|
expect(pushResponse2.recipients[0].toString()).to.eq(nimPeerId.toString());
|
||||||
|
|
||||||
|
const messageCollector2 = new MessageCollector(nwaku);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await messageCollector.waitForMessages(1, {
|
||||||
|
pubSubTopic: customPubSubTopic
|
||||||
|
})
|
||||||
|
).to.eq(true);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await messageCollector2.waitForMessages(1, {
|
||||||
|
pubSubTopic: DefaultPubSubTopic
|
||||||
|
})
|
||||||
|
).to.eq(true);
|
||||||
|
|
||||||
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
|
expectedMessageText: "M1",
|
||||||
|
expectedContentTopic: customContentTopic,
|
||||||
|
expectedPubSubTopic: customPubSubTopic
|
||||||
|
});
|
||||||
|
messageCollector2.verifyReceivedMessage(0, {
|
||||||
|
expectedMessageText: "M2",
|
||||||
|
expectedContentTopic: TestContentTopic,
|
||||||
|
expectedPubSubTopic: DefaultPubSubTopic
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Light push messages to 2 nwaku nodes each with different pubsubtopics", async function () {
|
||||||
|
// Set up and start a new nwaku node with Default PubSubtopic
|
||||||
|
nwaku2 = new NimGoNode(makeLogFileName(this) + "2");
|
||||||
|
await nwaku2.start({
|
||||||
|
filter: true,
|
||||||
|
lightpush: true,
|
||||||
|
relay: true,
|
||||||
|
topic: [DefaultPubSubTopic]
|
||||||
|
});
|
||||||
|
await waku.dial(await nwaku2.getMultiaddrWithId());
|
||||||
|
await waitForRemotePeer(waku, [Protocols.LightPush]);
|
||||||
|
|
||||||
|
const messageCollector2 = new MessageCollector(nwaku2);
|
||||||
|
|
||||||
|
let pushResponse1: SendResult;
|
||||||
|
let pushResponse2: SendResult;
|
||||||
|
// Making sure that we send messages to both nwaku nodes
|
||||||
|
// While loop is done because of https://github.com/waku-org/js-waku/issues/1606
|
||||||
|
while (
|
||||||
|
!(await messageCollector.waitForMessages(1, {
|
||||||
|
pubSubTopic: customPubSubTopic
|
||||||
|
})) ||
|
||||||
|
!(await messageCollector2.waitForMessages(1, {
|
||||||
|
pubSubTopic: DefaultPubSubTopic
|
||||||
|
})) ||
|
||||||
|
pushResponse1!.recipients[0].toString() ===
|
||||||
|
pushResponse2!.recipients[0].toString()
|
||||||
|
) {
|
||||||
|
pushResponse1 = await waku.lightPush.send(customEncoder, {
|
||||||
|
payload: utf8ToBytes("M1")
|
||||||
|
});
|
||||||
|
pushResponse2 = await waku.lightPush.send(TestEncoder, {
|
||||||
|
payload: utf8ToBytes("M2")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
messageCollector.verifyReceivedMessage(0, {
|
||||||
|
expectedMessageText: "M1",
|
||||||
|
expectedContentTopic: customContentTopic,
|
||||||
|
expectedPubSubTopic: customPubSubTopic
|
||||||
|
});
|
||||||
|
messageCollector2.verifyReceivedMessage(0, {
|
||||||
|
expectedMessageText: "M2",
|
||||||
|
expectedContentTopic: TestContentTopic,
|
||||||
|
expectedPubSubTopic: DefaultPubSubTopic
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -14,20 +14,18 @@ export const messagePayload = { payload: utf8ToBytes(messageText) };
|
|||||||
|
|
||||||
export async function runNodes(
|
export async function runNodes(
|
||||||
context: Mocha.Context,
|
context: Mocha.Context,
|
||||||
pubSubTopic?: string
|
pubSubTopics: string[]
|
||||||
): Promise<[NimGoNode, LightNode]> {
|
): Promise<[NimGoNode, LightNode]> {
|
||||||
const nwakuOptional = pubSubTopic ? { topic: pubSubTopic } : {};
|
|
||||||
const nwaku = new NimGoNode(makeLogFileName(context));
|
const nwaku = new NimGoNode(makeLogFileName(context));
|
||||||
await nwaku.startWithRetries({
|
await nwaku.startWithRetries(
|
||||||
lightpush: true,
|
{ lightpush: true, relay: true, topic: pubSubTopics },
|
||||||
relay: true,
|
{ retries: 3 }
|
||||||
...nwakuOptional
|
);
|
||||||
});
|
|
||||||
|
|
||||||
let waku: LightNode | undefined;
|
let waku: LightNode | undefined;
|
||||||
try {
|
try {
|
||||||
waku = await createLightNode({
|
waku = await createLightNode({
|
||||||
pubSubTopics: pubSubTopic ? [pubSubTopic] : undefined,
|
pubSubTopics: pubSubTopics,
|
||||||
staticNoiseKey: NOISE_KEY_1
|
staticNoiseKey: NOISE_KEY_1
|
||||||
});
|
});
|
||||||
await waku.start();
|
await waku.start();
|
||||||
@ -38,6 +36,7 @@ export async function runNodes(
|
|||||||
if (waku) {
|
if (waku) {
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
await waku.dial(await nwaku.getMultiaddrWithId());
|
||||||
await waitForRemotePeer(waku, [Protocols.LightPush]);
|
await waitForRemotePeer(waku, [Protocols.LightPush]);
|
||||||
|
await nwaku.ensureSubscriptions(pubSubTopics);
|
||||||
return [nwaku, waku];
|
return [nwaku, waku];
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Failed to initialize waku");
|
throw new Error("Failed to initialize waku");
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import debug from "debug";
|
|||||||
import {
|
import {
|
||||||
delay,
|
delay,
|
||||||
makeLogFileName,
|
makeLogFileName,
|
||||||
|
MessageCollector,
|
||||||
NOISE_KEY_1,
|
NOISE_KEY_1,
|
||||||
NOISE_KEY_2,
|
NOISE_KEY_2,
|
||||||
NOISE_KEY_3
|
NOISE_KEY_3
|
||||||
@ -260,13 +261,14 @@ describe("Waku Relay [node only]", () => {
|
|||||||
let waku2: RelayNode;
|
let waku2: RelayNode;
|
||||||
let waku3: RelayNode;
|
let waku3: RelayNode;
|
||||||
|
|
||||||
const pubSubTopic = "/some/pubsub/topic";
|
const CustomContentTopic = "/test/2/waku-relay/utf8";
|
||||||
|
const CustomPubSubTopic = "/some/pubsub/topic";
|
||||||
|
|
||||||
const CustomTopicEncoder = createEncoder({
|
const CustomEncoder = createEncoder({
|
||||||
contentTopic: TestContentTopic,
|
contentTopic: CustomContentTopic,
|
||||||
pubSubTopic: pubSubTopic
|
pubSubTopic: CustomPubSubTopic
|
||||||
});
|
});
|
||||||
const CustomTopicDecoder = createDecoder(TestContentTopic, pubSubTopic);
|
const CustomDecoder = createDecoder(CustomContentTopic, CustomPubSubTopic);
|
||||||
|
|
||||||
afterEach(async function () {
|
afterEach(async function () {
|
||||||
!!waku1 &&
|
!!waku1 &&
|
||||||
@ -277,18 +279,196 @@ describe("Waku Relay [node only]", () => {
|
|||||||
waku3.stop().catch((e) => console.log("Waku failed to stop", e));
|
waku3.stop().catch((e) => console.log("Waku failed to stop", e));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Publish", async function () {
|
[
|
||||||
|
{
|
||||||
|
pubsub: CustomPubSubTopic,
|
||||||
|
encoder: CustomEncoder,
|
||||||
|
decoder: CustomDecoder
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pubsub: DefaultPubSubTopic,
|
||||||
|
encoder: TestEncoder,
|
||||||
|
decoder: TestDecoder
|
||||||
|
}
|
||||||
|
].forEach((testItem) => {
|
||||||
|
it(`3 nodes on ${testItem.pubsub} topic`, async function () {
|
||||||
|
this.timeout(10000);
|
||||||
|
|
||||||
|
const [msgCollector1, msgCollector2, msgCollector3] = Array(3)
|
||||||
|
.fill(null)
|
||||||
|
.map(() => new MessageCollector());
|
||||||
|
|
||||||
|
[waku1, waku2, waku3] = await Promise.all([
|
||||||
|
createRelayNode({
|
||||||
|
pubSubTopics: [testItem.pubsub],
|
||||||
|
staticNoiseKey: NOISE_KEY_1
|
||||||
|
}).then((waku) => waku.start().then(() => waku)),
|
||||||
|
createRelayNode({
|
||||||
|
pubSubTopics: [testItem.pubsub],
|
||||||
|
staticNoiseKey: NOISE_KEY_2,
|
||||||
|
libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }
|
||||||
|
}).then((waku) => waku.start().then(() => waku)),
|
||||||
|
createRelayNode({
|
||||||
|
pubSubTopics: [testItem.pubsub],
|
||||||
|
staticNoiseKey: NOISE_KEY_3
|
||||||
|
}).then((waku) => waku.start().then(() => waku))
|
||||||
|
]);
|
||||||
|
|
||||||
|
await waku1.libp2p.peerStore.merge(waku2.libp2p.peerId, {
|
||||||
|
multiaddrs: waku2.libp2p.getMultiaddrs()
|
||||||
|
});
|
||||||
|
await waku3.libp2p.peerStore.merge(waku2.libp2p.peerId, {
|
||||||
|
multiaddrs: waku2.libp2p.getMultiaddrs()
|
||||||
|
});
|
||||||
|
await Promise.all([
|
||||||
|
waku1.dial(waku2.libp2p.peerId),
|
||||||
|
waku3.dial(waku2.libp2p.peerId)
|
||||||
|
]);
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
waitForRemotePeer(waku1, [Protocols.Relay]),
|
||||||
|
waitForRemotePeer(waku2, [Protocols.Relay]),
|
||||||
|
waitForRemotePeer(waku3, [Protocols.Relay])
|
||||||
|
]);
|
||||||
|
|
||||||
|
await waku1.relay.subscribe([testItem.decoder], msgCollector1.callback);
|
||||||
|
await waku2.relay.subscribe([testItem.decoder], msgCollector2.callback);
|
||||||
|
await waku3.relay.subscribe([testItem.decoder], msgCollector3.callback);
|
||||||
|
|
||||||
|
// The nodes are setup in such a way that all messages send should be relayed to the other nodes in the network
|
||||||
|
const relayResponse1 = await waku1.relay.send(testItem.encoder, {
|
||||||
|
payload: utf8ToBytes("M1")
|
||||||
|
});
|
||||||
|
const relayResponse2 = await waku2.relay.send(testItem.encoder, {
|
||||||
|
payload: utf8ToBytes("M2")
|
||||||
|
});
|
||||||
|
const relayResponse3 = await waku3.relay.send(testItem.encoder, {
|
||||||
|
payload: utf8ToBytes("M3")
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(relayResponse1.recipients[0].toString()).to.eq(
|
||||||
|
waku2.libp2p.peerId.toString()
|
||||||
|
);
|
||||||
|
expect(relayResponse3.recipients[0].toString()).to.eq(
|
||||||
|
waku2.libp2p.peerId.toString()
|
||||||
|
);
|
||||||
|
expect(relayResponse2.recipients.map((r) => r.toString())).to.include(
|
||||||
|
waku1.libp2p.peerId.toString()
|
||||||
|
);
|
||||||
|
expect(relayResponse2.recipients.map((r) => r.toString())).to.include(
|
||||||
|
waku3.libp2p.peerId.toString()
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(await msgCollector1.waitForMessages(2, { exact: true })).to.eq(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(await msgCollector2.waitForMessages(2, { exact: true })).to.eq(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(await msgCollector3.waitForMessages(2, { exact: true })).to.eq(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(msgCollector1.hasMessage(testItem.pubsub, "M2")).to.be.true;
|
||||||
|
expect(msgCollector1.hasMessage(testItem.pubsub, "M3")).to.be.true;
|
||||||
|
expect(msgCollector2.hasMessage(testItem.pubsub, "M1")).to.be.true;
|
||||||
|
expect(msgCollector2.hasMessage(testItem.pubsub, "M3")).to.be.true;
|
||||||
|
expect(msgCollector3.hasMessage(testItem.pubsub, "M1")).to.be.true;
|
||||||
|
expect(msgCollector3.hasMessage(testItem.pubsub, "M2")).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Nodes with multiple pubsub topic", async function () {
|
||||||
this.timeout(10000);
|
this.timeout(10000);
|
||||||
|
|
||||||
// 1 and 2 uses a custom pubsub
|
const [msgCollector1, msgCollector2, msgCollector3] = Array(3)
|
||||||
// 3 uses the default pubsub
|
.fill(null)
|
||||||
|
.map(() => new MessageCollector());
|
||||||
|
|
||||||
|
// Waku1 and waku2 are using multiple pubsub topis
|
||||||
[waku1, waku2, waku3] = await Promise.all([
|
[waku1, waku2, waku3] = await Promise.all([
|
||||||
createRelayNode({
|
createRelayNode({
|
||||||
pubSubTopics: [pubSubTopic],
|
pubSubTopics: [DefaultPubSubTopic, CustomPubSubTopic],
|
||||||
staticNoiseKey: NOISE_KEY_1
|
staticNoiseKey: NOISE_KEY_1
|
||||||
}).then((waku) => waku.start().then(() => waku)),
|
}).then((waku) => waku.start().then(() => waku)),
|
||||||
createRelayNode({
|
createRelayNode({
|
||||||
pubSubTopics: [pubSubTopic],
|
pubSubTopics: [DefaultPubSubTopic, CustomPubSubTopic],
|
||||||
|
staticNoiseKey: NOISE_KEY_2,
|
||||||
|
libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }
|
||||||
|
}).then((waku) => waku.start().then(() => waku)),
|
||||||
|
createRelayNode({
|
||||||
|
pubSubTopics: [DefaultPubSubTopic],
|
||||||
|
staticNoiseKey: NOISE_KEY_3
|
||||||
|
}).then((waku) => waku.start().then(() => waku))
|
||||||
|
]);
|
||||||
|
|
||||||
|
await waku1.libp2p.peerStore.merge(waku2.libp2p.peerId, {
|
||||||
|
multiaddrs: waku2.libp2p.getMultiaddrs()
|
||||||
|
});
|
||||||
|
await waku3.libp2p.peerStore.merge(waku2.libp2p.peerId, {
|
||||||
|
multiaddrs: waku2.libp2p.getMultiaddrs()
|
||||||
|
});
|
||||||
|
await Promise.all([
|
||||||
|
waku1.dial(waku2.libp2p.peerId),
|
||||||
|
waku3.dial(waku2.libp2p.peerId)
|
||||||
|
]);
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
waitForRemotePeer(waku1, [Protocols.Relay]),
|
||||||
|
waitForRemotePeer(waku2, [Protocols.Relay]),
|
||||||
|
waitForRemotePeer(waku3, [Protocols.Relay])
|
||||||
|
]);
|
||||||
|
|
||||||
|
await waku1.relay.subscribe(
|
||||||
|
[TestDecoder, CustomDecoder],
|
||||||
|
msgCollector1.callback
|
||||||
|
);
|
||||||
|
await waku2.relay.subscribe(
|
||||||
|
[TestDecoder, CustomDecoder],
|
||||||
|
msgCollector2.callback
|
||||||
|
);
|
||||||
|
await waku3.relay.subscribe([TestDecoder], msgCollector3.callback);
|
||||||
|
|
||||||
|
// The nodes are setup in such a way that all messages send should be relayed to the other nodes in the network
|
||||||
|
// However onlt waku1 and waku2 are receiving messages on the CustomPubSubTopic
|
||||||
|
await waku1.relay.send(TestEncoder, { payload: utf8ToBytes("M1") });
|
||||||
|
await waku1.relay.send(CustomEncoder, { payload: utf8ToBytes("M2") });
|
||||||
|
await waku2.relay.send(TestEncoder, { payload: utf8ToBytes("M3") });
|
||||||
|
await waku2.relay.send(CustomEncoder, { payload: utf8ToBytes("M4") });
|
||||||
|
await waku3.relay.send(TestEncoder, { payload: utf8ToBytes("M5") });
|
||||||
|
await waku3.relay.send(CustomEncoder, { payload: utf8ToBytes("M6") });
|
||||||
|
|
||||||
|
expect(await msgCollector1.waitForMessages(3, { exact: true })).to.eq(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(await msgCollector2.waitForMessages(3, { exact: true })).to.eq(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(await msgCollector3.waitForMessages(2, { exact: true })).to.eq(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(msgCollector1.hasMessage(DefaultPubSubTopic, "M3")).to.be.true;
|
||||||
|
expect(msgCollector1.hasMessage(CustomPubSubTopic, "M4")).to.be.true;
|
||||||
|
expect(msgCollector1.hasMessage(DefaultPubSubTopic, "M5")).to.be.true;
|
||||||
|
expect(msgCollector1.hasMessage(DefaultPubSubTopic, "M1")).to.be.true;
|
||||||
|
expect(msgCollector1.hasMessage(CustomPubSubTopic, "M2")).to.be.true;
|
||||||
|
expect(msgCollector1.hasMessage(DefaultPubSubTopic, "M5")).to.be.true;
|
||||||
|
expect(msgCollector2.hasMessage(CustomPubSubTopic, "M1")).to.be.true;
|
||||||
|
expect(msgCollector2.hasMessage(DefaultPubSubTopic, "M3")).to.be.true;
|
||||||
|
expect(msgCollector3.hasMessage(DefaultPubSubTopic, "M1")).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("n1 and n2 uses a custom pubsub, n3 uses the default pubsub", async function () {
|
||||||
|
this.timeout(10000);
|
||||||
|
|
||||||
|
[waku1, waku2, waku3] = await Promise.all([
|
||||||
|
createRelayNode({
|
||||||
|
pubSubTopics: [CustomPubSubTopic],
|
||||||
|
staticNoiseKey: NOISE_KEY_1
|
||||||
|
}).then((waku) => waku.start().then(() => waku)),
|
||||||
|
createRelayNode({
|
||||||
|
pubSubTopics: [CustomPubSubTopic],
|
||||||
staticNoiseKey: NOISE_KEY_2,
|
staticNoiseKey: NOISE_KEY_2,
|
||||||
libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }
|
libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }
|
||||||
}).then((waku) => waku.start().then(() => waku)),
|
}).then((waku) => waku.start().then(() => waku)),
|
||||||
@ -317,7 +497,7 @@ describe("Waku Relay [node only]", () => {
|
|||||||
|
|
||||||
const waku2ReceivedMsgPromise: Promise<DecodedMessage> = new Promise(
|
const waku2ReceivedMsgPromise: Promise<DecodedMessage> = new Promise(
|
||||||
(resolve) => {
|
(resolve) => {
|
||||||
void waku2.relay.subscribe([CustomTopicDecoder], resolve);
|
void waku2.relay.subscribe([CustomDecoder], resolve);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -330,7 +510,7 @@ describe("Waku Relay [node only]", () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
await waku1.relay.send(CustomTopicEncoder, {
|
await waku1.relay.send(CustomEncoder, {
|
||||||
payload: utf8ToBytes(messageText)
|
payload: utf8ToBytes(messageText)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -338,7 +518,7 @@ describe("Waku Relay [node only]", () => {
|
|||||||
await waku3NoMsgPromise;
|
await waku3NoMsgPromise;
|
||||||
|
|
||||||
expect(bytesToUtf8(waku2ReceivedMsg.payload!)).to.eq(messageText);
|
expect(bytesToUtf8(waku2ReceivedMsg.payload!)).to.eq(messageText);
|
||||||
expect(waku2ReceivedMsg.pubSubTopic).to.eq(pubSubTopic);
|
expect(waku2ReceivedMsg.pubSubTopic).to.eq(CustomPubSubTopic);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Publishes <= 1 MB and rejects others", async function () {
|
it("Publishes <= 1 MB and rejects others", async function () {
|
||||||
@ -348,11 +528,11 @@ describe("Waku Relay [node only]", () => {
|
|||||||
// 1 and 2 uses a custom pubsub
|
// 1 and 2 uses a custom pubsub
|
||||||
[waku1, waku2] = await Promise.all([
|
[waku1, waku2] = await Promise.all([
|
||||||
createRelayNode({
|
createRelayNode({
|
||||||
pubSubTopics: [pubSubTopic],
|
pubSubTopics: [CustomPubSubTopic],
|
||||||
staticNoiseKey: NOISE_KEY_1
|
staticNoiseKey: NOISE_KEY_1
|
||||||
}).then((waku) => waku.start().then(() => waku)),
|
}).then((waku) => waku.start().then(() => waku)),
|
||||||
createRelayNode({
|
createRelayNode({
|
||||||
pubSubTopics: [pubSubTopic],
|
pubSubTopics: [CustomPubSubTopic],
|
||||||
staticNoiseKey: NOISE_KEY_2,
|
staticNoiseKey: NOISE_KEY_2,
|
||||||
libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }
|
libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } }
|
||||||
}).then((waku) => waku.start().then(() => waku))
|
}).then((waku) => waku.start().then(() => waku))
|
||||||
@ -370,7 +550,7 @@ describe("Waku Relay [node only]", () => {
|
|||||||
|
|
||||||
const waku2ReceivedMsgPromise: Promise<DecodedMessage> = new Promise(
|
const waku2ReceivedMsgPromise: Promise<DecodedMessage> = new Promise(
|
||||||
(resolve) => {
|
(resolve) => {
|
||||||
void waku2.relay.subscribe([CustomTopicDecoder], () =>
|
void waku2.relay.subscribe([CustomDecoder], () =>
|
||||||
resolve({
|
resolve({
|
||||||
payload: new Uint8Array([])
|
payload: new Uint8Array([])
|
||||||
} as DecodedMessage)
|
} as DecodedMessage)
|
||||||
@ -378,18 +558,18 @@ describe("Waku Relay [node only]", () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
let sendResult = await waku1.relay.send(CustomTopicEncoder, {
|
let sendResult = await waku1.relay.send(CustomEncoder, {
|
||||||
payload: generateRandomUint8Array(1 * MB)
|
payload: generateRandomUint8Array(1 * MB)
|
||||||
});
|
});
|
||||||
expect(sendResult.recipients.length).to.eq(1);
|
expect(sendResult.recipients.length).to.eq(1);
|
||||||
|
|
||||||
sendResult = await waku1.relay.send(CustomTopicEncoder, {
|
sendResult = await waku1.relay.send(CustomEncoder, {
|
||||||
payload: generateRandomUint8Array(1 * MB + 65536)
|
payload: generateRandomUint8Array(1 * MB + 65536)
|
||||||
});
|
});
|
||||||
expect(sendResult.recipients.length).to.eq(0);
|
expect(sendResult.recipients.length).to.eq(0);
|
||||||
expect(sendResult.errors).to.include(SendError.SIZE_TOO_BIG);
|
expect(sendResult.errors).to.include(SendError.SIZE_TOO_BIG);
|
||||||
|
|
||||||
sendResult = await waku1.relay.send(CustomTopicEncoder, {
|
sendResult = await waku1.relay.send(CustomEncoder, {
|
||||||
payload: generateRandomUint8Array(2 * MB)
|
payload: generateRandomUint8Array(2 * MB)
|
||||||
});
|
});
|
||||||
expect(sendResult.recipients.length).to.eq(0);
|
expect(sendResult.recipients.length).to.eq(0);
|
||||||
|
|||||||
@ -1,637 +0,0 @@
|
|||||||
import {
|
|
||||||
createCursor,
|
|
||||||
createDecoder,
|
|
||||||
createEncoder,
|
|
||||||
DecodedMessage,
|
|
||||||
PageDirection,
|
|
||||||
waitForRemotePeer
|
|
||||||
} from "@waku/core";
|
|
||||||
import type { IMessage, LightNode } from "@waku/interfaces";
|
|
||||||
import { Protocols } from "@waku/interfaces";
|
|
||||||
import {
|
|
||||||
createDecoder as createEciesDecoder,
|
|
||||||
createEncoder as createEciesEncoder,
|
|
||||||
generatePrivateKey,
|
|
||||||
getPublicKey
|
|
||||||
} from "@waku/message-encryption/ecies";
|
|
||||||
import {
|
|
||||||
createDecoder as createSymDecoder,
|
|
||||||
createEncoder as createSymEncoder,
|
|
||||||
generateSymmetricKey
|
|
||||||
} from "@waku/message-encryption/symmetric";
|
|
||||||
import { createLightNode } from "@waku/sdk";
|
|
||||||
import { bytesToUtf8, utf8ToBytes } from "@waku/utils/bytes";
|
|
||||||
import { expect } from "chai";
|
|
||||||
import debug from "debug";
|
|
||||||
|
|
||||||
import {
|
|
||||||
delay,
|
|
||||||
makeLogFileName,
|
|
||||||
NOISE_KEY_1,
|
|
||||||
NOISE_KEY_2
|
|
||||||
} from "../src/index.js";
|
|
||||||
import { NimGoNode } from "../src/node/node.js";
|
|
||||||
|
|
||||||
const log = debug("waku:test:store");
|
|
||||||
|
|
||||||
const TestContentTopic = "/test/1/waku-store/utf8";
|
|
||||||
const TestEncoder = createEncoder({ contentTopic: TestContentTopic });
|
|
||||||
const TestDecoder = createDecoder(TestContentTopic);
|
|
||||||
|
|
||||||
describe("Waku Store", () => {
|
|
||||||
let waku: LightNode;
|
|
||||||
let nwaku: NimGoNode;
|
|
||||||
|
|
||||||
beforeEach(async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
nwaku = new NimGoNode(makeLogFileName(this));
|
|
||||||
await nwaku.start({ store: true, lightpush: true, relay: true });
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(async function () {
|
|
||||||
!!nwaku &&
|
|
||||||
nwaku.stop().catch((e) => console.log("Nwaku failed to stop", e));
|
|
||||||
!!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Generator", async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
const totalMsgs = 20;
|
|
||||||
|
|
||||||
for (let i = 0; i < totalMsgs; i++) {
|
|
||||||
expect(
|
|
||||||
await nwaku.sendMessage(
|
|
||||||
NimGoNode.toMessageRpcQuery({
|
|
||||||
payload: new Uint8Array([i]),
|
|
||||||
contentTopic: TestContentTopic
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).to.be.true;
|
|
||||||
}
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
const messages: IMessage[] = [];
|
|
||||||
let promises: Promise<void>[] = [];
|
|
||||||
for await (const msgPromises of waku.store.queryGenerator([TestDecoder])) {
|
|
||||||
const _promises = msgPromises.map(async (promise) => {
|
|
||||||
const msg = await promise;
|
|
||||||
if (msg) {
|
|
||||||
messages.push(msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
promises = promises.concat(_promises);
|
|
||||||
}
|
|
||||||
await Promise.all(promises);
|
|
||||||
|
|
||||||
expect(messages?.length).eq(totalMsgs);
|
|
||||||
const result = messages?.findIndex((msg) => {
|
|
||||||
return msg.payload[0]! === 0;
|
|
||||||
});
|
|
||||||
expect(result).to.not.eq(-1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Generator, no message returned", async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
const messages: IMessage[] = [];
|
|
||||||
let promises: Promise<void>[] = [];
|
|
||||||
for await (const msgPromises of waku.store.queryGenerator([TestDecoder])) {
|
|
||||||
const _promises = msgPromises.map(async (promise) => {
|
|
||||||
const msg = await promise;
|
|
||||||
if (msg) {
|
|
||||||
messages.push(msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
promises = promises.concat(_promises);
|
|
||||||
}
|
|
||||||
await Promise.all(promises);
|
|
||||||
|
|
||||||
expect(messages?.length).eq(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Passing a cursor", async function () {
|
|
||||||
this.timeout(4_000);
|
|
||||||
const totalMsgs = 20;
|
|
||||||
|
|
||||||
for (let i = 0; i < totalMsgs; i++) {
|
|
||||||
expect(
|
|
||||||
await nwaku.sendMessage(
|
|
||||||
NimGoNode.toMessageRpcQuery({
|
|
||||||
payload: utf8ToBytes(`Message ${i}`),
|
|
||||||
contentTopic: TestContentTopic
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).to.be.true;
|
|
||||||
}
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
const query = waku.store.queryGenerator([TestDecoder]);
|
|
||||||
|
|
||||||
// messages in reversed order (first message at last index)
|
|
||||||
const messages: DecodedMessage[] = [];
|
|
||||||
for await (const page of query) {
|
|
||||||
for await (const msg of page.reverse()) {
|
|
||||||
messages.push(msg as DecodedMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// index 2 would mean the third last message sent
|
|
||||||
const cursorIndex = 2;
|
|
||||||
|
|
||||||
// create cursor to extract messages after the 3rd index
|
|
||||||
const cursor = await createCursor(messages[cursorIndex]);
|
|
||||||
|
|
||||||
const messagesAfterCursor: DecodedMessage[] = [];
|
|
||||||
for await (const page of waku.store.queryGenerator([TestDecoder], {
|
|
||||||
cursor
|
|
||||||
})) {
|
|
||||||
for await (const msg of page.reverse()) {
|
|
||||||
messagesAfterCursor.push(msg as DecodedMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const testMessage = messagesAfterCursor[0];
|
|
||||||
|
|
||||||
expect(messages.length).be.eq(totalMsgs);
|
|
||||||
|
|
||||||
expect(bytesToUtf8(testMessage.payload)).to.be.eq(
|
|
||||||
bytesToUtf8(messages[cursorIndex + 1].payload)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Callback on promise", async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
|
|
||||||
const totalMsgs = 15;
|
|
||||||
|
|
||||||
for (let i = 0; i < totalMsgs; i++) {
|
|
||||||
expect(
|
|
||||||
await nwaku.sendMessage(
|
|
||||||
NimGoNode.toMessageRpcQuery({
|
|
||||||
payload: new Uint8Array([i]),
|
|
||||||
contentTopic: TestContentTopic
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).to.be.true;
|
|
||||||
}
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
const messages: IMessage[] = [];
|
|
||||||
await waku.store.queryWithPromiseCallback(
|
|
||||||
[TestDecoder],
|
|
||||||
async (msgPromise) => {
|
|
||||||
const msg = await msgPromise;
|
|
||||||
if (msg) {
|
|
||||||
messages.push(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(messages?.length).eq(totalMsgs);
|
|
||||||
const result = messages?.findIndex((msg) => {
|
|
||||||
return msg.payload[0]! === 0;
|
|
||||||
});
|
|
||||||
expect(result).to.not.eq(-1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Callback on promise, aborts when callback returns true", async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
|
|
||||||
const totalMsgs = 20;
|
|
||||||
|
|
||||||
for (let i = 0; i < totalMsgs; i++) {
|
|
||||||
expect(
|
|
||||||
await nwaku.sendMessage(
|
|
||||||
NimGoNode.toMessageRpcQuery({
|
|
||||||
payload: new Uint8Array([i]),
|
|
||||||
contentTopic: TestContentTopic
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).to.be.true;
|
|
||||||
}
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
const desiredMsgs = 14;
|
|
||||||
const messages: IMessage[] = [];
|
|
||||||
await waku.store.queryWithPromiseCallback(
|
|
||||||
[TestDecoder],
|
|
||||||
async (msgPromise) => {
|
|
||||||
const msg = await msgPromise;
|
|
||||||
if (msg) {
|
|
||||||
messages.push(msg);
|
|
||||||
}
|
|
||||||
return messages.length >= desiredMsgs;
|
|
||||||
},
|
|
||||||
{ pageSize: 7 }
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(messages?.length).eq(desiredMsgs);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Ordered Callback - Forward", async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
|
|
||||||
const totalMsgs = 18;
|
|
||||||
for (let i = 0; i < totalMsgs; i++) {
|
|
||||||
expect(
|
|
||||||
await nwaku.sendMessage(
|
|
||||||
NimGoNode.toMessageRpcQuery({
|
|
||||||
payload: new Uint8Array([i]),
|
|
||||||
contentTopic: TestContentTopic
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).to.be.true;
|
|
||||||
await delay(1); // to ensure each timestamp is unique.
|
|
||||||
}
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
const messages: IMessage[] = [];
|
|
||||||
await waku.store.queryWithOrderedCallback(
|
|
||||||
[TestDecoder],
|
|
||||||
async (msg) => {
|
|
||||||
messages.push(msg);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pageDirection: PageDirection.FORWARD
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(messages?.length).eq(totalMsgs);
|
|
||||||
const payloads = messages.map((msg) => msg.payload[0]!);
|
|
||||||
expect(payloads).to.deep.eq(Array.from(Array(totalMsgs).keys()));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Ordered Callback - Backward", async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
|
|
||||||
const totalMsgs = 18;
|
|
||||||
for (let i = 0; i < totalMsgs; i++) {
|
|
||||||
expect(
|
|
||||||
await nwaku.sendMessage(
|
|
||||||
NimGoNode.toMessageRpcQuery({
|
|
||||||
payload: new Uint8Array([i]),
|
|
||||||
contentTopic: TestContentTopic
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).to.be.true;
|
|
||||||
await delay(1); // to ensure each timestamp is unique.
|
|
||||||
}
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
let messages: IMessage[] = [];
|
|
||||||
await waku.store.queryWithOrderedCallback(
|
|
||||||
[TestDecoder],
|
|
||||||
async (msg) => {
|
|
||||||
messages.push(msg);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pageDirection: PageDirection.BACKWARD
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
messages = messages.reverse();
|
|
||||||
|
|
||||||
expect(messages?.length).eq(totalMsgs);
|
|
||||||
const payloads = messages.map((msg) => msg.payload![0]!);
|
|
||||||
expect(payloads).to.deep.eq(Array.from(Array(totalMsgs).keys()));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Generator, with asymmetric & symmetric encrypted messages", async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
|
|
||||||
const asymText = "This message is encrypted for me using asymmetric";
|
|
||||||
const asymTopic = "/test/1/asymmetric/proto";
|
|
||||||
const symText =
|
|
||||||
"This message is encrypted for me using symmetric encryption";
|
|
||||||
const symTopic = "/test/1/symmetric/proto";
|
|
||||||
const clearText = "This is a clear text message for everyone to read";
|
|
||||||
const otherText =
|
|
||||||
"This message is not for and I must not be able to read it";
|
|
||||||
|
|
||||||
const timestamp = new Date();
|
|
||||||
|
|
||||||
const asymMsg = { payload: utf8ToBytes(asymText), timestamp };
|
|
||||||
const symMsg = {
|
|
||||||
payload: utf8ToBytes(symText),
|
|
||||||
timestamp: new Date(timestamp.valueOf() + 1)
|
|
||||||
};
|
|
||||||
const clearMsg = {
|
|
||||||
payload: utf8ToBytes(clearText),
|
|
||||||
timestamp: new Date(timestamp.valueOf() + 2)
|
|
||||||
};
|
|
||||||
const otherMsg = {
|
|
||||||
payload: utf8ToBytes(otherText),
|
|
||||||
timestamp: new Date(timestamp.valueOf() + 3)
|
|
||||||
};
|
|
||||||
|
|
||||||
const privateKey = generatePrivateKey();
|
|
||||||
const symKey = generateSymmetricKey();
|
|
||||||
const publicKey = getPublicKey(privateKey);
|
|
||||||
|
|
||||||
const eciesEncoder = createEciesEncoder({
|
|
||||||
contentTopic: asymTopic,
|
|
||||||
publicKey
|
|
||||||
});
|
|
||||||
const symEncoder = createSymEncoder({
|
|
||||||
contentTopic: symTopic,
|
|
||||||
symKey
|
|
||||||
});
|
|
||||||
|
|
||||||
const otherEncoder = createEciesEncoder({
|
|
||||||
contentTopic: TestContentTopic,
|
|
||||||
publicKey: getPublicKey(generatePrivateKey())
|
|
||||||
});
|
|
||||||
|
|
||||||
const eciesDecoder = createEciesDecoder(asymTopic, privateKey);
|
|
||||||
const symDecoder = createSymDecoder(symTopic, symKey);
|
|
||||||
|
|
||||||
const [waku1, waku2, nimWakuMultiaddr] = await Promise.all([
|
|
||||||
createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
}).then((waku) => waku.start().then(() => waku)),
|
|
||||||
createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_2
|
|
||||||
}).then((waku) => waku.start().then(() => waku)),
|
|
||||||
nwaku.getMultiaddrWithId()
|
|
||||||
]);
|
|
||||||
|
|
||||||
log("Waku nodes created");
|
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
waku1.dial(nimWakuMultiaddr),
|
|
||||||
waku2.dial(nimWakuMultiaddr)
|
|
||||||
]);
|
|
||||||
|
|
||||||
log("Waku nodes connected to nwaku");
|
|
||||||
|
|
||||||
await waitForRemotePeer(waku1, [Protocols.LightPush]);
|
|
||||||
|
|
||||||
log("Sending messages using light push");
|
|
||||||
await Promise.all([
|
|
||||||
waku1.lightPush.send(eciesEncoder, asymMsg),
|
|
||||||
waku1.lightPush.send(symEncoder, symMsg),
|
|
||||||
waku1.lightPush.send(otherEncoder, otherMsg),
|
|
||||||
waku1.lightPush.send(TestEncoder, clearMsg)
|
|
||||||
]);
|
|
||||||
|
|
||||||
await waitForRemotePeer(waku2, [Protocols.Store]);
|
|
||||||
|
|
||||||
const messages: DecodedMessage[] = [];
|
|
||||||
log("Retrieve messages from store");
|
|
||||||
|
|
||||||
for await (const msgPromises of waku2.store.queryGenerator([
|
|
||||||
eciesDecoder,
|
|
||||||
symDecoder,
|
|
||||||
TestDecoder
|
|
||||||
])) {
|
|
||||||
for (const promise of msgPromises) {
|
|
||||||
const msg = await promise;
|
|
||||||
if (msg) {
|
|
||||||
messages.push(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Messages are ordered from oldest to latest within a page (1 page query)
|
|
||||||
expect(bytesToUtf8(messages[0].payload!)).to.eq(asymText);
|
|
||||||
expect(bytesToUtf8(messages[1].payload!)).to.eq(symText);
|
|
||||||
expect(bytesToUtf8(messages[2].payload!)).to.eq(clearText);
|
|
||||||
expect(messages?.length).eq(3);
|
|
||||||
|
|
||||||
!!waku1 && waku1.stop().catch((e) => console.log("Waku failed to stop", e));
|
|
||||||
!!waku2 && waku2.stop().catch((e) => console.log("Waku failed to stop", e));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Ordered callback, using start and end time", async function () {
|
|
||||||
this.timeout(20000);
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
|
|
||||||
const startTime = new Date();
|
|
||||||
// Set start time 15 seconds in the past
|
|
||||||
startTime.setTime(now.getTime() - 15 * 1000);
|
|
||||||
|
|
||||||
const message1Timestamp = new Date();
|
|
||||||
// Set first message was 10 seconds in the past
|
|
||||||
message1Timestamp.setTime(now.getTime() - 10 * 1000);
|
|
||||||
|
|
||||||
const message2Timestamp = new Date();
|
|
||||||
// Set second message 2 seconds in the past
|
|
||||||
message2Timestamp.setTime(now.getTime() - 2 * 1000);
|
|
||||||
const messageTimestamps = [message1Timestamp, message2Timestamp];
|
|
||||||
|
|
||||||
const endTime = new Date();
|
|
||||||
// Set end time 1 second in the past
|
|
||||||
endTime.setTime(now.getTime() - 1000);
|
|
||||||
|
|
||||||
for (let i = 0; i < 2; i++) {
|
|
||||||
expect(
|
|
||||||
await nwaku.sendMessage(
|
|
||||||
NimGoNode.toMessageRpcQuery({
|
|
||||||
payload: new Uint8Array([i]),
|
|
||||||
contentTopic: TestContentTopic,
|
|
||||||
timestamp: messageTimestamps[i]
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).to.be.true;
|
|
||||||
}
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
const firstMessages: IMessage[] = [];
|
|
||||||
await waku.store.queryWithOrderedCallback(
|
|
||||||
[TestDecoder],
|
|
||||||
(msg) => {
|
|
||||||
if (msg) {
|
|
||||||
firstMessages.push(msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timeFilter: { startTime, endTime: message1Timestamp }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const bothMessages: IMessage[] = [];
|
|
||||||
await waku.store.queryWithOrderedCallback(
|
|
||||||
[TestDecoder],
|
|
||||||
async (msg) => {
|
|
||||||
bothMessages.push(msg);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timeFilter: {
|
|
||||||
startTime,
|
|
||||||
endTime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(firstMessages?.length).eq(1);
|
|
||||||
|
|
||||||
expect(firstMessages[0].payload![0]!).eq(0);
|
|
||||||
|
|
||||||
expect(bothMessages?.length).eq(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Ordered callback, aborts when callback returns true", async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
|
|
||||||
const totalMsgs = 20;
|
|
||||||
|
|
||||||
for (let i = 0; i < totalMsgs; i++) {
|
|
||||||
expect(
|
|
||||||
await nwaku.sendMessage(
|
|
||||||
NimGoNode.toMessageRpcQuery({
|
|
||||||
payload: new Uint8Array([i]),
|
|
||||||
contentTopic: TestContentTopic
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).to.be.true;
|
|
||||||
await delay(1); // to ensure each timestamp is unique.
|
|
||||||
}
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
const desiredMsgs = 14;
|
|
||||||
const messages: IMessage[] = [];
|
|
||||||
await waku.store.queryWithOrderedCallback(
|
|
||||||
[TestDecoder],
|
|
||||||
async (msg) => {
|
|
||||||
messages.push(msg);
|
|
||||||
return messages.length >= desiredMsgs;
|
|
||||||
},
|
|
||||||
{ pageSize: 7 }
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(messages?.length).eq(desiredMsgs);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Waku Store, custom pubsub topic", () => {
|
|
||||||
const customPubSubTopic = "/waku/2/custom-dapp/proto";
|
|
||||||
let waku: LightNode;
|
|
||||||
let nwaku: NimGoNode;
|
|
||||||
|
|
||||||
const CustomPubSubTestDecoder = createDecoder(
|
|
||||||
TestContentTopic,
|
|
||||||
customPubSubTopic
|
|
||||||
);
|
|
||||||
|
|
||||||
beforeEach(async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
nwaku = new NimGoNode(makeLogFileName(this));
|
|
||||||
await nwaku.start({
|
|
||||||
store: true,
|
|
||||||
topic: customPubSubTopic,
|
|
||||||
relay: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(async function () {
|
|
||||||
!!nwaku &&
|
|
||||||
nwaku.stop().catch((e) => console.log("Nwaku failed to stop", e));
|
|
||||||
!!waku && waku.stop().catch((e) => console.log("Waku failed to stop", e));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Generator, custom pubsub topic", async function () {
|
|
||||||
this.timeout(15_000);
|
|
||||||
|
|
||||||
const totalMsgs = 20;
|
|
||||||
for (let i = 0; i < totalMsgs; i++) {
|
|
||||||
expect(
|
|
||||||
await nwaku.sendMessage(
|
|
||||||
NimGoNode.toMessageRpcQuery({
|
|
||||||
payload: new Uint8Array([i]),
|
|
||||||
contentTopic: TestContentTopic
|
|
||||||
}),
|
|
||||||
customPubSubTopic
|
|
||||||
)
|
|
||||||
).to.be.true;
|
|
||||||
}
|
|
||||||
|
|
||||||
waku = await createLightNode({
|
|
||||||
staticNoiseKey: NOISE_KEY_1,
|
|
||||||
pubSubTopics: [customPubSubTopic]
|
|
||||||
});
|
|
||||||
await waku.start();
|
|
||||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
|
||||||
await waitForRemotePeer(waku, [Protocols.Store]);
|
|
||||||
|
|
||||||
const messages: IMessage[] = [];
|
|
||||||
let promises: Promise<void>[] = [];
|
|
||||||
for await (const msgPromises of waku.store.queryGenerator([
|
|
||||||
CustomPubSubTestDecoder
|
|
||||||
])) {
|
|
||||||
const _promises = msgPromises.map(async (promise) => {
|
|
||||||
const msg = await promise;
|
|
||||||
if (msg) {
|
|
||||||
messages.push(msg);
|
|
||||||
expect(msg.pubSubTopic).to.eq(customPubSubTopic);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
promises = promises.concat(_promises);
|
|
||||||
}
|
|
||||||
await Promise.all(promises);
|
|
||||||
|
|
||||||
expect(messages?.length).eq(totalMsgs);
|
|
||||||
const result = messages?.findIndex((msg) => {
|
|
||||||
return msg.payload![0]! === 0;
|
|
||||||
});
|
|
||||||
expect(result).to.not.eq(-1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +1,18 @@
|
|||||||
import { createDecoder } from "@waku/core";
|
import {
|
||||||
import type { LightNode } from "@waku/interfaces";
|
createDecoder,
|
||||||
|
DefaultPubSubTopic,
|
||||||
|
waitForRemotePeer
|
||||||
|
} from "@waku/core";
|
||||||
|
import type { IMessage, LightNode } from "@waku/interfaces";
|
||||||
|
import { createLightNode, Protocols } from "@waku/sdk";
|
||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
|
||||||
import { makeLogFileName, NimGoNode, tearDownNodes } from "../../src/index.js";
|
import {
|
||||||
|
makeLogFileName,
|
||||||
|
NimGoNode,
|
||||||
|
NOISE_KEY_1,
|
||||||
|
tearDownNodes
|
||||||
|
} from "../../src/index.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
processMessages,
|
processMessages,
|
||||||
@ -10,41 +20,41 @@ import {
|
|||||||
startAndConnectLightNode
|
startAndConnectLightNode
|
||||||
} from "./utils.js";
|
} from "./utils.js";
|
||||||
|
|
||||||
const customPubSubTopic = "/waku/2/custom-dapp/proto";
|
|
||||||
const TestContentTopic = "/test/1/waku-store/utf8";
|
const TestContentTopic = "/test/1/waku-store/utf8";
|
||||||
const CustomPubSubTestDecoder = createDecoder(
|
const TestDecoder = createDecoder(TestContentTopic);
|
||||||
TestContentTopic,
|
const customContentTopic = "/test/2/waku-store/utf8";
|
||||||
customPubSubTopic
|
const customPubSubTopic = "/waku/2/custom-dapp/proto";
|
||||||
);
|
const customTestDecoder = createDecoder(customContentTopic, customPubSubTopic);
|
||||||
const totalMsgs = 20;
|
const totalMsgs = 20;
|
||||||
|
|
||||||
describe("Waku Store, custom pubsub topic", function () {
|
describe("Waku Store, custom pubsub topic", function () {
|
||||||
this.timeout(15000);
|
this.timeout(15000);
|
||||||
let waku: LightNode;
|
let waku: LightNode;
|
||||||
let nwaku: NimGoNode;
|
let nwaku: NimGoNode;
|
||||||
|
let nwaku2: NimGoNode;
|
||||||
|
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
this.timeout(15000);
|
this.timeout(15000);
|
||||||
nwaku = new NimGoNode(makeLogFileName(this));
|
nwaku = new NimGoNode(makeLogFileName(this));
|
||||||
await nwaku.startWithRetries({
|
await nwaku.start({
|
||||||
store: true,
|
store: true,
|
||||||
relay: true,
|
topic: [customPubSubTopic, DefaultPubSubTopic],
|
||||||
topic: customPubSubTopic
|
relay: true
|
||||||
});
|
});
|
||||||
await nwaku.ensureSubscriptions([customPubSubTopic]);
|
await nwaku.ensureSubscriptions([customPubSubTopic, DefaultPubSubTopic]);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async function () {
|
afterEach(async function () {
|
||||||
this.timeout(15000);
|
this.timeout(15000);
|
||||||
await tearDownNodes([nwaku], [waku]);
|
await tearDownNodes([nwaku, nwaku2], [waku]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Generator, custom pubsub topic", async function () {
|
it("Generator, custom pubsub topic", async function () {
|
||||||
await sendMessages(nwaku, totalMsgs, TestContentTopic, customPubSubTopic);
|
await sendMessages(nwaku, totalMsgs, customContentTopic, customPubSubTopic);
|
||||||
waku = await startAndConnectLightNode(nwaku, [customPubSubTopic]);
|
waku = await startAndConnectLightNode(nwaku, [customPubSubTopic]);
|
||||||
const messages = await processMessages(
|
const messages = await processMessages(
|
||||||
waku,
|
waku,
|
||||||
[CustomPubSubTestDecoder],
|
[customTestDecoder],
|
||||||
customPubSubTopic
|
customPubSubTopic
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -54,4 +64,84 @@ describe("Waku Store, custom pubsub topic", function () {
|
|||||||
});
|
});
|
||||||
expect(result).to.not.eq(-1);
|
expect(result).to.not.eq(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Generator, 2 different pubsubtopics", async function () {
|
||||||
|
this.timeout(10000);
|
||||||
|
|
||||||
|
const totalMsgs = 10;
|
||||||
|
await sendMessages(nwaku, totalMsgs, customContentTopic, customPubSubTopic);
|
||||||
|
await sendMessages(nwaku, totalMsgs, TestContentTopic, DefaultPubSubTopic);
|
||||||
|
|
||||||
|
waku = await startAndConnectLightNode(nwaku, [
|
||||||
|
customPubSubTopic,
|
||||||
|
DefaultPubSubTopic
|
||||||
|
]);
|
||||||
|
|
||||||
|
const customMessages = await processMessages(
|
||||||
|
waku,
|
||||||
|
[customTestDecoder],
|
||||||
|
customPubSubTopic
|
||||||
|
);
|
||||||
|
expect(customMessages?.length).eq(totalMsgs);
|
||||||
|
const result1 = customMessages?.findIndex((msg) => {
|
||||||
|
return msg.payload![0]! === 0;
|
||||||
|
});
|
||||||
|
expect(result1).to.not.eq(-1);
|
||||||
|
|
||||||
|
const testMessages = await processMessages(
|
||||||
|
waku,
|
||||||
|
[TestDecoder],
|
||||||
|
DefaultPubSubTopic
|
||||||
|
);
|
||||||
|
expect(testMessages?.length).eq(totalMsgs);
|
||||||
|
const result2 = testMessages?.findIndex((msg) => {
|
||||||
|
return msg.payload![0]! === 0;
|
||||||
|
});
|
||||||
|
expect(result2).to.not.eq(-1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Generator, 2 nwaku nodes each with different pubsubtopics", async function () {
|
||||||
|
this.timeout(10000);
|
||||||
|
|
||||||
|
// Set up and start a new nwaku node with Default PubSubtopic
|
||||||
|
nwaku2 = new NimGoNode(makeLogFileName(this) + "2");
|
||||||
|
await nwaku2.start({
|
||||||
|
store: true,
|
||||||
|
topic: [DefaultPubSubTopic],
|
||||||
|
relay: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalMsgs = 10;
|
||||||
|
await sendMessages(nwaku, totalMsgs, customContentTopic, customPubSubTopic);
|
||||||
|
await sendMessages(nwaku2, totalMsgs, TestContentTopic, DefaultPubSubTopic);
|
||||||
|
|
||||||
|
waku = await createLightNode({
|
||||||
|
staticNoiseKey: NOISE_KEY_1,
|
||||||
|
pubSubTopics: [customPubSubTopic, DefaultPubSubTopic]
|
||||||
|
});
|
||||||
|
await waku.start();
|
||||||
|
|
||||||
|
await waku.dial(await nwaku.getMultiaddrWithId());
|
||||||
|
await waku.dial(await nwaku2.getMultiaddrWithId());
|
||||||
|
await waitForRemotePeer(waku, [Protocols.Store]);
|
||||||
|
|
||||||
|
let customMessages: IMessage[] = [];
|
||||||
|
let testMessages: IMessage[] = [];
|
||||||
|
|
||||||
|
while (
|
||||||
|
customMessages.length != totalMsgs ||
|
||||||
|
testMessages.length != totalMsgs
|
||||||
|
) {
|
||||||
|
customMessages = await processMessages(
|
||||||
|
waku,
|
||||||
|
[customTestDecoder],
|
||||||
|
customPubSubTopic
|
||||||
|
);
|
||||||
|
testMessages = await processMessages(
|
||||||
|
waku,
|
||||||
|
[TestDecoder],
|
||||||
|
DefaultPubSubTopic
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user