Allow multiple wakunodes to be started in parallel

This commit is contained in:
Franck Royer 2021-03-12 17:08:42 +11:00
parent a0d6784e3c
commit fdbcbe0896
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
3 changed files with 57 additions and 62 deletions

View File

@ -1,6 +1,5 @@
import test from 'ava';
import Pubsub from 'libp2p-interfaces/src/pubsub';
import multiaddr from 'multiaddr';
import { delay } from '../test_utils/delay';
import { NimWaku } from '../test_utils/nim_waku';
@ -61,7 +60,7 @@ test('Nim-interop: nim-waku node connects to js node', async (t) => {
const multiAddrWithId = localMultiaddr + '/p2p/' + peerId;
const nimWaku = new NimWaku();
await nimWaku.start({ staticnode: multiAddrWithId });
await nimWaku.start(t.title, { staticnode: multiAddrWithId });
const nimPeers = await nimWaku.peers();
@ -73,11 +72,10 @@ test('Nim-interop: nim-waku node connects to js node', async (t) => {
},
]);
const nimAddress = await nimWaku.info().then((info) => info.listenStr);
const nimPeerId = nimAddress.match(/[\d\w]+$/)[0];
const nimPeerId = await nimWaku.getPeerId();
const jsPeers = node.peerStore.peers;
t.true(jsPeers.has(nimPeerId));
t.true(jsPeers.has(nimPeerId.toB58String()));
});
test('Nim-interop: js node subscribes to default waku topic (only checking js side)', async (t) => {
@ -91,16 +89,15 @@ test('Nim-interop: js node subscribes to default waku topic (only checking js si
const multiAddrWithId = localMultiaddr + '/p2p/' + peerId;
const nimWaku = new NimWaku();
await nimWaku.start({ staticnode: multiAddrWithId });
await nimWaku.start(t.title, { staticnode: multiAddrWithId });
const wakuRelayNode = new WakuRelay(node.pubsub);
await wakuRelayNode.subscribe();
const nimAddress = await nimWaku.info().then((info) => info.listenStr);
const nimPeerId = multiaddr(nimAddress).getPeerId();
const nimPeerId = await nimWaku.getPeerId();
const subscribers = node.pubsub.getSubscribers(TOPIC);
t.true(subscribers.includes(nimPeerId));
t.true(subscribers.includes(nimPeerId.toB58String()));
});
test('Nim-interop: nim node sends message', async (t) => {
@ -108,15 +105,13 @@ test('Nim-interop: nim node sends message', async (t) => {
const peerId = node.peerId.toB58String();
console.log(`js peer id: ${peerId}`);
const localMultiaddr = node.multiaddrs.find((addr) =>
addr.toString().match(/127\.0\.0\.1/)
);
const multiAddrWithId = localMultiaddr + '/p2p/' + peerId;
const nimWaku = new NimWaku();
await nimWaku.start({ staticnode: multiAddrWithId });
await nimWaku.start(t.title, { staticnode: multiAddrWithId });
const wakuRelayNode = new WakuRelay(node.pubsub);
await wakuRelayNode.subscribe();

View File

@ -1,9 +1,11 @@
import test from 'ava';
import { argsToArray, bufToHex, mergeArguments, strToHex } from './nim_waku';
import { argsToArray, bufToHex, defaultArgs, strToHex } from './nim_waku';
test('Correctly serialized arguments', (t) => {
const args = defaultArgs();
Object.assign(args, { portsShift: 42 });
test('Default arguments are correct', (t) => {
const args = mergeArguments({});
const actual = argsToArray(args);
const expected = [
@ -12,26 +14,7 @@ test('Default arguments are correct', (t) => {
'--relay=true',
'--rpc=true',
'--rpc-admin=true',
'--nodekey=B2C4E3DB22EA6EB6850689F7B3DF3DDA73F59C87EFFD902BEDCEE90A3A2341A6',
];
t.deepEqual(actual, expected);
});
test('Passing staticnode argument return default + static node', (t) => {
const args = mergeArguments({
staticnode: '/ip4/1.1.1.1/tcp/1234/p2p/aabbbccdd',
});
const actual = argsToArray(args);
const expected = [
'--nat=none',
'--listen-address=127.0.0.1',
'--relay=true',
'--rpc=true',
'--rpc-admin=true',
'--nodekey=B2C4E3DB22EA6EB6850689F7B3DF3DDA73F59C87EFFD902BEDCEE90A3A2341A6',
'--staticnode=/ip4/1.1.1.1/tcp/1234/p2p/aabbbccdd',
'--ports-shift=42',
];
t.deepEqual(actual, expected);

View File

@ -1,4 +1,5 @@
import { ChildProcess, spawn } from 'child_process';
import { randomInt } from 'crypto';
import * as fs from 'fs';
import { promisify } from 'util';
@ -14,12 +15,9 @@ import waitForLine from './log_file';
const openAsync = promisify(fs.open);
const NIM_WAKU_DEFAULT_P2P_PORT = 60000;
const NIM_WAKU_DEFAULT_RPC_PORT = 8545;
const NIM_WAKU_BIN = '/home/froyer/src/status-im/nim-waku/build/wakunode2';
const NIM_WAKU_RPC_URL = 'http://localhost:8545/';
const NIM_WAKU_PEER_ID = PeerId.createFromB58String(
'16Uiu2HAkyzsXzENw5XBDYEQQAeQTCYjBJpMLgBmEXuwbtcrgxBJ4'
);
const NIM_WAKKU_LISTEN_ADDR = multiaddr('/ip4/127.0.0.1/tcp/60000/');
export interface Args {
staticnode?: string;
@ -29,21 +27,32 @@ export interface Args {
rpc?: boolean;
rpcAdmin?: boolean;
nodekey?: string;
portsShift?: number;
}
export class NimWaku {
private process?: ChildProcess;
private portsShift: number;
private peerId?: PeerId;
async start(args: Args) {
// Start a local only node with the right RPC commands
// The fixed nodekey ensures the node has a fixed Peerid: 16Uiu2HAkyzsXzENw5XBDYEQQAeQTCYjBJpMLgBmEXuwbtcrgxBJ4
constructor() {
this.portsShift = randomInt(0, 5000);
}
const logPath = './nim-waku.log';
async start(testName: string, args: Args) {
const logFilePrefix = testName.replace(/ /g, '_').replace(/[':()]/g, '');
const logPath = `./${logFilePrefix}-nim-waku.log`;
const logFile = await openAsync(logPath, 'w');
const mergedArgs = argsToArray(mergeArguments(args));
this.process = spawn(NIM_WAKU_BIN, mergedArgs, {
const mergedArgs = defaultArgs();
// Object.assign overrides the properties with the source (if there are conflicts)
Object.assign(mergedArgs, { portsShift: this.portsShift }, args);
const argsArray = argsToArray(mergedArgs);
this.process = spawn(NIM_WAKU_BIN, argsArray, {
cwd: '/home/froyer/src/status-im/nim-waku/',
stdio: [
'ignore', // stdin
@ -57,7 +66,6 @@ export class NimWaku {
});
await waitForLine(logPath, 'RPC Server started');
console.log('Nim waku RPC is started');
}
/** Calls nim-waku2 JSON-RPC API `get_waku_v2_admin_v1_peers` to check
@ -72,7 +80,7 @@ export class NimWaku {
return res.result;
}
async info() {
async info(): Promise<RpcInfoResponse> {
this.checkProcess();
const res = await this.rpcCall('get_waku_v2_debug_v1_info', []);
@ -111,17 +119,30 @@ export class NimWaku {
return res.result;
}
get peerId(): PeerId {
return NIM_WAKU_PEER_ID;
async getPeerId(): Promise<PeerId> {
if (this.peerId) {
return this.peerId;
}
const res = await this.info();
const strPeerId = multiaddr(res.listenStr).getPeerId();
return PeerId.createFromB58String(strPeerId);
}
get multiaddr(): Multiaddr {
return NIM_WAKKU_LISTEN_ADDR;
const port = NIM_WAKU_DEFAULT_P2P_PORT + this.portsShift;
return multiaddr(`/ip4/127.0.0.1/tcp/${port}/`);
}
get rpcUrl(): string {
const port = NIM_WAKU_DEFAULT_RPC_PORT + this.portsShift;
return `http://localhost:${port}/`;
}
private async rpcCall(method: string, params: any[]) {
const res = await axios.post(
NIM_WAKU_RPC_URL,
this.rpcUrl,
{
jsonrpc: '2.0',
id: 1,
@ -159,25 +180,16 @@ export function argsToArray(args: Args): Array<string> {
return array;
}
function defaultArgs(): Args {
export function defaultArgs(): Args {
return {
nat: 'none',
listenAddress: '127.0.0.1',
relay: true,
rpc: true,
rpcAdmin: true,
nodekey: 'B2C4E3DB22EA6EB6850689F7B3DF3DDA73F59C87EFFD902BEDCEE90A3A2341A6',
};
}
export function mergeArguments(args: Args): Args {
const res = defaultArgs();
Object.assign(res, args);
return res;
}
export function strToHex(str: string): string {
let hex: string;
try {
@ -202,3 +214,8 @@ export function bufToHex(buffer: Uint8Array) {
.join('')
);
}
interface RpcInfoResponse {
// multiaddr including id.
listenStr: string;
}