diff --git a/.cspell.json b/.cspell.json index 0272a7c6b4..85ac69bf95 100644 --- a/.cspell.json +++ b/.cspell.json @@ -63,6 +63,7 @@ "nodekey", "opendns", "peerhave", + "portfinder", "prettierignore", "proto", "protobuf", diff --git a/package-lock.json b/package-lock.json index a46a37fbcb..be7b273864 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,6 +66,7 @@ "npm-run-all": "^4.1.5", "nyc": "^15.1.0", "p-timeout": "^4.1.0", + "portfinder": "^1.0.28", "prettier": "^2.1.1", "process": "^0.11.10", "puppeteer": "^13.0.1", @@ -11799,7 +11800,6 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "peer": true, "dependencies": { "minimist": "^1.2.5" }, @@ -13588,6 +13588,29 @@ "node": ">=6" } }, + "node_modules/portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -27204,7 +27227,6 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "peer": true, "requires": { "minimist": "^1.2.5" } @@ -28557,6 +28579,28 @@ "xmldom": "^0.6.0" } }, + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", diff --git a/package.json b/package.json index 8255870e83..27d1f5b777 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "npm-run-all": "^4.1.5", "nyc": "^15.1.0", "p-timeout": "^4.1.0", + "portfinder": "^1.0.28", "prettier": "^2.1.1", "process": "^0.11.10", "puppeteer": "^13.0.1", diff --git a/src/lib/waku_message/index.node.spec.ts b/src/lib/waku_message/index.node.spec.ts index a8b7e8fadb..b39b120bd1 100644 --- a/src/lib/waku_message/index.node.spec.ts +++ b/src/lib/waku_message/index.node.spec.ts @@ -36,13 +36,17 @@ describe('Waku Message [node only]', function () { nimWaku = new NimWaku(makeLogFileName(this)); dbg('Starting nim-waku node'); - await nimWaku.start({ rpcPrivate: true, lightpush: true }); + await nimWaku.start({ rpcPrivate: true }); dbg('Dialing to nim-waku node'); await waku.dial(await nimWaku.getMultiaddrWithId()); dbg('Wait for remote peer'); - await waku.waitForRemotePeer([Protocols.Relay, Protocols.LightPush]); + await waku.waitForRemotePeer([Protocols.Relay]); dbg('Remote peer ready'); + // As this test uses the nim-waku RPC API, we somehow often face + // Race conditions where the nim-waku node does not have the js-waku + // Node in its relay mesh just yet. + await delay(500); }); afterEach(async function () { diff --git a/src/lib/waku_store/index.node.spec.ts b/src/lib/waku_store/index.node.spec.ts index 96754e5cc8..e1b96f0f31 100644 --- a/src/lib/waku_store/index.node.spec.ts +++ b/src/lib/waku_store/index.node.spec.ts @@ -60,7 +60,7 @@ describe('Waku Store', () => { }); it('Retrieves history using callback', async function () { - this.timeout(5_000); + this.timeout(10_000); nimWaku = new NimWaku(makeLogFileName(this)); await nimWaku.start({ persistMessages: true }); diff --git a/src/lib/waku_store/index.ts b/src/lib/waku_store/index.ts index ee98e1fdaf..a2bc857ce5 100644 --- a/src/lib/waku_store/index.ts +++ b/src/lib/waku_store/index.ts @@ -143,7 +143,10 @@ export class WakuStore { }, { contentTopics } ); - dbg('Querying history with the following options', options); + dbg('Querying history with the following options', { + peerId: options?.peerId?.toB58String(), + ...options, + }); let peer; if (opts.peerId) { diff --git a/src/test_utils/nim_waku.ts b/src/test_utils/nim_waku.ts index 45acb94466..62960ede6d 100644 --- a/src/test_utils/nim_waku.ts +++ b/src/test_utils/nim_waku.ts @@ -4,13 +4,13 @@ */ import { ChildProcess, spawn } from 'child_process'; -import { randomInt } from 'crypto'; import appRoot from 'app-root-path'; import axios from 'axios'; import debug from 'debug'; import { Multiaddr, multiaddr } from 'multiaddr'; import PeerId from 'peer-id'; +import portfinder from 'portfinder'; import { hexToBuf } from '../lib/utils'; import { DefaultPubSubTopic } from '../lib/waku'; @@ -22,7 +22,6 @@ import waitForLine from './log_file'; const dbg = debug('waku:nim-waku'); -const NIM_WAKU_DEFAULT_RPC_PORT = 8545; const NIM_WAKU_DIR = appRoot + '/nim-waku'; const NIM_WAKU_BIN = NIM_WAKU_DIR + '/build/wakunode2'; @@ -43,6 +42,9 @@ export interface Args { topics?: string; rpcPrivate?: boolean; websocketSupport?: boolean; + tcpPort?: number; + rpcPort?: number; + websocketPort?: number; } export enum LogLevel { @@ -69,13 +71,12 @@ export interface WakuRelayMessage { export class NimWaku { private process?: ChildProcess; private pid?: number; - private portsShift: number; private peerId?: PeerId; private multiaddrWithId?: Multiaddr; - private logPath: string; + private readonly logPath: string; + private rpcPort?: number; constructor(logName: string) { - this.portsShift = randomInt(0, 5000); this.logPath = `${LOG_DIR}/nim-waku_${logName}.log`; } @@ -95,14 +96,29 @@ export class NimWaku { const mergedArgs = defaultArgs(); + const ports: number[] = await new Promise((resolve, reject) => { + portfinder.getPorts(3, {}, (err, ports) => { + if (err) reject(err); + resolve(ports); + }); + }); + + this.rpcPort = ports[0]; + // Object.assign overrides the properties with the source (if there are conflicts) Object.assign( mergedArgs, - { portsShift: this.portsShift, logLevel: LogLevel.Trace }, + { + tcpPort: ports[1], + rpcPort: this.rpcPort, + websocketPort: ports[2], + logLevel: LogLevel.Trace, + }, args ); const argsArray = argsToArray(mergedArgs); + dbg(`nim-waku args: ${argsArray}`); this.process = spawn(NIM_WAKU_BIN, argsArray, { cwd: NIM_WAKU_DIR, stdio: [ @@ -328,8 +344,7 @@ export class NimWaku { } get rpcUrl(): string { - const port = NIM_WAKU_DEFAULT_RPC_PORT + this.portsShift; - return `http://localhost:${port}/`; + return `http://localhost:${this.rpcPort}/`; } private async rpcCall(