From 176965595bfc87e8cbd0785935bc2ababaa554b4 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Sat, 3 Oct 2026 22:29:44 +0000 Subject: [PATCH] Site: one spacing system on every page Measured at 375, 768, 1280 and 1680 with headless Chrome. One token set in all four stylesheets: container 1200 px with a clamp(16px,4vw,32px) gutter, section rhythm clamp(56px,8vw,96px), cards clamp(18px,3vw,28px) padding and 18 px radius, tiles 18 by 20 px padding and 14 px radius, 24 px card gap and 12 px tile gap, headings h1 clamp(32,5.5vw,56) h2 clamp(28,4.2vw,44) h3 clamp(18,2vw,22), tile values clamp(20,2.2vw,26). Home: the live strip spans the full hero width with economics-spec tiles; stat strip and economics tiles share one spec; journey phases and log take the tile and card boxes; inline padding-top overrides removed, consecutive dark sections share one gap; every nav anchor lands the heading 11 px under the sticky bar at every width (padded sections subtract their own padding). Live: head, strip, cards and gaps on the tokens; four tiles a row, two on phones; network name no longer clips. Litepaper: real gutter instead of a fixed 16 px, cover, layout, tables, figures, pull quotes and stat tiles on the tokens, pager stacks on phones. Engineering log: same tokens, long code tokens wrap so phones no longer scroll sideways, duplicate h1 hidden. Copy shortened so no label orphans at any width: stat strip labels, the economics tiles, the strip tile labels, the litepaper stat tiles, the mining-program eyebrow. The light-client card block is untouched. Co-Authored-By: Claude Fable 5.1 --- site/bench.html | 50 +++++++++++++------- site/build.mjs | 35 ++++++++------ site/index.html | 110 +++++++++++++++++++++++--------------------- site/litepaper.html | 54 ++++++++++++---------- site/live.html | 38 ++++++++------- 5 files changed, 165 insertions(+), 122 deletions(-) diff --git a/site/bench.html b/site/bench.html index 36f85b548..17ae5a827 100644 --- a/site/bench.html +++ b/site/bench.html @@ -29,30 +29,37 @@ @@ -61,7 +68,7 @@ footer{border-top:1px solid var(--line);padding-block:24px 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

@@ -119,7 +126,18 @@ footer{border-top:1px solid var(--line);padding-block:24px 48px;font-size:13px;c
  • Before (the pre-fix order, replayed by calling the engine with the header's own unvalidated day seed): 50 cold 256 MiB builds, 10,595 ms, and the honest day's entry is evicted (KEEP was 3).
  • After (the new order): 0 builds, all 50 rejected (TimeTooOld or UnexpectedHeaderDaaScore) in 14 ms total. The live day stays resident.

Tests: kaspa-pow --features igneum-pow 8 pass (engine smoke, one_build_per_seed_pair_under_contention, live_days_survive_off_day_builds, build_queue_is_bounded, index and live-day helpers, shared-engine, stub); kaspa-consensus header_processor cheap_checks_run_before_the_pow_engine pass; kaspa-p2p-flows pow_guard 2 pass; the full kaspa-consensus release suite otherwise unchanged. M16 Metal note (R3.5, cheap reconfirmation only): the Mac --inline-dataset shortcut at the 256 MiB cache, 256 MiB dataset, under the same heavy load, ran honest 91.7 Mhash/s against inline 5.29 Mhash/s (inline about 17x slower); this is noisier and slower than the idle-machine figures already in proto-metal/MEMHARD.md (10x slower at a 256 MiB dataset, 4.8x at 1 GiB), because the inline kernel is compute-bound and the machine was loaded. The 64 MiB on-die-SRAM emulation M16 wants (inline kernel with a 64 MiB cache, cacheLog2Words = 24 in proto-metal/main.swift) is the RTX 5090 run reserved for the project lead's PC, as R3.5 states; it is not done here and the Mac number above does not price a die. Not done: the real-engine daemon RPC run (honest blocks need GPU-mined pow, so the measurement used the equivalent validate path with skip_proof_of_work); the 64 MiB-cache inline kernel on the 5090; the chain-derived day seed by DAA score (spec 01 section 1.12, still the timestamp-day devnet rule); the VDF epoch seed and finality.

3 October 2026, difficulty controller: devnet record, simulator, Igneum dual-lane rule, 3-node CPU test network (consensus-engineer)

-

Machine: the same Apple M5 Max, shared with two other build agents (load average 60 to 98 during the Rust builds). Fork worktree vendor/igneum-node-diff, branch difficulty from d62708a8. Everything in docs/analysis/difficulty-2026-10-03.md; raw outputs in sim/difficulty/results.md. Record: 3,682 headers of the overnight devnet pulled read-only through the observer node's wRPC JSON (ws://127.0.0.1:28640, getBlocks from genesis) into sim/difficulty/devnet-2026-10-03.csv. Kaspa's sampled DAA held genesis difficulty 134,217,727 through block 600 at 0.6 blocks/s (PC, 116 MH/s estimated from the blocks), then eased 4.8x at the first retarget (DAA 600, 19:56:12 UTC) and on to 15.7x (8,552,118) because the 600-block window spanned the 21-minute Metal-only period and a 13-minute idle gap; 5.44 blocks/s over the next five minutes, 355 blocks in the peak minute, 1,633 blocks above 2x, then 1.5x too hard; the DAG widened to 3,681 blocks for 1,656 chain blocks. Exact replay of the record's bits through rusty-kaspa's integer arithmetic matches 244 of 244 retargets while the devnet was a chain and diverges from DAA 845 (merged blocks a chain-only replay cannot see). Simulator sim/difficulty/sim.py (Python, one chain, exponential solve times, 1 BPS): Kaspa sampled DAA, Monero 720, LWMA 60 and 120, the Igneum rule and the brief's literal trigger, on nine synthetic profiles plus the record. Two design findings: Zawy's average-target LWMA estimator is biased while targets ramp (the fast lane stalled at 15x of a 50x step), so every Igneum lane uses work over time (Kaspa's estimateNetworkHashesPerSecond estimator); the brief's trigger (short-window rate off target) chatters once the short window is back on target while the long window is still polluted (polluted case 1,876 s against 70 s), so the trigger compares the two lanes. Tuned on the synthetic set only: short window 120, hold 8, prior 16, long lane from 600 blocks of the epoch, trigger 25%, harden 3% per block, ease 10% per block, solvetime cap 20 T. Settled seconds (121-block mean within 10% for 100 blocks), Kaspa / Monero / LWMA60 / LWMA120 / Igneum: x50 step 1,542 / 94 / 105 / 231 / 62; /50 step 12,296 / 6,433 / 578 / 1,074 / 657 (worst gap 179 / 187 / 119 / 65 / 35 s); epoch +-30% steps 1,583 / 456 / 157 / 153 / 144; 10x hopping never / 284 (6 of 12 never) / 264 / 326 / 212; polluted window 2,748 (peak 7.9x) / 124 (peak 15x) / 66 / 110 / 70; genesis 10x too hard never / 287 / 155 / 188 / 322; steady std of rate 0.012 / 0.037 / 0.131 / 0.092 / 0.038; the record's 75x step never (peak 7.6x, 2,340 blocks above 2x) / 136 / 75 / 157 / 79. With +-500 ms timestamp jitter the ordering holds (Igneum x50 169 s, /50 1,047 s, epoch 55 s, polluted 71 s). Implementation: DifficultyRule { KaspaSampled, IgneumDual } as a network parameter (IgneumDual on all four networks, "difficulty_rule": "kaspa-sampled" in the override file selects Kaspa's), OverrideParams.genesis_bits (genesis hash recomputed) for test networks, SampledDifficultyManager::igneum_difficulty_bits over a selected-chain walk plus the in-epoch samples of the existing window, pure integer core igneum_target (Uint320). cargo test -p kaspa-consensus --lib difficulty: 9 pass (hold, steady state, 3% harden, 10% ease, trigger, epoch shrinkage, max target, Kaspa's two level-work tests); cargo test -p kaspa-consensus-core --lib params: 4 pass. The miner now takes the genesis from the node (pruning point before the first pruning) so it mines an override-genesis network; before the fix it hashed the compiled devnet genesis as the epoch seed and every block was rejected. TESTNET_BENCH Not done: no DAG in the simulator (red blocks' work is ignored by every lane, as by Kaspa's estimator); Monero and LWMA reproduced from memory (approximate); real-time targeting left out; the chain walk (600 reads per header early in an epoch) must be re-measured before the 4 BPS step.

+

Machine: the same Apple M5 Max, shared with two other build agents (load average 60 to 98 during the Rust builds). Fork worktree vendor/igneum-node-diff, branch difficulty from d62708a8. Everything in docs/analysis/difficulty-2026-10-03.md; raw outputs in sim/difficulty/results.md. Record: 3,682 headers of the overnight devnet pulled read-only through the observer node's wRPC JSON (ws://127.0.0.1:28640, getBlocks from genesis) into sim/difficulty/devnet-2026-10-03.csv. Kaspa's sampled DAA held genesis difficulty 134,217,727 through block 600 at 0.6 blocks/s (PC, 116 MH/s estimated from the blocks), then eased 4.8x at the first retarget (DAA 600, 19:56:12 UTC) and on to 15.7x (8,552,118) because the 600-block window spanned the 21-minute Metal-only period and a 13-minute idle gap; 5.44 blocks/s over the next five minutes, 355 blocks in the peak minute, 1,633 blocks above 2x, then 1.5x too hard; the DAG widened to 3,681 blocks for 1,656 chain blocks. Exact replay of the record's bits through rusty-kaspa's integer arithmetic matches 244 of 244 retargets while the devnet was a chain and diverges from DAA 845 (merged blocks a chain-only replay cannot see). Simulator sim/difficulty/sim.py (Python, one chain, exponential solve times, 1 BPS): Kaspa sampled DAA, Monero 720, LWMA 60 and 120, the Igneum rule and the brief's literal trigger, on nine synthetic profiles plus the record. Two design findings: Zawy's average-target LWMA estimator is biased while targets ramp (the fast lane stalled at 15x of a 50x step), so every Igneum lane uses work over time (Kaspa's estimateNetworkHashesPerSecond estimator); the brief's trigger (short-window rate off target) chatters once the short window is back on target while the long window is still polluted (polluted case 1,876 s against 70 s), so the trigger compares the two lanes. Tuned on the synthetic set only: short window 120, hold 8, prior 16, long lane from 600 blocks of the epoch, trigger 25%, harden 3% per block, ease 10% per block, solvetime cap 20 T. Settled seconds (121-block mean within 10% for 100 blocks), Kaspa / Monero / LWMA60 / LWMA120 / Igneum: x50 step 1,542 / 94 / 105 / 231 / 62; /50 step 12,296 / 6,433 / 578 / 1,074 / 657 (worst gap 179 / 187 / 119 / 65 / 35 s); epoch +-30% steps 1,583 / 456 / 157 / 153 / 144; 10x hopping never / 284 (6 of 12 never) / 264 / 326 / 212; polluted window 2,748 (peak 7.9x) / 124 (peak 15x) / 66 / 110 / 70; genesis 10x too hard never / 287 / 155 / 188 / 322; steady std of rate 0.012 / 0.037 / 0.131 / 0.092 / 0.038; the record's 75x step never (peak 7.6x, 2,340 blocks above 2x) / 136 / 75 / 157 / 79. With +-500 ms timestamp jitter the ordering holds (Igneum x50 169 s, /50 1,047 s, epoch 55 s, polluted 71 s). Implementation: DifficultyRule { KaspaSampled, IgneumDual } as a network parameter (IgneumDual on all four networks, "difficulty_rule": "kaspa-sampled" in the override file selects Kaspa's), OverrideParams.genesis_bits (genesis hash recomputed) for test networks, SampledDifficultyManager::igneum_difficulty_bits over a selected-chain walk plus the in-epoch samples of the existing window, pure integer core igneum_target (Uint320). cargo test -p kaspa-consensus --lib difficulty: 9 pass (hold, steady state, 3% harden, 10% ease, trigger, epoch shrinkage, max target, Kaspa's two level-work tests); cargo test -p kaspa-consensus-core --lib params: 4 pass. The miner now takes the genesis from the node (pruning point before the first pruning) so it mines an override-genesis network; before the fix it hashed the compiled devnet genesis as the epoch seed and every block was rejected. Test network (ports 26800 to 26821, appdir /tmp/igneum-diff-test, override file with difficulty_rule and genesis_bits 0x1e200000): 3 igneumd nodes, 3 CPU miners of 4 threads (A for 1,200 s; B and C from 359 s to 779 s), 1,133 blocks, 0 rejected, one sink. Delivered hash rate 0.0653 / 0.0988 / 0.0686 MH/s (the join is x1.51, not 3x: shared cores at load 50 to 90). Genesis 4x too hard. Measured first within 10% of 1 block/s (61-block mean): warm-up 132 s, join 214 s (23 s to first touch), leave 85 s; simulator on the same profile, 5 seeds: medians 263 s, 61 s, 231 s; worst gap 7.3 s. Kaspa's rule on the same genesis: no retarget inside 20 minutes in any seed (600-block dead zone). Kaspa's rule live on the same genesis, 10 minutes: 70 blocks, bits unchanged on all 70, 0.08 blocks/s, worst gap 63 s, never within 10% of target. Not done: no DAG in the simulator (red blocks' work is ignored by every lane, as by Kaspa's estimator); Monero and LWMA reproduced from memory (approximate); real-time targeting left out; the chain walk (600 reads per header early in an epoch) must be re-measured before the 4 BPS step.

+

3 October 2026, igneum-node devnet v2: sustained-mining finality rule v2 on a four-miner test network, and as a follower of the live devnet (consensus-engineer and cryptographer)

+

Machine: Apple M5 Max, rustc 1.99.0, fork vendor/igneum-node at commits "Finality: BLS12-381 vote keys ..." through "Miner: BLS identity ..." (four commits on top of the rename). Builds in target-finality (CARGO_TARGET_DIR=target-finality cargo build --release --features igneum-pow): igneumd 36 MB (66 MB with line tables for the stall hunt), igneum-miner 7.6 MB; Windows cross-builds with Homebrew mingw-w64 in target-finality/x86_64-pc-windows-gnu/release/: igneum-miner.exe 9.7 MB and igneumd.exe 44 MB (rocksdb compiled under mingw without trouble, 8 min 13 s). Unit tests: kaspa-consensus-core 71 pass (4 new: key derivation and proof of possession, vote sign/verify/aggregate, section codec with reveal, sortition threshold), kaspa-notify 131, kaspa-rpc-core 20, 0 failures. Rule as implemented: docs/spec/03-finality.md section 3.10 and docs/fork-divergence.md "Finality v2". Crypto: blst min-pubkey BLS12-381, votes over "igneum-vote-v1/" || chain_id || 0 || index || hash, sortition VRF = SHA-256 of the sortition signature, aggregate certificates with a bitmap over the canonical voter list. Devnet parameters: checkpoint every 30 blue score, determined at +20, weight window 7,200 DAA s, dust 5 blocks, presence 20 indices, 8 aggregators, ban 7,200 DAA s, quorum 2/3 of active and 17/30 of total. Test network (--devnet --devnet-suffix=7, network id igneum-devnet-7, genesis bits 0x1e400000 through --override-params-file, finality params as devnet): three igneumd nodes on gRPC 26650/26660/26670, p2p 26651/26661/26671, wRPC JSON 28650/28660/28670 (nodes 2 and 3 --addpeer node 1, node 3 also node 2), peers at protocol version 12; four 4-thread CPU igneum-miner mine --engine igneum-pow identities m1, m2 (node 1), m3 (node 2), m4 (node 3); 21:59:48 to 22:53 BST. Block rate 0.25 blocks/s per miner (m1: 736 blocks in 3,000 s, 0.072 MH/s, 0 rejected), 2,193 blocks at 22:35; difficulty 149,037 at DAA 2,193. Key reveal: all four keys revealed from the first block of each identity (Finality: vote key revealed), hash matches the header on all three nodes. Weights at checkpoint 4 (DAA 119): 34 + 31 + 30 + 24 blocks, total 119, 4 voters, participation 1.0 (all keys younger than the presence window). Checkpoints and locks, steady state (indices 1 to 72, all four voting until the equivocation at 43, three after): 72 of 72 determined checkpoints locked on all three nodes; lock latency from determination to lock on node 1: median 0.80 s, p90 1.08 s, max 1.55 s (the vote round trip is bounded by the miners' 1-s poll); first lock 61 s after the first block (checkpoint 1 at blue score 31). Certificates built by the first node to see quorum: node 1 built 91, node 2 92, node 3 90 of 93, 0 conflicting certificates on any node; identical checkpoint hashes, states, signed and total weights on all three nodes at every RPC sample (getFinalityCheckpoints on 28650, 28660, 28670). Checkpoint 2 and 3 locked with 3 of 4 votes (74.6% and 73.0% of total) because the per-template vote carriage and the 1-s poll leave one vote outside the aggregator's first certificate; the lock still met both tests. Sortition: with 4 voters every voter is eligible (threshold = 1 when voters <= 8); aggregators lists the keys whose proof verified, 3 to 4 per checkpoint, and the certificate names the local eligible voter of the building node. Equivocation (m4 restarted with --equivocate at 22:19:41): at index 43 m4 submitted a vote for the checkpoint and one for the hash with its last bit flipped; node 3 answered the second with accepted=false equivocation=true, every node logged EQUIVOCATION by key 56da130c... at index 43 ... weight stripped until daa 8512, and from checkpoint 44 the key is voter false, stripped_until 8931 (the ban is re-stamped at each detection, m4 kept equivocating at every index), the voter list is 3, total weight excludes its 526 blocks, and locks continued at 3 of 3 votes (checkpoint 64: 938 of 953 active, 1,400 total). Evidence items were carried in blocks (evidence carriers) and re-detected by the follower path; 21 detections on node 3 in 10 minutes. Partition test (m4 stripped throughout, so the honest set is m1, m2, m3 with 33% of weight each): phase A, m3 stopped 22:31:07 to 22:35:10 (240 s): locks continued (72 at the end, signed 1,088 of 1,105 active and 1,563 total). Phase B, m2 also stopped 22:35:19 to 22:47:48 (749 s), m1 alone voting: 0 locks in 12 checkpoints (73 to 84); at the end m1's weight was 696 of 1,759 total (39.6%) and 696 of 962 active (72.3%), so the ACTIVE test passed as the two silent keys decayed out of the presence window and the 56.7% FLOOR alone held the lock back, which is the sim's 3.3.1 scenario on a real DAG. finality_active stayed true until the lock at 72 fell out of the 20-index window. Phase C, m2 and m3 restarted at 22:47:56: the returning miners signed every open index of the presence window, checkpoints 73 to 85 locked within 30 s (determined-to-locked 749 s for 73 down to 121 s for 84, 0 s for 85), 86 to 92 locked at the steady cadence (signed 1,784 of 1,784 at 86, 1,287 of 1,921 at 92, 3 voters). No conflicting certificate and no stall on any node through the heal. Observer and site: tools/observer/observer.mjs with LIVE_TABLE_PREFIX=fintest_ against 28650 wrote fintest_live_checkpoints (49 rows, 42 locked at the first sample) and checkpoint_locked events ("checkpoint 42 locked (76.2% of weight, 96.5% of active, 3 votes of 4 voters) at block 0d1405d0"), from both the FinalityLock subscription and the 2-s poll; live_state.finality carried the weights snapshot. site/api/live.mjs adds the live_checkpoints query and locked/final flags per block; site/live.html draws the locked-checkpoint ring, the dashed "final" line at the newest lock and the locked counter. Not deployed to Vercel tonight. Live devnet follower (igneumd v2 on gRPC 26690, p2p 26691, JSON 28690, --connect=127.0.0.1:26611, never mining): IBD of 5,254 blocks from node 1 in under a second, kept in sync (5,418 blocks at 21:53, 0.70 blocks/s on the live chain), determined checkpoints 1 to 302 within 1 s of IBD; weights at checkpoint 296 (DAA 8,935): 16 keys, 14 above dust, total 7,146 blocks (eight RTX 5090 identities at 862 to 936 blocks, six at 4 to 10), 0 revealed keys, 0 votes, participation 0, 0 locks, finality_active false, exactly as expected while the Windows miners run the pre-v2 binary. RSS 1.1 GB. It only ever receives from node 1 (its protocol version 12 against node 1's 11 means no finality messages in either direction). Open: one stall of all three test nodes at 21:48:43 BST in the first run (stripped binary, right after the follower, the equivocating miner and the test observer started): all three logs stop in the same second, every RPC times out, CPU 0%, node 1 of the live devnet unaffected; not reproduced in 28 minutes of the same scenario on the symbolized build (lock 40 to 93 without a pause, including the equivocation and the partition). The first run's self-deadlock (compute_weights taking the state lock its callers hold) was found and fixed before that stall, and Router::enqueue is a non-blocking try_send, so the gossip pump cannot deadlock across nodes; cause unknown. Also open: C3 validity rule and F3 pruning bound not enforced; d = 20 chosen without the reorg-depth distribution; the weight walk is O(window) per checkpoint; one certificate per index per node means a certificate often names fewer signers than the votes that exist. Not demonstrated: locks on the live devnet (its miners do not vote yet), the Windows binaries on Windows, a certificate carried into a block and verified by a cold node that missed the gossip (the follower had no votes to receive), the 2-hour presence window at full length (the run was 53 minutes).

+

3 October 2026, execution layer devnet v3: revm over the selected chain, 3-node simnet, viem smoke test (execution-engineer)

+

Machine: the same Apple M5 Max (18 cores), shared with two other agents' builds (load 15 to 55). Branch execution-layer in vendor/igneum-node-exec, worktree of vendor/igneum-node from d62708a8; revm 43.0.3, alloy-primitives 1.7.3, alloy-consensus 2.5.0, alloy-trie 0.9.8, axum 0.8.9; viem 2.57.2, solc 0.8.37 (tools/evm-smoke). Release build CARGO_TARGET_DIR=target cargo build --release -p kaspad -p igneum-miner --features igneum-pow: first full build with the new crates about 20 min under nice -n 10 -j 10 on the loaded machine; incremental igneumd rebuilds 35 s to 4 min. Test network: 3 igneumd --simnet nodes (devnet block rate and depths, proof of work skipped, chain id 4463) on gRPC 26700/26710/26720, p2p 26701/26711/26721, eth RPC 26790/26791/26792, appdirs /tmp/igneum-exec-test; 3 single-thread igneum-miner --engine stub --hold-ms 2500 (exponential hold, mean 2.5 s per miner). Rate: 130 blocks in 120 s = 1.08 blocks/s; 68 chain blocks; selected-chain reorgs 22 in 120 s, depth 1 (17) and 2 (5), identical on the 3 nodes. Earlier run with a fixed 900 ms hold: 3 blocks/s in lockstep rounds and 80 to 92 reorgs in 60 s with flips 45 to 69 deep (equal-work chains kept alive by the hash tie-break); every flip was unwound correctly (state roots identical on 3 nodes at block 32 after 65-deep flips), the fix is Poisson pacing in the miner. Smoke test (node tools/evm-smoke/smoke.mjs, stock viem paths): 87 checks passed, 0 failed, 36 s wall, tip at chain block 78. eth_chainId 0x116f, net_version 4463. Miner 1 (EVM address = low 20 bytes of its vote key hash) held 91.28 IGN at chain block 53 from 80% subsidy shares of 36.59 IGN per blue block (3,168,808,781 sompi x 1e10 x 0.8, launch-ramp day 0 is not applied on simnet's genesis timestamp); proving pool escrow 92.55 IGN at the end. Funding: 3 transfers of 5 IGN, eth_estimateGas 25,380 (21,000 plus the pgas fold and the 15% margin), all status 1, balances exact. 50 transfers between 3 accounts (each sender's transactions to one node, no p2p relay of EVM transactions): all 50 executed in 16 s wall across chain blocks 58 (17), 61 (20), 62 (13); 57 executed transactions in 7 chain blocks over the run, max 20 per chain block; 19 skipped copies (the same miner re-including transactions handed out before its earlier template landed, every one skipped by the nonce rule with no fee and no receipt). Balances of the 3 accounts matched the receipt accounting to the wei (value plus gas_used x effectiveGasPrice plus burnedProvingFee). Transfer receipt: gasUsed 21,000, pgasUsed 200, effectiveGasPrice 2 gwei (base 1 gwei, tip 1 gwei), burnedProvingFee 200 gwei (200 pgas x 1 gwei), minerTip 16,800 gwei (80% of 21,000 gwei), developerShares [burned 4,200 gwei] (unregistered, 20%). Contract call increment(5): gasUsed 45,354, pgasUsed 1,288, minerTip 36,283.2 gwei (80%), developer share 9,070.8 gwei (20%) credited to the payee the constructor registered (balance delta equal). Deployment via viem deployContract: gasUsed 185,948, pgasUsed 1,438, registry creatorOf = deployer and payeeOf = constructor argument (executor CREATE rule plus register). eth_estimateGas reports the revert of increment(0); eth_call hashLoop(50) returns; eth_estimateGas hashLoop(200) = 98,900 with the fold; eth_getLogs finds the event. Measured pgas/gas: 0.0095 transfer, 0.028 storage write with event, 0.0077 deployment, 0.0099 averaged (prototype table, below the design's 0.1 to 10 band as expected before calibration). Duplicates in parallel blocks: one identical copy sent to nodes 1 and 2 was included twice (chain blocks 63 and 64, blocks c09c9329... and 3f401bd2...), executed once, the second skipped NonceTooLow { expected: 18, got: 17 }; a conflicting same-nonce pair (different values, one copy per node) executed exactly once (B1), the loser never reached a block because its node's pool dropped it once the nonce had passed (igneum_getTransactionStatus: includedIn [], executed false). Execution time per chain block (node 1, igneum.executionMicros, includes the full-recompute state root): 50, 71, 93, 57, 41, 46, 50 us for the 7 chain blocks with 3, 17, 20, 13, 2, 1, 1 transactions; 71 empty chain blocks averaged 11 us; the same chain block on the 3 nodes: 50 / 192 / 85 us (block 56) and 50 / 88 / 46 us (block 78). State roots as outputs: genesis (registry only) 7e37a9fb19b154d32daf5bf30a50d339a75029fbc9eec9ea20e95439dba5a311; chain block 56 (3 funding transfers) 68cacfd393b00ead784a69b10d57a3e2dd57858029df107b529487a49f393b50; chain block 78 5b18b3a58f6c1d21b22caad4a1dbd9ee8a6394a02db2220255e556a9d4f90878; identical hash and root on all 3 nodes at heights 0, 56, 74 and 78; the root advanced at every block with transactions. Base fees stayed at the 1 gwei floor (segments far below the 15 M gas target). Differential (igneum-exec-diff seq.json, plain revm without inspector, pgas or split, balances adjusted by the exported Igneum-only flows): segments 0 to 78, 57 executed transactions compared (status, gas used, logs), 19 skipped copies confirmed rejected by plain revm at their positions, 10 accounts compared (balance, nonce, code hash), 0 mismatches. cargo test -p igneum-evm-types: 3 passed. Not done: on-disk state and incremental trie (state rebuilt from genesis at start), header fields utxo_commitment and accepted_id_merkle_root kept (proofs_root is an RPC placeholder), body miner field and proofs section, pgas calibration, proving layer, eager virtual execution, eth_getProof/subscribe/debug, EVM transaction relay between nodes, the finality merge (plan in the design document, section 10.4). Test network stopped at the end of the run.

+

2026-10-03, consensus attack harness (consensus-engineer), catalogue run on the ordering-layer node

+

Machine: Apple M5 Max, 64 GB, load 61.19 55.26 50.53. Private test network of igneumd (release, skip_proof_of_work devnet) on 127.0.0.1 ports 27200+, data /tmp/igneum-harness; the live devnet and the PC node were not touched. Harness: tools/harness/, node fork worktree vendor/igneum-node-harness.

+
ScenarioCriterion (spec)MeasuredPass
5 malformed and boundary inputs on every p2p message and RPC method the fork touchesrejected without a crash or a cache build (spec 02 2.4; fork-divergence header and RPC rows; ledger M15)63 cases (46 RPC, 17 p2p): node stayed up on every case; all malformed inputs rejected or disconnected. 5 cases (rpc:timestamp-zero, rpc:timestamp-past-3-days, rpc:daa-score-bogus, p2p:ts-past-day, p2p:daa-bogus) built a 256 MiB cache = ledger M15 reproduced on HEAD d62708a8, which the r3-fixes branch drives to 0 (bench-log M15 entry). Other unexpected cache builds: 0. Over-length vote_key_hash (vkh-33-bytes) and an unknown JSON field were normalized and accepted rather than rejected (minor, no safety impact).pass
2 timestamp boundaries (live)rejected at ts <= past median, accepted at pmt+1; accepted below now+132 s, rejected above (spec 02 section 2.3)past: pmt-1=rejected, pmt=rejected, pmt+1=accepted, pmt+2=accepted; future flip between +132.00 s and +132.01 spass
2 timestamp stretch drift (sim)controller response to a 33% miner stretching timestamps inside the rules is measured (blocks per second drift against an honest run)honest 0.9952 b/s (difficulty x1.016); ahead 131 s: 1.0222 b/s (+2.7%, x0.96); oscillate: 1.0422 b/s (+4.7%, x0.923); over 6000 virtual spass
1 withhold a=0.1 release every 5attacker blue share <= 0.1 + 2 sigma (0.014) over 1927 bluesblue share 5.4% (104 blue, 81 red of 186 made); honest reorgs depth:count 1:2 2:5 3:2 4:2 5:2 8:2, max 8pass
1 withhold a=0.1 release every 20attacker blue share <= 0.1 + 2 sigma (0.014) over 1858 bluesblue share 1.2% (23 blue, 157 red of 186 made); honest reorgs depth:count 1:1 2:1 5:1, max 5pass
1 withhold a=0.25 release every 5attacker blue share <= 0.25 + 2 sigma (0.020) over 1942 bluesblue share 22.0% (428 blue, 42 red of 474 made); honest reorgs depth:count 1:11 2:11 3:6 4:17 5:6 6:9 7:5 8:6 9:2 10:1, max 10pass
1 withhold a=0.25 release every 20attacker blue share <= 0.25 + 2 sigma (0.021) over 1693 bluesblue share 12.6% (214 blue, 266 red of 489 made); honest reorgs depth:count 1:3 3:3 4:1 5:1 6:1 7:1 8:2 11:2 13:1 14:2 16:1 25:1 30:1, max 30pass
1 withhold a=0.33 release every 5attacker blue share <= 0.33 + 2 sigma (0.021) over 2039 bluesblue share 31.5% (643 blue, 17 red of 663 made); honest reorgs depth:count 1:15 2:18 3:21 4:21 5:15 6:14 7:10 8:5 12:1 13:1, max 13pass
1 withhold a=0.33 release every 20attacker blue share <= 0.33 + 2 sigma (0.024) over 1561 bluesblue share 27.4% (428 blue, 212 red of 640 made); honest reorgs depth:count 2:2 3:1 4:1 5:1 6:1 7:1 8:2 12:1 13:1 15:1 19:1 22:1 23:3 25:2 26:1 28:2 29:1 32:2 33:1, max 33pass
1 withhold a=0.45 release every 5attacker blue share <= 0.45 + 2 sigma (0.022) over 2002 bluesblue share 44.2% (885 blue, 0 red of 886 made); honest reorgs depth:count 1:24 2:27 3:23 4:29 5:22 6:16 7:7 8:8 9:2 13:2 14:1 15:1, max 15pass
1 withhold a=0.45 release every 20attacker blue share <= 0.45 + 2 sigma (0.024) over 1657 bluesblue share 50.7% (840 blue, 40 red of 886 made); honest reorgs depth:count 3:1 8:2 9:1 11:3 12:1 13:1 15:1 16:5 17:2 18:2 19:3 20:3 21:1 22:4 23:3 25:3 26:2 28:1 29:1 31:1 32:2 36:1, max 36FAIL
3 partition 120 sone chain after the merge-depth rule; reorg depth and time to heal recordedone chain: true (blue scores within 3 at the end); healed in 10 s; losing-side reorg at heal 41 chain blocks (per node 41/41/0/2); rejects nonepass
3 partition 600 sone chain after the merge-depth rule; reorg depth and time to heal recordedone chain: true (blue scores within 4 at the end); healed in 10 s; losing-side reorg at heal 234 chain blocks (per node 0/0/233/234); rejects nonepass
3 partition 1800 sone chain after the merge-depth rule; reorg depth and time to heal recordedone chain: true (blue scores within 4 at the end); healed in 10 s; losing-side reorg at heal 920 chain blocks (per node 0/0/920/920); rejects nonepass
3 partition 3700 s (beyond merge depth)one chain after the merge-depth rule; reorg depth and time to heal recordedone chain: true (blue scores within 4 at the end); healed in 10 s; losing-side reorg at heal 2160 chain blocks (per node 0/5/2160/2159); rejects MissingParents:1; MissingParents:1; MissingParents:5; MissingParents:5pass
6 resource exhaustion (50x template, submit and mempool floods from one peer)honest template p95 < 200 ms and both nodes under baseline RSS + 512 MB, alive, one sinkhonest template p95 worst 3.7 ms across loads (baseline 33.2 ms); template 500ps 500/s, submit 50ps 50/s, mempool 500ps 500/s; RSS growth template +4MB, submit +11MB, mempool +14MB; alive true; same sink truepass
4 eclipse 600 svictim rejoins the honest chain on reconnection within the merge-depth bound; reorg depth recordedvictim rejoined 10 s after reconnection (blue-score gap to honest 3 at the end); victim reorg depth 149 chain blocks; adversary built 242 blocks that never entered the honest chainpass
4 eclipse 1800 svictim rejoins the honest chain on reconnection within the merge-depth bound; reorg depth recordedvictim rejoined 10 s after reconnection (blue-score gap to honest 0 at the end); victim reorg depth 447 chain blocks; adversary built 497 blocks that never entered the honest chainpass
7 fast-miner flood, controller trajectory (sim, Kaspa sampled DAA on HEAD)trajectory recorded for the difficulty branch (bits, blocks per second, settle times)50x joins at 600 s: peak 25.27 blocks/s, difficulty x28.4, within 25% of 1 BPS after never s; leaves at 1200 s: trough 0 blocks/s, back within 25% after never spass
7 fast-miner flood, live (50 blocks/s from one peer)node stays responsive: honest template p95 < 200 ms, both nodes alive, same sinkflood accepted 721 blocks in 60 s (12.0/s); honest template p50/p95/max 0.4/0.8/1.3 ms under flood (baseline 0.4/0.8/1.2); rss a 303->333 MB, b 305->332 MB; alive true; same sink truepass
1b withhold vs finality weight (finality branch)spec 03: a withholder gains no vote weight beyond its hash share; under the 56.7% total floor, 0 conflicting locks (CLAUDE.md, ledger F18)stub: run s1 withhold against a node built with the finality-v2 branch, with miner --vote keys, and read getFinalityWeights and getFinalityCheckpoints; assert blue-weight share within noise and no conflicting lock. Needs the finality branch merged into the harness worktree.stub
3b partition vs finality lock (finality branch)spec 03.5 and ledger F16: after a partition heals, no certified lock is revoked (an exchange relies on "locked" being final); the F16 decision (Kaspa halt vs re-evaluate) is exercisedstub: run s3 partition with voting miners on both sides; record every FinalityLock notification and assert no locked checkpoint changes hash after the heal. Needs the finality branch.stub
4b eclipse vs finality presence window (finality branch)spec 03.3 F2 and ledger F2: a 2-hour presence window does not let an eclipsed victim be fed a locked side chain; the victim rejoins without accepting a revoked lockstub: run s4 eclipse with voting miners; assert the victim never reports a lock on the adversary chain that the honest chain does not also certify. Needs the finality branch.stub
2b difficulty controller under timestamp stretch (difficulty branch)docs/analysis/difficulty-2026-10-03.md: the igneum-dual rule holds the block rate under a timestamp-stretching miner better than Kaspa sampled DAA; forged timestamps move a lane by at most a few percent (spec 02 section 2.3)stub: run s2 Part B with {"difficulty_rule":"igneum-dual"} in the override file against the difficulty branch, compare the drift to the kaspa-sampled baseline this branch measured. Needs the difficulty branch (vendor/igneum-node-diff) merged into the harness worktree.stub
7b fast-miner flood on the dual-lane controller (difficulty branch)docs/analysis/difficulty-2026-10-03.md: on the igneum-dual rule the 50x step settles within about 62 s and the step-down within about 11 minutes, against Kaspa sampled DAA never settling (the record of the devnet event)stub: run s7 Part A with the difficulty branch and {"difficulty_rule":"igneum-dual"}, compare the trajectory to the kaspa-sampled baseline this harness records. Needs the difficulty branch.stub
+

Full JSON per scenario under /tmp/igneum-harness/results and /tmp/igneum-harness/sim. The simulator (igneum/harness-sim in the fork worktree) runs real consensus code in virtual time with PoW skipped, as rusty-kaspa simpa does; the live scenarios (5, 6, 7 Part B) drive real igneumd processes over wRPC and the fork's own p2p (igneum/p2p-probe).

+

Finality and difficulty-controller scenarios are stubs here: their criteria are written and they run against those branches once merged into the harness worktree (see tools/harness/scenarios/stubs.mjs).

+

3 October 2026, weak-program census: 400,000 program runs through the CPU reference, the redundant-load finding, and the rules for M5 and M6 (cryptographer)

+

Machine: Apple M5 Max, 8 threads at nice -n 15 while a devnet build and its simulations shared the box (load average 25 to 107), rustc 1.99.0, release build with LTO. New crate igneum-census/ (path dependency on igneum-pow, nothing in igneum-pow changed); the instrumented interpreter is checked against igneum_pow::hash_warp on the first warp of every program and against the igneum-genesis spec vectors at start. Commands: igneum-census run --root igneum-census-2026-10-03 --count 100000 --warps 128 --threads 8 --gen default (memory-hard, 1 GiB, day 2026-10-03; 2,797 s), the same with --gen fixed16-fresh --warps 64 (1,049 s), --gen fixed16-fresh2 --warps 64 (6,650 s, starved to under a core for most of it), and --gen default --closed-form --warps 128 (125.6 s once the machine was quiet); summarise, probe, show. Full tables and the rules in docs/analysis/weak-program-census-2026-10-03.md. Current generator, 100,000 programs x 4,096 nonces: loads per hash 24 to 256 (mean 127.9); distinct addresses per hash 24 to 200 (mean 102.4): 19.9 percent of all loads re-read an address the same hash already read, 94.8 percent of programs have at least one such load, 22.5 percent have a pair that cancels to the identity. The Mac rates of the eight bench seeds vary 1.38x by static loads/s and 1.10x by distinct loads/s (3.51 to 3.85 G/s), so the GPU is bound by the distinct count; igneum-second-seed/epoch1 (144 static, 104 distinct) hashes at the rate of igneum-second-seed (104 and 104). Weak programs, current generator: 2.43 percent have a register with no injecting write (saturates to all ones); 0.73 percent have a register with a nonce-independent bit, 0.03 percent a whole nonce-independent register, 0.03 percent a load site read at one address by all 32 lanes, 0.68 percent more than 1 percent of final registers at 0 or all ones, 6 programs an output bit past 6 sigma (0.03 expected by chance). Avalanche clean on every program (mean 31.85 to 32.15, every output bit flips 0.473 to 0.523). Mechanisms: no injecting write; zero-absorbing register sets closed under mulhi/mul; or or mul as the last write. Rules: G1 exactly 16 load slots drawn first from slots 1..63; G2 a load reads only a register written earlier in the program and not read by a load since; R-a no cyclically redundant load; R-b every register has an injecting write; R-c 64 fixed warps on the seed-keyed closed-form dataset with no constant register bit, no lane-constant site, saturation under 1 percent, no output bit past 6 sigma, more than 120 distinct addresses per hash on average. Rejection: 95.0 percent under the current generator (the redundancy alone), 38.3 percent under the first form of G2 (the iteration wrap), 5.14 percent under the proposed form (R-a or R-b 3.93 percent, R-c 2.05 percent), so 1.054 candidates per epoch on average; the accepted population does 120.05 to 128 distinct loads per hash, median 128.00. Closed-form check: with the same seeds and nonces on the closed-form dataset instead of the memory-hard one, R-c agrees on 99,961 of the 100,000 proposed-generator programs (2,054 rejected memory-hard, 2,055 closed-form; the 39 that differ sit at a threshold edge, one nearly constant bit or a bias near 6 sigma) and the per-program metrics agree to three decimals, so the acceptance test can be a pure function of the program. Hash-rate spread: today 2.7x between the 1st and 99th percentile program by distinct loads (56 to 152 per hash; 321 to 118 Mhash/s projected on the RTX 5090 at 18.0 G distinct loads/s), 8.3x min to max; under G1 + G2 every program does 128 distinct loads, projected 141 Mhash/s on the 5090 and 28 on the M5 Max, with the 1.10x program-shape residual the only spread left, approximate. One 5090 run of igneum-second-seed (predicted 173 Mhash/s if distinct-bound, 228 if static-bound) settles the reading on NVIDIA. Not done: no GPU run of the new generator; the spec text is proposed in the analysis doc, section 9, not written into docs/spec/01-lottery-hash.md; test vectors are re-cut when the generator rule is adopted.

diff --git a/site/build.mjs b/site/build.mjs index 51206fa82..0418dbd43 100644 --- a/site/build.mjs +++ b/site/build.mjs @@ -83,30 +83,37 @@ function page(title, desc, bodyHtml, toc, note, { path = '/bench', heading = tit ${meta(title, desc, path)} diff --git a/site/index.html b/site/index.html index 3a7ef526a..e1a4a157d 100644 --- a/site/index.html +++ b/site/index.html @@ -35,11 +35,17 @@ @@ -252,15 +258,6 @@ footer .wrap{padding-block:48px 32px} Start mining Read the litepaper -
- -
-
0
miners active
-
0.0
blocks / s
-
0.0 MH/s
network hash rate
-
0
blocks on the devnet
-
-
@@ -282,16 +279,25 @@ footer .wrap{padding-block:48px 32px}
+
+ +
+
0
miners active
+
0.0
blocks / s
+
0.0 MH/s
hash rate
+
0
devnet blocks
+
+
1 / s
blocks, rising to 10
-
~60 s
to a verified proof at launch
-
0
premine, pre-sale, allocation
+
~60 s
to a proof at launch
+
0
premine
4B
IGN hard cap, ever
-
100%
of emission to miners and provers
+
100%
to miners and provers
@@ -316,7 +322,7 @@ footer .wrap{padding-block:48px 32px}
-
This hour's mining program
next in 59:59
+
This hour's program
next in 59:59

         

A new program every hour. Last hour's chip is already obsolete.

@@ -335,7 +341,7 @@ footer .wrap{padding-block:48px 32px}
-
+

Monero's idea, finished for GPUs

@@ -358,7 +364,7 @@ footer .wrap{padding-block:48px 32px}
-
+

One chain, three jobs

@@ -392,9 +398,9 @@ footer .wrap{padding-block:48px 32px}

One client switches the card between hashing and proving by itself.

-
01

Block reward

80% of emission to the miner who wins the block.

-
02

Proving the chain

20% of emission plus a share of every block's gas.

-
03

Proving for others

Rollups and bridges pay for proofs in their own money.

+
01

Block reward

80% of emission to the miner who wins the block.

+
02

Proving the chain

20% of emission plus a share of every block's gas.

+
03

Proving for others

Rollups and bridges pay for proofs in their own money.

Windows @@ -422,7 +428,7 @@ footer .wrap{padding-block:48px 32px}
-
+
@@ -439,9 +445,9 @@ footer .wrap{padding-block:48px 32px}
0
premine
-
0
stake in consensus
+
0
stake, anywhere
0
admin keys
-
90%
of blocks must signal before any upgrade
+
90%
of blocks must signal to upgrade

No premine, no stake, no fee to any team. Base fee burned.

diff --git a/site/litepaper.html b/site/litepaper.html index a98680787..8a1b225ad 100644 --- a/site/litepaper.html +++ b/site/litepaper.html @@ -34,6 +34,10 @@ --ink:#0C0C0E; --ink-2:#3D3B37; --quiet:#6E6B65; --ember:#D9430F; --ember-ink:#FFFFFF; --molten:#B9741C; --tint:#FBE9E0; --code:#16161A; --code-ink:#E6E2DA; + /* one system for every page: container, gutter, section rhythm, card and tile boxes, heading scale (same tokens as the homepage) */ + --max:1200px;--gutter:clamp(16px,4vw,32px);--sec:clamp(56px,8vw,96px);--head:clamp(40px,6vw,64px); + --card-pad:clamp(18px,3vw,28px);--card-r:18px;--tile-pad:18px 20px;--tile-r:14px;--gap:24px;--gap-tile:12px; + --fs-h1:clamp(32px,5.5vw,56px);--fs-h2:clamp(28px,4.2vw,44px);--fs-h3:clamp(18px,2vw,22px);--fs-tile:clamp(20px,2.2vw,26px); } @media (prefers-color-scheme: dark){ :root:not([data-theme="light"]){ @@ -52,21 +56,21 @@ color-scheme:dark; } *{box-sizing:border-box} -body{margin:0;background:var(--ground);color:var(--ink);font-family:'IBM Plex Sans',system-ui,-apple-system,sans-serif;font-size:17px;line-height:1.6;padding-inline:16px;padding-block:0} +body{margin:0;background:var(--ground);color:var(--ink);font-family:'IBM Plex Sans',system-ui,-apple-system,sans-serif;font-size:17px;line-height:1.6;padding:0} a{color:var(--ember);text-decoration:none} a:hover{text-decoration:underline} a:focus-visible,button:focus-visible{outline:2px solid var(--ember);outline-offset:3px} -.wrap{max-width:1180px;margin:0 auto} -.cover{padding-block:48px 40px;border-bottom:1px solid var(--line);display:flex;flex-wrap:wrap;gap:32px;align-items:flex-end;justify-content:space-between} +.wrap{max-width:var(--max);margin:0 auto;padding-inline:var(--gutter)} +.cover{padding-block:var(--head) 40px;border-bottom:1px solid var(--line);display:flex;flex-wrap:wrap;gap:32px;align-items:flex-end;justify-content:space-between} .brand{display:flex;align-items:center;gap:14px} .brand .word{font-family:'Unbounded',sans-serif;font-weight:900;font-size:26px;letter-spacing:.06em} .eyebrow{font-family:'IBM Plex Mono',monospace;font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--quiet)} -.cover h1{margin:12px 0 10px;font-family:'Unbounded',sans-serif;font-weight:900;font-size:clamp(34px,6vw,64px);line-height:1.02;letter-spacing:-.01em;text-wrap:balance} +.cover h1{margin:12px 0 10px;font-family:'Unbounded',sans-serif;font-weight:900;font-size:var(--fs-h1);line-height:1.05;letter-spacing:-.01em;text-wrap:balance} .cover .tag{font-size:20px;color:var(--ink-2);max-width:40ch} .meta{display:flex;flex-direction:column;gap:6px;font-family:'IBM Plex Mono',monospace;font-size:13px;color:var(--quiet);text-align:right} .meta b{color:var(--ink);font-weight:500} -.layout{display:grid;grid-template-columns:minmax(0,1fr);gap:40px;padding-block:40px 80px} -@media (min-width:960px){.layout{grid-template-columns:240px minmax(0,1fr);gap:64px}} +.layout{display:grid;grid-template-columns:minmax(0,1fr);gap:32px;padding-block:40px var(--sec)} +@media (min-width:960px){.layout{grid-template-columns:240px minmax(0,1fr);gap:56px}} .toc{align-self:start} @media (min-width:960px){.toc{position:sticky;top:calc(env(safe-area-inset-top,0px) + 24px)}} .toc ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px;counter-reset:s} @@ -75,35 +79,36 @@ a:focus-visible,button:focus-visible{outline:2px solid var(--ember);outline-offs .toc li a:hover{background:var(--surface-2);text-decoration:none;color:var(--ink)} .toc .dl{margin-top:18px;padding-top:18px;border-top:1px solid var(--line);font-size:13px;color:var(--quiet)} article{max-width:72ch} -section{padding-block:34px;border-top:1px solid var(--line)} +section{padding-block:40px;border-top:1px solid var(--line)} section:first-of-type{border-top:0;padding-top:0} -h2{margin:0 0 18px;font-family:'Unbounded',sans-serif;font-weight:700;font-size:clamp(24px,3.2vw,32px);line-height:1.15;text-wrap:balance} -h3{margin:28px 0 8px;font-family:'Unbounded',sans-serif;font-weight:500;font-size:17px;line-height:1.3} +h2{margin:0 0 18px;font-family:'Unbounded',sans-serif;font-weight:700;font-size:var(--fs-h2);line-height:1.1;text-wrap:balance} +h3{margin:28px 0 8px;font-family:'Unbounded',sans-serif;font-weight:500;font-size:var(--fs-h3);line-height:1.3} p{margin:0 0 16px} .lead{font-size:20px;line-height:1.5;color:var(--ink-2)} ul,ol{margin:0 0 16px;padding-left:22px} li{margin-bottom:8px} strong{font-weight:600} -.pull{margin:24px 0;padding:22px 26px;border-left:4px solid var(--ember);background:var(--tint);border-radius:0 12px 12px 0;font-family:'Unbounded',sans-serif;font-weight:500;font-size:19px;line-height:1.4} -.tbl{overflow-x:auto;margin:18px 0 22px;border:1px solid var(--line);border-radius:12px;background:var(--surface)} +.pull{margin:24px 0;padding:20px var(--card-pad);border-left:4px solid var(--ember);background:var(--tint);border-radius:0 var(--tile-r) var(--tile-r) 0;font-family:'Unbounded',sans-serif;font-weight:500;font-size:19px;line-height:1.4} +.tbl{overflow-x:auto;margin:18px 0 24px;border:1px solid var(--line);border-radius:var(--card-r);background:var(--surface)} table{border-collapse:collapse;width:100%;min-width:560px;font-size:15px} th,td{padding:12px 14px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)} th{font-family:'IBM Plex Mono',monospace;font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--quiet);font-weight:500;background:var(--surface-2)} tr:last-child td{border-bottom:0} td.num{font-family:'IBM Plex Mono',monospace;font-variant-numeric:tabular-nums;white-space:nowrap} -.figure{margin:22px 0 26px;padding:22px;background:var(--surface);border:1px solid var(--line);border-radius:14px;overflow-x:auto} +.figure{margin:24px 0;padding:var(--card-pad);background:var(--surface);border:1px solid var(--line);border-radius:var(--card-r);overflow-x:auto} .figure svg{display:block;width:100%;height:auto;max-width:100%} .figure .cap{margin-top:12px;font-family:'IBM Plex Mono',monospace;font-size:12px;color:var(--quiet)} -.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin:8px 0 22px} -.stat{padding:16px;background:var(--surface);border:1px solid var(--line);border-radius:12px} -.stat .v{font-family:'Unbounded',sans-serif;font-weight:700;font-size:26px;color:var(--ember);line-height:1.1} -.stat .k{margin-top:6px;font-size:13px;color:var(--quiet)} -pre{margin:0 0 16px;padding:16px 18px;background:var(--code);color:var(--code-ink);border-radius:12px;font-family:'IBM Plex Mono',monospace;font-size:13px;line-height:1.6;overflow-x:auto} -.foot{padding-block:28px 48px;border-top:1px solid var(--line);display:flex;flex-wrap:wrap;gap:16px 32px;justify-content:space-between;font-size:14px;color:var(--quiet)} +.stats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--gap-tile);margin:8px 0 24px} +@media (min-width:700px){.stats{grid-template-columns:repeat(4,minmax(0,1fr))}} +.stat{padding:var(--tile-pad);background:var(--surface);border:1px solid var(--line);border-radius:var(--tile-r);min-width:0} +.stat .v{font-family:'Unbounded',sans-serif;font-weight:700;font-size:var(--fs-tile);color:var(--ember);line-height:1.1} +.stat .k{margin-top:6px;font-size:14px;color:var(--quiet);line-height:1.35;text-wrap:balance} +pre{margin:0 0 16px;padding:16px 18px;background:var(--code);color:var(--code-ink);border-radius:var(--card-r);font-family:'IBM Plex Mono',monospace;font-size:13px;line-height:1.6;overflow-x:auto} +.foot{padding-block:32px 48px;border-top:1px solid var(--line);display:flex;flex-wrap:wrap;gap:16px 32px;justify-content:space-between;font-size:14px;color:var(--quiet)} .mark{flex:0 0 auto} article section{display:none;border-top:0;padding-top:0} article section.active{display:block} -body.all article section{display:block;border-top:1px solid var(--line);padding-top:34px} +body.all article section{display:block;border-top:1px solid var(--line);padding-top:40px} body.all article section:first-of-type{border-top:0;padding-top:0} .toc li a.active{background:var(--tint);color:var(--ink);font-weight:600} .toc li a.active::before{color:var(--ember)} @@ -116,8 +121,9 @@ body.all article section:first-of-type{border-top:0;padding-top:0} .pager a span{color:var(--quiet);font-family:'IBM Plex Mono',monospace;font-size:11px;letter-spacing:.12em;text-transform:uppercase} .pager a.next{margin-left:auto;text-align:right} body.all .pager{display:none} +@media (max-width:600px){.pager{flex-direction:column}.pager a{max-width:none;justify-content:space-between}.pager a.next{margin-left:0}} @media (max-width:959px){ - .toc{position:sticky;top:0;z-index:5;background:var(--ground);margin-inline:-16px;padding:10px 16px;border-bottom:1px solid var(--line)} + .toc{position:sticky;top:0;z-index:5;background:var(--ground);margin-inline:calc(-1 * var(--gutter));padding:10px var(--gutter);border-bottom:1px solid var(--line)} .toc ol{flex-direction:row;overflow-x:auto;gap:6px;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px} .toc ol::-webkit-scrollbar{display:none} .toc li a{white-space:nowrap;border:1px solid var(--line);border-radius:999px;padding:8px 12px;font-size:13px;gap:6px} @@ -182,10 +188,10 @@ body.all .pager{display:none}

Igneum is a proof-of-work blockchain mined on graphics cards, where the same cards prove every block with zero-knowledge proofs and sell proving to other chains.

It runs the Ethereum virtual machine, so anything built for Ethereum runs on Igneum unchanged. Transactions are included in about one second, proven within about a minute at launch, and locked by miners within about two. There is no premine, no pre-sale, no treasury taken from emission, no stake anywhere in consensus, and no dependence on any other chain. Mining stays open to anyone with a GPU because the mining program itself changes every hour, so there is nothing for a specialised chip to be built for. Nothing in it ever needs a human to keep it that way.

-
1 / s
blocks at launch, rising to 10
-
~60 s
to a verified proof at launch
-
0
premine, pre-sale, allocation, stake
-
100%
of emission to miners and provers
+
1 / s
blocks, rising to 10
+
~60 s
to a proof at launch
+
0
premine or stake
+
100%
to miners and provers
diff --git a/site/live.html b/site/live.html index d8917f85d..195fa5936 100644 --- a/site/live.html +++ b/site/live.html @@ -32,7 +32,10 @@ @@ -158,7 +164,7 @@ footer{border-top:1px solid var(--line);padding-block:48px 32px}
Status
OFFLINE
no observer update yet
-
Network
igneum-devnet
node
+
Network
igneum-devnet
node
Blocks / s
0.00
over 60 s
Blue score
0
0 blocks
Difficulty
0
target per block
@@ -179,7 +185,7 @@ footer{border-top:1px solid var(--line);padding-block:48px 32px} locked checkpoint, final just arrived parent edge - 2ea5116eminer short id, one lane each + 2ea5116eminer short id, one lane each
@@ -200,7 +206,7 @@ footer{border-top:1px solid var(--line);padding-block:48px 32px} -
+

Blocks per minute

last hour

Counted by the observer as blocks arrive.

@@ -248,7 +254,7 @@ footer{border-top:1px solid var(--line);padding-block:48px 32px} // formatting function $(id){return document.getElementById(id);} function compact(n){if(n===null||n===undefined||isNaN(n))return '0';var a=Math.abs(n);if(a>=1e12)return (n/1e12).toFixed(2)+'T';if(a>=1e9)return (n/1e9).toFixed(2)+'G';if(a>=1e6)return (n/1e6).toFixed(2)+'M';if(a>=1e3)return (n/1e3).toFixed(1)+'k';return String(Math.round(n));} - function hashrate(n){if(n===null||n===undefined)return 'n/a';var u=['H/s','kH/s','MH/s','GH/s','TH/s'],i=0;while(n>=1000&&i=1000&&i/g,'>');} @@ -335,7 +341,7 @@ footer{border-top:1px solid var(--line);padding-block:48px 32px} setStatus(on,s.age_s===null?'no observer update yet':'observer updated '+rel(s.age_s*1000)); $('st-network').textContent=s.network||'igneum-devnet';$('st-node').textContent=s.node_version?'node '+s.node_version:'node'; $('st-bps').textContent=(s.blocks_per_second_60s||0).toFixed(2); - $('st-blue').textContent=compact(s.blue_score);$('st-count').textContent=compact(s.block_count)+' blocks, '+compact(s.header_count)+' headers'; + $('st-blue').textContent=compact(s.blue_score);$('st-count').textContent=compact(s.block_count)+' blocks'; $('st-diff').textContent=compact(s.difficulty);$('st-hps').textContent=hashrate(s.hashes_per_second_estimate); $('st-miners').textContent=s.miners_10m;$('st-peers').textContent=s.peers===null?'0':s.peers;$('st-mempool').textContent='mempool '+(s.mempool||0); var now=new Date(d.now).getTime();