exec-sync harness case 7: the PC shape (tip-0 pair, peer flag) recovers over p2p; bench-log line

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-06 18:13:44 +00:00
parent 75a6364384
commit 98bdeeb88b
2 changed files with 34 additions and 1 deletions

View file

@ -2284,3 +2284,11 @@ pre-state root 0x64304441... and post-state root 0x60d60bba..., equal to node 1'
and 139,952 (an independent node). Consequence: a prover on a snapshot-restored node (every hand, nine fleet boxes) cuts a
provable fixture again with the 0.3.14 app and exporter; what is left for a paid record is the proof itself (the PCs or
the fleet, not this Mac).
### 6 October 2026, 18:11Z to 18:13Z, the PC shape over p2p (Mac, `tools/lock/with-lock.sh run`)
Fork 1255c0f9. `node tools/exec-sync/net.mjs`: 18/18 in 117.5 s. Case 7: a node whose data dir holds the tip-0 pair the 0.3.13
genesis replay left behind, with `--igneum-exec-snapshot=peer`, sets the pair aside (.bin.tip0), asks A over p2p and loads
A's state with no hand action; its state root at 60 equals A's. `reorg.mjs` 18/18 in 262.1 s on the same binary; the exec
suite 20. Consequence: a PC or a box left with the tip-0 pair recovers on its own once a hand serves (the 5-minute
no-progress rule fires the ask even when the error text is new); until 0.3.14.1 the recovery file by hand is the way.

View file

@ -13,10 +13,11 @@
// "unknown to consensus" (the file's tip is from another chain: a second simnet)
// 5. known-failed: a node E whose flag names a file that cannot be read blocks loudly (0.3.13.1), never genesis
// 6. the account dump (0.3.14): export [tip-1, tip] from B carries preState; the exporter seeds from it and cuts
// 7. the PC shape (0.3.14.1): G with the tip-0 pair and --igneum-exec-snapshot=peer recovers from A over p2p
// Usage: node tools/exec-sync/net.mjs [--blocks 60]
// IGNEUM_EXEC_BIN=<dir with igneumd and igneum-miner> (default vendor/igneum-node/target-exec-sync/release)
import { spawn, spawnSync } from 'node:child_process';
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync, openSync } from 'node:fs';
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync, openSync, copyFileSync } from 'node:fs';
import { createHash } from 'node:crypto';
const ROOT = new URL('../../', import.meta.url).pathname;
@ -81,10 +82,14 @@ function sha256(path) { return '0x' + createHash('sha256').update(readFileSync(p
async function main() {
const a = await new Node(0).start();
log(`node A up on ${a.evm}`);
const tip0File = `${TMP}/tip0.bin`;
const miner = mine(a, 'exec-sync-a');
await waitTip(a, BLOCKS, 900);
const tipA = hexn(await a.eth('eth_blockNumber'));
const st0 = await a.eth('igneum_getExecStatus');
// a tip-0 snapshot (the genesis replay's leftover shape) for case 7: the state after chain block 0, from A's ring
const t0x = await a.eth('igneum_exportExecSnapshot', [tip0File, '0x0']);
if (!existsSync(tip0File) || hexn(t0x.tip) !== 0) throw new Error('no tip-0 export');
check('A executes from genesis', st0.startedFrom === 'genesis' && st0.blocked === null && hexn(st0.executedTip) >= BLOCKS, st0);
// case 1: the export, the stop, the resume
const file = `${TMP}/snapshot.bin`;
@ -151,6 +156,26 @@ async function main() {
const out = (r.stdout || '') + (r.stderr || '');
check('the exporter seeds from the dump and cuts the block (state root equals the node\'s)', r.status === 0 && existsSync(fix) && /account dump: \d+ accounts after chain block/.test(out) && !/differs from the node/.test(out), { status: r.status, line: (out.split('\n').find(l => /account dump/.test(l)) || out.slice(-200)).slice(0, 200) });
}
// 7. the PC shape (0.3.14.1): a node G whose data dir holds the tip-0 pair the 0.3.13 genesis replay left behind,
// with --igneum-exec-snapshot=peer: G refuses the pair (set aside as .tip0), blocks, asks A over p2p and loads
// A's state with no hand action; then it follows the chain. (A pruning point above the anchor is not reproducible
// on a simnet in minutes; the pruned-node branch of the same classifier is unit-tested in service.rs.)
{
const g = new Node(6, [`127.0.0.1:${a.p2pPort}`], ['--igneum-exec-snapshot=peer']);
const evmDir = `${g.dir}/igneum-devnet-${SUFFIX}/datadir/evm`;
mkdirSync(evmDir, { recursive: true });
copyFileSync(tip0File, `${evmDir}/exec-snapshot.bin`); copyFileSync(tip0File, `${evmDir}/exec-snapshot.prev.bin`);
await g.start();
let stG = null;
for (let k = 0; k < 240; k++) { stG = await g.eth('igneum_getExecStatus'); if (stG.startedFrom.startsWith('peer') && hexn(stG.executedTip) > 0) break; await sleep(500); }
const gline = g.logText().split('\n').find(l => /tip 0 \(a genesis state\) is never a resume/.test(l));
check('G refused the tip-0 pair in its data dir and set it aside', !!gline && existsSync(`${evmDir}/exec-snapshot.bin.tip0`), { line: gline && gline.slice(-140) });
check('G recovered over p2p from A with no hand action and follows the chain', stG.startedFrom.startsWith('peer') && hexn(stG.executedTip) > 0 && stG.blocked === null, { startedFrom: stG.startedFrom, tip: stG.executedTip });
const h = hexn(stG.executedTip);
const ra = await a.eth('eth_getBlockByNumber', ['0x' + h.toString(16), false]), rg = await g.eth('eth_getBlockByNumber', ['0x' + h.toString(16), false]);
check('G\'s state root at its tip equals A\'s', ra.stateRoot === rg.stateRoot, { height: h });
await g.stop();
}
// 5. known-failed: a node E whose flag names a file that does not exist (the seed, 6 October 2026: unreadable under
// /root) blocks loudly, never runs as if the flag were unset, never executes genesis
const e = await new Node(5, [`127.0.0.1:${a.p2pPort}`], ['--igneum-exec-snapshot=/nonexistent/exec-snapshot.bin,0x00']).start();