From a98c18694f7ddd3f3e392fc721a2543df85d279c Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Wed, 7 Oct 2026 19:26:48 +0000 Subject: [PATCH] fast-time digest case: the first run (19:25:30Z: one digest c0d6998e for the v5 key absent, at never and on the pre-v5 binary; the set key at 8d8f6208 with no peer and the refusal line in the pre-v5 node's log; 0 rejected) and its one fault: the pre-v5 miner was given --exec-rpc, which it does not have, and exited on usage; the new miner alone made 19 blocks in 180 s on a box at load 360. The old miner takes no exec flag, both take --threads (default 4), a usage exit is a named check Co-Authored-By: Claude Fable 5.1 --- .../class-v5-harness/fasttime/digest.json | 215 ++++++++++++++++++ .../class-v5-harness/fasttime/digest.log | 18 ++ infra/fast-time/class-v5-digest.mjs | 16 +- 3 files changed, 243 insertions(+), 6 deletions(-) create mode 100644 docs/design/class-v5-harness/fasttime/digest.json create mode 100644 docs/design/class-v5-harness/fasttime/digest.log diff --git a/docs/design/class-v5-harness/fasttime/digest.json b/docs/design/class-v5-harness/fasttime/digest.json new file mode 100644 index 000000000..67ae2d62e --- /dev/null +++ b/docs/design/class-v5-harness/fasttime/digest.json @@ -0,0 +1,215 @@ +{ + "pass": false, + "case": "digest", + "utc": "2026-10-07T19:25:30.598Z", + "checks": { + "new_absent_new_never_and_old_absent_print_one_digest": true, + "the_set_v5_field_moves_the_digest": true, + "n0_peers_with_n1_and_n2": true, + "old_node_peers_with_the_new_hub": true, + "v5_set_node_has_no_peer": true, + "refusal_line_in_the_pre_v5_node_log": true, + "refusal_line_in_the_v5_set_node_or_hub_log": true, + "v5_set_node_prints_the_floor_line": true, + "new_node_mined_blocks": true, + "old_node_mined_blocks": false, + "zero_rejected_on_the_shared_chain": true, + "one_sink_on_n0_n1_n2": true, + "equal_counts_on_n0_n1_n2": true, + "every_mined_header_is_block_version_2_object_byte_7": true + }, + "new": "/srv/builds/igneum-wt-v5-fasttime/vendor/igneum-node-v5-fasttime/target/release/igneumd", + "old": "/srv/builds/igneum-wt-v5-fasttime/vendor/igneum-node-0323/target/release/igneumd", + "override_keys_dropped": [ + "sig_scheme", + "sig_scheme_activation_daa", + "finality_succession_activation_daa", + "latency_ladder_cache_rung" + ], + "floor": 900, + "secs": 180, + "digests": [ + "c0d6998e35a55983", + "c0d6998e35a55983", + "c0d6998e35a55983", + "8d8f620872b96308" + ], + "peers": [ + 2, + 1, + 1, + 0 + ], + "refusal_lines": { + "old": [ + "Refusing peer 127.0.0.1:39276: consensus params digest mismatch, local c0d6998e35a559836eebafafae318655245be83234505e4212b26ce95d27f5aa remote 8d8f620872b963089995d98571a04d20c55bf59dfbb43cd40f8634135da47b15 (the peer's ", + "Refusing peer 127.0.0.1:60182: consensus params digest mismatch, local c0d6998e35a559836eebafafae318655245be83234505e4212b26ce95d27f5aa remote 8d8f620872b963089995d98571a04d20c55bf59dfbb43cd40f8634135da47b15 (the peer's " + ], + "set": [ + "Refusing peer 127.0.0.1:30221: consensus params digest mismatch, local 8d8f620872b963089995d98571a04d20c55bf59dfbb43cd40f8634135da47b15 remote c0d6998e35a559836eebafafae318655245be83234505e4212b26ce95d27f5aa (the peer's ", + "Refusing peer 127.0.0.1:30201: consensus params digest mismatch, local 8d8f620872b963089995d98571a04d20c55bf59dfbb43cd40f8634135da47b15 remote c0d6998e35a559836eebafafae318655245be83234505e4212b26ce95d27f5aa (the peer's " + ], + "hub": [ + "Refusing peer 127.0.0.1:48478: consensus params digest mismatch, local c0d6998e35a559836eebafafae318655245be83234505e4212b26ce95d27f5aa remote 8d8f620872b963089995d98571a04d20c55bf59dfbb43cd40f8634135da47b15 (the peer's ", + "Refusing peer 127.0.0.1:42518: consensus params digest mismatch, local c0d6998e35a559836eebafafae318655245be83234505e4212b26ce95d27f5aa remote 8d8f620872b963089995d98571a04d20c55bf59dfbb43cd40f8634135da47b15 (the peer's " + ] + }, + "accepted": { + "new": 19, + "old": 0 + }, + "rejected": [ + 0, + 0, + 0, + 0 + ], + "sinks": [ + "d11b1ea258556729", + "d11b1ea258556729", + "d11b1ea258556729", + "234e082d653dc69d" + ], + "counts": [ + 19, + 19, + 19, + 0 + ], + "header_versions": { + "1794": 18 + }, + "object_bytes": { + "0": 1, + "7": 19 + }, + "blocks": 20, + "samples": [ + { + "t": 5, + "counts": [ + 0, + 0, + 0, + 0 + ], + "sinks": [ + "234e082d", + "234e082d", + "234e082d", + "234e082d" + ], + "peers": [ + 2, + 1, + 1, + 0 + ] + }, + { + "t": 35.1, + "counts": [ + 3, + 3, + 3, + 0 + ], + "sinks": [ + "d987e239", + "d987e239", + "d987e239", + "234e082d" + ], + "peers": [ + 2, + 1, + 1, + 0 + ] + }, + { + "t": 65.2, + "counts": [ + 9, + 9, + 9, + 0 + ], + "sinks": [ + "cf40baec", + "cf40baec", + "cf40baec", + "234e082d" + ], + "peers": [ + 2, + 1, + 1, + 0 + ] + }, + { + "t": 95.3, + "counts": [ + 12, + 12, + 12, + 0 + ], + "sinks": [ + "529446a8", + "529446a8", + "529446a8", + "234e082d" + ], + "peers": [ + 2, + 1, + 1, + 0 + ] + }, + { + "t": 125.5, + "counts": [ + 14, + 14, + 14, + 0 + ], + "sinks": [ + "ae37a496", + "ae37a496", + "ae37a496", + "234e082d" + ], + "peers": [ + 2, + 1, + 1, + 0 + ] + }, + { + "t": 155.6, + "counts": [ + 18, + 18, + 18, + 0 + ], + "sinks": [ + "871a461f", + "871a461f", + "871a461f", + "234e082d" + ], + "peers": [ + 2, + 1, + 1, + 0 + ] + } + ] +} \ No newline at end of file diff --git a/docs/design/class-v5-harness/fasttime/digest.log b/docs/design/class-v5-harness/fasttime/digest.log new file mode 100644 index 000000000..1b513b1ec --- /dev/null +++ b/docs/design/class-v5-harness/fasttime/digest.log @@ -0,0 +1,18 @@ +19:22:20.802 override: 4 key(s) dropped from every file (sig_scheme, sig_scheme_activation_daa, finality_succession_activation_daa, latency_ladder_cache_rung) +19:22:20.803 case digest: new /srv/builds/igneum-wt-v5-fasttime/vendor/igneum-node-v5-fasttime/target/release/igneumd, old /srv/builds/igneum-wt-v5-fasttime/vendor/igneum-node-0323/target/release/igneumd; A = the v5 key absent, B = at never, C = 900; 180 s of mixed mining +19:22:22.372 n0 new, v5 key absent up pid 1198594 p2p 30201: digest c0d6998e35a55983, (no v5 line: a pre-v5 binary) +19:22:23.879 n1 new, v5 key at never up pid 1198808 p2p 30211 addpeer 30201: digest c0d6998e35a55983, Program class v5 from the override file: never (the byte stays 5, the amended v4's; a byte 6 on the chain counts for not +19:22:25.386 n2 OLD (pre-v5), v5 key absent up pid 1199052 p2p 30221 addpeer 30201: digest c0d6998e35a55983, (no v5 line: a pre-v5 binary) +19:22:26.894 n3 new, v5 key set at 900 up pid 1199278 p2p 30231 addpeer 30201,30221: digest 8d8f620872b96308, Program class v5 from the override file: enabled, the floor at epoch 15 (DAA score 900 rounded up to the epoch boundary +19:22:26.900 mining: the new node n0 and the old node n2, one CPU thread each, 180 s +19:22:31.905 t=5.0 s blocks/sink 0/234e082d 0/234e082d 0/234e082d 0/234e082d peers 2/1/1/0 +19:23:02.020 t=35.1 s blocks/sink 3/d987e239 3/d987e239 3/d987e239 0/234e082d peers 2/1/1/0 +19:23:32.109 t=65.2 s blocks/sink 9/cf40baec 9/cf40baec 9/cf40baec 0/234e082d peers 2/1/1/0 +19:24:02.219 t=95.3 s blocks/sink 12/529446a8 12/529446a8 12/529446a8 0/234e082d peers 2/1/1/0 +19:24:32.347 t=125.5 s blocks/sink 14/ae37a496 14/ae37a496 14/ae37a496 0/234e082d peers 2/1/1/0 +19:25:02.477 t=155.6 s blocks/sink 18/871a461f 18/871a461f 18/871a461f 0/234e082d peers 2/1/1/0 +19:25:30.598 SUMMARY FAIL (digest) 2026-10-07T19:25:30.598Z: digests new-absent c0d6998e35a55983 new-never c0d6998e35a55983 old-absent c0d6998e35a55983 new-set 8d8f620872b96308; peers 2/1/1/0; refusal lines old 3 set 6 hub 3; mixed mining 180 s: new accepted 19, old accepted 0, rejected 0/0/0/0, sinks d11b1ea258556729 d11b1ea258556729 d11b1ea258556729 at 19/19/19; header versions {"1794":18} +19:25:30.599 Refusing peer 127.0.0.1:39276: consensus params digest mismatch, local c0d6998e35a559836eebafafae318655245be83234505e4212b26ce95d27f5aa remote 8d8f620872b963089995d98571a04d20c55bf59dfbb43cd40f8634135da47b15 (the peer's +19:25:30.599 Refusing peer 127.0.0.1:30221: consensus params digest mismatch, local 8d8f620872b963089995d98571a04d20c55bf59dfbb43cd40f8634135da47b15 remote c0d6998e35a559836eebafafae318655245be83234505e4212b26ce95d27f5aa (the peer's +19:25:30.599 FAILED CHECK old_node_mined_blocks +19:25:30.599 summary: /tmp/igneum-fast-time-v5d-digest/summary.json and /srv/builds/igneum-wt-v5-fasttime/docs/design/class-v5-harness/fasttime/digest.json diff --git a/infra/fast-time/class-v5-digest.mjs b/infra/fast-time/class-v5-digest.mjs index 5c32170d0..d1190b0e9 100644 --- a/infra/fast-time/class-v5-digest.mjs +++ b/infra/fast-time/class-v5-digest.mjs @@ -15,7 +15,7 @@ // mined header at block version 2 with object byte 7 (class v4 sub-version 3: the pre-v5 default, and the new binary's // default while v5 is unset) on both binaries. // node infra/fast-time/class-v5-digest.mjs --old --old-miner [--new ] -// [--miner ] [--secs 180] [--floor 900] [--case digest] [--out ] +// [--miner ] [--secs 180] [--threads 4] [--floor 900] [--case digest] [--out ] // IGNEUMD and IGNEUM_MINER are the NEW binaries' defaults (tools/fast-time-remote.sh sets them); the OLD pair defaults to // vendor/igneum-node-0323/target/release under IGNEUM_NODE_ROOT (the release-0.3.23-node build on the box). @@ -34,7 +34,7 @@ const NEW = sflag('new') || process.env.IGNEUMD || `${ROOT}vendor/igneum-node-v5 const NEW_MINER = sflag('miner') || process.env.IGNEUM_MINER || `${ROOT}vendor/igneum-node-v5-fasttime/target/release/igneum-miner`; const OLD = sflag('old') || `${NODE_ROOT}vendor/igneum-node-0323/target/release/igneumd`; const OLD_MINER = sflag('old-miner') || `${NODE_ROOT}vendor/igneum-node-0323/target/release/igneum-miner`; -const SECS = flag('secs', 180), FLOOR = flag('floor', 900), GENESIS_BITS = flag('genesis-bits', 0x1f010000); +const SECS = flag('secs', 180), FLOOR = flag('floor', 900), GENESIS_BITS = flag('genesis-bits', 0x1f010000), THREADS = flag('threads', 4); const CASE = sflag('case') || 'digest'; const OUT = sflag('out') || `${ROOT}docs/design/class-v5-harness/fasttime`; const TMP = `/tmp/igneum-fast-time-v5d-${CASE}`; @@ -90,9 +90,12 @@ class Node { async peers_() { try { const r = await this.rpc.call('getConnectedPeerInfo', {}); const list = r.peerInfo || r.peer_info || r.infos || r; return Array.isArray(list) ? list.length : null; } catch (e) { return null; } } async dag() { try { return await this.rpc.call('getBlockDagInfo'); } catch (e) { return { error: e.message }; } } } -function miner(bin, i, node) { +function miner(bin, i, node, old = false) { const out = openSync(`${TMP}/cpu${i}.log`, 'a'); - const p = spawn(bin, ['mine', node.grpc, '1', String(SECS + 30), `cpu${i}`, '--engine', 'igneum-pow', '--payout-label', `cpu${i}`, '--status-secs', '30', '--no-vote', '--exec-rpc', `http://127.0.0.1:${node.execPort}`], { stdio: ['ignore', out, out], env: { ...process.env, IGNEUM_POW_DAY_MS: String(DAY_MS) } }); + // the pre-v5 miner has no --exec-rpc (the first digest run, 19:22Z: it exited on usage and mined nothing); the new one + // takes its node's exec port; --threads (default 4) because one CPU thread on a loaded box made 19 blocks in 180 s + const extra = old ? [] : ['--exec-rpc', `http://127.0.0.1:${node.execPort}`]; + const p = spawn(bin, ['mine', node.grpc, String(THREADS), String(SECS + 30), `cpu${i}`, '--engine', 'igneum-pow', '--payout-label', `cpu${i}`, '--status-secs', '30', '--no-vote', ...extra], { stdio: ['ignore', out, out], env: { ...process.env, IGNEUM_POW_DAY_MS: String(DAY_MS) } }); started.push(p); recordPid(p); } async function stopAll() { for (const p of started.slice().reverse()) { try { p.kill('SIGINT'); } catch { } } await sleep(1500); for (const p of started) { try { p.kill('SIGKILL'); } catch { } } } @@ -108,8 +111,8 @@ const n3 = await new Node(3, NEW, fileC, [n0.p2pPort, n2.p2pPort], `new, v5 key const nodes = [n0, n1, n2, n3]; const t0 = Date.now(); const since = () => ((Date.now() - t0) / 1000).toFixed(1); -miner(NEW_MINER, 0, n0); miner(OLD_MINER, 2, n2); -log(`mining: the new node n0 and the old node n2, one CPU thread each, ${SECS} s`); +miner(NEW_MINER, 0, n0); miner(OLD_MINER, 2, n2, true); +log(`mining: the new node n0 and the old node n2, ${THREADS} CPU thread(s) each, ${SECS} s`); const samples = []; let lastReport = 0; while (Date.now() - t0 < SECS * 1000) { @@ -157,6 +160,7 @@ const checks = { v5_set_node_prints_the_floor_line: n3.grep(/Program class v5 from the override file: enabled, the floor at epoch/).length > 0, new_node_mined_blocks: accepted.new > 0, old_node_mined_blocks: accepted.old > 0, + old_miner_started: !minerLog(2).some(l => /^usage:/.test(l)), zero_rejected_on_the_shared_chain: rejected[0] === 0 && rejected[1] === 0 && rejected[2] === 0, one_sink_on_n0_n1_n2: new Set(sinks.slice(0, 3)).size === 1, equal_counts_on_n0_n1_n2: new Set(counts.slice(0, 3).map(String)).size === 1,