From d3cf542eb85387aedf48f52081513035bc54c11a Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Sun, 4 Oct 2026 09:14:18 +0000 Subject: [PATCH] Bench log: first GPU proof on the RTX 5090 and the devnet v4 cut-over; ledger P20 Co-Authored-By: Claude Fable 5.1 --- docs/bench-log.md | 37 +++++++++++++++++++++++++++++++++++++ docs/fud-ledger.md | 9 +++++++++ site/bench.html | 10 ++++++++-- site/build.mjs | 4 +++- site/journey.json | 10 ++++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/docs/bench-log.md b/docs/bench-log.md index 20496144..38808e19 100644 --- a/docs/bench-log.md +++ b/docs/bench-log.md @@ -574,3 +574,40 @@ The long-heal run is the measurement the 3 October harness could not make: the o The inclusive comparison at exactly two thirds is pinned by the integer test `3 x signed >= 2 x total` and the unit test (4 of 6, 2 of 3 lock; the 3 October S6B run had already measured the active test passing at exactly 2/3 with 4 of 6 equal voters); the devnet's 4 side sat at 67.9% rather than 66.67% because block counts are Poisson, and locked at the first checkpoint after the cut. Notes. (1) The v4 node logged "PoW rejected ... by igneum-lottery-v1-bound" about five times a second per node (2,952 lines on n0 over 6A) although the override carries `skip_proof_of_work` and the six miners saw every submission accepted; the window held exactly 1,800 blocks of weight on every node and each side's DAA advanced at 3 per second as planned, so the lines did not move the measurement, but what the v4 pipeline is re-checking there is a question for the consensus engineer before the v4 cut-over (30 of a sample of 200 rejected hashes were later accepted on the same node). (2) The repo harness `tools/finality-attacks/run.mjs` s6 criterion text and the s5 "below the 56.7% floor" pass test are now stale and should read two thirds. (3) Not done: the two-hour presence window and a 30-day window at mainnet length; the first-month gate under the new floor is unchanged (`min_daa` = window). (4) The harness's 60-s heal window (6A, 6B) is shorter than the connection manager's redial backoff for a `--connect` peer after a cut, so a healed proxy does not mean a reconnected n0 inside it; the long-heal run used 300 s and n0 redialled at 59 s after the gate reopened. (5) Stop everything: every node, miner and proxy of the three runs was stopped by the harness at the end of each run; ports 29200 to 29299 were free afterwards (`lsof` 0 listeners). + +## 4 October 2026, proving v0 on the RTX 5090: first GPU proof of an Igneum block (WSL2, SP1 6.8.1 cuda) + +Machine: the project lead's Windows 11 PC, RTX 5090 (32,607 MiB, driver 617.14), 16 cores and 45 GB visible to WSL2 Ubuntu 24.04, mining +paused. Package `proving/windows-wsl2` (SETUP-PROVER then PROVE-BLOCK), host `igneum-prove-host` built with the `cuda` feature, +`SP1_PROVER=cuda`, sp1-gpu-server 6.8.1 on device 0. Fixture `block-78-increment` (chain 4463, 2 transactions, 10 accounts). +Run id `prove--20261004-084838`, log intake id 10154. + +| Stage | RTX 5090 | Apple M5 Max CPU (3 October, loaded) | +|---|---|---| +| native re-execution | 0.0003 s, state root MATCHES the fixture | 0.0004 s, matches | +| setup (one per program id) | 23.23 s | 20.55 s on the PC's CPU; Mac not timed separately | +| execute | 626,876 cycles, prover gas 844,704, 0.19 s, 14 cycles per EVM gas | 626,246 cycles, 0.15 s on the PC's CPU | +| core proof | prove 1.4 s, 7,317,217 bytes, verify 0.221 s, VERIFIED | prove 22.0 s, 7.3 MB, verify 0.16 s | +| compressed proof | prove 2.7 s, 1,272,769 bytes, verify 0.038 s, VERIFIED | prove 55.7 s, 1.27 MB, verify 0.03 s | + +Reading: 15.7x on core and 20.6x on compressed against a loaded laptop CPU. The block is far below one SP1 shard, so these are +the fixed per-proof overheads of the proof system on this card; the throughput number needs the larger fixtures (proving e2e +standard). Post-state root and receipts root identical to the node's on every stage. Two defects, neither in the proof: the +host aborted (exit 134) AFTER writing and uploading the results, in `sp1-cuda`'s destructor outside a Tokio runtime; and the +host was silent for ten minutes between the core and compressed stages with the card idle. Ledger P20. Setup on the PC +needed three package fixes found only by running it on Windows: `protobuf-compiler` in the apt list, the WSL distro check +(UTF-16 output), the elevated window closing; and WSL2 itself needed `bcdedit /set hypervisorlaunchtype auto` on a PC whose +BIOS already had SVM on. + +## 4 October 2026, devnet v4 cut-over: generator v2, 2/3 floor, three nodes and a seed on a fresh chain + +Sequence (BST): seed re-staged from `6457ca95` (build 55 min on the 2-vCPU VM, 08:55 to 09:54); node 1 stopped and the v3 +database moved aside at 10:05:30, `igneumd` v4 up at 10:05:31 with the execution layer; observer peer and `observer.mjs` +restarted on fresh appdirs at 10:06:10; seed switched with `switch-v4.sh` at 10:06:28 and synced at 10:07:38 (`blocks=2`, +`peers=1`); Mac Metal miner (generator v2 port, `prepare 1`) first accepted block at 10:07:35; the PC joined at 10:10:55 +(protocol version 12) and its first blocks followed within the minute. Block rate went from about 1 per second (Mac alone, +difficulty easing 9.1% a block from the 134M genesis value) to about 2 per second with the 5090; the live page followed from +block 0 with 9 identities after five minutes. First NVIDIA card to mine a generator v2 program; CPU re-check passed on every +Mac share. One launcher defect found only on Windows: `"$machine:$vendorName"` in `igneum-common.ps1` is a drive-qualified +variable to PowerShell, so the file failed to parse (fixed, braces). The first finality lock is due at DAA 7,200, two hours +after the v4 genesis; the first hourly swap at DAA 3,600. diff --git a/docs/fud-ledger.md b/docs/fud-ledger.md index 52d04db7..e50e0b9b 100644 --- a/docs/fud-ledger.md +++ b/docs/fud-ledger.md @@ -1460,6 +1460,15 @@ Evidence: `docs/bench-log.md`, 4 October 2026 "execution layer attack fixes" (be ## Difficulty attack findings (4 October 2026): fixed +### P20. The SP1 GPU client panics on shutdown and the compressed stage waited ten minutes +"Your first GPU proof run aborted with a core dump. What else aborts?" + +Status: Open, found by the team (4 October 2026, morning, first RTX 5090 run through WSL2, SP1 6.8.1). + +Answer: Two separate things, neither in the proof. (1) After every proof was written, verified and uploaded, `sp1-cuda`'s client dropped its session key outside a Tokio runtime and panicked in its destructor (`sp1-cuda-6.8.1/src/pk.rs:63`, `client.rs:221`), so the host exited 134 with the results already on disk. Fix in our host: hold a runtime for the client's lifetime or drop the proof system inside one. (2) Between the core proof (08:49:10 UTC) and "Proving with mode: Compressed" (08:59:02 UTC) the host was silent for ten minutes while the card was idle; the compressed mode's recursion setup on first use is the suspect, and the second run must time it. Both go on the proving e2e benchmark standard as fixed overheads to measure, not hide. + +Evidence: `docs/bench-log.md` "4 October 2026, proving v0 on the RTX 5090"; results file `block-78-increment-cuda-20261004-084838.json` on the PC; log intake id 10154. Experiment: O-7.4 (re-run with `--mode compressed` alone and a timestamp per stage). + ### M23. Forge timestamps inside the rules and the controller mines you a 10x difficulty for free "Your fast controller clamps every solvetime to 20 s both ways and says the next honest block cancels a forged one. Good: I stamp every block of mine at the earliest the past median allows, the honest block after me gets clamped to +20 s, the pair sums to zero, and your lanes measure 1 - 2a(1 - a) of real time at my share a. With half the hashrate your chain runs at a fifth of its rate and 9.9x the difficulty, on no extra hash. Kaspa's window only drifts 5 to 11%. And while I am at it, 85 blocks a second of PoW-less input drives your target below 2^64 and `calc_work` panics the node." diff --git a/site/bench.html b/site/bench.html index 4750d4b7..92e49823 100644 --- a/site/bench.html +++ b/site/bench.html @@ -68,7 +68,7 @@ footer{border-top:1px solid var(--line);padding-block:32px 48px;font-size:13px;c

Engineering log

Every measurement the project has made, newest at the bottom, written by the people and agents who ran it, with the commands and hardware. Prototype numbers are not mining numbers and say so.

- +

Igneum bench log

Append-only. Every number here was measured on the machine named, on the date given.

2026-10-03 proto-metal / igneum-bench, first run

@@ -203,7 +203,13 @@ footer{border-top:1px solid var(--line);padding-block:32px 48px;font-size:13px;c
ScenarioCriterion (spec Q3, 3.3.1)MeasuredVerdict
6A, 3/3 (a0 a1 a2 on n0; b0 b1 on n1, b2 on n2), 150 szero new locks on any node during the split (each side under two thirds of its own table); no conflicting certificates; locks resume after the healcut at DAA 2,250 with 75 locks on all three nodes, window 1,800 of 1,800, side A at 48.3% and side B at 51.7% of every node's table; new locks during the split 0 / 0 / 0; shares at the end of the split 60.8% (A) and 62.7% (B), both still under the floor and both past the old 56.7% floor (B crossed it at about 76 s, A at about 106 s, so the 3 October rule would have locked on both sides inside this split); conflicting certificates 0 / 0 / 0; finality_reason stayed active throughout (a lock within the last 20 indices); after the heal n1 and n2 resumed (75 to 97 within 60 s), n0 did not redial the proxy within 60 s (the connection manager retries a --connect peer at 30 x 2^attempts seconds, so after four failed attempts during the split the next redial was minutes away); the third run below extends the heal windowPASS on the floor (0 locks either side, 0 conflicts); the 60-s heal window was too short for n0's redial, see 6A long heal
6B, 4/2 (p0 p1 on n1, p2 p3 on n2; q0 q1 on n0), 150 sthe 4 side locks on both its nodes, the 2 side does not; no conflicting certificates; identical locked hashes across nodescut at DAA 2,399 with 79 / 80 / 79 locks; the 4 side held 1,222 of 1,800 = 67.9% of every table (Poisson noise put it 1.2 points over the floor at the cut); first new lock on the 4 side 2 s (n2, index 80) and 8 s (n1, index 81) after the cut, signed 1,222, active 1,800, total 1,800: 67.9% of total and of active, 4 votes seen, the two silent keys still at participation 1 inside the presence window so the two tests bound at the same fraction; 20 and 21 new locks on the 4 side during the split, 0 on the 2 side (32.1% rising to 42.1% of its own table by the end); 0 conflicting certificates; 0 locked indices disagreeing across nodes; n1 and n2 at 109 after the healPASS
6A again, long heal (igneum-devnet-923), 150-s split, 300-s heal windowas 6A, with a heal window longer than the redial backoffcut at DAA 2,279 with 75 / 76 / 75 locks, sides at 49.9% and 50.1%; new locks during the 150-s split 0 / 0 / 1, the one being n2 catching up to the common pre-split checkpoint 76 at the instant of the cut (signed by both sides, 67.7% of total), so 0 side-alone locks either side; shares at the end of the split 61.1% and 61.8%. The gate reopened at 150 s but n0's redial came at 209 s (the 30 x 2^attempts backoff), so the sides kept mining apart. Side B locked alone first at 205 s after the cut: checkpoint 96 (blue score 2,880, 601 own blocks after the cut) by its 3 keys at 1,206 of 1,800 = 67.0% of total, one lock over the floor, against the predicted bound W / (3 R) = 200 s. Side A (n0) locked alone from checkpoint 98 at 215 s, 6 s after its redial, by its 3 keys at 1,017 of a table of 1,362 = 74.7%: once side B's 600 post-split blocks arrived they were merged red, so in n0's view they count for nothing (W2 counts blue blocks) and its own share rose at once. From there each side's F1 pinned it to its own certified chain: 26 conflicting certificates logged on n0 (indices 98 to 123), 2 on n1 and 3 on n2 (indices 118 to 120, the first of n0's to reach them), 23 locked indices disagreeing across the three nodes at the end of the 300-s heal window, 39 / 42 / 42 locks in all, no equivocation and no strip (each key voted once per index, for its own side's checkpoint). The network healed and finality did not: a finality fork with no attacker, exactly the state 3.11.4 leaves to operators (F5)PASS on the floor for 150 s (0 side-alone locks); the window bound crossed at 205 s against 200 predicted; the heal does not undo it (spec 3.7 item 9, ledger F21)

The long-heal run is the measurement the 3 October harness could not make: the old floor fell at 84 s of a young window (S6A); the two-thirds floor on a full 1,800-DAA window held for 150 s and fell at 205 s, 3.25x later as the arithmetic says (2F / (13R) against F / (2R) on a young window, 2W / (15R) against W / (3R) on a full one), and it fell on both sides within 10 s of each other because a 50/50 split crosses the bound at the same moment from both ends. On mainnet the same bound is 10 days of a 30-day window at 50/50 (spec 3.3.1, sim/results_v2.md L4). What the DAG adds to the simulation: after the heal the losing side's blocks are red in the winner's view, so the crossing is sudden rather than gradual, and once either side has certified a checkpoint of its own F1 never lets it back, so the fork is permanent until an operator sets a trusted certificate (F5, not implemented).

The inclusive comparison at exactly two thirds is pinned by the integer test 3 x signed >= 2 x total and the unit test (4 of 6, 2 of 3 lock; the 3 October S6B run had already measured the active test passing at exactly 2/3 with 4 of 6 equal voters); the devnet's 4 side sat at 67.9% rather than 66.67% because block counts are Poisson, and locked at the first checkpoint after the cut.

-

Notes. (1) The v4 node logged "PoW rejected ... by igneum-lottery-v1-bound" about five times a second per node (2,952 lines on n0 over 6A) although the override carries skip_proof_of_work and the six miners saw every submission accepted; the window held exactly 1,800 blocks of weight on every node and each side's DAA advanced at 3 per second as planned, so the lines did not move the measurement, but what the v4 pipeline is re-checking there is a question for the consensus engineer before the v4 cut-over (30 of a sample of 200 rejected hashes were later accepted on the same node). (2) The repo harness tools/finality-attacks/run.mjs s6 criterion text and the s5 "below the 56.7% floor" pass test are now stale and should read two thirds. (3) Not done: the two-hour presence window and a 30-day window at mainnet length; the first-month gate under the new floor is unchanged (min_daa = window). (4) The harness's 60-s heal window (6A, 6B) is shorter than the connection manager's redial backoff for a --connect peer after a cut, so a healed proxy does not mean a reconnected n0 inside it; the long-heal run used 300 s and n0 redialled at 59 s after the gate reopened. (5) Stop everything: every node, miner and proxy of the three runs was stopped by the harness at the end of each run; ports 29200 to 29299 were free afterwards (lsof 0 listeners).

+

Notes. (1) The v4 node logged "PoW rejected ... by igneum-lottery-v1-bound" about five times a second per node (2,952 lines on n0 over 6A) although the override carries skip_proof_of_work and the six miners saw every submission accepted; the window held exactly 1,800 blocks of weight on every node and each side's DAA advanced at 3 per second as planned, so the lines did not move the measurement, but what the v4 pipeline is re-checking there is a question for the consensus engineer before the v4 cut-over (30 of a sample of 200 rejected hashes were later accepted on the same node). (2) The repo harness tools/finality-attacks/run.mjs s6 criterion text and the s5 "below the 56.7% floor" pass test are now stale and should read two thirds. (3) Not done: the two-hour presence window and a 30-day window at mainnet length; the first-month gate under the new floor is unchanged (min_daa = window). (4) The harness's 60-s heal window (6A, 6B) is shorter than the connection manager's redial backoff for a --connect peer after a cut, so a healed proxy does not mean a reconnected n0 inside it; the long-heal run used 300 s and n0 redialled at 59 s after the gate reopened. (5) Stop everything: every node, miner and proxy of the three runs was stopped by the harness at the end of each run; ports 29200 to 29299 were free afterwards (lsof 0 listeners).

+

4 October 2026, proving v0 on the RTX 5090: first GPU proof of an Igneum block (WSL2, SP1 6.8.1 cuda)

+

Machine: the project lead's Windows 11 PC, RTX 5090 (32,607 MiB, driver 617.14), 16 cores and 45 GB visible to WSL2 Ubuntu 24.04, mining paused. Package proving/windows-wsl2 (SETUP-PROVER then PROVE-BLOCK), host igneum-prove-host built with the cuda feature, SP1_PROVER=cuda, sp1-gpu-server 6.8.1 on device 0. Fixture block-78-increment (chain 4463, 2 transactions, 10 accounts). Run id prove-<pc>-20261004-084838, log intake id 10154.

+
StageRTX 5090Apple M5 Max CPU (3 October, loaded)
native re-execution0.0003 s, state root MATCHES the fixture0.0004 s, matches
setup (one per program id)23.23 s20.55 s on the PC's CPU; Mac not timed separately
execute626,876 cycles, prover gas 844,704, 0.19 s, 14 cycles per EVM gas626,246 cycles, 0.15 s on the PC's CPU
core proofprove 1.4 s, 7,317,217 bytes, verify 0.221 s, VERIFIEDprove 22.0 s, 7.3 MB, verify 0.16 s
compressed proofprove 2.7 s, 1,272,769 bytes, verify 0.038 s, VERIFIEDprove 55.7 s, 1.27 MB, verify 0.03 s
+

Reading: 15.7x on core and 20.6x on compressed against a loaded laptop CPU. The block is far below one SP1 shard, so these are the fixed per-proof overheads of the proof system on this card; the throughput number needs the larger fixtures (proving e2e standard). Post-state root and receipts root identical to the node's on every stage. Two defects, neither in the proof: the host aborted (exit 134) AFTER writing and uploading the results, in sp1-cuda's destructor outside a Tokio runtime; and the host was silent for ten minutes between the core and compressed stages with the card idle. Ledger P20. Setup on the PC needed three package fixes found only by running it on Windows: protobuf-compiler in the apt list, the WSL distro check (UTF-16 output), the elevated window closing; and WSL2 itself needed bcdedit /set hypervisorlaunchtype auto on a PC whose BIOS already had SVM on.

+

4 October 2026, devnet v4 cut-over: generator v2, 2/3 floor, three nodes and a seed on a fresh chain

+

Sequence (BST): seed re-staged from 6457ca95 (build 55 min on the 2-vCPU VM, 08:55 to 09:54); node 1 stopped and the v3 database moved aside at 10:05:30, igneumd v4 up at 10:05:31 with the execution layer; observer peer and observer.mjs restarted on fresh appdirs at 10:06:10; seed switched with switch-v4.sh at 10:06:28 and synced at 10:07:38 (blocks=2, peers=1); Mac Metal miner (generator v2 port, prepare 1) first accepted block at 10:07:35; the PC joined at 10:10:55 (protocol version 12) and its first blocks followed within the minute. Block rate went from about 1 per second (Mac alone, difficulty easing 9.1% a block from the 134M genesis value) to about 2 per second with the 5090; the live page followed from block 0 with 9 identities after five minutes. First NVIDIA card to mine a generator v2 program; CPU re-check passed on every Mac share. One launcher defect found only on Windows: "$machine:$vendorName" in igneum-common.ps1 is a drive-qualified variable to PowerShell, so the file failed to parse (fixed, braces). The first finality lock is due at DAA 7,200, two hours after the v4 genesis; the first hourly swap at DAA 3,600.

diff --git a/site/build.mjs b/site/build.mjs index 7355bc43..9ba8dc17 100644 --- a/site/build.mjs +++ b/site/build.mjs @@ -151,6 +151,7 @@ if (existsSync(join(docs, 'bench-log.md'))) { ['Igneum-node devnet v2', 'Finality rule v2 live on a four-miner test network'], ['Execution layer devnet v3', 'EVM execution layer: identical state on three nodes'], ['Weak-program census', 'Census of 400,000 programs: redundant loads found'], + ['Proving v0 on the RTX 5090', 'First GPU proof of an Igneum block: 1.4 s on an RTX 5090'], ['Proving v0', 'First SP1 proof of an Igneum block, on a laptop CPU'], ['Windows node package', 'Windows node package: cross-compiled, two-peer sync'], ['R3.26 / M15', 'Cache-build attack closed: 10.6 s of rebuilds to 14 ms'], @@ -170,6 +171,7 @@ if (existsSync(join(docs, 'bench-log.md'))) { ['First prototype of the random-program', 'First prototype of the lottery hash on Apple silicon'], ['Igneum named', 'Igneum named. Litepaper, brand and wallet designs published'], ['Finality floor', 'Finality floor raised to two thirds of all weight'], + ['Devnet v4 cut-over', 'Devnet v4 live: generator v2, two-thirds floor, fresh chain'], ]; function shortTitle(t) { for (const [k, v] of SHORT) if (t.startsWith(k)) return v; @@ -189,7 +191,7 @@ if (existsSync(join(docs, 'bench-log.md'))) { const j = JSON.parse(readFileSync(jp, 'utf8')); const seen = new Set(j.log.map(e => e.date + '|' + e.text)); for (const e of entries.reverse()) { const k = e.date + '|' + e.text; if (!seen.has(k)) { j.log.unshift(e); seen.add(k); } } - for (const e of j.log) if (!e.short) e.short = shortTitle(e.text); + for (const e of j.log) e.short = shortTitle(e.text); j.log.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0)); j.log = j.log.slice(0, 40); j.updated = j.log[0] ? j.log[0].date : j.updated; diff --git a/site/journey.json b/site/journey.json index e0664fc2..5f5fa752 100644 --- a/site/journey.json +++ b/site/journey.json @@ -50,6 +50,16 @@ } ], "log": [ + { + "date": "2026-10-04", + "text": "Proving v0 on the RTX 5090: first GPU proof of an Igneum block", + "short": "First GPU proof of an Igneum block: 1.4 s on an RTX 5090" + }, + { + "date": "2026-10-04", + "text": "Devnet v4 cut-over: generator v2, 2/3 floor, three nodes and a seed on a fresh chain", + "short": "Devnet v4 live: generator v2, two-thirds floor, fresh chain" + }, { "date": "2026-10-04", "text": "Generator version 2 adopted: exact load count, fresh-source loads, program acceptance; every vector re-cut, three workers re-checked, 20,000-program census, devnet-v4 binaries rebuilt",