From 52b1d640325cfd7c6b37c92d81d6d524316f1845 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Wed, 1 Nov 2023 11:45:19 +0000 Subject: [PATCH 01/21] fix node_logs for chopsticks --- .changeset/sweet-bats-punch.md | 6 ++++++ packages/cli/src/internal/localNode.ts | 4 ++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/sweet-bats-punch.md diff --git a/.changeset/sweet-bats-punch.md b/.changeset/sweet-bats-punch.md new file mode 100644 index 00000000..fe80fdbd --- /dev/null +++ b/.changeset/sweet-bats-punch.md @@ -0,0 +1,6 @@ +--- +"@moonwall/cli": patch +--- + +Fixes for tanssi +- [#295](https://github.com/Moonsong-Labs/moonwall/issues/295) diff --git a/packages/cli/src/internal/localNode.ts b/packages/cli/src/internal/localNode.ts index 2a119fb4..98de2015 100644 --- a/packages/cli/src/internal/localNode.ts +++ b/packages/cli/src/internal/localNode.ts @@ -1,6 +1,7 @@ import Debug from "debug"; import { execaCommand, execaCommandSync } from "execa"; import path from "path"; +import fs from "fs"; import WebSocket from "ws"; import { checkAccess, checkExists } from "./fileCheckers"; const debugNode = Debug("global:node"); @@ -17,6 +18,9 @@ export async function launchNode(cmd: string, args: string[], name: string): Pro } const dirPath = path.join(process.cwd(), "tmp", "node_logs"); + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true }); + } debugNode(`Launching dev node: ${name}`); const logLocation = path From 9bba37404ac454a4843a79cfc521723d6dfef71a Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Wed, 1 Nov 2023 18:35:17 +0000 Subject: [PATCH 02/21] switch nodes in tail zombie logs --- .changeset/sweet-bats-punch.md | 1 + packages/cli/src/cmds/runNetwork.ts | 190 ++++++++++++------ .../cli/src/internal/cmdFunctions/tempLogs.ts | 4 +- packages/cli/src/lib/globalContext.ts | 7 +- 4 files changed, 132 insertions(+), 70 deletions(-) diff --git a/.changeset/sweet-bats-punch.md b/.changeset/sweet-bats-punch.md index fe80fdbd..2383fea8 100644 --- a/.changeset/sweet-bats-punch.md +++ b/.changeset/sweet-bats-punch.md @@ -4,3 +4,4 @@ Fixes for tanssi - [#295](https://github.com/Moonsong-Labs/moonwall/issues/295) +- [#297](https://github.com/Moonsong-Labs/moonwall/issues/297) \ No newline at end of file diff --git a/packages/cli/src/cmds/runNetwork.ts b/packages/cli/src/cmds/runNetwork.ts index a57a202a..0e14a5ae 100644 --- a/packages/cli/src/cmds/runNetwork.ts +++ b/packages/cli/src/cmds/runNetwork.ts @@ -356,94 +356,154 @@ const resolveTestChoice = async (env: Environment, silent: boolean = false) => { const resolveTailChoice = async (env: Environment) => { let tailing: boolean = true; + let zombieNodePointer: number = 0; + let bottomBarContents = ""; + let switchNode: boolean; + let zombieNodes: string[] | undefined; + const resumePauseProse = [ - `, ${chalk.bgWhite.black("[p]")} - pause tail\n`, - `, ${chalk.bgWhite.black("[r]")} - resume tail\n`, + `, ${chalk.bgWhite.black("[p]")} - pause tail`, + `, ${chalk.bgWhite.black("[r]")} - resume tail`, ]; - const bottomBarContents = `📜 Tailing Logs, commands: ${chalk.bgWhite.black( + + const bottomBarBase = `📜 Tailing Logs, commands: ${chalk.bgWhite.black( "[q]" )} - quit, ${chalk.bgWhite.black("[t]")} - test, ${chalk.bgWhite.black("[g]")} - grep test`; + bottomBarContents = bottomBarBase + resumePauseProse[0]; const ui = new inquirer.ui.BottomBar({ - bottomBar: bottomBarContents + resumePauseProse[0], + bottomBar: bottomBarContents + "\n", }); - await new Promise(async (resolve) => { - const onData = (chunk: any) => ui.log.write(chunk.toString()); - const logFilePath = process.env.MOON_MONITORED_NODE - ? process.env.MOON_MONITORED_NODE - : process.env.MOON_LOG_LOCATION; + for (;;) { + if (process.env.MOON_ZOMBIE_NODES) { + zombieNodes = process.env.MOON_ZOMBIE_NODES + ? process.env.MOON_ZOMBIE_NODES.split("|") + : undefined; - // eslint-disable-next-line prefer-const - let currentReadPosition = 0; + bottomBarContents = + bottomBarBase + + resumePauseProse[0] + + `, ${chalk.bgWhite.black("[,]")} Next Log, ${chalk.bgWhite.black( + "[.]" + )} Previous Log | CurrentLog: ${`${zombieNodes[zombieNodePointer]} (${ + zombieNodePointer + 1 + }/${zombieNodes.length})`}`; + ui.updateBottomBar(bottomBarContents + "\n"); + } - const printLogs = (newReadPosition: number, currentReadPosition: number) => { - const stream = fs.createReadStream(logFilePath, { - start: currentReadPosition, - end: newReadPosition, - }); - stream.on("data", onData); - stream.on("end", () => { - currentReadPosition = newReadPosition; - }); - }; + switchNode = false; + await new Promise(async (resolve) => { + const onData = (chunk: any) => ui.log.write(chunk.toString()); + const logFilePath = process.env.MOON_MONITORED_NODE + ? process.env.MOON_MONITORED_NODE + : process.env.MOON_LOG_LOCATION; + + // eslint-disable-next-line prefer-const + let currentReadPosition = 0; + + const printLogs = (newReadPosition: number, currentReadPosition: number) => { + const stream = fs.createReadStream(logFilePath, { + start: currentReadPosition, + end: newReadPosition, + }); + stream.on("data", onData); + stream.on("end", () => { + currentReadPosition = newReadPosition; + }); + }; + + const readLog = () => { + const stats = fs.statSync(logFilePath); + const newReadPosition = stats.size; + + if (newReadPosition > currentReadPosition && tailing) { + printLogs(newReadPosition, currentReadPosition); + } + }; - const readLog = () => { - const stats = fs.statSync(logFilePath); - const newReadPosition = stats.size; + const incrPtr = () => { + zombieNodePointer = (zombieNodePointer + 1) % zombieNodes.length; + }; - if (newReadPosition > currentReadPosition && tailing) { - printLogs(newReadPosition, currentReadPosition); - } - }; + const decrPtr = () => { + zombieNodePointer = (zombieNodePointer - 1) % zombieNodes.length; + }; - printLogs(fs.statSync(logFilePath).size, 0); + printLogs(fs.statSync(logFilePath).size, 0); - const handleInputData = async (key: any) => { - ui.rl.input.pause(); - const char = key.toString().trim(); + const renderBottomBar = (...parts: any[]) => { + ui.updateBottomBar(bottomBarBase + " " + parts?.join(" ") + "\n"); + }; - if (char === "p") { - tailing = false; - ui.updateBottomBar(bottomBarContents + resumePauseProse[1]); - } + const handleInputData = async (key: any) => { + ui.rl.input.pause(); + const char = key.toString().trim(); - if (char === "r") { - printLogs(fs.statSync(logFilePath).size, currentReadPosition); - tailing = true; - ui.updateBottomBar(bottomBarContents + resumePauseProse[0]); - } + if (char === "p") { + tailing = false; + renderBottomBar(resumePauseProse[1]); + } - if (char === "q") { - ui.rl.input.removeListener("data", handleInputData); - ui.rl.input.pause(); - fs.unwatchFile(logFilePath); - resolve(""); - } + if (char === "r") { + printLogs(fs.statSync(logFilePath).size, currentReadPosition); + tailing = true; + renderBottomBar(resumePauseProse[0]); + } - if (char === "t") { - await resolveTestChoice(env, true); - ui.updateBottomBar(bottomBarContents + resumePauseProse[tailing ? 0 : 1]); - } + if (char === "q") { + ui.rl.input.removeListener("data", handleInputData); + ui.rl.input.pause(); + fs.unwatchFile(logFilePath); + resolve(""); + } - if (char === "g") { - ui.rl.input.pause(); - tailing = false; - await resolveGrepChoice(env, true); - ui.updateBottomBar(bottomBarContents + resumePauseProse[tailing ? 0 : 1]); - tailing = true; - ui.rl.input.resume(); - } + if (char === "t") { + await resolveTestChoice(env, true); + renderBottomBar(resumePauseProse[tailing ? 0 : 1]); + } - ui.rl.input.resume(); - }; + if (char === ",") { + ui.rl.input.removeListener("data", handleInputData); + ui.rl.input.pause(); + fs.unwatchFile(logFilePath); + switchNode = true; + incrPtr(); + resolve(""); + } - ui.rl.input.on("data", handleInputData); + if (char === ".") { + ui.rl.input.removeListener("data", handleInputData); + ui.rl.input.pause(); + fs.unwatchFile(logFilePath); + switchNode = true; + decrPtr(); + resolve(""); + } + + if (char === "g") { + ui.rl.input.pause(); + tailing = false; + await resolveGrepChoice(env, true); + renderBottomBar(resumePauseProse[tailing ? 0 : 1]); + tailing = true; + ui.rl.input.resume(); + } - fs.watchFile(logFilePath, () => { - readLog(); + ui.rl.input.resume(); + }; + + ui.rl.input.on("data", handleInputData); + + fs.watchFile(logFilePath, () => { + readLog(); + }); }); - }); + + if (!switchNode) { + break; + } + } ui.close(); }; diff --git a/packages/cli/src/internal/cmdFunctions/tempLogs.ts b/packages/cli/src/internal/cmdFunctions/tempLogs.ts index 7e8e0553..4c1e8eb1 100644 --- a/packages/cli/src/internal/cmdFunctions/tempLogs.ts +++ b/packages/cli/src/internal/cmdFunctions/tempLogs.ts @@ -22,7 +22,9 @@ export function reportLogLocation(silent: boolean = false) { let consoleMessage = ""; let filePath = ""; try { - filePath = process.env.MOON_LOG_LOCATION + filePath = process.env.MOON_ZOMBIE_DIR + ? process.env.MOON_ZOMBIE_DIR + : process.env.MOON_LOG_LOCATION ? process.env.MOON_LOG_LOCATION : path.join(dirPath, result.find((file) => path.extname(file) == ".log")!); consoleMessage = ` đŸĒĩ Log location: ${filePath}`; diff --git a/packages/cli/src/lib/globalContext.ts b/packages/cli/src/lib/globalContext.ts index e7bbb282..9e220955 100644 --- a/packages/cli/src/lib/globalContext.ts +++ b/packages/cli/src/lib/globalContext.ts @@ -164,8 +164,6 @@ export class MoonwallContext { const network = await zombie.start("", zombieConfig, { logType: "silent" }); process.env.MOON_RELAY_WSS = network.relay[0].wsUri; process.env.MOON_PARA_WSS = Object.values(network.paras)[0].nodes[0].wsUri; - process.env.MOON_ZOMBIE_PATH = network.client.tmpDir; - if ( env.foundation.type == "zombie" && env.foundation.zombieSpec.monitoredNode && @@ -174,6 +172,7 @@ export class MoonwallContext { process.env.MOON_MONITORED_NODE = `${network.tmpDir}/${env.foundation.zombieSpec.monitoredNode}.log`; } const nodeNames = Object.keys(network.nodesByName); + process.env.MOON_ZOMBIE_DIR = `${network.tmpDir}`; process.env.MOON_ZOMBIE_NODES = nodeNames.join("|"); const processIds = Object.values((network.client as any).processMap) @@ -254,10 +253,10 @@ export class MoonwallContext { if (this.foundation == "zombie") { let readStreams: any[]; if (!isOptionSet("disableLogEavesdropping")) { - console.log(`đŸĻģ Eavesdropping on node logs at ${process.env.MOON_ZOMBIE_PATH}`); + console.log(`đŸĻģ Eavesdropping on node logs at ${process.env.MOON_ZOMBIE_DIR}`); const zombieNodeLogs = process.env .MOON_ZOMBIE_NODES!.split("|") - .map((nodeName) => `${process.env.MOON_ZOMBIE_PATH}/${nodeName}.log`); + .map((nodeName) => `${process.env.MOON_ZOMBIE_DIR}/${nodeName}.log`); readStreams = zombieNodeLogs.map((logPath) => { const readStream = fs.createReadStream(logPath, { encoding: "utf8" }); From 8fbed43c022f302f4bd1742f454ada4c48444e3f Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Wed, 1 Nov 2023 18:53:45 +0000 Subject: [PATCH 03/21] logic fix --- packages/cli/src/cmds/runNetwork.ts | 30 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/cli/src/cmds/runNetwork.ts b/packages/cli/src/cmds/runNetwork.ts index 0e14a5ae..f81b887f 100644 --- a/packages/cli/src/cmds/runNetwork.ts +++ b/packages/cli/src/cmds/runNetwork.ts @@ -359,16 +359,18 @@ const resolveTailChoice = async (env: Environment) => { let zombieNodePointer: number = 0; let bottomBarContents = ""; let switchNode: boolean; + let zombieContent: string; let zombieNodes: string[] | undefined; const resumePauseProse = [ - `, ${chalk.bgWhite.black("[p]")} - pause tail`, - `, ${chalk.bgWhite.black("[r]")} - resume tail`, + `, ${chalk.bgWhite.black("[p]")} Pause tail`, + `, ${chalk.bgWhite.black("[r]")} Resume tail`, ]; const bottomBarBase = `📜 Tailing Logs, commands: ${chalk.bgWhite.black( "[q]" - )} - quit, ${chalk.bgWhite.black("[t]")} - test, ${chalk.bgWhite.black("[g]")} - grep test`; + )} Quit, ${chalk.bgWhite.black("[t]")} Test, ${chalk.bgWhite.black("[g]")} Grep test`; + bottomBarContents = bottomBarBase + resumePauseProse[0]; const ui = new inquirer.ui.BottomBar({ @@ -381,15 +383,15 @@ const resolveTailChoice = async (env: Environment) => { ? process.env.MOON_ZOMBIE_NODES.split("|") : undefined; - bottomBarContents = - bottomBarBase + - resumePauseProse[0] + - `, ${chalk.bgWhite.black("[,]")} Next Log, ${chalk.bgWhite.black( - "[.]" - )} Previous Log | CurrentLog: ${`${zombieNodes[zombieNodePointer]} (${ - zombieNodePointer + 1 - }/${zombieNodes.length})`}`; - ui.updateBottomBar(bottomBarContents + "\n"); + zombieContent = `, ${chalk.bgWhite.black("[,]")} Next Log, ${chalk.bgWhite.black( + "[.]" + )} Previous Log | CurrentLog: ${`${zombieNodes[zombieNodePointer]} (${ + zombieNodePointer + 1 + }/${zombieNodes.length})`}`; + + bottomBarContents = bottomBarBase + resumePauseProse[tailing ? 0 : 1] + zombieContent; + + ui.updateBottomBar(bottomBarContents, "\n"); } switchNode = false; @@ -427,13 +429,13 @@ const resolveTailChoice = async (env: Environment) => { }; const decrPtr = () => { - zombieNodePointer = (zombieNodePointer - 1) % zombieNodes.length; + zombieNodePointer = (zombieNodePointer - 1 + zombieNodes.length) % zombieNodes.length; }; printLogs(fs.statSync(logFilePath).size, 0); const renderBottomBar = (...parts: any[]) => { - ui.updateBottomBar(bottomBarBase + " " + parts?.join(" ") + "\n"); + ui.updateBottomBar(bottomBarBase + " " + parts?.join(" ") + zombieContent + "\n"); }; const handleInputData = async (key: any) => { From 78abb1e27104d4830fc94230d304cfa632b97358 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Thu, 2 Nov 2023 10:08:54 +0000 Subject: [PATCH 04/21] fmt fix --- packages/cli/src/cmds/runNetwork.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/cmds/runNetwork.ts b/packages/cli/src/cmds/runNetwork.ts index f81b887f..7f1a5c17 100644 --- a/packages/cli/src/cmds/runNetwork.ts +++ b/packages/cli/src/cmds/runNetwork.ts @@ -385,9 +385,9 @@ const resolveTailChoice = async (env: Environment) => { zombieContent = `, ${chalk.bgWhite.black("[,]")} Next Log, ${chalk.bgWhite.black( "[.]" - )} Previous Log | CurrentLog: ${`${zombieNodes[zombieNodePointer]} (${ - zombieNodePointer + 1 - }/${zombieNodes.length})`}`; + )} Previous Log | CurrentLog: ${chalk.bgWhite.black( + `${zombieNodes[zombieNodePointer]} (${zombieNodePointer + 1}/${zombieNodes.length})` + )}`; bottomBarContents = bottomBarBase + resumePauseProse[tailing ? 0 : 1] + zombieContent; From 7492e9c39e4ab01443047729ec39a1999198dcb9 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Thu, 2 Nov 2023 10:27:17 +0000 Subject: [PATCH 05/21] chopsticks cleans up logs --- .changeset/sweet-bats-punch.md | 3 ++- packages/cli/src/cmds/runNetwork.ts | 5 ++++- packages/cli/src/cmds/runTests.ts | 5 ++++- .../cli/src/internal/cmdFunctions/tempLogs.ts | 8 +++----- packages/types/config_schema.json | 4 ++++ packages/types/src/config.ts | 15 ++++++++++----- 6 files changed, 27 insertions(+), 13 deletions(-) diff --git a/.changeset/sweet-bats-punch.md b/.changeset/sweet-bats-punch.md index 2383fea8..c03336b0 100644 --- a/.changeset/sweet-bats-punch.md +++ b/.changeset/sweet-bats-punch.md @@ -4,4 +4,5 @@ Fixes for tanssi - [#295](https://github.com/Moonsong-Labs/moonwall/issues/295) -- [#297](https://github.com/Moonsong-Labs/moonwall/issues/297) \ No newline at end of file +- [#297](https://github.com/Moonsong-Labs/moonwall/issues/297) +- [#278](https://github.com/Moonsong-Labs/moonwall/issues/278) \ No newline at end of file diff --git a/packages/cli/src/cmds/runNetwork.ts b/packages/cli/src/cmds/runNetwork.ts index 7f1a5c17..4a936339 100644 --- a/packages/cli/src/cmds/runNetwork.ts +++ b/packages/cli/src/cmds/runNetwork.ts @@ -123,7 +123,10 @@ export async function runNetworkCmd(args) { }, ]; - if (env.foundation.type == "dev" && !env.foundation.launchSpec[0].retainAllLogs) { + if ( + (env.foundation.type == "dev" && !env.foundation.launchSpec[0].retainAllLogs) || + (env.foundation.type == "chopsticks" && !env.foundation.launchSpec[0].retainAllLogs) + ) { clearNodeLogs(); } diff --git a/packages/cli/src/cmds/runTests.ts b/packages/cli/src/cmds/runTests.ts index fcc69b53..a5ff5d55 100644 --- a/packages/cli/src/cmds/runTests.ts +++ b/packages/cli/src/cmds/runTests.ts @@ -26,7 +26,10 @@ export async function testCmd(envName: string, additionalArgs?: object): Promise await commonChecks(env); - if (env.foundation.type == "dev" && !env.foundation.launchSpec[0].retainAllLogs) { + if ( + (env.foundation.type == "dev" && !env.foundation.launchSpec[0].retainAllLogs) || + (env.foundation.type == "chopsticks" && !env.foundation.launchSpec[0].retainAllLogs) + ) { clearNodeLogs(); } const vitest = await executeTests(env, additionalArgs); diff --git a/packages/cli/src/internal/cmdFunctions/tempLogs.ts b/packages/cli/src/internal/cmdFunctions/tempLogs.ts index 4c1e8eb1..69f17597 100644 --- a/packages/cli/src/internal/cmdFunctions/tempLogs.ts +++ b/packages/cli/src/internal/cmdFunctions/tempLogs.ts @@ -1,15 +1,15 @@ import path from "path"; import fs from "fs"; -export function clearNodeLogs() { +export function clearNodeLogs(silent: boolean = true) { const dirPath = path.join(process.cwd(), "tmp", "node_logs"); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } - // Check for existing log files and delete const files = fs.readdirSync(dirPath); for (const file of files) { + !silent && console.log(`Deleting log: ${file}`); if (file.endsWith(".log")) { fs.unlinkSync(path.join(dirPath, file)); } @@ -32,9 +32,7 @@ export function reportLogLocation(silent: boolean = false) { console.error(e); } - if (!silent) { - console.log(consoleMessage); - } + !silent && console.log(consoleMessage); return filePath.trim(); } diff --git a/packages/types/config_schema.json b/packages/types/config_schema.json index 8af8f317..c8bc3f12 100644 --- a/packages/types/config_schema.json +++ b/packages/types/config_schema.json @@ -41,6 +41,10 @@ }, "type": "array" }, + "retainAllLogs": { + "description": "An optional flag to retain node logs from previous runs.", + "type": "boolean" + }, "running": { "description": "UNUSED", "type": "boolean" diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index cb0fd874..9a1470dd 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -291,6 +291,11 @@ export interface ChopsticksLaunchSpec extends GenericLaunchSpec { * This is only supported for single mode chopsticks. */ buildBlockMode?: "batch" | "manual" | "instant"; + + /** + * An optional flag to retain node logs from previous runs. + */ + retainAllLogs?: boolean; } /** @@ -317,11 +322,6 @@ export interface DevLaunchSpec extends GenericLaunchSpec { */ newRpcBehaviour?: boolean; - /** - * An optional flag to retain node logs from previous runs. - */ - retainAllLogs?: boolean; - /** * An optional object with p2pPort, wsPort, and rpcPort. */ @@ -341,6 +341,11 @@ export interface DevLaunchSpec extends GenericLaunchSpec { */ wsPort: number; }; + + /** + * An optional flag to retain node logs from previous runs. + */ + retainAllLogs?: boolean; } /** From d9022307e7e2600bbb51c67ce05d4cf3b3e443e9 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Thu, 2 Nov 2023 18:19:58 +0000 Subject: [PATCH 06/21] multiple confs --- packages/cli/package.json | 1 + packages/cli/src/cmds/entrypoint.ts | 15 +++- packages/cli/src/lib/configReader.ts | 33 +++++-- pnpm-lock.yaml | 129 ++++++++++++++++++++++++--- test/wadawmoonwall.config | 56 ++++++++++++ 5 files changed, 215 insertions(+), 19 deletions(-) create mode 100644 test/wadawmoonwall.config diff --git a/packages/cli/package.json b/packages/cli/package.json index 0cf68371..99172fae 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -86,6 +86,7 @@ "execa": "^8.0.1", "inquirer": "^9.2.11", "inquirer-press-to-continue": "^1.2.0", + "jsonc-parser": "^3.2.0", "minimatch": "^9.0.3", "node-fetch": "^3.3.2", "semver": "^7.5.4", diff --git a/packages/cli/src/cmds/entrypoint.ts b/packages/cli/src/cmds/entrypoint.ts index 4eeb0126..8bfe3672 100755 --- a/packages/cli/src/cmds/entrypoint.ts +++ b/packages/cli/src/cmds/entrypoint.ts @@ -1,6 +1,7 @@ import "../internal/logging"; import "@moonbeam-network/api-augment"; import yargs from "yargs"; +import fs from "fs"; import { hideBin } from "yargs/helpers"; import { testCmd } from "./runTests"; import { runNetworkCmd } from "./runNetwork"; @@ -10,6 +11,18 @@ import { fetchArtifact } from "../internal/cmdFunctions/fetchArtifact"; import dotenv from "dotenv"; dotenv.config(); +const defaultConfigFiles = ["./moonwall.config", "./moonwall.config.json"]; + +function findExistingConfig(files: string[]): string | undefined { + for (const file of files) { + if (fs.existsSync(file)) { + return file; + } + } +} + +const defaultConfigFile = findExistingConfig(defaultConfigFiles) || "./moonwall.config.json"; + // Hack to expose config-path to all commands and fallback const parsed = yargs(hideBin(process.argv)) .options({ @@ -17,7 +30,7 @@ const parsed = yargs(hideBin(process.argv)) type: "string", alias: "c", description: "path to MoonwallConfig file", - default: "./moonwall.config.json", + default: defaultConfigFile, }, }) .parseSync(); diff --git a/packages/cli/src/lib/configReader.ts b/packages/cli/src/lib/configReader.ts index 4cfeb309..01349f9b 100644 --- a/packages/cli/src/lib/configReader.ts +++ b/packages/cli/src/lib/configReader.ts @@ -2,10 +2,31 @@ import "@moonbeam-network/api-augment"; import { MoonwallConfig } from "@moonwall/types"; import fs, { readFile } from "fs/promises"; import { readFileSync } from "fs"; -import path from "path"; +import JSONC from "jsonc-parser"; +import path, { extname } from "path"; let cachedConfig: MoonwallConfig | undefined; +async function parseConfig(filePath: string) { + let result: any; + + const file = await readFile(filePath, "utf8"); + + switch (extname(filePath)) { + case ".json": + result = JSON.parse(file); + break; + case ".config": + result = JSONC.parse(file); + break; + default: + result = undefined; + break; + } + + return result; +} + export async function loadConfig(path: string): Promise { if ( !(await fs @@ -89,11 +110,13 @@ export async function importAsyncConfig(): Promise { const filePath = path.isAbsolute(configPath) ? configPath : path.join(process.cwd(), configPath); try { - const file = await readFile(filePath, "utf8"); - const json = JSON.parse(file); - const replacedJson = replaceEnvVars(json); + // const file = await readFile(filePath, "utf8"); + // const json = JSON.parse(file); - cachedConfig = replacedJson as MoonwallConfig; + const config = await parseConfig(filePath); + const replacedConfig = replaceEnvVars(config); + + cachedConfig = replacedConfig as MoonwallConfig; return cachedConfig; } catch (e) { console.error(e); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0da3e20..eb9748d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -129,6 +129,9 @@ importers: inquirer-press-to-continue: specifier: ^1.2.0 version: 1.2.0(inquirer@9.2.11) + jsonc-parser: + specifier: ^3.2.0 + version: 3.2.0 minimatch: specifier: ^9.0.3 version: 9.0.3 @@ -353,7 +356,7 @@ importers: devDependencies: '@acala-network/chopsticks': specifier: ^0.9.0 - version: 0.9.0(@polkadot/util@12.5.1)(debug@4.3.4) + version: 0.9.0(@polkadot/util@12.5.1) '@moonbeam-network/api-augment': specifier: ^0.2400.0 version: 0.2400.0 @@ -486,6 +489,48 @@ packages: '@polkadot/util': 12.5.1 '@polkadot/wasm-util': 7.2.2(@polkadot/util@12.5.1) + /@acala-network/chopsticks@0.9.0(@polkadot/util@12.5.1): + resolution: {integrity: sha512-jhbIjfgiM1A2RJssstgGUvNf3geOT/Ztm5Rz5m1qnmub/sCciQhHTg8rUtl2kNGdsW14WFm/HORIaz0lT/CyJA==} + hasBin: true + dependencies: + '@acala-network/chopsticks-core': 0.9.0(@polkadot/util@12.5.1) + '@acala-network/chopsticks-db': 0.9.0(@polkadot/util@12.5.1) + '@pnpm/npm-conf': 2.2.2 + axios: 1.5.1 + dotenv: 16.3.1 + global-agent: 3.0.0 + js-yaml: 4.1.0 + jsondiffpatch: 0.5.0 + lodash: 4.17.21 + ws: 8.14.2 + yargs: 17.7.2 + zod: 3.22.4 + transitivePeerDependencies: + - '@google-cloud/spanner' + - '@polkadot/util' + - '@sap/hana-client' + - better-sqlite3 + - bluebird + - bufferutil + - debug + - encoding + - hdb-pool + - ioredis + - mongodb + - mssql + - mysql2 + - oracledb + - pg + - pg-native + - pg-query-stream + - redis + - sql.js + - supports-color + - ts-node + - typeorm-aurora-data-api-driver + - utf-8-validate + dev: true + /@acala-network/chopsticks@0.9.0(@polkadot/util@12.5.1)(debug@4.3.4): resolution: {integrity: sha512-jhbIjfgiM1A2RJssstgGUvNf3geOT/Ztm5Rz5m1qnmub/sCciQhHTg8rUtl2kNGdsW14WFm/HORIaz0lT/CyJA==} hasBin: true @@ -526,6 +571,7 @@ packages: - ts-node - typeorm-aurora-data-api-driver - utf-8-validate + dev: false /@adraffy/ens-normalize@1.10.0: resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} @@ -1453,7 +1499,7 @@ packages: '@polkadot/api-augment': 10.10.1 '@polkadot/api-base': 10.10.1 '@polkadot/api-derive': 10.10.1 - '@polkadot/keyring': 12.5.1(@polkadot/util-crypto@12.5.1)(@polkadot/util@12.5.1) + '@polkadot/keyring': 12.5.1(@polkadot/util@12.5.1) '@polkadot/rpc-augment': 10.10.1 '@polkadot/rpc-core': 10.10.1 '@polkadot/rpc-provider': 10.10.1 @@ -1482,6 +1528,17 @@ packages: '@polkadot/util': 12.5.1 '@polkadot/util-crypto': 12.5.1(@polkadot/util@12.5.1) tslib: 2.6.2 + dev: false + + /@polkadot/keyring@12.5.1(@polkadot/util@12.5.1): + resolution: {integrity: sha512-u6b+Q7wI6WY/vwmJS9uUHy/5hKZ226nTlVNmxjkj9GvrRsQvUSwS94163yHPJwiZJiIv5xK5m0rwCMyoYu+wjA==} + engines: {node: '>=16'} + peerDependencies: + '@polkadot/util': 12.5.1 + dependencies: + '@polkadot/util': 12.5.1 + '@polkadot/util-crypto': 12.5.1(@polkadot/util@12.5.1) + tslib: 2.6.2 /@polkadot/networks@12.5.1: resolution: {integrity: sha512-PP6UUdzz6iHHZH4q96cUEhTcydHj16+61sqeaYEJSF6Q9iY+5WVWQ26+rdjmre/EBdrMQkSS/CKy73mO5z/JkQ==} @@ -1524,7 +1581,7 @@ packages: resolution: {integrity: sha512-VMDWoJgx6/mPHAOT66Sq+Jf2lJABfV/ZUIXtT2k8HjOndbm6oKrFqGEOSSLvB2q4olDee3FkFFxkyW1s6k4JaQ==} engines: {node: '>=16'} dependencies: - '@polkadot/keyring': 12.5.1(@polkadot/util-crypto@12.5.1)(@polkadot/util@12.5.1) + '@polkadot/keyring': 12.5.1(@polkadot/util@12.5.1) '@polkadot/types': 10.10.1 '@polkadot/types-support': 10.10.1 '@polkadot/util': 12.5.1 @@ -1590,7 +1647,7 @@ packages: resolution: {integrity: sha512-Ben62P1tjYEhKag34GBGcLX6NqcFR1VD5nNbWaxgr+t36Jl/tlHs6P9DlbFqQP7Tt9FmGrAYY0m3oTkhjG1NzA==} engines: {node: '>=16'} dependencies: - '@polkadot/keyring': 12.5.1(@polkadot/util-crypto@12.5.1)(@polkadot/util@12.5.1) + '@polkadot/keyring': 12.5.1(@polkadot/util@12.5.1) '@polkadot/types-augment': 10.10.1 '@polkadot/types-codec': 10.10.1 '@polkadot/types-create': 10.10.1 @@ -2463,7 +2520,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 transitivePeerDependencies: - supports-color @@ -2693,6 +2750,16 @@ packages: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} + /axios@1.5.1: + resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} + dependencies: + follow-redirects: 1.15.3 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: true + /axios@1.5.1(debug@4.3.4): resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} dependencies: @@ -2701,6 +2768,7 @@ packages: proxy-from-env: 1.1.0 transitivePeerDependencies: - debug + dev: false /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2751,6 +2819,7 @@ packages: /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + requiresBuild: true dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 @@ -3098,6 +3167,7 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + requiresBuild: true /config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} @@ -3209,6 +3279,17 @@ packages: ms: 2.1.3 dev: true + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -4061,6 +4142,16 @@ packages: tabbable: 6.2.0 dev: true + /follow-redirects@1.15.3: + resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: true + /follow-redirects@1.15.3(debug@4.3.4): resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} engines: {node: '>=4.0'} @@ -4071,6 +4162,7 @@ packages: optional: true dependencies: debug: 4.3.4(supports-color@8.1.1) + dev: false /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -4254,6 +4346,7 @@ packages: /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + requiresBuild: true dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -4318,6 +4411,7 @@ packages: /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + requiresBuild: true /grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} @@ -4407,7 +4501,7 @@ packages: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 transitivePeerDependencies: - supports-color optional: true @@ -4428,7 +4522,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 transitivePeerDependencies: - supports-color @@ -4461,6 +4555,7 @@ packages: /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + requiresBuild: true dependencies: safer-buffer: 2.1.2 @@ -4486,10 +4581,12 @@ packages: /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + requiresBuild: true /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + requiresBuild: true /infer-owner@1.0.4: resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} @@ -4771,6 +4868,7 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + requiresBuild: true /iso-random-stream@2.0.2: resolution: {integrity: sha512-yJvs+Nnelic1L2vH2JzWvvPQFA4r7kSTnpST/+LkAQjSz0hos2oqLD+qIVi9Qk38Hoe7mNDt3j0S27R58MVjLQ==} @@ -5183,6 +5281,7 @@ packages: /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + requiresBuild: true dependencies: brace-expansion: 1.1.11 @@ -5348,6 +5447,7 @@ packages: /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + requiresBuild: true /multiformats@9.9.0: resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} @@ -5436,7 +5536,7 @@ packages: resolution: {integrity: sha512-DDpmn5oLEdCTclEqweOT4U7bEpuoifBMFUXem9sA4turDAZ5tlbrEoWqCorwXey8CaAw44mst5JOQeVNiwtkhw==} engines: {node: '>= 10.13'} dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 json-stringify-safe: 5.0.1 lodash: 4.17.21 propagate: 2.0.1 @@ -5795,6 +5895,7 @@ packages: /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + requiresBuild: true /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} @@ -6290,6 +6391,7 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + requiresBuild: true /saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} @@ -6454,7 +6556,7 @@ packages: requiresBuild: true dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 socks: 2.7.1 transitivePeerDependencies: - supports-color @@ -6476,7 +6578,7 @@ packages: dependencies: command-exists: 1.2.9 commander: 8.3.0 - follow-redirects: 1.15.3(debug@4.3.4) + follow-redirects: 1.15.3 js-sha3: 0.8.0 memorystream: 0.3.1 semver: 5.7.2 @@ -7145,7 +7247,7 @@ packages: chalk: 4.1.2 cli-highlight: 2.1.11 date-fns: 2.30.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 dotenv: 16.3.1 glob: 8.1.0 mkdirp: 2.1.6 @@ -7353,7 +7455,7 @@ packages: hasBin: true dependencies: cac: 6.7.14 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 @@ -7599,7 +7701,7 @@ packages: acorn-walk: 8.2.0 cac: 6.7.14 chai: 4.3.10 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 local-pkg: 0.4.3 magic-string: 0.30.5 pathe: 1.1.1 @@ -8130,6 +8232,7 @@ packages: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + requiresBuild: true dependencies: isexe: 2.0.0 diff --git a/test/wadawmoonwall.config b/test/wadawmoonwall.config new file mode 100644 index 00000000..47f5592e --- /dev/null +++ b/test/wadawmoonwall.config @@ -0,0 +1,56 @@ +{ + "label": "Global Test Config đŸ¯", + "defaultTestTimeout": 60000, + "scriptsDir": "scripts/", + "additionalRepos": [ + { + "name": "astar", + "ghAuthor": "AstarNetwork", + "ghRepo": "Astar", + "binaries": [ + { + "name": "astar-collator*ubuntu-x86*", + "type": "tar", + "defaultArgs": ["--dev", "--sealing=manual", "--no-hardware-benchmarks", "--no-telemetry"] + } + ] + }, + { + "name": "hydra", + "ghAuthor": "galacticcouncil", + "ghRepo": "HydraDX-node", + "binaries": [ + { + "name": "hydradx" + } + ] + }, + { + "name": "interlay", + "ghAuthor": "interlay", + "ghRepo": "interbtc", + "binaries": [ + { + "name": "interbtc-parachain" + } + ] + } + ], + "environments": [ + { + "name": "interbtc", + "testFileDir": ["suites/basic"], + "description": "A star is born", + "foundation": { + "type": "dev", + "launchSpec": [ + { + "binPath": "./tmp/interbtc-parachain", + "disableDefaultEthProviders": true + } + ] + } + }, + + ] +} From e8f21b56a2de25d44f1cc9785a51dfd69b7556bd Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Thu, 2 Nov 2023 18:22:58 +0000 Subject: [PATCH 07/21] multiple confs --- test/{wadawmoonwall.config => moonwall.config} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{wadawmoonwall.config => moonwall.config} (100%) diff --git a/test/wadawmoonwall.config b/test/moonwall.config similarity index 100% rename from test/wadawmoonwall.config rename to test/moonwall.config From a9191fb7b189f2b18e2371dc2277ecddfee8c904 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Mon, 6 Nov 2023 09:47:47 +0000 Subject: [PATCH 08/21] Moved explicit schema definition from moonwall config file --- .changeset/sweet-bats-punch.md | 5 +++-- docs/guide/intro/getting-started.md | 2 -- packages/cli/src/cmds/entrypoint.ts | 2 +- packages/cli/src/internal/cmdFunctions/initialisation.ts | 8 +++++--- packages/types/config_schema.json | 4 ---- packages/types/src/config.ts | 5 ----- 6 files changed, 9 insertions(+), 17 deletions(-) diff --git a/.changeset/sweet-bats-punch.md b/.changeset/sweet-bats-punch.md index c03336b0..9827e074 100644 --- a/.changeset/sweet-bats-punch.md +++ b/.changeset/sweet-bats-punch.md @@ -1,8 +1,9 @@ --- -"@moonwall/cli": patch +"@moonwall/cli": minor --- Fixes for tanssi - [#295](https://github.com/Moonsong-Labs/moonwall/issues/295) - [#297](https://github.com/Moonsong-Labs/moonwall/issues/297) -- [#278](https://github.com/Moonsong-Labs/moonwall/issues/278) \ No newline at end of file +- [#278](https://github.com/Moonsong-Labs/moonwall/issues/278) +- [#221](https://github.com/Moonsong-Labs/moonwall/issues/221) \ No newline at end of file diff --git a/docs/guide/intro/getting-started.md b/docs/guide/intro/getting-started.md index 9e0fa6ac..1879e29d 100644 --- a/docs/guide/intro/getting-started.md +++ b/docs/guide/intro/getting-started.md @@ -92,7 +92,6 @@ After following the wizard, the following json file will be created: ```json { - "$schema": "https://raw.githubusercontent.com/Moonsong-Labs/moonwall/main/packages/types/config_schema.json", "label": "moonwall_config", "defaultTestTimeout": 30000, "environments": [ @@ -165,7 +164,6 @@ Open your code editor and edit the `moonwall.config.json` so that it now has the ```json{12-16} { - "$schema": "https://raw.githubusercontent.com/Moonsong-Labs/moonwall/main/packages/types/config_schema.json", "label": "moonwall_config", "defaultTestTimeout": 30000, "environments": [ diff --git a/packages/cli/src/cmds/entrypoint.ts b/packages/cli/src/cmds/entrypoint.ts index 8bfe3672..91373ee6 100755 --- a/packages/cli/src/cmds/entrypoint.ts +++ b/packages/cli/src/cmds/entrypoint.ts @@ -44,7 +44,7 @@ yargs(hideBin(process.argv)) type: "string", alias: "c", description: "path to MoonwallConfig file", - default: "./moonwall.config.json", + default: defaultConfigFile, }, }) .middleware((argv) => { diff --git a/packages/cli/src/internal/cmdFunctions/initialisation.ts b/packages/cli/src/internal/cmdFunctions/initialisation.ts index 44e985bb..c97828c4 100644 --- a/packages/cli/src/internal/cmdFunctions/initialisation.ts +++ b/packages/cli/src/internal/cmdFunctions/initialisation.ts @@ -32,7 +32,8 @@ export async function generateConfig() { 3 ); - await fs.writeFile("moonwall.config.json", JSONBlob, "utf-8"); + await fs.writeFile("moonwall.config", textBlob + JSONBlob, "utf-8"); + process.env.MOON_CONFIG_PATH = "./moonwall.config" break; } else { console.log("ℹī¸ Config file already exists at this location. Quitting."); @@ -111,8 +112,6 @@ export function createConfig(options: { testDir: string; }): MoonwallConfig { return { - $schema: - "https://raw.githubusercontent.com/Moonsong-Labs/moonwall/main/packages/types/config_schema.json", label: options.label, defaultTestTimeout: options.timeout, environments: [ @@ -126,3 +125,6 @@ export function createConfig(options: { ], }; } + + +const textBlob = `// TEST TEST TEST\n` \ No newline at end of file diff --git a/packages/types/config_schema.json b/packages/types/config_schema.json index c8bc3f12..fbfbd310 100644 --- a/packages/types/config_schema.json +++ b/packages/types/config_schema.json @@ -500,10 +500,6 @@ }, "description": "The main configuration object for Moonwall.", "properties": { - "$schema": { - "description": "The JSON schema for the config.", - "type": "string" - }, "additionalRepos": { "description": "Use this to specify additional repos to download binaries from.\nPolkadot, Tanssi and Moonbeam are available by default.", "items": { diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index 9a1470dd..b94d18eb 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -5,11 +5,6 @@ import type { LogType } from "@zombienet/utils"; * The main configuration object for Moonwall. */ export type MoonwallConfig = { - /** - * The JSON schema for the config. - */ - $schema: string; - /** * A label for the config. */ From 35af606b4d0894e17c5ca1e640a2ecb33f30b548 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Mon, 6 Nov 2023 09:48:47 +0000 Subject: [PATCH 09/21] removed test config file --- test/moonwall.config | 56 -------------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 test/moonwall.config diff --git a/test/moonwall.config b/test/moonwall.config deleted file mode 100644 index 47f5592e..00000000 --- a/test/moonwall.config +++ /dev/null @@ -1,56 +0,0 @@ -{ - "label": "Global Test Config đŸ¯", - "defaultTestTimeout": 60000, - "scriptsDir": "scripts/", - "additionalRepos": [ - { - "name": "astar", - "ghAuthor": "AstarNetwork", - "ghRepo": "Astar", - "binaries": [ - { - "name": "astar-collator*ubuntu-x86*", - "type": "tar", - "defaultArgs": ["--dev", "--sealing=manual", "--no-hardware-benchmarks", "--no-telemetry"] - } - ] - }, - { - "name": "hydra", - "ghAuthor": "galacticcouncil", - "ghRepo": "HydraDX-node", - "binaries": [ - { - "name": "hydradx" - } - ] - }, - { - "name": "interlay", - "ghAuthor": "interlay", - "ghRepo": "interbtc", - "binaries": [ - { - "name": "interbtc-parachain" - } - ] - } - ], - "environments": [ - { - "name": "interbtc", - "testFileDir": ["suites/basic"], - "description": "A star is born", - "foundation": { - "type": "dev", - "launchSpec": [ - { - "binPath": "./tmp/interbtc-parachain", - "disableDefaultEthProviders": true - } - ] - } - }, - - ] -} From fc1e674268de0d0663a21860b8b24d5694eafb34 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Mon, 6 Nov 2023 09:49:31 +0000 Subject: [PATCH 10/21] fmt fix --- packages/cli/src/internal/cmdFunctions/initialisation.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/internal/cmdFunctions/initialisation.ts b/packages/cli/src/internal/cmdFunctions/initialisation.ts index c97828c4..df0c953e 100644 --- a/packages/cli/src/internal/cmdFunctions/initialisation.ts +++ b/packages/cli/src/internal/cmdFunctions/initialisation.ts @@ -33,7 +33,7 @@ export async function generateConfig() { ); await fs.writeFile("moonwall.config", textBlob + JSONBlob, "utf-8"); - process.env.MOON_CONFIG_PATH = "./moonwall.config" + process.env.MOON_CONFIG_PATH = "./moonwall.config"; break; } else { console.log("ℹī¸ Config file already exists at this location. Quitting."); @@ -126,5 +126,4 @@ export function createConfig(options: { }; } - -const textBlob = `// TEST TEST TEST\n` \ No newline at end of file +const textBlob = `// TEST TEST TEST\n`; From 34914bbac71ac43a246ebfbd0ae38299270fba8b Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Mon, 6 Nov 2023 10:07:40 +0000 Subject: [PATCH 11/21] fix config --- .../internal/cmdFunctions/initialisation.ts | 6 ++- packages/cli/src/lib/configReader.ts | 47 +++++++++---------- test/moonwall.config | 23 +++++++++ ...ll.config.json => wwwmoonwall.config.json} | 0 4 files changed, 51 insertions(+), 25 deletions(-) create mode 100644 test/moonwall.config rename test/{moonwall.config.json => wwwmoonwall.config.json} (100%) diff --git a/packages/cli/src/internal/cmdFunctions/initialisation.ts b/packages/cli/src/internal/cmdFunctions/initialisation.ts index df0c953e..058cf62e 100644 --- a/packages/cli/src/internal/cmdFunctions/initialisation.ts +++ b/packages/cli/src/internal/cmdFunctions/initialisation.ts @@ -126,4 +126,8 @@ export function createConfig(options: { }; } -const textBlob = `// TEST TEST TEST\n`; +const textBlob = `// This Moonwall Config file should be modified to include all types +// of environments you wish to test against. + +// For more information on how to configure Moonwall, please visit: +// https://moonsong-labs.github.io/moonwall/config/intro.html\n`; diff --git a/packages/cli/src/lib/configReader.ts b/packages/cli/src/lib/configReader.ts index 01349f9b..a5e1d838 100644 --- a/packages/cli/src/lib/configReader.ts +++ b/packages/cli/src/lib/configReader.ts @@ -1,6 +1,6 @@ import "@moonbeam-network/api-augment"; import { MoonwallConfig } from "@moonwall/types"; -import fs, { readFile } from "fs/promises"; +import { readFile } from "fs/promises"; import { readFileSync } from "fs"; import JSONC from "jsonc-parser"; import path, { extname } from "path"; @@ -26,22 +26,27 @@ async function parseConfig(filePath: string) { return result; } + function parseConfigSync(filePath: string) { + let result: any; + + const file = readFileSync(filePath, "utf8"); -export async function loadConfig(path: string): Promise { - if ( - !(await fs - .access(path) - .then(() => true) - .catch(() => false)) - ) { - throw new Error(`Moonwall Config file ${path} cannot be found`); + switch (extname(filePath)) { + case ".json": + result = JSON.parse(file); + break; + case ".config": + result = JSONC.parse(file); + break; + default: + result = undefined; + break; } - const file = await fs.readFile(path, { encoding: "utf-8" }); - const json: MoonwallConfig = JSON.parse(file); - return json; + return result; } + export async function importConfig(configPath: string): Promise { return await import(configPath); } @@ -70,10 +75,9 @@ export async function cacheConfig() { const configPath = process.env.MOON_CONFIG_PATH!; const filePath = path.isAbsolute(configPath) ? configPath : path.join(process.cwd(), configPath); try { - const file = await readFile(filePath, "utf8"); - const json = JSON.parse(file); - const replacedJson = replaceEnvVars(json); - cachedConfig = replacedJson as MoonwallConfig; + const config = parseConfigSync(filePath); + const replacedConfig = replaceEnvVars(config); + cachedConfig = replacedConfig as MoonwallConfig; } catch (e) { console.error(e); throw new Error(`Error import config at ${filePath}`); @@ -89,11 +93,9 @@ export function importJsonConfig(): MoonwallConfig { const filePath = path.isAbsolute(configPath) ? configPath : path.join(process.cwd(), configPath); try { - const file = readFileSync(filePath, "utf8"); - const json = JSON.parse(file); - const replacedJson = replaceEnvVars(json); - - cachedConfig = replacedJson as MoonwallConfig; + const config = parseConfigSync(filePath); + const replacedConfig = replaceEnvVars(config); + cachedConfig = replacedConfig as MoonwallConfig; return cachedConfig; } catch (e) { console.error(e); @@ -110,9 +112,6 @@ export async function importAsyncConfig(): Promise { const filePath = path.isAbsolute(configPath) ? configPath : path.join(process.cwd(), configPath); try { - // const file = await readFile(filePath, "utf8"); - // const json = JSON.parse(file); - const config = await parseConfig(filePath); const replacedConfig = replaceEnvVars(config); diff --git a/test/moonwall.config b/test/moonwall.config new file mode 100644 index 00000000..1c7dce7f --- /dev/null +++ b/test/moonwall.config @@ -0,0 +1,23 @@ +// This Moonwall Config file should be modified to include all types +// of environments you wish to test against. + +// For more information on how to configure Moonwall, please visit: +// https://moonsong-labs.github.io/moonwall/config/intro.html +{ + "label": "moonwall_config", + "defaultTestTimeout": 30000, + "environments": [ + { + "name": "default_env", + "testFileDir": [ + "tests/" + ], + "foundation": { + "type": "dev", + "launchSpec": [{ + "binPath": "./tmp/moonbeam" + }] + } + } + ] +} \ No newline at end of file diff --git a/test/moonwall.config.json b/test/wwwmoonwall.config.json similarity index 100% rename from test/moonwall.config.json rename to test/wwwmoonwall.config.json From 6b94aaf694c16574f50a38b8f0472d46e50dad24 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Mon, 6 Nov 2023 10:42:45 +0000 Subject: [PATCH 12/21] tail msg fix --- packages/cli/src/cmds/runNetwork.ts | 5 ++++- packages/cli/src/internal/fileCheckers.ts | 14 ++++++++++---- packages/cli/src/internal/localNode.ts | 2 +- packages/cli/src/lib/configReader.ts | 3 +-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/cmds/runNetwork.ts b/packages/cli/src/cmds/runNetwork.ts index 4a936339..3f27143c 100644 --- a/packages/cli/src/cmds/runNetwork.ts +++ b/packages/cli/src/cmds/runNetwork.ts @@ -438,7 +438,10 @@ const resolveTailChoice = async (env: Environment) => { printLogs(fs.statSync(logFilePath).size, 0); const renderBottomBar = (...parts: any[]) => { - ui.updateBottomBar(bottomBarBase + " " + parts?.join(" ") + zombieContent + "\n"); + const content = process.env.MOON_ZOMBIE_NODES + ? bottomBarBase + " " + parts?.join(" ") + zombieContent + "\n" + : bottomBarBase + " " + parts?.join(" ") + "\n"; + ui.updateBottomBar(content); }; const handleInputData = async (key: any) => { diff --git a/packages/cli/src/internal/fileCheckers.ts b/packages/cli/src/internal/fileCheckers.ts index d50285e7..fc52a5dd 100644 --- a/packages/cli/src/internal/fileCheckers.ts +++ b/packages/cli/src/internal/fileCheckers.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; -import { execFileSync, execSync } from "child_process"; +import { execSync } from "child_process"; +import { execaSync } from "execa"; import chalk from "chalk"; import os from "node:os"; import inquirer from "inquirer"; @@ -109,11 +110,16 @@ export function checkAlreadyRunning(binaryName: string): number[] { try { console.log(`Checking if ${chalk.bgWhiteBright.blackBright(binaryName)} is already running...`); // pgrep only supports 15 characters - const stdOut = execFileSync("pgrep", [binaryName.slice(0, 14)], { encoding: "utf-8" }); - const pIdStrings = stdOut.split("\n").filter(Boolean); + const { stdout } = execaSync("pgrep", [binaryName.slice(0, 14)], { + encoding: "utf8", + shell: true, + timeout: 2000, + cleanup: true, + }); + const pIdStrings = stdout.split("\n").filter(Boolean); return pIdStrings.map((pId) => parseInt(pId, 10)); } catch (error: any) { - if (error.status === 1) { + if (error.exitCode === 1) { return []; } throw error; diff --git a/packages/cli/src/internal/localNode.ts b/packages/cli/src/internal/localNode.ts index 98de2015..eec90d8f 100644 --- a/packages/cli/src/internal/localNode.ts +++ b/packages/cli/src/internal/localNode.ts @@ -159,7 +159,7 @@ async function checkWebSocketJSONRPC(port: number): Promise { function findPortsByPid(pid: number, retryDelay: number = 10000) { for (;;) { const command = `lsof -i -n -P | grep LISTEN | grep ${pid} || true`; - const { stdout } = execaCommandSync(command, { shell: true, cleanup: true }); + const { stdout } = execaCommandSync(command, { shell: true, cleanup: true, timeout: 2000 }); const ports: number[] = []; const lines = stdout.split("\n"); diff --git a/packages/cli/src/lib/configReader.ts b/packages/cli/src/lib/configReader.ts index a5e1d838..b5a2dc85 100644 --- a/packages/cli/src/lib/configReader.ts +++ b/packages/cli/src/lib/configReader.ts @@ -26,7 +26,7 @@ async function parseConfig(filePath: string) { return result; } - function parseConfigSync(filePath: string) { +function parseConfigSync(filePath: string) { let result: any; const file = readFileSync(filePath, "utf8"); @@ -46,7 +46,6 @@ async function parseConfig(filePath: string) { return result; } - export async function importConfig(configPath: string): Promise { return await import(configPath); } From 273f8a1500f6299f2f0c656583bbf8994747f8ba Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Mon, 6 Nov 2023 10:47:08 +0000 Subject: [PATCH 13/21] restore config --- test/moonwall.config | 23 ------------------- ...nwall.config.json => moonwall.config.json} | 0 2 files changed, 23 deletions(-) delete mode 100644 test/moonwall.config rename test/{wwwmoonwall.config.json => moonwall.config.json} (100%) diff --git a/test/moonwall.config b/test/moonwall.config deleted file mode 100644 index 1c7dce7f..00000000 --- a/test/moonwall.config +++ /dev/null @@ -1,23 +0,0 @@ -// This Moonwall Config file should be modified to include all types -// of environments you wish to test against. - -// For more information on how to configure Moonwall, please visit: -// https://moonsong-labs.github.io/moonwall/config/intro.html -{ - "label": "moonwall_config", - "defaultTestTimeout": 30000, - "environments": [ - { - "name": "default_env", - "testFileDir": [ - "tests/" - ], - "foundation": { - "type": "dev", - "launchSpec": [{ - "binPath": "./tmp/moonbeam" - }] - } - } - ] -} \ No newline at end of file diff --git a/test/wwwmoonwall.config.json b/test/moonwall.config.json similarity index 100% rename from test/wwwmoonwall.config.json rename to test/moonwall.config.json From b71fe1c7a62f1dc23a37b12f26cb2a590ac1b95e Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:51:54 +0000 Subject: [PATCH 14/21] zombienet two-way IPC communication --- packages/cli/package.json | 8 +- packages/cli/src/lib/globalContext.ts | 63 ++++- packages/types/package.json | 4 +- packages/util/package.json | 2 +- pnpm-lock.yaml | 378 +++++++------------------- test/package.json | 6 +- test/suites/zombie/test_basic.ts | 64 ++++- 7 files changed, 215 insertions(+), 310 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 99172fae..0938d0b3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -73,8 +73,8 @@ "@polkadot/types-codec": "^10.10.1", "@polkadot/util": "^12.5.1", "@polkadot/util-crypto": "^12.5.1", - "@zombienet/orchestrator": "^0.0.59", - "@zombienet/utils": "^0.0.23", + "@zombienet/orchestrator": "^0.0.62", + "@zombienet/utils": "^0.0.24", "bottleneck": "^2.19.5", "chalk": "^5.3.0", "clear": "^0.1.0", @@ -82,7 +82,7 @@ "colors": "^1.4.0", "debug": "^4.3.4", "dotenv": "^16.3.1", - "ethers": "^6.8.0", + "ethers": "^6.8.1", "execa": "^8.0.1", "inquirer": "^9.2.11", "inquirer-press-to-continue": "^1.2.0", @@ -101,7 +101,7 @@ "devDependencies": { "@types/cli-progress": "^3.11.4", "@types/debug": "^4.1.10", - "@types/node": "^20.8.9", + "@types/node": "^20.8.10", "@types/yargs": "^17.0.29", "prettier": "^2.8.8", "tsup": "^7.2.0", diff --git a/packages/cli/src/lib/globalContext.ts b/packages/cli/src/lib/globalContext.ts index 9e220955..8e101120 100644 --- a/packages/cli/src/lib/globalContext.ts +++ b/packages/cli/src/lib/globalContext.ts @@ -12,6 +12,7 @@ import zombie, { Network } from "@zombienet/orchestrator"; import { execaCommand, execaCommandSync } from "execa"; import Debug from "debug"; import fs from "fs"; +import net from "net"; import readline from "readline"; import { setTimeout as timer } from "timers/promises"; import { parseChopsticksRunCmd, parseRunCmd, parseZombieCmd } from "../internal/commandParsers"; @@ -38,6 +39,7 @@ export class MoonwallContext { foundation: FoundationType; zombieNetwork?: Network; rtUpgradePath?: string; + ipcServer?: net.Server; constructor(config: MoonwallConfig) { const env = config.environments.find(({ name }) => name == process.env.MOON_TEST_ENV)!; @@ -187,6 +189,47 @@ export class MoonwallContext { } }; + const socketPath = `${network.tmpDir}/node-ipc.sock`; + + const server = net.createServer((client) => { + client.on("end", () => { + console.log("📨 IPC client disconnected"); + }); + + client.on("data", async (data) => { + try { + const message = JSON.parse(data.toString()); + + if (message.cmd === "restart") { + console.log(`Restarting ${message.node}, please wait...`); + await network.client.restartNode(message.node, 0); + console.log(`✅ Node: "${message.node}" restarted`); + + // change the process map to use the new PID + await this.disconnect(); + await this.connectEnvironment(true); + + if (client.writable) { + client.write( + JSON.stringify({ status: "success", message: `${message.node} restarted` }) + ); + } else { + console.log("Client disconnected, cannot send response."); + } + } + } catch (e) { + console.log("📨 Message from client:", data.toString()); + } + }); + }); + + server.listen(socketPath, () => { + console.log("📨 IPC Server listening on", socketPath); + }); + + this.ipcServer = server; + process.env.MOON_IPC_SOCKET = socketPath; + process.once("exit", onProcessExit); process.once("SIGINT", onProcessExit); @@ -225,7 +268,7 @@ export class MoonwallContext { return MoonwallContext.getContext(); } - public async connectEnvironment(): Promise { + public async connectEnvironment(silent: boolean = false): Promise { const config = await importAsyncConfig(); const env = config.environments.find(({ name }) => name == process.env.MOON_TEST_ENV)!; @@ -253,7 +296,7 @@ export class MoonwallContext { if (this.foundation == "zombie") { let readStreams: any[]; if (!isOptionSet("disableLogEavesdropping")) { - console.log(`đŸĻģ Eavesdropping on node logs at ${process.env.MOON_ZOMBIE_DIR}`); + !silent && console.log(`đŸĻģ Eavesdropping on node logs at ${process.env.MOON_ZOMBIE_DIR}`); const zombieNodeLogs = process.env .MOON_ZOMBIE_NODES!.split("|") .map((nodeName) => `${process.env.MOON_ZOMBIE_DIR}/${nodeName}.log`); @@ -283,7 +326,7 @@ export class MoonwallContext { ) .map(async (provider) => { return await new Promise(async (resolve) => { - console.log(`⏲ī¸ Waiting for chain ${provider.name} to produce blocks...`); + !silent && console.log(`⏲ī¸ Waiting for chain ${provider.name} to produce blocks...`); while ( ( await (provider.api as ApiPromise).rpc.chain.getBlock() @@ -291,7 +334,7 @@ export class MoonwallContext { ) { await timer(500); } - console.log(`✅ Chain ${provider.name} producing blocks, continuing`); + !silent && console.log(`✅ Chain ${provider.name} producing blocks, continuing`); resolve(""); }); }); @@ -337,16 +380,6 @@ export class MoonwallContext { return MoonwallContext.instance; } - private killAllChildProcesses() { - this.nodes.forEach((child) => { - try { - child.kill(); - } catch (err) { - console.error("Failed to kill child process", err); - } - }); - } - public static async destroy() { const ctx = this.instance; @@ -372,6 +405,8 @@ export class MoonwallContext { if (ctx.zombieNetwork) { console.log("đŸĒ“ Killing zombie nodes"); await ctx.zombieNetwork.stop(); + ctx.ipcServer?.close(); + ctx.ipcServer?.removeAllListeners(); } } } diff --git a/packages/types/package.json b/packages/types/package.json index 36f8df6f..8e023eab 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -65,10 +65,10 @@ "@polkadot/util": "^12.5.1", "@polkadot/util-crypto": "^12.5.1", "@types/node": "^20.8.9", - "@zombienet/utils": "^0.0.22", + "@zombienet/utils": "^0.0.24", "bottleneck": "^2.19.5", "debug": "^4.3.4", - "ethers": "^6.8.0", + "ethers": "^6.8.1", "viem": "^1.18.0", "web3": "4.2.1" }, diff --git a/packages/util/package.json b/packages/util/package.json index 9070f008..3533855d 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -75,7 +75,7 @@ "colors": "^1.4.0", "debug": "^4.3.4", "dotenv": "^16.3.1", - "ethers": "^6.8.0", + "ethers": "^6.8.1", "inquirer": "^9.2.11", "inquirer-press-to-continue": "^1.2.0", "node-fetch": "^3.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb9748d4..0c857e44 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -91,11 +91,11 @@ importers: specifier: ^12.5.1 version: 12.5.1(@polkadot/util@12.5.1) '@zombienet/orchestrator': - specifier: ^0.0.59 - version: 0.0.59(@polkadot/util@12.5.1)(@types/node@20.8.9) + specifier: ^0.0.62 + version: 0.0.62(@polkadot/util@12.5.1)(@types/node@20.8.10) '@zombienet/utils': - specifier: ^0.0.23 - version: 0.0.23(@types/node@20.8.9)(typescript@5.2.2) + specifier: ^0.0.24 + version: 0.0.24(@types/node@20.8.10)(typescript@5.2.2) bottleneck: specifier: ^2.19.5 version: 2.19.5 @@ -118,8 +118,8 @@ importers: specifier: ^16.3.1 version: 16.3.1 ethers: - specifier: ^6.8.0 - version: 6.8.0 + specifier: ^6.8.1 + version: 6.8.1 execa: specifier: ^8.0.1 version: 8.0.1 @@ -143,10 +143,10 @@ importers: version: 7.5.4 viem: specifier: ^1.18.0 - version: 1.18.0(typescript@5.2.2) + version: 1.18.6(typescript@5.2.2) vitest: specifier: 1.0.0-beta.3 - version: 1.0.0-beta.3(@types/node@20.8.9) + version: 1.0.0-beta.3(@types/node@20.8.10)(@vitest/ui@1.0.0-beta.1) web3: specifier: 4.2.1 version: 4.2.1(typescript@5.2.2) @@ -158,7 +158,7 @@ importers: version: 8.14.2 yaml: specifier: ^2.3.3 - version: 2.3.3 + version: 2.3.4 yargs: specifier: ^17.7.2 version: 17.7.2 @@ -170,8 +170,8 @@ importers: specifier: ^4.1.10 version: 4.1.10 '@types/node': - specifier: ^20.8.9 - version: 20.8.9 + specifier: ^20.8.10 + version: 20.8.10 '@types/yargs': specifier: ^17.0.29 version: 17.0.29 @@ -212,8 +212,8 @@ importers: specifier: ^20.8.9 version: 20.8.9 '@zombienet/utils': - specifier: ^0.0.22 - version: 0.0.22(@types/node@20.8.9)(typescript@5.2.2) + specifier: ^0.0.24 + version: 0.0.24(@types/node@20.8.9)(typescript@5.2.2) bottleneck: specifier: ^2.19.5 version: 2.19.5 @@ -221,8 +221,8 @@ importers: specifier: ^4.3.4 version: 4.3.4(supports-color@8.1.1) ethers: - specifier: ^6.8.0 - version: 6.8.0 + specifier: ^6.8.1 + version: 6.8.1 viem: specifier: ^1.18.0 version: 1.18.0(typescript@5.2.2) @@ -297,8 +297,8 @@ importers: specifier: ^16.3.1 version: 16.3.1 ethers: - specifier: ^6.8.0 - version: 6.8.0 + specifier: ^6.8.1 + version: 6.8.1 inquirer: specifier: ^9.2.11 version: 9.2.11 @@ -356,10 +356,10 @@ importers: devDependencies: '@acala-network/chopsticks': specifier: ^0.9.0 - version: 0.9.0(@polkadot/util@12.5.1) + version: 0.9.0(@polkadot/util@12.5.1)(debug@4.3.4) '@moonbeam-network/api-augment': - specifier: ^0.2400.0 - version: 0.2400.0 + specifier: ^0.2500.0 + version: 0.2500.0 '@moonwall/cli': specifier: workspace:* version: link:../packages/cli @@ -388,8 +388,8 @@ importers: specifier: 1.0.0-beta.1 version: 1.0.0-beta.1(vitest@1.0.0-beta.3) bun-types: - specifier: ^1.0.7 - version: 1.0.7 + specifier: ^1.0.9 + version: 1.0.9 chai: specifier: ^4.3.10 version: 4.3.10 @@ -397,8 +397,8 @@ importers: specifier: ^5.3.0 version: 5.3.0 ethers: - specifier: ^6.8.0 - version: 6.8.0 + specifier: ^6.8.1 + version: 6.8.1 pnpm: specifier: 8.6.2 version: 8.6.2 @@ -416,7 +416,7 @@ importers: version: 5.2.2 viem: specifier: ^1.18.1 - version: 1.18.1(typescript@5.2.2) + version: 1.18.6(typescript@5.2.2) vitest: specifier: 1.0.0-beta.3 version: 1.0.0-beta.3(@types/node@20.8.10)(@vitest/ui@1.0.0-beta.1) @@ -489,48 +489,6 @@ packages: '@polkadot/util': 12.5.1 '@polkadot/wasm-util': 7.2.2(@polkadot/util@12.5.1) - /@acala-network/chopsticks@0.9.0(@polkadot/util@12.5.1): - resolution: {integrity: sha512-jhbIjfgiM1A2RJssstgGUvNf3geOT/Ztm5Rz5m1qnmub/sCciQhHTg8rUtl2kNGdsW14WFm/HORIaz0lT/CyJA==} - hasBin: true - dependencies: - '@acala-network/chopsticks-core': 0.9.0(@polkadot/util@12.5.1) - '@acala-network/chopsticks-db': 0.9.0(@polkadot/util@12.5.1) - '@pnpm/npm-conf': 2.2.2 - axios: 1.5.1 - dotenv: 16.3.1 - global-agent: 3.0.0 - js-yaml: 4.1.0 - jsondiffpatch: 0.5.0 - lodash: 4.17.21 - ws: 8.14.2 - yargs: 17.7.2 - zod: 3.22.4 - transitivePeerDependencies: - - '@google-cloud/spanner' - - '@polkadot/util' - - '@sap/hana-client' - - better-sqlite3 - - bluebird - - bufferutil - - debug - - encoding - - hdb-pool - - ioredis - - mongodb - - mssql - - mysql2 - - oracledb - - pg - - pg-native - - pg-query-stream - - redis - - sql.js - - supports-color - - ts-node - - typeorm-aurora-data-api-driver - - utf-8-validate - dev: true - /@acala-network/chopsticks@0.9.0(@polkadot/util@12.5.1)(debug@4.3.4): resolution: {integrity: sha512-jhbIjfgiM1A2RJssstgGUvNf3geOT/Ztm5Rz5m1qnmub/sCciQhHTg8rUtl2kNGdsW14WFm/HORIaz0lT/CyJA==} hasBin: true @@ -571,7 +529,6 @@ packages: - ts-node - typeorm-aurora-data-api-driver - utf-8-validate - dev: false /@adraffy/ens-normalize@1.10.0: resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} @@ -1327,11 +1284,11 @@ packages: /@moonbeam-network/api-augment@0.2400.0: resolution: {integrity: sha512-Kec+G3ohgRJyt09bsxfWFB2m24cja6aU81o3NICoOOftD1Jrn6EnKRPLilELYFTRZwYYRQT5TcUELRx1JzLicA==} engines: {node: '>=14.0.0'} + dev: false /@moonbeam-network/api-augment@0.2500.0: resolution: {integrity: sha512-HOHQE9FCw9Pft+t5bWKe+c5+mKJ/5ZD1UztJlGBMxg4NRLCdZiKxdbPBiv2OTpRsBRq5v6PD2LaTFayRjXZYNQ==} engines: {node: '>=14.0.0'} - dev: false /@noble/curves@1.1.0: resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} @@ -1365,12 +1322,10 @@ packages: dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: true /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} @@ -1378,7 +1333,6 @@ packages: dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 - dev: true /@npmcli/fs@1.1.1: resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} @@ -1441,7 +1395,6 @@ packages: /@polka/url@1.0.0-next.23: resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==} - dev: true /@polkadot/api-augment@10.10.1: resolution: {integrity: sha512-J0r1DT1M5y75iO1iwcpUBokKD3q6b22kWlPfiHEDNFydVw5vm7OTRBk9Njjl8rOnlSzcW/Ya8qWfV/wkrqHxUQ==} @@ -1499,7 +1452,7 @@ packages: '@polkadot/api-augment': 10.10.1 '@polkadot/api-base': 10.10.1 '@polkadot/api-derive': 10.10.1 - '@polkadot/keyring': 12.5.1(@polkadot/util@12.5.1) + '@polkadot/keyring': 12.5.1(@polkadot/util-crypto@12.5.1)(@polkadot/util@12.5.1) '@polkadot/rpc-augment': 10.10.1 '@polkadot/rpc-core': 10.10.1 '@polkadot/rpc-provider': 10.10.1 @@ -1528,17 +1481,6 @@ packages: '@polkadot/util': 12.5.1 '@polkadot/util-crypto': 12.5.1(@polkadot/util@12.5.1) tslib: 2.6.2 - dev: false - - /@polkadot/keyring@12.5.1(@polkadot/util@12.5.1): - resolution: {integrity: sha512-u6b+Q7wI6WY/vwmJS9uUHy/5hKZ226nTlVNmxjkj9GvrRsQvUSwS94163yHPJwiZJiIv5xK5m0rwCMyoYu+wjA==} - engines: {node: '>=16'} - peerDependencies: - '@polkadot/util': 12.5.1 - dependencies: - '@polkadot/util': 12.5.1 - '@polkadot/util-crypto': 12.5.1(@polkadot/util@12.5.1) - tslib: 2.6.2 /@polkadot/networks@12.5.1: resolution: {integrity: sha512-PP6UUdzz6iHHZH4q96cUEhTcydHj16+61sqeaYEJSF6Q9iY+5WVWQ26+rdjmre/EBdrMQkSS/CKy73mO5z/JkQ==} @@ -1581,7 +1523,7 @@ packages: resolution: {integrity: sha512-VMDWoJgx6/mPHAOT66Sq+Jf2lJABfV/ZUIXtT2k8HjOndbm6oKrFqGEOSSLvB2q4olDee3FkFFxkyW1s6k4JaQ==} engines: {node: '>=16'} dependencies: - '@polkadot/keyring': 12.5.1(@polkadot/util@12.5.1) + '@polkadot/keyring': 12.5.1(@polkadot/util-crypto@12.5.1)(@polkadot/util@12.5.1) '@polkadot/types': 10.10.1 '@polkadot/types-support': 10.10.1 '@polkadot/util': 12.5.1 @@ -1647,7 +1589,7 @@ packages: resolution: {integrity: sha512-Ben62P1tjYEhKag34GBGcLX6NqcFR1VD5nNbWaxgr+t36Jl/tlHs6P9DlbFqQP7Tt9FmGrAYY0m3oTkhjG1NzA==} engines: {node: '>=16'} dependencies: - '@polkadot/keyring': 12.5.1(@polkadot/util@12.5.1) + '@polkadot/keyring': 12.5.1(@polkadot/util-crypto@12.5.1)(@polkadot/util@12.5.1) '@polkadot/types-augment': 10.10.1 '@polkadot/types-codec': 10.10.1 '@polkadot/types-create': 10.10.1 @@ -1936,7 +1878,7 @@ packages: /@types/cli-progress@3.11.4: resolution: {integrity: sha512-yufTxeeNCZuEIxx2uebK8lpSAsJM4lvzakm/VxzYhDtqhXCzwH9jpn7nPCxzrROuEbLATqhFq4MIPoG0tlrsvw==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.8.10 dev: true /@types/debug@4.1.10: @@ -1996,6 +1938,7 @@ packages: resolution: {integrity: sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==} dependencies: undici-types: 5.26.5 + dev: false /@types/normalize-package-data@2.4.2: resolution: {integrity: sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==} @@ -2012,7 +1955,7 @@ packages: /@types/ws@8.5.3: resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.8.10 /@types/yargs-parser@21.0.1: resolution: {integrity: sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==} @@ -2194,7 +2137,6 @@ packages: picocolors: 1.0.0 sirv: 2.0.3 vitest: 1.0.0-beta.3(@types/node@20.8.10)(@vitest/ui@1.0.0-beta.1) - dev: true /@vitest/utils@1.0.0-beta.1: resolution: {integrity: sha512-jfcqEzZamUA2Th76NVOHyRMAUIAuxMG9q+BstUbxzPQ9IkbCjz5GkhagPfy4r6zTFiElhX7mmPVj/nvB/Ea/bQ==} @@ -2202,7 +2144,6 @@ packages: diff-sequences: 29.6.3 loupe: 2.3.6 pretty-format: 29.7.0 - dev: true /@vitest/utils@1.0.0-beta.3: resolution: {integrity: sha512-8j7Xg3A13kt78DqWJC3ludyMsBbKQn/LcX9wcULxZFMGQqmSkUFN8ij6JWFQs67w39T+clLWzPrV+NRxe+Mc9g==} @@ -2373,14 +2314,14 @@ packages: - vue dev: true - /@zombienet/orchestrator@0.0.59(@polkadot/util@12.5.1)(@types/node@20.8.9): - resolution: {integrity: sha512-8QfhKTDwlOK/mP6UJWQVYch/UZF2A1FQ6EH1hq1oGkw6kC8sOX6GqaI6IPooEQFK5bDff1Cfrxl1Kvf1ku3wjQ==} + /@zombienet/orchestrator@0.0.62(@polkadot/util@12.5.1)(@types/node@20.8.10): + resolution: {integrity: sha512-nUX9/UrEv4k2kW7zOPBKIK6opaQ/7/QWQ4ZRfWooihM0k2cZ+HVeJ1AVXeDKnnbvaxfHG2/jrhIx5btuRYvbyQ==} engines: {node: '>=18'} dependencies: '@polkadot/api': 10.10.1 '@polkadot/keyring': 12.5.1(@polkadot/util-crypto@12.5.1)(@polkadot/util@12.5.1) '@polkadot/util-crypto': 12.5.1(@polkadot/util@12.5.1) - '@zombienet/utils': 0.0.23(@types/node@20.8.9)(typescript@5.2.2) + '@zombienet/utils': 0.0.24(@types/node@20.8.10)(typescript@5.2.2) JSONStream: 1.3.5 chai: 4.3.10 debug: 4.3.4(supports-color@8.1.1) @@ -2395,7 +2336,7 @@ packages: peer-id: 0.16.0 tmp-promise: 3.0.3 typescript: 5.2.2 - yaml: 2.3.3 + yaml: 2.3.4 transitivePeerDependencies: - '@polkadot/util' - '@swc/core' @@ -2408,8 +2349,8 @@ packages: - utf-8-validate dev: false - /@zombienet/utils@0.0.22(@types/node@20.8.9)(typescript@5.2.2): - resolution: {integrity: sha512-jr2RAP0jYxzHPFSIWJP3W0ctili7XpwH/cs3BGFUmCU/Nj3dqkZpMqEBoxMECGUNQ4MS3jdgDoqR86UcsALXWw==} + /@zombienet/utils@0.0.24(@types/node@20.8.10)(typescript@5.2.2): + resolution: {integrity: sha512-CUHn4u04ryfRqCQQsZHSpMIpMxzdMvSZR86Gp3Hwexf7wZTkHNZ5hsJnQO+J/yl28ny0GcjLJSU1hZ2kMV+hqw==} engines: {node: '>=18'} dependencies: cli-table3: 0.6.3 @@ -2417,7 +2358,7 @@ packages: mocha: 10.2.0 nunjucks: 3.2.4 toml: 3.0.0 - ts-node: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) + ts-node: 10.9.1(@types/node@20.8.10)(typescript@5.2.2) transitivePeerDependencies: - '@swc/core' - '@swc/wasm' @@ -2427,8 +2368,8 @@ packages: - typescript dev: false - /@zombienet/utils@0.0.23(@types/node@20.8.9)(typescript@5.2.2): - resolution: {integrity: sha512-7cWy9izglJC2yaglVhP1Ro0uTKaB0Oiq71jTeLu4vfs/xqZOz24/s+Giqv7cGXfetUJ1Ip7Q6I03rHEnjvx6Nw==} + /@zombienet/utils@0.0.24(@types/node@20.8.9)(typescript@5.2.2): + resolution: {integrity: sha512-CUHn4u04ryfRqCQQsZHSpMIpMxzdMvSZR86Gp3Hwexf7wZTkHNZ5hsJnQO+J/yl28ny0GcjLJSU1hZ2kMV+hqw==} engines: {node: '>=18'} dependencies: cli-table3: 0.6.3 @@ -2520,7 +2461,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -2750,16 +2691,6 @@ packages: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} - /axios@1.5.1: - resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} - dependencies: - follow-redirects: 1.15.3 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: true - /axios@1.5.1(debug@4.3.4): resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} dependencies: @@ -2768,7 +2699,6 @@ packages: proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - dev: false /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2868,8 +2798,8 @@ packages: semver: 7.5.4 dev: true - /bun-types@1.0.7: - resolution: {integrity: sha512-zlIp+SCutbbugs6xDy+3WC3KO3zKySpF/bRfiTk/VJUdKt+WHAzlCtLplS7XglRYDFzhRhlzXMW/R5BHkw+u2Q==} + /bun-types@1.0.9: + resolution: {integrity: sha512-9zWU5b/D41v4h5YgQxMW7aUvwYqMhU7WRjhPMN73XE6MNl5mvZ5vgAEWV8Lisdd4JgDSdWk2t9oY6kYqeDhQSA==} dev: true /bundle-require@4.0.2(esbuild@0.18.20): @@ -3279,17 +3209,6 @@ packages: ms: 2.1.3 dev: true - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -3958,8 +3877,8 @@ packages: '@scure/bip32': 1.3.1 '@scure/bip39': 1.2.1 - /ethers@6.8.0: - resolution: {integrity: sha512-zrFbmQRlraM+cU5mE4CZTLBurZTs2gdp2ld0nG/f3ecBK+x6lZ69KSxBqZ4NjclxwfTxl5LeNufcBbMsTdY53Q==} + /ethers@6.8.1: + resolution: {integrity: sha512-iEKm6zox5h1lDn6scuRWdIdFJUCGg3+/aQWu0F4K0GVyEZiktFkqrJbRjTn1FlYEPz7RKA707D6g5Kdk6j7Ljg==} engines: {node: '>=14.0.0'} dependencies: '@adraffy/ens-normalize': 1.10.0 @@ -4041,7 +3960,6 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: true /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -4062,7 +3980,6 @@ packages: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: reusify: 1.0.4 - dev: true /fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} @@ -4073,7 +3990,6 @@ packages: /fflate@0.8.1: resolution: {integrity: sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==} - dev: true /figures@5.0.0: resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} @@ -4134,7 +4050,6 @@ packages: /flatted@3.2.9: resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} - dev: true /focus-trap@7.5.3: resolution: {integrity: sha512-7UsT/eSJcTPF0aZp73u7hBRTABz26knRRTJfoTGFCQD5mUImLIIOwWWCrtoQdmWa7dykBi6H+Cp5i3S/kvsMeA==} @@ -4142,16 +4057,6 @@ packages: tabbable: 6.2.0 dev: true - /follow-redirects@1.15.3: - resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: true - /follow-redirects@1.15.3(debug@4.3.4): resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} engines: {node: '>=4.0'} @@ -4162,7 +4067,6 @@ packages: optional: true dependencies: debug: 4.3.4(supports-color@8.1.1) - dev: false /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -4501,7 +4405,7 @@ packages: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color optional: true @@ -4522,7 +4426,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -5245,7 +5149,6 @@ packages: /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - dev: true /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} @@ -5253,7 +5156,6 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: true /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} @@ -5440,7 +5342,6 @@ packages: /mrmime@1.0.1: resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} engines: {node: '>=10'} - dev: true /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -5536,7 +5437,7 @@ packages: resolution: {integrity: sha512-DDpmn5oLEdCTclEqweOT4U7bEpuoifBMFUXem9sA4turDAZ5tlbrEoWqCorwXey8CaAw44mst5JOQeVNiwtkhw==} engines: {node: '>= 10.13'} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) json-stringify-safe: 5.0.1 lodash: 4.17.21 propagate: 2.0.1 @@ -6026,7 +5927,7 @@ packages: optional: true dependencies: lilconfig: 2.1.0 - yaml: 2.3.3 + yaml: 2.3.4 dev: true /postcss@8.4.31: @@ -6119,7 +6020,7 @@ packages: '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 '@types/long': 4.0.2 - '@types/node': 20.8.9 + '@types/node': 20.8.10 long: 4.0.0 dev: false @@ -6150,7 +6051,6 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true /quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} @@ -6313,7 +6213,6 @@ packages: /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} @@ -6357,7 +6256,6 @@ packages: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 - dev: true /rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} @@ -6514,7 +6412,6 @@ packages: '@polka/url': 1.0.0-next.23 mrmime: 1.0.1 totalist: 3.0.1 - dev: true /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} @@ -6556,7 +6453,7 @@ packages: requiresBuild: true dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) socks: 2.7.1 transitivePeerDependencies: - supports-color @@ -6578,7 +6475,7 @@ packages: dependencies: command-exists: 1.2.9 commander: 8.3.0 - follow-redirects: 1.15.3 + follow-redirects: 1.15.3(debug@4.3.4) js-sha3: 0.8.0 memorystream: 0.3.1 semver: 5.7.2 @@ -6921,7 +6818,6 @@ packages: /totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - dev: true /tough-cookie@4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} @@ -7003,6 +6899,37 @@ packages: yn: 3.1.1 dev: true + /ts-node@10.9.1(@types/node@20.8.10)(typescript@5.2.2): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.8.10 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.2.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: false + /ts-node@10.9.1(@types/node@20.8.9)(typescript@5.2.2): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -7247,7 +7174,7 @@ packages: chalk: 4.1.2 cli-highlight: 2.1.11 date-fns: 2.30.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) dotenv: 16.3.1 glob: 8.1.0 mkdirp: 2.1.6 @@ -7426,8 +7353,8 @@ packages: - zod dev: false - /viem@1.18.1(typescript@5.2.2): - resolution: {integrity: sha512-dkZG1jI8iL7G0+KZ8ZKHCXbzZxzu8Iib7OLCxkdaqdrlNrWTEMIZSp/2AHpbjpPeAg3VFD1CUayKPTJv2ZMXCg==} + /viem@1.18.6(typescript@5.2.2): + resolution: {integrity: sha512-oKkrxF2aqxjJ4pmm0ko7j+ZFRekP6VGIknSroV+6+dF+T31bscltPZwJ0fOJDxCOVhoVtxrKFRTkkasEVDblUA==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -7447,7 +7374,6 @@ packages: - bufferutil - utf-8-validate - zod - dev: true /vite-node@1.0.0-beta.3(@types/node@20.8.10): resolution: {integrity: sha512-qpdoB+N9LV2Lr3W6k8vZwm/lN3hdmz+c0Tixh2ktnX/ywF0OkQf7wIWLeiFLvW4Fa/iw4qhye7xiBBMP1o6/sA==} @@ -7455,7 +7381,7 @@ packages: hasBin: true dependencies: cac: 6.7.14 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 @@ -7469,7 +7395,6 @@ packages: - sugarss - supports-color - terser - dev: true /vite-node@1.0.0-beta.3(@types/node@20.8.7): resolution: {integrity: sha512-qpdoB+N9LV2Lr3W6k8vZwm/lN3hdmz+c0Tixh2ktnX/ywF0OkQf7wIWLeiFLvW4Fa/iw4qhye7xiBBMP1o6/sA==} @@ -7493,28 +7418,6 @@ packages: - terser dev: false - /vite-node@1.0.0-beta.3(@types/node@20.8.9): - resolution: {integrity: sha512-qpdoB+N9LV2Lr3W6k8vZwm/lN3hdmz+c0Tixh2ktnX/ywF0OkQf7wIWLeiFLvW4Fa/iw4qhye7xiBBMP1o6/sA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.3.4(supports-color@8.1.1) - mlly: 1.4.2 - pathe: 1.1.1 - picocolors: 1.0.0 - vite: 4.4.11(@types/node@20.8.9) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: false - /vite@4.4.11(@types/node@20.8.10): resolution: {integrity: sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7549,7 +7452,6 @@ packages: rollup: 3.29.4 optionalDependencies: fsevents: 2.3.3 - dev: true /vite@4.4.11(@types/node@20.8.7): resolution: {integrity: sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==} @@ -7585,43 +7487,6 @@ packages: rollup: 3.29.4 optionalDependencies: fsevents: 2.3.3 - dev: false - - /vite@4.4.11(@types/node@20.8.9): - resolution: {integrity: sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - '@types/node': 20.8.9 - esbuild: 0.18.20 - postcss: 8.4.31 - rollup: 3.29.4 - optionalDependencies: - fsevents: 2.3.3 - dev: false /vitepress@1.0.0-rc.10(@algolia/client-search@4.20.0)(search-insights@2.8.3): resolution: {integrity: sha512-+MsahIWqq5WUEmj6MR4obcKYbT7im07jZPCQPdNJExkeOSbOAJ4xypSLx88x7rvtzWHhHc5aXbOhCRvGEGjFrw==} @@ -7636,7 +7501,7 @@ packages: mark.js: 8.11.1 minisearch: 6.1.0 shiki: 0.14.5 - vite: 4.4.11(@types/node@20.8.10) + vite: 4.4.11(@types/node@20.8.7) vue: 3.3.4 transitivePeerDependencies: - '@algolia/client-search' @@ -7701,7 +7566,7 @@ packages: acorn-walk: 8.2.0 cac: 6.7.14 chai: 4.3.10 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) local-pkg: 0.4.3 magic-string: 0.30.5 pathe: 1.1.1 @@ -7721,7 +7586,6 @@ packages: - sugarss - supports-color - terser - dev: true /vitest@1.0.0-beta.3(@types/node@20.8.7): resolution: {integrity: sha512-Ytj70kgJq1MxWpS8U33nRwF7Mngzr0NxD6J1J8WZGZrYhGRktW3t0AwbjLyFg1URiW3ds6FSp/T3C8JEnP49cA==} @@ -7780,63 +7644,6 @@ packages: - terser dev: false - /vitest@1.0.0-beta.3(@types/node@20.8.9): - resolution: {integrity: sha512-Ytj70kgJq1MxWpS8U33nRwF7Mngzr0NxD6J1J8WZGZrYhGRktW3t0AwbjLyFg1URiW3ds6FSp/T3C8JEnP49cA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': '*' - '@vitest/ui': '*' - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - dependencies: - '@types/node': 20.8.9 - '@vitest/expect': 1.0.0-beta.3 - '@vitest/runner': 1.0.0-beta.3 - '@vitest/snapshot': 1.0.0-beta.3 - '@vitest/spy': 1.0.0-beta.3 - '@vitest/utils': 1.0.0-beta.3 - acorn: 8.10.0 - acorn-walk: 8.2.0 - cac: 6.7.14 - chai: 4.3.10 - debug: 4.3.4(supports-color@8.1.1) - local-pkg: 0.4.3 - magic-string: 0.30.5 - pathe: 1.1.1 - picocolors: 1.0.0 - std-env: 3.4.3 - strip-literal: 1.3.0 - tinybench: 2.5.1 - tinypool: 0.8.1 - vite: 4.4.11(@types/node@20.8.9) - vite-node: 1.0.0-beta.3(@types/node@20.8.9) - why-is-node-running: 2.2.2 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: false - /vscode-oniguruma@1.7.0: resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} dev: true @@ -8335,6 +8142,11 @@ packages: /yaml@2.3.3: resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} engines: {node: '>= 14'} + dev: false + + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + engines: {node: '>= 14'} /yargs-parser@18.1.3: resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} diff --git a/test/package.json b/test/package.json index 62c0b517..7e147be0 100644 --- a/test/package.json +++ b/test/package.json @@ -14,7 +14,7 @@ }, "devDependencies": { "@acala-network/chopsticks": "^0.9.0", - "@moonbeam-network/api-augment": "^0.2400.0", + "@moonbeam-network/api-augment": "^0.2500.0", "@moonwall/cli": "workspace:*", "@moonwall/types": "workspace:*", "@moonwall/util": "workspace:*", @@ -24,10 +24,10 @@ "@polkadot/util": "^12.5.1", "@types/node": "^20.8.10", "@vitest/ui": "1.0.0-beta.1", - "bun-types": "^1.0.7", + "bun-types": "^1.0.9", "chai": "^4.3.10", "chalk": "^5.3.0", - "ethers": "^6.8.0", + "ethers": "^6.8.1", "pnpm": "8.6.2", "prettier": "^2.8.8", "solc": "^0.8.22", diff --git a/test/suites/zombie/test_basic.ts b/test/suites/zombie/test_basic.ts index 7d366037..ff8b196c 100644 --- a/test/suites/zombie/test_basic.ts +++ b/test/suites/zombie/test_basic.ts @@ -1,7 +1,10 @@ import "@moonbeam-network/api-augment"; +import "@polkadot/api-augment"; import { beforeAll, describeSuite, expect } from "@moonwall/cli"; +import net from "net"; import { ALITH_ADDRESS, GLMR, baltathar } from "@moonwall/util"; import { ApiPromise } from "@polkadot/api"; +import { setTimeout } from "timers/promises"; describeSuite({ id: "Z1", @@ -10,16 +13,39 @@ describeSuite({ testCases: function ({ it, context, log }) { let paraApi: ApiPromise; let relayApi: ApiPromise; + let client: net.Socket; + let resume = false; - beforeAll(() => { + beforeAll(async () => { paraApi = context.polkadotJs("parachain"); relayApi = context.polkadotJs("relaychain"); - }); + + // TODO: Turn this into runner function + // TODO: Raise zombienet PR to remove logging + client = net.createConnection({ path: process.env.MOON_IPC_SOCKET }, () => { + client.write("Connected to server!"); + }); + + client.on("data", (data) => { + const message = JSON.parse(data.toString()); + log(message); + if (message.status === "success") { + resume = true; + } + }); + + for (;;) { + if (!client.connecting) { + break; + } + await setTimeout(100); + } + }, 10000); it({ id: "T01", title: "Check relaychain api correctly connected", - test: function () { + test: async function () { const rt = relayApi.consts.system.version.specVersion.toNumber(); expect(rt).to.be.greaterThan(0); @@ -32,6 +58,11 @@ describeSuite({ id: "T02", title: "Check parachain api correctly connected", test: async function () { + const socketPath = process.env.MOON_IPC_SOCKET; + const client = net.createConnection({ path: socketPath }, () => { + client.write("Hello from client again"); + }); + const network = paraApi.consts.system.version.specName.toString(); expect(network).to.contain("moonbase"); @@ -74,6 +105,7 @@ describeSuite({ const balAfter = (await paraApi.query.system.account(ALITH_ADDRESS)).data.free; expect(balBefore.lt(balAfter)).to.be.true; + client.write("test case 4 after"); }, }); @@ -89,5 +121,31 @@ describeSuite({ log((await paraApi.rpc.chain.getBlock()).block.header.number.toNumber()); }, }); + + it({ + id: "T06", + title: "Restart a node from test", + timeout: 600000, + test: async function () { + const message = { + message: "Restarting node 1", + cmd: "restart", + node: "alith", + }; + + await new Promise((resolve) => { + client.write(JSON.stringify(message), () => resolve("Sent!")); + }); + + for (;;) { + if (resume) { + break; + } + await setTimeout(100); + } + + await context.waitBlock(2, "parachain", "quantity"); + }, + }); }, }); From ea5423eb8b0de16e2c6476cb89116ea2c04f8aac Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Tue, 7 Nov 2023 11:23:57 +0000 Subject: [PATCH 15/21] added new zombie commands to test context --- .../src/internal/foundations/zombieHelpers.ts | 72 ++++++++++++++ packages/cli/src/lib/globalContext.ts | 99 ++++++++++++++----- .../cli/src/lib/handlers/zombieHandler.ts | 43 ++++++++ packages/types/src/runner.ts | 60 ++++++++++- test/suites/zombie/test_basic.ts | 66 +++++-------- tsconfig.json | 2 +- 6 files changed, 275 insertions(+), 67 deletions(-) diff --git a/packages/cli/src/internal/foundations/zombieHelpers.ts b/packages/cli/src/internal/foundations/zombieHelpers.ts index 0bde519b..86d52658 100644 --- a/packages/cli/src/internal/foundations/zombieHelpers.ts +++ b/packages/cli/src/internal/foundations/zombieHelpers.ts @@ -2,6 +2,8 @@ import { LaunchConfig } from "@zombienet/orchestrator"; import chalk from "chalk"; import fs from "node:fs"; import { checkAccess, checkExists } from "../fileCheckers"; +import { setTimeout as timer } from "timers/promises"; +import net from "net"; export async function checkZombieBins(config: LaunchConfig) { const relayBinPath = config.relaychain.default_command!; @@ -47,3 +49,73 @@ export function getZombieConfig(path: string) { const buffer = fs.readFileSync(path, "utf-8"); return JSON.parse(buffer) as LaunchConfig; } + +export type IPCRequestMessage = { + text: string; + cmd: "restart" | "pause" | "resume" | "kill" | "isup"; + nodeName: string; +}; + +export type IPCResponseMessage = { + status: "success" | "failure"; + result: boolean; + message: string; +}; + +export async function sendIpcMessage(message: IPCRequestMessage) { + let resume = false; + let response: IPCResponseMessage; + const ipcPath = process.env.MOON_IPC_SOCKET; + const client = net.createConnection({ path: ipcPath }, () => { + client.write("Connected to server!"); + }); + + // Listener to return control flow after server responds + client.on("data", (data) => { + response = JSON.parse(data.toString()); + if (response.status === "success") { + resume = true; + } + }); + + for (let i = 0; ; i++) { + if (!client.connecting) { + break; + } + + if (i > 100) { + throw new Error(`Connection to ${ipcPath} failed`); + } + await timer(100); + } + + await new Promise((resolve) => { + client.write(JSON.stringify(message), () => resolve("Sent!")); + }); + + for (let i = 0; ; i++) { + if (resume) { + break; + } + + if (i > 100) { + throw new Error(`${message.text} failed`); + } + await timer(100); + } + + client.end(); + + for (let i = 0; ; i++) { + if (client.closed) { + break; + } + + if (i > 100) { + throw new Error(`Closing IPC connection failed`); + } + await timer(100); + } + + return response; +} diff --git a/packages/cli/src/lib/globalContext.ts b/packages/cli/src/lib/globalContext.ts index 8e101120..6ddc4edb 100644 --- a/packages/cli/src/lib/globalContext.ts +++ b/packages/cli/src/lib/globalContext.ts @@ -16,7 +16,12 @@ import net from "net"; import readline from "readline"; import { setTimeout as timer } from "timers/promises"; import { parseChopsticksRunCmd, parseRunCmd, parseZombieCmd } from "../internal/commandParsers"; -import { checkZombieBins, getZombieConfig } from "../internal/foundations/zombieHelpers"; +import { + IPCRequestMessage, + IPCResponseMessage, + checkZombieBins, + getZombieConfig, +} from "../internal/foundations/zombieHelpers"; import { LaunchedNode, launchNode } from "../internal/localNode"; import { ProviderFactory, @@ -177,14 +182,14 @@ export class MoonwallContext { process.env.MOON_ZOMBIE_DIR = `${network.tmpDir}`; process.env.MOON_ZOMBIE_NODES = nodeNames.join("|"); - const processIds = Object.values((network.client as any).processMap) - .filter((item) => item!["pid"]) - .map((process) => process!["pid"]); - const onProcessExit = () => { try { + const processIds = Object.values((this.zombieNetwork.client as any).processMap) + .filter((item) => item!["pid"]) + .map((process) => process!["pid"]); execaCommandSync(`kill ${processIds.join(" ")}`); } catch (err) { + console.log(err); console.log("Failed to kill zombie nodes"); } }; @@ -196,29 +201,79 @@ export class MoonwallContext { console.log("📨 IPC client disconnected"); }); + // Client message handling client.on("data", async (data) => { + const writeToClient = (message: IPCResponseMessage) => { + if (client.writable) { + client.write(JSON.stringify(message)); + } else { + console.log("Client disconnected, cannot send response."); + } + }; + try { - const message = JSON.parse(data.toString()); - - if (message.cmd === "restart") { - console.log(`Restarting ${message.node}, please wait...`); - await network.client.restartNode(message.node, 0); - console.log(`✅ Node: "${message.node}" restarted`); - - // change the process map to use the new PID - await this.disconnect(); - await this.connectEnvironment(true); - - if (client.writable) { - client.write( - JSON.stringify({ status: "success", message: `${message.node} restarted` }) - ); - } else { - console.log("Client disconnected, cannot send response."); + const message: IPCRequestMessage = JSON.parse(data.toString()); + + const node = network.getNodeByName(message.nodeName); + + switch (message.cmd) { + case "restart": { + await node.restart(); + await this.disconnect(); + await this.connectEnvironment(true); + writeToClient({ + status: "success", + result: true, + message: `${message.nodeName} restarted`, + }); + break; + } + + case "resume": { + const result = await node.resume(); + writeToClient({ + status: "success", + result, + message: `${message.nodeName} resumed with result ${result}`, + }); + break; } + case "pause": { + const result = await node.pause(); + writeToClient({ + status: "success", + result, + message: `${message.nodeName} paused with result ${result}`, + }); + break; + } + case "kill": { + const pid = (network.client as any).processMap[message.nodeName].pid; + const result = await execaCommand(`kill ${pid}`, { timeout: 1000 }); + writeToClient({ + status: "success", + result: result.exitCode === 0, + message: `${message.nodeName}, pid ${pid} killed with exitCode ${result.exitCode}`, + }); + break; + } + + case "isup": { + const result = await node.isUp(); + writeToClient({ + status: "success", + result, + message: `${message.nodeName} isUp result is ${result}`, + }); + break; + } + + default: + throw new Error(`Invalid command received: ${message.cmd}`); } } catch (e) { console.log("📨 Message from client:", data.toString()); + writeToClient({ status: "failure", result: false, message: e }); } }); }); diff --git a/packages/cli/src/lib/handlers/zombieHandler.ts b/packages/cli/src/lib/handlers/zombieHandler.ts index 2ee054a5..ea07568a 100644 --- a/packages/cli/src/lib/handlers/zombieHandler.ts +++ b/packages/cli/src/lib/handlers/zombieHandler.ts @@ -3,6 +3,7 @@ import { ApiPromise } from "@polkadot/api"; import { upgradeRuntime } from "../upgradeProcedures"; import { MoonwallContext } from "../globalContext"; import { alith } from "@moonwall/util"; +import { sendIpcMessage } from "../../internal/foundations/zombieHelpers"; export const zombieHandler: FoundationHandler<"zombie"> = ({ testCases, @@ -38,6 +39,7 @@ export const zombieHandler: FoundationHandler<"zombie"> = ({ } } }, + upgradeRuntime: async (options: UpgradePreferences = {}) => { const ctx = MoonwallContext.getContext(); const provider = ctx.providers.find((prov) => prov.name === "parachain"); @@ -62,6 +64,47 @@ export const zombieHandler: FoundationHandler<"zombie"> = ({ await upgradeRuntime(api, params); }, + + restartNode: async (nodeName: string): Promise => { + await sendIpcMessage({ + text: `Restarting node ${nodeName}`, + cmd: "restart", + nodeName: nodeName, + }); + }, + + pauseNode: async (nodeName: string): Promise => { + await sendIpcMessage({ + text: `Pausing node ${nodeName}`, + cmd: "pause", + nodeName: nodeName, + }); + }, + + resumeNode: async (nodeName: string): Promise => { + await sendIpcMessage({ + text: `Resuming node ${nodeName}`, + cmd: "resume", + nodeName: nodeName, + }); + }, + + killNode: async (nodeName: string): Promise => { + await sendIpcMessage({ + text: `Killing node ${nodeName}`, + cmd: "kill", + nodeName: nodeName, + }); + }, + + isUp: async (nodeName: string): Promise => { + const response = await sendIpcMessage({ + text: `Checking if node ${nodeName} is up`, + cmd: "isup", + nodeName: nodeName, + }); + return response.status === "success"; + }, }, it: testCase, log: logger(), diff --git a/packages/types/src/runner.ts b/packages/types/src/runner.ts index b50f738d..04fa21bd 100644 --- a/packages/types/src/runner.ts +++ b/packages/types/src/runner.ts @@ -209,10 +209,67 @@ export interface ReadOnlyContext extends GenericContext { } /** - * ZombieContext - Interface that extends from GenericContext and includes methods for upgrading runtime and waiting a certain number of blocks. + * ZombieContext - Interface that extends from GenericContext and includes methods for managing runtime upgrades and node operations within a blockchain network. */ export interface ZombieContext extends GenericContext { + /** + * Initiates the runtime upgrade process with the provided upgrade preferences. + * + * @param {UpgradePreferences} options The configuration options for the upgrade, including runtime details and migration settings. + * @returns {Promise} A promise that resolves when the upgrade process has been initiated. + */ upgradeRuntime: (options: UpgradePreferences) => Promise; + + /** + * Checks if the specified node is running. + * + * @param {string} nodeName The name of the node to check. + * @returns {Promise} A promise that resolves to a boolean indicating whether the node is up and running. + */ + isUp: (nodeName: string) => Promise; + + /** + * Restarts the node with the given name. + * + * @param {string} nodeName The name of the node to restart. + * @returns {Promise} A promise that resolves when the node restart has been completed. + */ + restartNode: (nodeName: string) => Promise; + + /** + * Pauses the node with the specified name. + * + * @param {string} nodeName The name of the node to pause. + * @returns {Promise} A promise that resolves when the node has been successfully paused. + */ + pauseNode: (nodeName: string) => Promise; + + /** + * ⚠ī¸ WARNING: This doesn't seem to be working yet. ⚠ī¸ + * + * Resumes the operation of a paused node with the given name. + * + * @param {string} nodeName The name of the node to resume. + * @returns {Promise} A promise that resolves when the node has resumed operations. + */ + resumeNode: (nodeName: string) => Promise; + + /** + * Terminates the node with the provided name. + * + * @param {string} nodeName The name of the node to terminate. + * @returns {Promise} A promise that resolves when the node has been successfully terminated. + */ + killNode: (nodeName: string) => Promise; + + /** + * Waits for a specified number of blocks before resolving. This can be based on block height or quantity, depending on the mode. + * + * @param {number} [blocksToWaitFor] The number of blocks to wait for before the promise resolves. If not provided, defaults to some predetermined quantity. + * @param {string} [chain] The name of the blockchain to monitor for block production. + * @param {"height" | "quantity"} [mode] The mode to determine the block wait criteria - by height or by quantity. + * @returns {Promise} A promise that resolves after waiting for the specified number of blocks. + */ waitBlock: ( blocksToWaitFor?: number, chain?: string, @@ -220,6 +277,7 @@ export interface ZombieContext extends GenericContext { ) => Promise; } + /** * ChopsticksContext - Interface that extends from GenericContext and includes methods for creating a block, setting storage, and upgrading runtime. */ diff --git a/test/suites/zombie/test_basic.ts b/test/suites/zombie/test_basic.ts index ff8b196c..1c94f91a 100644 --- a/test/suites/zombie/test_basic.ts +++ b/test/suites/zombie/test_basic.ts @@ -4,7 +4,7 @@ import { beforeAll, describeSuite, expect } from "@moonwall/cli"; import net from "net"; import { ALITH_ADDRESS, GLMR, baltathar } from "@moonwall/util"; import { ApiPromise } from "@polkadot/api"; -import { setTimeout } from "timers/promises"; +import { setTimeout as timer } from "timers/promises"; describeSuite({ id: "Z1", @@ -13,33 +13,10 @@ describeSuite({ testCases: function ({ it, context, log }) { let paraApi: ApiPromise; let relayApi: ApiPromise; - let client: net.Socket; - let resume = false; beforeAll(async () => { paraApi = context.polkadotJs("parachain"); relayApi = context.polkadotJs("relaychain"); - - // TODO: Turn this into runner function - // TODO: Raise zombienet PR to remove logging - client = net.createConnection({ path: process.env.MOON_IPC_SOCKET }, () => { - client.write("Connected to server!"); - }); - - client.on("data", (data) => { - const message = JSON.parse(data.toString()); - log(message); - if (message.status === "success") { - resume = true; - } - }); - - for (;;) { - if (!client.connecting) { - break; - } - await setTimeout(100); - } }, 10000); it({ @@ -105,7 +82,6 @@ describeSuite({ const balAfter = (await paraApi.query.system.account(ALITH_ADDRESS)).data.free; expect(balBefore.lt(balAfter)).to.be.true; - client.write("test case 4 after"); }, }); @@ -124,28 +100,32 @@ describeSuite({ it({ id: "T06", - title: "Restart a node from test", + title: "Restart a node from test script", timeout: 600000, test: async function () { - const message = { - message: "Restarting node 1", - cmd: "restart", - node: "alith", - }; - - await new Promise((resolve) => { - client.write(JSON.stringify(message), () => resolve("Sent!")); - }); - - for (;;) { - if (resume) { - break; - } - await setTimeout(100); - } - + await context.restartNode("alith"); await context.waitBlock(2, "parachain", "quantity"); }, }); + + it({ + id: "T07", + title: "Pause/Resume a node", + timeout: 600000, + test: async function () { + const blockBefore = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); + await context.pauseNode("alith"); + log("waiting 30s and checking block production is paused") + await timer(20000) + const blockAfter = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); + expect(blockBefore).to.be.equal(blockAfter); + + + await context.resumeNode("alith"); + await context.waitBlock(1, "parachain", "quantity"); + const blockAfterResume = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); + expect(blockAfterResume).to.be.greaterThan(blockAfter); + }, + }); }, }); diff --git a/tsconfig.json b/tsconfig.json index 8d312cc1..ad14d36a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ "preserveSymlinks": true, "skipDefaultLibCheck": true, "preserveConstEnums": true, - "sourceMap": false, + "sourceMap": true, "esModuleInterop": true, "resolveJsonModule": true, "noEmit": true, From cc83e9520ab03cf2698a8c74f4b03f96c53bd3f0 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:33:05 +0000 Subject: [PATCH 16/21] updated interfaces --- .../src/internal/foundations/zombieHelpers.ts | 14 +++++--- packages/cli/src/lib/globalContext.ts | 19 +++++++--- packages/types/src/runner.ts | 27 +++++++------- test/moonwall.config.json | 1 + test/suites/zombie/test_basic.ts | 36 ++++++++++++------- 5 files changed, 65 insertions(+), 32 deletions(-) diff --git a/packages/cli/src/internal/foundations/zombieHelpers.ts b/packages/cli/src/internal/foundations/zombieHelpers.ts index 86d52658..6fb79338 100644 --- a/packages/cli/src/internal/foundations/zombieHelpers.ts +++ b/packages/cli/src/internal/foundations/zombieHelpers.ts @@ -52,8 +52,8 @@ export function getZombieConfig(path: string) { export type IPCRequestMessage = { text: string; - cmd: "restart" | "pause" | "resume" | "kill" | "isup"; - nodeName: string; + cmd: "restart" | "pause" | "resume" | "kill" | "isup" | "init"; + nodeName?: string; }; export type IPCResponseMessage = { @@ -66,8 +66,14 @@ export async function sendIpcMessage(message: IPCRequestMessage) { let resume = false; let response: IPCResponseMessage; const ipcPath = process.env.MOON_IPC_SOCKET; - const client = net.createConnection({ path: ipcPath }, () => { - client.write("Connected to server!"); + const client = net.createConnection({ path: ipcPath }, async () => { + // const msg: IPCRequestMessage = { + // cmd: "init", + // text: "Connected to server", + // }; + // await new Promise((resolve) => { + // client.write(JSON.stringify(msg), () => resolve("Sent!")); + // }); }); // Listener to return control flow after server responds diff --git a/packages/cli/src/lib/globalContext.ts b/packages/cli/src/lib/globalContext.ts index 6ddc4edb..42aa5a7b 100644 --- a/packages/cli/src/lib/globalContext.ts +++ b/packages/cli/src/lib/globalContext.ts @@ -197,9 +197,9 @@ export class MoonwallContext { const socketPath = `${network.tmpDir}/node-ipc.sock`; const server = net.createServer((client) => { - client.on("end", () => { - console.log("📨 IPC client disconnected"); - }); + // client.on("end", () => { + // console.log("📨 IPC client disconnected"); + // }); // Client message handling client.on("data", async (data) => { @@ -215,11 +215,12 @@ export class MoonwallContext { const message: IPCRequestMessage = JSON.parse(data.toString()); const node = network.getNodeByName(message.nodeName); + const zombieClient = network.client; switch (message.cmd) { case "restart": { - await node.restart(); await this.disconnect(); + await zombieClient.restartNode(message.nodeName, null); await this.connectEnvironment(true); writeToClient({ status: "success", @@ -230,7 +231,10 @@ export class MoonwallContext { } case "resume": { + await this.disconnect(); const result = await node.resume(); + await (zombieClient as any).wait_node_ready(message.nodeName); + await this.connectEnvironment(true); writeToClient({ status: "success", result, @@ -238,8 +242,11 @@ export class MoonwallContext { }); break; } + case "pause": { + await this.disconnect(); const result = await node.pause(); + await timer(1000); // TODO: Replace when zombienet has an appropriate fn writeToClient({ status: "success", result, @@ -247,9 +254,13 @@ export class MoonwallContext { }); break; } + case "kill": { + // await this.disconnect(); const pid = (network.client as any).processMap[message.nodeName].pid; + delete (network.client as any).processMap[message.nodeName]; const result = await execaCommand(`kill ${pid}`, { timeout: 1000 }); + // await this.connectEnvironment(true); writeToClient({ status: "success", result: result.exitCode === 0, diff --git a/packages/types/src/runner.ts b/packages/types/src/runner.ts index 04fa21bd..1d40bdbd 100644 --- a/packages/types/src/runner.ts +++ b/packages/types/src/runner.ts @@ -214,49 +214,53 @@ export interface ReadOnlyContext extends GenericContext { export interface ZombieContext extends GenericContext { /** * Initiates the runtime upgrade process with the provided upgrade preferences. - * + * * @param {UpgradePreferences} options The configuration options for the upgrade, including runtime details and migration settings. * @returns {Promise} A promise that resolves when the upgrade process has been initiated. */ upgradeRuntime: (options: UpgradePreferences) => Promise; /** + * ⚠ī¸ WARNING: This doesn't seem to be working yet. ⚠ī¸ + * * Checks if the specified node is running. - * + * * @param {string} nodeName The name of the node to check. * @returns {Promise} A promise that resolves to a boolean indicating whether the node is up and running. */ - isUp: (nodeName: string) => Promise; + isUp?: (nodeName: string) => Promise; /** * Restarts the node with the given name. - * + * * @param {string} nodeName The name of the node to restart. * @returns {Promise} A promise that resolves when the node restart has been completed. */ restartNode: (nodeName: string) => Promise; /** + * * ⚠ī¸ WARNING: This doesn't seem to be working yet. ⚠ī¸ + * * Pauses the node with the specified name. - * + * * @param {string} nodeName The name of the node to pause. * @returns {Promise} A promise that resolves when the node has been successfully paused. */ - pauseNode: (nodeName: string) => Promise; + pauseNode?: (nodeName: string) => Promise; /** * ⚠ī¸ WARNING: This doesn't seem to be working yet. ⚠ī¸ - * + * * Resumes the operation of a paused node with the given name. - * + * * @param {string} nodeName The name of the node to resume. * @returns {Promise} A promise that resolves when the node has resumed operations. */ - resumeNode: (nodeName: string) => Promise; + resumeNode?: (nodeName: string) => Promise; /** * Terminates the node with the provided name. - * + * * @param {string} nodeName The name of the node to terminate. * @returns {Promise} A promise that resolves when the node has been successfully terminated. */ @@ -264,7 +268,7 @@ export interface ZombieContext extends GenericContext { /** * Waits for a specified number of blocks before resolving. This can be based on block height or quantity, depending on the mode. - * + * * @param {number} [blocksToWaitFor] The number of blocks to wait for before the promise resolves. If not provided, defaults to some predetermined quantity. * @param {string} [chain] The name of the blockchain to monitor for block production. * @param {"height" | "quantity"} [mode] The mode to determine the block wait criteria - by height or by quantity. @@ -277,7 +281,6 @@ export interface ZombieContext extends GenericContext { ) => Promise; } - /** * ChopsticksContext - Interface that extends from GenericContext and includes methods for creating a block, setting storage, and upgrading runtime. */ diff --git a/test/moonwall.config.json b/test/moonwall.config.json index c3b5e164..38fd8de7 100644 --- a/test/moonwall.config.json +++ b/test/moonwall.config.json @@ -142,6 +142,7 @@ "name": "zombie_test", "testFileDir": ["suites/zombie"], "timeout": 300000, + "envVars": ["DEBUG_COLORS=1"], "reporters": ["basic"], "foundation": { "type": "zombie", diff --git a/test/suites/zombie/test_basic.ts b/test/suites/zombie/test_basic.ts index 1c94f91a..fdbf4c3e 100644 --- a/test/suites/zombie/test_basic.ts +++ b/test/suites/zombie/test_basic.ts @@ -5,6 +5,7 @@ import net from "net"; import { ALITH_ADDRESS, GLMR, baltathar } from "@moonwall/util"; import { ApiPromise } from "@polkadot/api"; import { setTimeout as timer } from "timers/promises"; +import { stat } from "fs"; describeSuite({ id: "Z1", @@ -113,18 +114,29 @@ describeSuite({ title: "Pause/Resume a node", timeout: 600000, test: async function () { - const blockBefore = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); - await context.pauseNode("alith"); - log("waiting 30s and checking block production is paused") - await timer(20000) - const blockAfter = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); - expect(blockBefore).to.be.equal(blockAfter); - - - await context.resumeNode("alith"); - await context.waitBlock(1, "parachain", "quantity"); - const blockAfterResume = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); - expect(blockAfterResume).to.be.greaterThan(blockAfter); + + // await context.pauseNode("alice"); + + await context.killNode("alice"); + const status = await context.isUp("alice"); + + log(status); + expect(status).toBe(false) + // expect(await context.isUp("alith"), "Alith node is not running").toBe(true); + // const blockBefore = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); + // await context.pauseNode("alith"); + // log("waiting 20s and checking block production is paused"); + // await timer(20000); + // const blockAfter = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); + // expect(blockBefore).to.be.equal(blockAfter); + // expect(await context.isUp("alith"), "Alith node is not paused").toBe(false); + + // await context.resumeNode("alith"); + // await context.waitBlock(1, "parachain", "quantity"); + // const blockAfterResume = ( + // await paraApi.rpc.chain.getBlock() + // ).block.header.number.toNumber(); + // expect(blockAfterResume).to.be.greaterThan(blockAfter); }, }); }, From f1a59953c4ac2eb31f5da30c1218e53abff89f5f Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:42:55 +0000 Subject: [PATCH 17/21] restored test step --- test/suites/zombie/test_basic.ts | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/test/suites/zombie/test_basic.ts b/test/suites/zombie/test_basic.ts index fdbf4c3e..12780400 100644 --- a/test/suites/zombie/test_basic.ts +++ b/test/suites/zombie/test_basic.ts @@ -109,35 +109,5 @@ describeSuite({ }, }); - it({ - id: "T07", - title: "Pause/Resume a node", - timeout: 600000, - test: async function () { - - // await context.pauseNode("alice"); - - await context.killNode("alice"); - const status = await context.isUp("alice"); - - log(status); - expect(status).toBe(false) - // expect(await context.isUp("alith"), "Alith node is not running").toBe(true); - // const blockBefore = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); - // await context.pauseNode("alith"); - // log("waiting 20s and checking block production is paused"); - // await timer(20000); - // const blockAfter = (await paraApi.rpc.chain.getBlock()).block.header.number.toNumber(); - // expect(blockBefore).to.be.equal(blockAfter); - // expect(await context.isUp("alith"), "Alith node is not paused").toBe(false); - - // await context.resumeNode("alith"); - // await context.waitBlock(1, "parachain", "quantity"); - // const blockAfterResume = ( - // await paraApi.rpc.chain.getBlock() - // ).block.header.number.toNumber(); - // expect(blockAfterResume).to.be.greaterThan(blockAfter); - }, - }); }, }); From 50ea0a4a8bf5704b0872a1b231f6ef4478b1246e Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Tue, 7 Nov 2023 17:10:30 +0000 Subject: [PATCH 18/21] added runNetwork cmd steps --- packages/cli/src/cmds/runNetwork.ts | 51 ++++++++-- .../src/internal/foundations/zombieHelpers.ts | 95 ++++++++----------- packages/cli/src/lib/globalContext.ts | 5 +- packages/cli/tsconfig.json | 5 +- packages/types/tsconfig.json | 5 +- packages/util/tsconfig.json | 5 +- test/suites/zombie/test_basic.ts | 10 +- 7 files changed, 91 insertions(+), 85 deletions(-) diff --git a/packages/cli/src/cmds/runNetwork.ts b/packages/cli/src/cmds/runNetwork.ts index 3f27143c..ea4f1db0 100644 --- a/packages/cli/src/cmds/runNetwork.ts +++ b/packages/cli/src/cmds/runNetwork.ts @@ -12,6 +12,7 @@ import { commonChecks } from "../internal/launcherCommon"; import { cacheConfig, importAsyncConfig, loadEnvVars } from "../lib/configReader"; import { MoonwallContext, runNetworkOnly } from "../lib/globalContext"; import { executeTests } from "./runTests"; +import { sendIpcMessage } from "../internal/foundations/zombieHelpers"; inquirer.registerPrompt("press-to-continue", PressToContinuePrompt); @@ -71,16 +72,14 @@ export async function runNetworkCmd(args) { }, { name: - foundation == "dev" || foundation == "chopsticks" - ? `Command: Run command on network (e.g. createBlock) (${chalk.bgGrey.cyanBright( - foundation - )})` + foundation == "dev" || foundation == "chopsticks" || foundation == "zombie" + ? `Command: Run command on network (${chalk.bgGrey.cyanBright(foundation)})` : chalk.dim( `Not applicable for foundation type (${chalk.bgGrey.cyanBright(foundation)})` ), value: 3, short: "cmd", - disabled: foundation !== "dev" && foundation !== "chopsticks", + disabled: foundation !== "dev" && foundation !== "chopsticks" && foundation !== "zombie", }, { name: @@ -164,7 +163,9 @@ export async function runNetworkCmd(args) { break; case 3: - await resolveCommandChoice(); + env.foundation.type !== "zombie" + ? await resolveCommandChoice() + : await resolveZombieCommandChoice(); lastSelected = 2; break; @@ -232,6 +233,44 @@ const reportServicePorts = async () => { return portsList; }; +const resolveZombieCommandChoice = async () => { + const choice = await inquirer.prompt({ + name: "cmd", + type: "list", + choices: [ + { name: "â™ģī¸ Restart Node", value: "restart" }, + { name: "🗡ī¸ Kill Node", value: "kill" }, + new inquirer.Separator(), + { name: "🔙 Go Back", value: "back" }, + ], + message: "What command would you like to run? ", + default: "back", + }); + + if (choice.cmd == "back") { + return; + } else { + const whichNode = await inquirer.prompt({ + name: "nodeName", + type: "input", + message: `Which node would you like to ${choice.cmd}? `, + }); + + try { + await sendIpcMessage({ + cmd: choice.cmd, + nodeName: whichNode.nodeName, + text: `Running ${choice.cmd} on ${whichNode.nodeName}`, + }); + } catch (e) { + console.error("Error: "); + console.error(e.message); + } + } + + return; +}; + const resolveCommandChoice = async () => { const choice = await inquirer.prompt({ name: "cmd", diff --git a/packages/cli/src/internal/foundations/zombieHelpers.ts b/packages/cli/src/internal/foundations/zombieHelpers.ts index 6fb79338..8b3e0c3f 100644 --- a/packages/cli/src/internal/foundations/zombieHelpers.ts +++ b/packages/cli/src/internal/foundations/zombieHelpers.ts @@ -62,66 +62,49 @@ export type IPCResponseMessage = { message: string; }; -export async function sendIpcMessage(message: IPCRequestMessage) { - let resume = false; - let response: IPCResponseMessage; - const ipcPath = process.env.MOON_IPC_SOCKET; - const client = net.createConnection({ path: ipcPath }, async () => { - // const msg: IPCRequestMessage = { - // cmd: "init", - // text: "Connected to server", - // }; - // await new Promise((resolve) => { - // client.write(JSON.stringify(msg), () => resolve("Sent!")); - // }); - }); +export async function sendIpcMessage(message: IPCRequestMessage): Promise { + return new Promise(async (resolve, reject) => { + let response: IPCResponseMessage; + const ipcPath = process.env.MOON_IPC_SOCKET; + const client = net.createConnection({ path: ipcPath }); + + // Listener to return control flow after server responds + client.on("data", async (data) => { + response = JSON.parse(data.toString()); + if (response.status === "success") { + client.end(); + + for (let i = 0; ; i++) { + if (client.closed) { + break; + } + + if (i > 100) { + reject(new Error(`Closing IPC connection failed`)); + } + await timer(200); + } + resolve(response); + } - // Listener to return control flow after server responds - client.on("data", (data) => { - response = JSON.parse(data.toString()); - if (response.status === "success") { - resume = true; - } - }); + if (response.status === "failure") { + reject(new Error(JSON.stringify(response))); + } + }); - for (let i = 0; ; i++) { - if (!client.connecting) { - break; - } + for (let i = 0; ; i++) { + if (!client.connecting) { + break; + } - if (i > 100) { - throw new Error(`Connection to ${ipcPath} failed`); + if (i > 100) { + reject(new Error(`Connection to ${ipcPath} failed`)); + } + await timer(200); } - await timer(100); - } - await new Promise((resolve) => { - client.write(JSON.stringify(message), () => resolve("Sent!")); + await new Promise((resolve) => { + client.write(JSON.stringify(message), () => resolve("Sent!")); + }); }); - - for (let i = 0; ; i++) { - if (resume) { - break; - } - - if (i > 100) { - throw new Error(`${message.text} failed`); - } - await timer(100); - } - - client.end(); - - for (let i = 0; ; i++) { - if (client.closed) { - break; - } - - if (i > 100) { - throw new Error(`Closing IPC connection failed`); - } - await timer(100); - } - - return response; } diff --git a/packages/cli/src/lib/globalContext.ts b/packages/cli/src/lib/globalContext.ts index 42aa5a7b..1808eeaa 100644 --- a/packages/cli/src/lib/globalContext.ts +++ b/packages/cli/src/lib/globalContext.ts @@ -283,8 +283,9 @@ export class MoonwallContext { throw new Error(`Invalid command received: ${message.cmd}`); } } catch (e) { - console.log("📨 Message from client:", data.toString()); - writeToClient({ status: "failure", result: false, message: e }); + console.log("📨 Error processing message from client:", data.toString()); + console.error(e.message); + writeToClient({ status: "failure", result: false, message: e.message }); } }); }); diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index 8b766bfd..6a49e182 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -1,9 +1,6 @@ { "extends": "../../tsconfig.json", - "compilerOptions": { - // ensure that nobody can accidentally use this config for a build - "noEmit": true - }, + "compilerOptions": {}, "include": ["./src/**/*.ts"], "exclude": ["**/dist/**"] } diff --git a/packages/types/tsconfig.json b/packages/types/tsconfig.json index b3423365..6a49e182 100644 --- a/packages/types/tsconfig.json +++ b/packages/types/tsconfig.json @@ -1,9 +1,6 @@ { "extends": "../../tsconfig.json", - "compilerOptions": { - // ensure that nobody can accidentally use this config for a build - // "noEmit": true - }, + "compilerOptions": {}, "include": ["./src/**/*.ts"], "exclude": ["**/dist/**"] } diff --git a/packages/util/tsconfig.json b/packages/util/tsconfig.json index 8b766bfd..6a49e182 100644 --- a/packages/util/tsconfig.json +++ b/packages/util/tsconfig.json @@ -1,9 +1,6 @@ { "extends": "../../tsconfig.json", - "compilerOptions": { - // ensure that nobody can accidentally use this config for a build - "noEmit": true - }, + "compilerOptions": {}, "include": ["./src/**/*.ts"], "exclude": ["**/dist/**"] } diff --git a/test/suites/zombie/test_basic.ts b/test/suites/zombie/test_basic.ts index 12780400..bdcfafff 100644 --- a/test/suites/zombie/test_basic.ts +++ b/test/suites/zombie/test_basic.ts @@ -1,11 +1,8 @@ import "@moonbeam-network/api-augment"; -import "@polkadot/api-augment"; import { beforeAll, describeSuite, expect } from "@moonwall/cli"; -import net from "net"; import { ALITH_ADDRESS, GLMR, baltathar } from "@moonwall/util"; import { ApiPromise } from "@polkadot/api"; -import { setTimeout as timer } from "timers/promises"; -import { stat } from "fs"; +import "@polkadot/api-augment"; describeSuite({ id: "Z1", @@ -36,11 +33,6 @@ describeSuite({ id: "T02", title: "Check parachain api correctly connected", test: async function () { - const socketPath = process.env.MOON_IPC_SOCKET; - const client = net.createConnection({ path: socketPath }, () => { - client.write("Hello from client again"); - }); - const network = paraApi.consts.system.version.specName.toString(); expect(network).to.contain("moonbase"); From 22e139862e4fb5935d0c54536549a2c76c5aa602 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Tue, 7 Nov 2023 17:43:04 +0000 Subject: [PATCH 19/21] Fixed Tail cmd --- .changeset/sweet-bats-punch.md | 3 +- packages/cli/src/cmds/runNetwork.ts | 5 ++-- .../src/internal/foundations/zombieHelpers.ts | 4 +-- packages/cli/src/lib/globalContext.ts | 28 +++++++++++-------- packages/types/config_schema.json | 4 --- packages/types/src/config.ts | 5 ---- test/moonwall.config.json | 1 - 7 files changed, 23 insertions(+), 27 deletions(-) diff --git a/.changeset/sweet-bats-punch.md b/.changeset/sweet-bats-punch.md index 9827e074..6068f735 100644 --- a/.changeset/sweet-bats-punch.md +++ b/.changeset/sweet-bats-punch.md @@ -6,4 +6,5 @@ Fixes for tanssi - [#295](https://github.com/Moonsong-Labs/moonwall/issues/295) - [#297](https://github.com/Moonsong-Labs/moonwall/issues/297) - [#278](https://github.com/Moonsong-Labs/moonwall/issues/278) -- [#221](https://github.com/Moonsong-Labs/moonwall/issues/221) \ No newline at end of file +- [#221](https://github.com/Moonsong-Labs/moonwall/issues/221) +- [#290](https://github.com/Moonsong-Labs/moonwall/issues/290) \ No newline at end of file diff --git a/packages/cli/src/cmds/runNetwork.ts b/packages/cli/src/cmds/runNetwork.ts index ea4f1db0..f1cf9c37 100644 --- a/packages/cli/src/cmds/runNetwork.ts +++ b/packages/cli/src/cmds/runNetwork.ts @@ -420,6 +420,7 @@ const resolveTailChoice = async (env: Environment) => { }); for (;;) { + clear(); if (process.env.MOON_ZOMBIE_NODES) { zombieNodes = process.env.MOON_ZOMBIE_NODES ? process.env.MOON_ZOMBIE_NODES.split("|") @@ -439,9 +440,7 @@ const resolveTailChoice = async (env: Environment) => { switchNode = false; await new Promise(async (resolve) => { const onData = (chunk: any) => ui.log.write(chunk.toString()); - const logFilePath = process.env.MOON_MONITORED_NODE - ? process.env.MOON_MONITORED_NODE - : process.env.MOON_LOG_LOCATION; + const logFilePath = `${process.env.MOON_ZOMBIE_DIR}/${zombieNodes[zombieNodePointer]}.log`; // eslint-disable-next-line prefer-const let currentReadPosition = 0; diff --git a/packages/cli/src/internal/foundations/zombieHelpers.ts b/packages/cli/src/internal/foundations/zombieHelpers.ts index 8b3e0c3f..70e46c54 100644 --- a/packages/cli/src/internal/foundations/zombieHelpers.ts +++ b/packages/cli/src/internal/foundations/zombieHelpers.ts @@ -52,13 +52,13 @@ export function getZombieConfig(path: string) { export type IPCRequestMessage = { text: string; - cmd: "restart" | "pause" | "resume" | "kill" | "isup" | "init"; + cmd: "restart" | "pause" | "resume" | "kill" | "isup" | "init" | "networkmap"; nodeName?: string; }; export type IPCResponseMessage = { status: "success" | "failure"; - result: boolean; + result: boolean | object; message: string; }; diff --git a/packages/cli/src/lib/globalContext.ts b/packages/cli/src/lib/globalContext.ts index 1808eeaa..23d672f4 100644 --- a/packages/cli/src/lib/globalContext.ts +++ b/packages/cli/src/lib/globalContext.ts @@ -171,13 +171,7 @@ export class MoonwallContext { const network = await zombie.start("", zombieConfig, { logType: "silent" }); process.env.MOON_RELAY_WSS = network.relay[0].wsUri; process.env.MOON_PARA_WSS = Object.values(network.paras)[0].nodes[0].wsUri; - if ( - env.foundation.type == "zombie" && - env.foundation.zombieSpec.monitoredNode && - env.foundation.zombieSpec.monitoredNode in network.nodesByName - ) { - process.env.MOON_MONITORED_NODE = `${network.tmpDir}/${env.foundation.zombieSpec.monitoredNode}.log`; - } + const nodeNames = Object.keys(network.nodesByName); process.env.MOON_ZOMBIE_DIR = `${network.tmpDir}`; process.env.MOON_ZOMBIE_NODES = nodeNames.join("|"); @@ -214,10 +208,19 @@ export class MoonwallContext { try { const message: IPCRequestMessage = JSON.parse(data.toString()); - const node = network.getNodeByName(message.nodeName); const zombieClient = network.client; switch (message.cmd) { + case "networkmap": { + const result = Object.keys(network.nodesByName); + writeToClient({ + status: "success", + result: network.nodesByName, + message: result.join("|"), + }); + break; + } + case "restart": { await this.disconnect(); await zombieClient.restartNode(message.nodeName, null); @@ -231,6 +234,7 @@ export class MoonwallContext { } case "resume": { + const node = network.getNodeByName(message.nodeName); await this.disconnect(); const result = await node.resume(); await (zombieClient as any).wait_node_ready(message.nodeName); @@ -244,6 +248,7 @@ export class MoonwallContext { } case "pause": { + const node = network.getNodeByName(message.nodeName); await this.disconnect(); const result = await node.pause(); await timer(1000); // TODO: Replace when zombienet has an appropriate fn @@ -270,6 +275,7 @@ export class MoonwallContext { } case "isup": { + const node = network.getNodeByName(message.nodeName); const result = await node.isUp(); writeToClient({ status: "success", @@ -300,9 +306,9 @@ export class MoonwallContext { process.once("exit", onProcessExit); process.once("SIGINT", onProcessExit); - process.env.MOON_MONITORED_NODE = zombieConfig.parachains[0].collator - ? `${network.tmpDir}/${zombieConfig.parachains[0].collator.name}.log` - : `${network.tmpDir}/${zombieConfig.parachains[0].collators![0].name}.log`; + // process.env.MOON_MONITORED_NODE = zombieConfig.parachains[0].collator + // ? `${network.tmpDir}/${zombieConfig.parachains[0].collator.name}.log` + // : `${network.tmpDir}/${zombieConfig.parachains[0].collators![0].name}.log`; this.zombieNetwork = network; return; } diff --git a/packages/types/config_schema.json b/packages/types/config_schema.json index fbfbd310..2a6f104c 100644 --- a/packages/types/config_schema.json +++ b/packages/types/config_schema.json @@ -468,10 +468,6 @@ "description": "Specifies whether the framework should eavesdrop and log WARN, ERROR from the node logs.\nIf set to true, the eavesdropping on node logs is disabled.\nDefault behavior (when unset or set to false) is to listen to the logs.", "type": "boolean" }, - "monitoredNode": { - "description": "An optional monitored node.", - "type": "string" - }, "name": { "description": "The name of the launch spec.", "type": "string" diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index b94d18eb..61d2dde1 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -238,11 +238,6 @@ export interface ZombieLaunchSpec extends GenericLaunchSpec { */ configPath: string; - /** - * An optional monitored node. - */ - monitoredNode?: string; - /** * An optional array of blocks to skip checking. */ diff --git a/test/moonwall.config.json b/test/moonwall.config.json index 38fd8de7..485ce5b6 100644 --- a/test/moonwall.config.json +++ b/test/moonwall.config.json @@ -121,7 +121,6 @@ "name": "zombienet", "configPath": "./configs/zombieMulti.json", "disableLogEavesdropping": true, - "monitoredNode": "alice", "skipBlockCheck": ["para2"] } }, From 444cba9cfc1d4c4899d3cd4c80f08a6f06058616 Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Tue, 7 Nov 2023 18:09:21 +0000 Subject: [PATCH 20/21] zombie fix --- packages/cli/src/lib/globalContext.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/src/lib/globalContext.ts b/packages/cli/src/lib/globalContext.ts index 23d672f4..19f4f48b 100644 --- a/packages/cli/src/lib/globalContext.ts +++ b/packages/cli/src/lib/globalContext.ts @@ -224,6 +224,7 @@ export class MoonwallContext { case "restart": { await this.disconnect(); await zombieClient.restartNode(message.nodeName, null); + await timer(1000) // TODO: Replace when zombienet has an appropriate fn await this.connectEnvironment(true); writeToClient({ status: "success", From 49244f2ccd29277b94478b92b48d1ed743ee6afc Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Tue, 7 Nov 2023 18:10:40 +0000 Subject: [PATCH 21/21] fmt fix --- packages/cli/src/lib/globalContext.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/globalContext.ts b/packages/cli/src/lib/globalContext.ts index 19f4f48b..13f52cde 100644 --- a/packages/cli/src/lib/globalContext.ts +++ b/packages/cli/src/lib/globalContext.ts @@ -224,7 +224,7 @@ export class MoonwallContext { case "restart": { await this.disconnect(); await zombieClient.restartNode(message.nodeName, null); - await timer(1000) // TODO: Replace when zombienet has an appropriate fn + await timer(1000); // TODO: Replace when zombienet has an appropriate fn await this.connectEnvironment(true); writeToClient({ status: "success",