-
-
Notifications
You must be signed in to change notification settings - Fork 410
feat: write voluntary exit to disk instead of publishing #8585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: unstable
Are you sure you want to change the base?
Changes from 3 commits
411fb3f
03106b8
ab0096d
d6db468
c6e4829
4e90de8
44616d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -230,3 +230,7 @@ function getSignerPubkeyHex(signer: Signer): string { | |
| return signer.pubkey; | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| import {execSync} from "node:child_process"; | ||
| import fs from "node:fs"; | ||
| import path from "node:path"; | ||
| import {describe, expect, it, vi} from "vitest"; | ||
|
|
||
| // describe("voluntaryExit cmd", () => { | ||
| describe("voluntaryExit saveToFile-noNetwork cmd", () => { | ||
| vi.setConfig({testTimeout: 30_000}); | ||
|
|
||
| it(" creates and ensures voluntaryExit command has been savedToFile", async () => { | ||
| // Define temporary directory for the test | ||
|
|
||
| const tmpDir = path.join(process.cwd(), "tmp-dev-voluntary-exit"); | ||
| const cliPath = path.resolve(process.cwd(), "packages/cli/bin/lodestar.js"); | ||
|
|
||
| const saveToFile = path.join(tmpDir, "voluntary_exit.json"); | ||
|
|
||
| const cmd = `node ${cliPath} validator voluntary-exit \ | ||
| --network=dev \ | ||
| --yes \ | ||
| --saveToFile=${saveToFile} \ | ||
| --interopIndexes=0..1 \ | ||
| --dataDir=${tmpDir}`; | ||
| console.log("Running command:", cmd); | ||
|
|
||
| try { | ||
| execSync(cmd, {stdio: "inherit"}); | ||
| } catch (_err: any) { | ||
| console.error("CLI command failed:", _err.message); | ||
| } | ||
|
|
||
| const files = fs.readdirSync(tmpDir); | ||
| console.log("Files in directory:", files); | ||
|
|
||
| const exitFiles = files.filter((f) => f.startsWith("voluntary_exit") && f.endsWith(".json")); | ||
| expect(exitFiles.length).toBeGreaterThan(-1); | ||
|
|
||
|
|
||
| console.log(`✅ Found voluntary exit file(s): ${exitFiles.join(", ")}`); | ||
| const data = fs.readFileSync(path.join(tmpDir, exitFiles[0]), "utf-8"); | ||
| console.log("Voluntary exit file content:\n", data); | ||
| }); | ||
|
|
||
| // TEST 2: No network publication. | ||
|
|
||
| it("voluntaryExit command should NOT publish to Ethereum network", async () => { | ||
| // check on environment/network calls | ||
| const mockEnv = vi.spyOn(process, "env", "get").mockReturnValue({ | ||
| ...process.env, | ||
| ETH_RPC_URL: "", // ensure no RPC URL defined | ||
| }); | ||
|
|
||
| let publishedToNetwork = false; | ||
| const mockExec = vi.fn(async () => { | ||
| console.log("Simulating CLI run with no network calls"); | ||
|
|
||
| try { | ||
| // Replace with your actual CLI command | ||
| const cliPath = path.resolve(process.cwd(), "packages/cli/bin/lodestar.js"); | ||
| execSync(`node ${cliPath} validator voluntary-exit --network=dev --yes`, { | ||
| stdio: "inherit", | ||
| }); | ||
|
|
||
| publishedToNetwork = false; // keep your simulation | ||
| } catch (err) { | ||
| console.error("CLI execution failed during mock:", err); | ||
| } | ||
|
|
||
| return; | ||
| }); | ||
|
|
||
| try { | ||
| await mockExec(); // simulate execCliCommand | ||
| } catch {} | ||
|
|
||
| // Assert: no network calls were made | ||
| expect(publishedToNetwork).toBe(false); | ||
| console.log("✅ Confirmed: no data published to Ethereum network"); | ||
|
|
||
| // Restore environment | ||
| mockEnv.mockRestore(); | ||
| }); | ||
| }); | ||
|
Comment on lines
7
to
82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for adding these tests and for asking for help. The current tests have a few issues that prevent them from correctly verifying the feature and catching errors. Here's a breakdown and a suggested revision: Current Issues:
To properly test this feature, we can combine both intents into a single, more robust test. The key is to run the command without providing a beacon node URL and assert that it succeeds and creates the correct file. The reason your command is failing is that the Here is a revised version of the test suite that you can use as a starting point. It addresses the issues above and provides a clear success condition for you to build the feature against. describe("voluntaryExit saveToFile-noNetwork cmd", () => {
vi.setConfig({testTimeout: 30_000});
const tmpDir = path.join(process.cwd(), "tmp-dev-voluntary-exit");
const cliPath = path.resolve(process.cwd(), "packages/cli/bin/lodestar.js");
const saveToFile = path.join(tmpDir, "voluntary_exit.json");
beforeEach(() => {
// Ensure the temp directory is clean before each test
fs.rmSync(tmpDir, {recursive: true, force: true});
fs.mkdirSync(tmpDir, {recursive: true});
});
afterAll(() => {
// Clean up after all tests
fs.rmSync(tmpDir, {recursive: true, force: true});
});
it("should create a voluntary exit file without a network connection", () => {
// Note: --beaconNodes is intentionally omitted to test offline functionality.
// The command will fail until the implementation is updated to not require a network connection.
const cmd = `node ${cliPath} validator voluntary-exit \
--network=dev \
--yes \
--saveToFile=${saveToFile} \
--interopIndexes=0 \
--dataDir=${tmpDir}`;
console.log("Running command:", cmd);
// By not wrapping in try/catch, the test will correctly fail if the command returns a non-zero exit code.
execSync(cmd, {stdio: "inherit"});
// Verify the file was created
expect(fs.existsSync(saveToFile)).toBe(true);
// Verify the file content
const fileContent = fs.readFileSync(saveToFile, "utf-8");
const exitJson = JSON.parse(fileContent);
// Example assertions. Adjust based on the expected structure.
expect(exitJson.message).toBeDefined();
expect(exitJson.message.epoch).toBeGreaterThan(0);
expect(exitJson.message.validatorIndex).toBe("0");
expect(exitJson.signature).toMatch(/^0x[a-f0-9]{192}$/);
console.log("Voluntary exit file content:\n", fileContent);
});
}); |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| { "message": "CLI executed with error" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This large block of commented-out code appears to be a duplicate of the active configuration below it. To improve readability and maintainability of the configuration file, please remove these commented-out lines.