From 99ff23493d389acc2a045e88f8e56b8ccb93138a Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Thu, 8 Oct 2026 09:45:26 +0000 Subject: [PATCH] testnet-object harness: the miners outlive the run (the stop hook ends them) and the final finality read is taken as the run ends, while every voter signs (pod 2's false pause, 8 October 2026) Co-Authored-By: Claude Fable 5.1 --- infra/fast-time/testnet-object.mjs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/infra/fast-time/testnet-object.mjs b/infra/fast-time/testnet-object.mjs index 365225c3d..11e7747e7 100644 --- a/infra/fast-time/testnet-object.mjs +++ b/infra/fast-time/testnet-object.mjs @@ -203,7 +203,9 @@ const START_LINES = { }; for (const n of nodes) log(`n${n.i}: ${Object.entries(START_LINES).map(([k, re]) => `${k}=${n.grepLog(re).length > 0}`).join(' ')} | digest ${(n.grepLog(START_LINES.digest)[0] || '').replace(/^.*?digest: /, '').slice(0, 16)}`); // n0 and n1 vote (the key is the payout label's identity); n2 never votes: the silent key -const miners = nodes.map((n, i) => miner(CPU_MINER, ['mine', n.grpc, '1', String(SECS), `cpu${i}`, '--engine', 'igneum-pow', '--payout-label', LABELS[i], '--evm-address', EVM[i], '--dev-fee', '0', '--status-secs', '30', '--stall-secs', '0', ...(i === SILENT ? ['--no-vote'] : [])], `cpu${i}`, { IGNEUM_POW_DAY_MS: String(DAY_MS) })); +// the miners (and so the voters) outlive the run by five minutes and are stopped by the stop hook, so the final finality +// read never sees a table nobody signs (pod 2 of 8 October 2026 read "0.00% signing" after the voters had exited with the run) +const miners = nodes.map((n, i) => miner(CPU_MINER, ['mine', n.grpc, '1', String(SECS + 300), `cpu${i}`, '--engine', 'igneum-pow', '--payout-label', LABELS[i], '--evm-address', EVM[i], '--dev-fee', '0', '--status-secs', '30', '--stall-secs', '0', ...(i === SILENT ? ['--no-vote'] : [])], `cpu${i}`, { IGNEUM_POW_DAY_MS: String(DAY_MS) })); const pay = devAddress('fast-time-testnet-object'); const epochs = new Map(); @@ -250,6 +252,8 @@ while (Date.now() - t0 < SECS * 1000) { samples.push({ t: +since(), daa, epoch, class: cls, step, reps, locked: r?.latestLockedIndex ?? null, active: r?.finalityActive ?? null, nodes: counts }); } } +// the final finality read, taken the moment the run ends and while every voter still signs +const finalReports = await Promise.all(nodes.map(n => report(n, 3))); await sleep(3000); // the chain: every block with its coinbase outputs by address, and the execution layer's segment rewards by miner @@ -397,7 +401,6 @@ const sinks = dag.map(d => String(d.sink || '?').slice(0, 16)); const counts = dag.map(d => d.blockCount ?? '?'); const accepted = LABELS.map((_, i) => minerLog(i).filter(l => /ACCEPTED block/.test(l)).length); const rejectedNode = nodes.map(n => n.grepLog(/PoW rejected|Rejected block|rejected block/i).length); -const finalReports = await Promise.all(nodes.map(n => report(n, 3))); // the report's reason flickers for one read at every new lock (the table frozen at the lock reads 0.00 percent signing // for a second); a pause is consecutive inactive reads, measured in seconds of the 1-s poll, never one read function longestInactiveStretchAfter(daa) {