class v5 harness: the object bytes follow the 0.3.20 node line (the amended class v4 signals 5, class v5 signals 6)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
7f2bc3821c
commit
2618ea3acf
2 changed files with 14 additions and 12 deletions
|
|
@ -4,23 +4,24 @@
|
|||
// the v4 FLOOR at --v4-floor (default 120, epoch 2), the class v5 floor at --floor (default 100000: far away, so v5 is
|
||||
// ENABLED and the signal decides; `never` turns the object off), the signal window at --window (default 60 DAA, one
|
||||
// epoch; seven windows = 420 DAA, so the first epoch whose seed block has seven full windows below it is epoch 8 at
|
||||
// DAA 480), each node's object byte by IGNEUM_CLASS_SIGNAL (--signal a,b,c), each node's exec RPC on its own loopback
|
||||
// DAA 480), each node's object byte by IGNEUM_CLASS_SIGNAL (--signal a,b,c; since the 0.3.20 node line the amended
|
||||
// class v4 is object byte 5 and class v5 is 6), each node's exec RPC on its own loopback
|
||||
// port and each CPU miner's --exec-rpc pointing at its node (the state stream after each epoch's seed block). A fourth
|
||||
// node runs with --evm-disable (--stateless-node, default on): it mines until the flip and then serves no class v5
|
||||
// template, which the harness counts. Ports 29760 and up, network igneum-devnet-976, data /tmp/igneum-fast-time-v5s.
|
||||
//
|
||||
// The cases and the known-failed cases:
|
||||
// --signal 5,5,4 --expect no-flip two of three signal v5: 67 percent, the class must stay v4 (run 11 epochs)
|
||||
// --signal 5,5,5 --expect flip all three: v5 from epoch 8, the first boundary with seven full windows; every
|
||||
// --signal 6,6,5 --expect no-flip two of three signal v5: 67 percent, the class must stay v4 (run 11 epochs)
|
||||
// --signal 6,6,6 --expect flip all three: v5 from epoch 8, the first boundary with seven full windows; every
|
||||
// miner's v5 id equals the CLI's --program-class v5 id and differs from the same
|
||||
// seed's v4 id; the stateless node's miner accepts 0 blocks after the flip; 0 rejected
|
||||
// --signal 5,5,5 --floor never --expect no-flip the object off: byte 5 counts as v4 only
|
||||
// --signal 4,4,4 --floor 600 --expect floor nobody signals v5: it flips at the floor (epoch 10) and not before
|
||||
// --signal 5,5,5 --expect flip --stale 2 proof of following's known-failed case: miner 2 keeps the first stream it
|
||||
// --signal 6,6,6 --floor never --expect no-flip the object off: byte 6 counts as v4 only
|
||||
// --signal 5,5,5 --floor 600 --expect floor nobody signals v5: it flips at the floor (epoch 10) and not before
|
||||
// --signal 6,6,6 --expect flip --stale 2 proof of following's known-failed case: miner 2 keeps the first stream it
|
||||
// fetched (--freeze-state); from the epoch after the flip every block it mines is
|
||||
// rejected (accepted after the first refresh 0, rejected above 0); PASS means the
|
||||
// chain threw the stale miner off
|
||||
// --signal 5,5,4 --expect flip the known-failed case of the harness itself: it must report FAIL (no flip)
|
||||
// --signal 6,6,5 --expect flip the known-failed case of the harness itself: it must report FAIL (no flip)
|
||||
//
|
||||
// node infra/fast-time/class-v5-signal.mjs --signal a,b,c --expect flip|no-flip|floor [--floor <daa>|never]
|
||||
// [--v4-floor 120] [--window 60] [--v3-activation 60] [--secs 780] [--epochs 11] [--stale <miner index>] [--no-stateless-node]
|
||||
|
|
@ -55,7 +56,7 @@ const WINDOW = flag('window', 60);
|
|||
const STALE = sflag('stale') == null ? null : +sflag('stale');
|
||||
const STATELESS_NODE = !args.includes('--no-stateless-node');
|
||||
const WINDOWS = 7;
|
||||
const SIGNAL = (sflag('signal') || '5,5,5').split(',').map(Number);
|
||||
const SIGNAL = (sflag('signal') || '6,6,6').split(',').map(Number);
|
||||
const EXPECT = sflag('expect') || 'flip';
|
||||
if (!['flip', 'no-flip', 'floor'].includes(EXPECT) || SIGNAL.length !== 3) { console.error('usage: --signal a,b,c --expect flip|no-flip|floor'); process.exit(2); }
|
||||
const started = [];
|
||||
|
|
@ -219,7 +220,8 @@ const BOUNDARY = firstV4 ? firstV4.epoch * EPOCH : Infinity;
|
|||
const before = blocks.filter(b => b.daa < BOUNDARY), after = blocks.filter(b => b.daa >= BOUNDARY);
|
||||
// the signal bytes on the chain: the share of blocks whose version high byte is 4
|
||||
const versionBytes = blocks.reduce((m, b) => { const v = b.version >> 8; m[v] = (m[v] || 0) + 1; return m; }, {});
|
||||
const signalShareOnChain = blocks.length ? Math.round(10000 * (blocks.filter(b => (b.version >> 8) >= 5).length) / blocks.length) : 0;
|
||||
const V5_BYTE = 6;
|
||||
const signalShareOnChain = blocks.length ? Math.round(10000 * (blocks.filter(b => (b.version >> 8) >= V5_BYTE).length) / blocks.length) : 0;
|
||||
|
||||
const programs = new Map();
|
||||
for (const i of nodes.map(n => n.i)) for (const l of minerLog(i)) {
|
||||
|
|
@ -376,7 +378,7 @@ const summary = {
|
|||
sinks, block_counts: counts, signal_lines: signalLines, floor_lines: floorLines, samples,
|
||||
};
|
||||
writeFileSync(`${TMP}/summary.json`, JSON.stringify(summary, null, 2));
|
||||
log(`SUMMARY ${pass ? 'PASS' : 'FAIL'} (expect ${EXPECT}, signals ${SIGNAL.join('/')}, stale ${STALE ?? 'none'}): ${firstV4 ? `v5 from epoch ${firstV4.epoch} at DAA ${firstV4.daa}` : 'no v5 epoch'}; epochs seen ${[...epochs.entries()].map(([e, v]) => `e${e}:${v.class}:${v.bps5}bps:d${v.day}`).join(' ')}; chain bytes ${JSON.stringify(versionBytes)} (${signalShareOnChain} bps at byte 5+); blocks ${before.length} / ${after.length}; rejected miners ${rejectedMiner.map(r => r.length).join('/')} nodes ${rejectedNode.map(r => r.length).join('/')}; sinks ${sinks.join(' ')} (${checks.sinks_agree ? 'agree' : 'DIFFER'}); counts ${counts.join('/')}; signal lines ${signalLines.filter(Boolean).length}/3 (epochs ${signalEpochs.join('/')}, shares ${signalShares.join('/')}); floor lines ${floorLines.filter(Boolean).length}/3; state roots at the flip ${rootsAtFlip.map(r => String(r).slice(0, 18)).join(' ')}; stateless node accepted after the flip ${statelessAcceptedAfterFlip} (refusal lines ${statelessRefusals}); stale miner accepted after the first refresh ${staleAcceptedAfterRefresh ?? 'n/a'} rejected ${staleRejected ?? 'n/a'}; days ${daysSeen.join('/')}`);
|
||||
log(`SUMMARY ${pass ? 'PASS' : 'FAIL'} (expect ${EXPECT}, signals ${SIGNAL.join('/')}, stale ${STALE ?? 'none'}): ${firstV4 ? `v5 from epoch ${firstV4.epoch} at DAA ${firstV4.daa}` : 'no v5 epoch'}; epochs seen ${[...epochs.entries()].map(([e, v]) => `e${e}:${v.class}:${v.bps5}bps:d${v.day}`).join(' ')}; chain bytes ${JSON.stringify(versionBytes)} (${signalShareOnChain} bps at byte ${V5_BYTE}+); blocks ${before.length} / ${after.length}; rejected miners ${rejectedMiner.map(r => r.length).join('/')} nodes ${rejectedNode.map(r => r.length).join('/')}; sinks ${sinks.join(' ')} (${checks.sinks_agree ? 'agree' : 'DIFFER'}); counts ${counts.join('/')}; signal lines ${signalLines.filter(Boolean).length}/3 (epochs ${signalEpochs.join('/')}, shares ${signalShares.join('/')}); floor lines ${floorLines.filter(Boolean).length}/3; state roots at the flip ${rootsAtFlip.map(r => String(r).slice(0, 18)).join(' ')}; stateless node accepted after the flip ${statelessAcceptedAfterFlip} (refusal lines ${statelessRefusals}); stale miner accepted after the first refresh ${staleAcceptedAfterRefresh ?? 'n/a'} rejected ${staleRejected ?? 'n/a'}; days ${daysSeen.join('/')}`);
|
||||
for (const r of idRows) log(`PROGRAM ID epoch ${r.epoch} seed ${r.seed}: miners ${r.miners_id} (${r.miners} of 3) cli v5 ${r.cli_v5} cli v4 ${r.cli_v4}; state root ${r.state_root} (${r.state_records} records)`);
|
||||
for (const [k, v] of Object.entries(checks)) if (!v) log(`FAILED CHECK ${k}`);
|
||||
log(`summary: ${TMP}/summary.json`);
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
# no build slot and no measure hold (the Mac rule's `run` kind).
|
||||
#
|
||||
# tools/class-v5/harness-remote.sh <case-name> -- <class-v5-signal.mjs arguments>
|
||||
# tools/class-v5/harness-remote.sh failed-case -- --signal 5,5,4 --expect flip
|
||||
# BASE=29830 tools/class-v5/harness-remote.sh flip-stale -- --signal 5,5,5 --expect flip --stale 2 (another port base per
|
||||
# tools/class-v5/harness-remote.sh failed-case -- --signal 6,6,5 --expect flip
|
||||
# BASE=29830 tools/class-v5/harness-remote.sh flip-stale -- --signal 6,6,6 --expect flip --stale 2 (another port base per
|
||||
# case, so two cases never share ports; the harness kills the previous run's pids of its own data dir first)
|
||||
set -euo pipefail
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
|
|
|||
Loading…
Reference in a new issue