diff --git a/.changeset/sweet-bats-punch.md b/.changeset/sweet-bats-punch.md new file mode 100644 index 00000000..6068f735 --- /dev/null +++ b/.changeset/sweet-bats-punch.md @@ -0,0 +1,10 @@ +--- +"@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) +- [#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/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/package.json b/packages/cli/package.json index 0cf68371..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,10 +82,11 @@ "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", + "jsonc-parser": "^3.2.0", "minimatch": "^9.0.3", "node-fetch": "^3.3.2", "semver": "^7.5.4", @@ -100,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/cmds/entrypoint.ts b/packages/cli/src/cmds/entrypoint.ts index 4eeb0126..91373ee6 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(); @@ -31,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/cmds/runNetwork.ts b/packages/cli/src/cmds/runNetwork.ts index a57a202a..f1cf9c37 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: @@ -123,7 +122,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(); } @@ -161,7 +163,9 @@ export async function runNetworkCmd(args) { break; case 3: - await resolveCommandChoice(); + env.foundation.type !== "zombie" + ? await resolveCommandChoice() + : await resolveZombieCommandChoice(); lastSelected = 2; break; @@ -229,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", @@ -356,94 +398,158 @@ 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 zombieContent: string; + 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`; + )} 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 (;;) { + clear(); + 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; + zombieContent = `, ${chalk.bgWhite.black("[,]")} Next Log, ${chalk.bgWhite.black( + "[.]" + )} Previous Log | CurrentLog: ${chalk.bgWhite.black( + `${zombieNodes[zombieNodePointer]} (${zombieNodePointer + 1}/${zombieNodes.length})` + )}`; - const printLogs = (newReadPosition: number, currentReadPosition: number) => { - const stream = fs.createReadStream(logFilePath, { - start: currentReadPosition, - end: newReadPosition, - }); - stream.on("data", onData); - stream.on("end", () => { - currentReadPosition = newReadPosition; - }); - }; + bottomBarContents = bottomBarBase + resumePauseProse[tailing ? 0 : 1] + zombieContent; - const readLog = () => { - const stats = fs.statSync(logFilePath); - const newReadPosition = stats.size; + ui.updateBottomBar(bottomBarContents, "\n"); + } - if (newReadPosition > currentReadPosition && tailing) { - printLogs(newReadPosition, currentReadPosition); - } - }; + switchNode = false; + await new Promise(async (resolve) => { + const onData = (chunk: any) => ui.log.write(chunk.toString()); + const logFilePath = `${process.env.MOON_ZOMBIE_DIR}/${zombieNodes[zombieNodePointer]}.log`; + + // 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); + } + }; - printLogs(fs.statSync(logFilePath).size, 0); + const incrPtr = () => { + zombieNodePointer = (zombieNodePointer + 1) % zombieNodes.length; + }; - const handleInputData = async (key: any) => { - ui.rl.input.pause(); - const char = key.toString().trim(); + const decrPtr = () => { + zombieNodePointer = (zombieNodePointer - 1 + zombieNodes.length) % zombieNodes.length; + }; - if (char === "p") { - tailing = false; - ui.updateBottomBar(bottomBarContents + resumePauseProse[1]); - } + printLogs(fs.statSync(logFilePath).size, 0); - if (char === "r") { - printLogs(fs.statSync(logFilePath).size, currentReadPosition); - tailing = true; - ui.updateBottomBar(bottomBarContents + resumePauseProse[0]); - } + const renderBottomBar = (...parts: any[]) => { + const content = process.env.MOON_ZOMBIE_NODES + ? bottomBarBase + " " + parts?.join(" ") + zombieContent + "\n" + : bottomBarBase + " " + parts?.join(" ") + "\n"; + ui.updateBottomBar(content); + }; - if (char === "q") { - ui.rl.input.removeListener("data", handleInputData); + const handleInputData = async (key: any) => { ui.rl.input.pause(); - fs.unwatchFile(logFilePath); - resolve(""); - } + const char = key.toString().trim(); - if (char === "t") { - await resolveTestChoice(env, true); - ui.updateBottomBar(bottomBarContents + resumePauseProse[tailing ? 0 : 1]); - } + if (char === "p") { + tailing = false; + renderBottomBar(resumePauseProse[1]); + } - 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 === "r") { + printLogs(fs.statSync(logFilePath).size, currentReadPosition); + tailing = true; + renderBottomBar(resumePauseProse[0]); + } - ui.rl.input.resume(); - }; + if (char === "q") { + ui.rl.input.removeListener("data", handleInputData); + ui.rl.input.pause(); + fs.unwatchFile(logFilePath); + resolve(""); + } - ui.rl.input.on("data", handleInputData); + if (char === "t") { + await resolveTestChoice(env, true); + renderBottomBar(resumePauseProse[tailing ? 0 : 1]); + } + + if (char === ",") { + ui.rl.input.removeListener("data", handleInputData); + ui.rl.input.pause(); + fs.unwatchFile(logFilePath); + switchNode = true; + incrPtr(); + resolve(""); + } - fs.watchFile(logFilePath, () => { - readLog(); + 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(); + } + + 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/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/initialisation.ts b/packages/cli/src/internal/cmdFunctions/initialisation.ts index 44e985bb..058cf62e 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,9 @@ export function createConfig(options: { ], }; } + +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/internal/cmdFunctions/tempLogs.ts b/packages/cli/src/internal/cmdFunctions/tempLogs.ts index 7e8e0553..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)); } @@ -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}`; @@ -30,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/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/foundations/zombieHelpers.ts b/packages/cli/src/internal/foundations/zombieHelpers.ts index 0bde519b..70e46c54 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,62 @@ 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" | "init" | "networkmap"; + nodeName?: string; +}; + +export type IPCResponseMessage = { + status: "success" | "failure"; + result: boolean | object; + message: string; +}; + +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); + } + + if (response.status === "failure") { + reject(new Error(JSON.stringify(response))); + } + }); + + for (let i = 0; ; i++) { + if (!client.connecting) { + break; + } + + if (i > 100) { + reject(new Error(`Connection to ${ipcPath} failed`)); + } + await timer(200); + } + + await new Promise((resolve) => { + client.write(JSON.stringify(message), () => resolve("Sent!")); + }); + }); +} diff --git a/packages/cli/src/internal/localNode.ts b/packages/cli/src/internal/localNode.ts index 2a119fb4..eec90d8f 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 @@ -155,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 4cfeb309..b5a2dc85 100644 --- a/packages/cli/src/lib/configReader.ts +++ b/packages/cli/src/lib/configReader.ts @@ -1,24 +1,49 @@ 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 path from "path"; +import JSONC from "jsonc-parser"; +import path, { extname } from "path"; let cachedConfig: MoonwallConfig | undefined; -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`); +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; } - const file = await fs.readFile(path, { encoding: "utf-8" }); - const json: MoonwallConfig = JSON.parse(file); - return json; + return result; +} +function parseConfigSync(filePath: string) { + let result: any; + + const file = readFileSync(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 importConfig(configPath: string): Promise { @@ -49,10 +74,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}`); @@ -68,11 +92,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); @@ -89,11 +111,10 @@ 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 config = await parseConfig(filePath); + const replacedConfig = replaceEnvVars(config); - cachedConfig = replacedJson as MoonwallConfig; + cachedConfig = replacedConfig as MoonwallConfig; return cachedConfig; } catch (e) { console.error(e); diff --git a/packages/cli/src/lib/globalContext.ts b/packages/cli/src/lib/globalContext.ts index e7bbb282..13f52cde 100644 --- a/packages/cli/src/lib/globalContext.ts +++ b/packages/cli/src/lib/globalContext.ts @@ -12,10 +12,16 @@ 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"; -import { checkZombieBins, getZombieConfig } from "../internal/foundations/zombieHelpers"; +import { + IPCRequestMessage, + IPCResponseMessage, + checkZombieBins, + getZombieConfig, +} from "../internal/foundations/zombieHelpers"; import { LaunchedNode, launchNode } from "../internal/localNode"; import { ProviderFactory, @@ -38,6 +44,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)!; @@ -164,36 +171,145 @@ 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 && - 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("|"); - 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"); } }; + const socketPath = `${network.tmpDir}/node-ipc.sock`; + + const server = net.createServer((client) => { + // client.on("end", () => { + // 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: IPCRequestMessage = JSON.parse(data.toString()); + + 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); + await timer(1000); // TODO: Replace when zombienet has an appropriate fn + await this.connectEnvironment(true); + writeToClient({ + status: "success", + result: true, + message: `${message.nodeName} restarted`, + }); + break; + } + + 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); + await this.connectEnvironment(true); + writeToClient({ + status: "success", + result, + message: `${message.nodeName} resumed with result ${result}`, + }); + break; + } + + 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 + writeToClient({ + status: "success", + result, + message: `${message.nodeName} paused with result ${result}`, + }); + 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, + message: `${message.nodeName}, pid ${pid} killed with exitCode ${result.exitCode}`, + }); + break; + } + + case "isup": { + const node = network.getNodeByName(message.nodeName); + 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("📨 Error processing message from client:", data.toString()); + console.error(e.message); + writeToClient({ status: "failure", result: false, message: e.message }); + } + }); + }); + + 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); - 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; } @@ -226,7 +342,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)!; @@ -254,10 +370,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}`); + !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_PATH}/${nodeName}.log`); + .map((nodeName) => `${process.env.MOON_ZOMBIE_DIR}/${nodeName}.log`); readStreams = zombieNodeLogs.map((logPath) => { const readStream = fs.createReadStream(logPath, { encoding: "utf8" }); @@ -284,7 +400,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() @@ -292,7 +408,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(""); }); }); @@ -338,16 +454,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; @@ -373,6 +479,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/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/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/config_schema.json b/packages/types/config_schema.json index 8af8f317..2a6f104c 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" @@ -464,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" @@ -496,10 +496,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/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/types/src/config.ts b/packages/types/src/config.ts index cb0fd874..61d2dde1 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. */ @@ -243,11 +238,6 @@ export interface ZombieLaunchSpec extends GenericLaunchSpec { */ configPath: string; - /** - * An optional monitored node. - */ - monitoredNode?: string; - /** * An optional array of blocks to skip checking. */ @@ -291,6 +281,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 +312,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 +331,11 @@ export interface DevLaunchSpec extends GenericLaunchSpec { */ wsPort: number; }; + + /** + * An optional flag to retain node logs from previous runs. + */ + retainAllLogs?: boolean; } /** diff --git a/packages/types/src/runner.ts b/packages/types/src/runner.ts index b50f738d..1d40bdbd 100644 --- a/packages/types/src/runner.ts +++ b/packages/types/src/runner.ts @@ -209,10 +209,71 @@ 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; + + /** + * ⚠ī¸ 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; + + /** + * 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; + + /** + * ⚠ī¸ 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, 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/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/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/pnpm-lock.yaml b/pnpm-lock.yaml index b0da3e20..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 @@ -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 @@ -140,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) @@ -155,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 @@ -167,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 @@ -209,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 @@ -218,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) @@ -294,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 @@ -355,8 +358,8 @@ importers: specifier: ^0.9.0 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 @@ -385,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 @@ -394,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 @@ -413,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) @@ -1281,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==} @@ -1319,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==} @@ -1332,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==} @@ -1395,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==} @@ -1879,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: @@ -1939,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==} @@ -1955,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==} @@ -2137,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==} @@ -2145,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==} @@ -2316,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) @@ -2338,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' @@ -2351,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 @@ -2360,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' @@ -2370,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 @@ -2751,6 +2749,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 @@ -2799,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): @@ -3098,6 +3097,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==} @@ -3877,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 @@ -3960,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==} @@ -3981,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==} @@ -3992,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==} @@ -4053,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==} @@ -4254,6 +4250,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 +4315,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==} @@ -4461,6 +4459,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 +4485,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 +4772,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==} @@ -5147,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==} @@ -5155,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==} @@ -5183,6 +5183,7 @@ packages: /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + requiresBuild: true dependencies: brace-expansion: 1.1.11 @@ -5341,13 +5342,13 @@ 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==} /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + requiresBuild: true /multiformats@9.9.0: resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} @@ -5795,6 +5796,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==} @@ -5925,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: @@ -6018,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 @@ -6049,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==} @@ -6212,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==} @@ -6256,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==} @@ -6290,6 +6289,7 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + requiresBuild: true /saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} @@ -6412,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==} @@ -6819,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==} @@ -6901,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 @@ -7324,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: @@ -7345,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==} @@ -7367,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==} @@ -7391,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} @@ -7447,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==} @@ -7483,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==} @@ -7534,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' @@ -7619,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==} @@ -7678,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 @@ -8130,6 +8039,7 @@ packages: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + requiresBuild: true dependencies: isexe: 2.0.0 @@ -8232,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/moonwall.config.json b/test/moonwall.config.json index c3b5e164..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"] } }, @@ -142,6 +141,7 @@ "name": "zombie_test", "testFileDir": ["suites/zombie"], "timeout": 300000, + "envVars": ["DEBUG_COLORS=1"], "reporters": ["basic"], "foundation": { "type": "zombie", 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..bdcfafff 100644 --- a/test/suites/zombie/test_basic.ts +++ b/test/suites/zombie/test_basic.ts @@ -2,6 +2,7 @@ import "@moonbeam-network/api-augment"; import { beforeAll, describeSuite, expect } from "@moonwall/cli"; import { ALITH_ADDRESS, GLMR, baltathar } from "@moonwall/util"; import { ApiPromise } from "@polkadot/api"; +import "@polkadot/api-augment"; describeSuite({ id: "Z1", @@ -11,15 +12,15 @@ describeSuite({ let paraApi: ApiPromise; let relayApi: ApiPromise; - beforeAll(() => { + beforeAll(async () => { paraApi = context.polkadotJs("parachain"); relayApi = context.polkadotJs("relaychain"); - }); + }, 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); @@ -89,5 +90,16 @@ describeSuite({ log((await paraApi.rpc.chain.getBlock()).block.header.number.toNumber()); }, }); + + it({ + id: "T06", + title: "Restart a node from test script", + timeout: 600000, + test: async function () { + await context.restartNode("alith"); + await context.waitBlock(2, "parachain", "quantity"); + }, + }); + }, }); 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,