Merge master 5fd703f6 into wallet-bridge (master moved 24 commits during the landing's gate)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
commit
40be3175af
30 changed files with 649 additions and 41 deletions
1
contracts/bridge/test/vectors/.gitignore
vendored
1
contracts/bridge/test/vectors/.gitignore
vendored
|
|
@ -6,4 +6,3 @@ checkpoint-dn3.json
|
|||
weights-dn3.json
|
||||
checkpoints-dn3.json
|
||||
dn3-table.json
|
||||
dn3-account.json
|
||||
|
|
|
|||
15
contracts/bridge/test/vectors/dn3-account.json
Normal file
15
contracts/bridge/test/vectors/dn3-account.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"chain_id": "igneum-devnet-3",
|
||||
"state_root": "0x1fd551393d84009c398a9b9747cd296d0fdf1e31f85fa21c10426bc219694561",
|
||||
"block_number": 28462,
|
||||
"account": "0x085a7ca7338efaf797f3300fa7c64afa9d2c539b",
|
||||
"account_nonce": "0",
|
||||
"account_balance": "547807747463600000000",
|
||||
"account_storage_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"account_code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
|
||||
"account_proof": [
|
||||
"0xf90211a035a5663e80bde9c005c3f519613b5c3ff2add9bb9310908d4b6478ddfdd42b09a0628c3663581b1c12c36c5103080474c8f1503dc78e498e290e0ce309ee5dd580a048442259307de1a1ddc270914b19054e914a59f7ad1992c88fe9e5eeb91b91d3a0e72f8245f6bfe8fe9356e186352dc55a7f16e4eaf8bebfa8950625f0185ea699a0c8cf4b30c816ffbc8fc615de2e87ff7fe7ff384e22286b5cbb8aa29f126d2688a06819cfcddf29f3b1c72b4df680105c393217282d22439e204bfaf42eb5dfc3e0a0eafc7b7ab68e87b1574ce1c0a383b876ca03eb851e6d4074a6faa11583f8938fa0077c5575ade9c4657ef3094d44b493452279890fdd2028cbc46d7d7b260bfdf4a0f56e310ad31c53de3dd63db5823d99375f0ebed359d81efc13bc48e0fec734baa0a3a9b96516f395397fc8f86ada0e75c6b56fb56f26686b0de9b994828e7050a3a0f721a95427f32ec9105a8b6ae61ea87d68409f005eb4bb1bce08f8682de0f23aa08a09b8aba440e829c5b75680940ab07f7af7de4d5b784a7ebb4a9a55d5482686a072fed18995aede9d7cd457a87f58abb19b16d2794d7197e8808d049aa81fe4b1a058f1fadf00854cbe3d7b9fc0bdd2e38fe6c25bd944bc5b55f916c394282ba527a01e2b4f50116b9f85ef2b704b4e0858317961a715ff891e996eef10e4856c9d09a0588251a542d92fd21df94204ef0e7eb19224979273f6fa25a276ded6eca00b2080",
|
||||
"0xf8b180808080a0420981c3d36f89ff245988aee9cf67b0852aa20aac3c0dd683b6441b8325ee6680a077d4821f911305b34d67a0f25372b5102b157ed8a3bcbcca278d663f41c2740ba0ca001aa786bbd28c50b735599b74b883185be98a9ea6118b519720fbed7720b9808080a04ea6a6815f895cbcf98aab72a2db87a197fd077953c650a9d74782dd1ca064df808080a025c2908da5906b49a3da3c07e84912f3428889a96f91da09057604c4bf189ab880",
|
||||
"0xf872a0200f6ca86de6ec8bae815e435db88eb1e3ccc026af0d2049dc0299f37ac21622b84ff84d80891db25c13e886c5cc00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
||||
]
|
||||
}
|
||||
|
|
@ -15,21 +15,22 @@ What was measured today (all on igneum-build-1, the counter-asic-4 crate at 5984
|
|||
| The sound per-load shadow (one pass of a 256-instruction sub-block after every load, `mx8+shl4096x1`), the form 20.2a-close named and never drew | 234 of 256 seeds accepted within the 32-attempt cap, 0.927 rejection per candidate, mean accepted attempt 9.7; the iterated 16 x 27 form on the same seeds 76 of 256, 0.989 per candidate | measured (section 3.1) |
|
||||
| The same at class v4's instruction count (`mx8+shl2304x3`: 16 sub-blocks of 144, three passes, 55,296 shadow instructions per hash) | 224 of 256 seeds, 0.935 per candidate | measured |
|
||||
| The verifier on the sound forms, cold warp on core 40 with core 88 loaded (the ladder's method) | shl4096x1 8.28 to 8.55 ms; shl2304x3 8.44 to 8.82; class v4's shape 8.33 to 8.63 on the same core in the same minutes; all under the 10 ms gate | measured (section 3.2) |
|
||||
| The F8-form uniformity read at 2^20 nonces on 64 seeds (`v6inv-uniform`, the crate's own `trace_load_indices` in the class's execution order) | the sound forms read clean: `shl4096x1` 0 of 60 seeds over 1.2x at the top 0.1 percent of items (max 1.034x, one item at 251 reads against the control's 29 on seed 23), 0 sites under the (c''') floor of 0.995 (min 0.99707); `shl2304x3` 0 of 61 over 1.02x (max 1.0019), min site 0.99962; the raw class v4 shape drawn through the same v2/v3 rule (no (a'), no (c''): the pre-amendment class) 41 of 64 seeds over 1.2x at 7x to 36x the control, items at 350,000 to 396,564 reads, min site ratio 0.093: AP-F8-1's hot-set class, the harness's known-failed firing on real programs | measured (section 3.5) |
|
||||
| The per-load prototype's acceptance under a drawn era | 0 of 256 seeds on every per-load form: 5,536 of 7,862 bias rejections name index bit 26 or 27 "set in 0 or 16,384 of 16,384", the era WINDOW's fixed top bits, an instrument fault; so 20.2a-close's "1.4 percent accepted, 42 of 64 seeds exhaust" (run across drawn eras) measured the instrument, not the construction | measured; a correction for the research file (section 3.3) |
|
||||
| The two packs for the card row | `mx8_shl4096x1` (id 75ca9547da21b200) and `mx8_shl2304x3` (id bbfdfc1dcdda0b46), OVERALL PASS, in the hash lane's PC 1 job after the AMD grid (about 12:45 UK) | exported; the card row owed |
|
||||
| The two packs on the RTX 5090 (PC 1, the hash lane's job `run-ca4-pc1-v6-packs-5090-20261008`, 12:14 to 12:20 UK, self-test PASS and the pinned fingerprint on every row) | at class v4's own instruction count the sound per-load form (`shl2304x3`, 55,296 ops) costs the card 19 W MORE than the whole block unlocked (483.6 against 464.6 W at 135.85 against 137.62 MH/s) and 6.6 W more at the 1,300 MHz lock (303.4 against 296.8 W); per shadow instruction 19.7 pJ unlocked against the whole block's 17.2, the one-pass form (`shl4096x1`, 32,768 ops) 20.8: the per-load placement pays 15 to 20 percent more per instruction on this card, the OPPOSITE sign from the 16 x 27 v2 export's 13 to 14 W under | measured (section 3.4); the GPU column of rank 1 corrected |
|
||||
|
||||
**The ranked list of what v6 should add beyond the four** (section 4 has every column):
|
||||
|
||||
| Rank | Layer | What it does to the chip | What it costs the cards (5090 / 5070 Ti / M5 Max) | Status |
|
||||
|---|---|---|---|---|
|
||||
| 1 | **Layer 5: the shadow placed per load, one pass of a long sub-block** (the capex lever: the chip's core must sit inside every read's dependency, so controller, lanes and PHY share one N5-class die or an interposer) | energy edge unchanged (`k` is `k` whichever die the core sits on); project cost about USD 30 M to about 60 M, the break-even market cap about USD 100 M to about 200 M (the mission lane's model, modelled); capex per MH/s 3.0 to 4.3 USD (modelled) | 5090: the 16 x 27 form measured 13 to 14 W UNDER the whole block at the same instruction count (448 against 462 W unlocked; 283 against 296 at the 1,300 lock), rate within 1.2 percent; the 256 x 1 form's row in today's PC 1 job / no row, the 4070's 30 W premium at its tune point as the proxy / the 16 x 27 form -0.5 percent of rate measured; the 256 x 1 form's Metal footprint OWED | acceptance measured today (0.927 per candidate, P(exhaust at 256) about 4 x 10^-9); the sub-version 3 dataflow rule in execution order is the fix that brings it toward v4's 0.68 (gate plan, section 2.1) |
|
||||
| 1 | **Layer 5: the shadow placed per load, one pass of a long sub-block** (the capex lever: the chip's core must sit inside every read's dependency, so controller, lanes and PHY share one N5-class die or an interposer) | energy edge unchanged (`k` is `k` whichever die the core sits on); project cost about USD 30 M to about 60 M, the break-even market cap about USD 100 M to about 200 M (the mission lane's model, modelled); capex per MH/s 3.0 to 4.3 USD (modelled) | 5090: the sound form at class v4's instruction count measured +19 W (4 percent) unlocked and +6.6 W (2 percent) at the 1,300 lock against the whole block, rate -1.3 percent, 15 to 20 percent more per shadow instruction (PC 1, 12:1x UK) / no row, the 4070's 30 W premium at its tune point as the proxy / the 16 x 27 form -0.5 percent of rate measured; the sound form's Metal footprint OWED | acceptance measured today (0.927 per candidate, P(exhaust at 256) about 4 x 10^-9); the sub-version 3 dataflow rule in execution order is the fix that brings it toward v4's 0.68 (gate plan, section 2.1) |
|
||||
| 2 | **Layer 6: register-file width drawn per era (8 to 32 registers per lane)**, the link tax on layer 5 | with layer 5, the lane state crossing the controller twice per read grows from 64 B to 128 to 256 B: 2.2 to 9 TB/s of die-to-die traffic at the 5090's read rate, past any one-stack interposer, which closes the "or an interposer" branch and forces the single N5 die (modelled); alone, nothing | 0 rate on every card while latency-bound (a GPU lane holds up to 255 registers; 7,262 lanes x 256 B is 1.9 MB against the 5090's 43 MB of register file, approximate); the verifier's register-major arrays 4x (unmeasured, under 0.1 ms by the op law); no pack form today (the register count is a generator constant) | modelled; the pack form is a generator change with its own census (gate plan) |
|
||||
| 3 | **Layer 7: warp-uniform data-dependent block selection** (which of B shadow sub-blocks runs next is chosen by a warp-reduced register value, uniform across the 32 lanes, so no divergence) | nothing for the GPU-like chip (a sequencer already); an FPGA overlay or a fixed pipeline must hold all B blocks for one block's throughput: B x the shadow's LUT area (approximate); shortens a per-epoch bitstream's worth | one uniform indirect branch per iteration: about 0 (the `sel` register already does this for the immediates); verifier 0 | modelled; a generator change behind a pack (gate plan); rank 3 because it moves the FPGA lane only |
|
||||
| 4 | **The reserve ordered by hardware orthogonality** (layer 3 as it stands, with the order fixed: shuffle-crossbar families, then byte-permute, then popcount and priority encoder, the int8 tile last) | a chip pre-wires every family for about USD 4 of N5 (modelled); the order makes the first unlocks the ones a 12-op datapath lacks most | 0 at 4 points (measured step costs under 1 percent of ALU time on every vendor) | an ordering rule inside layer 3, not a new layer; the history's addition 6 |
|
||||
|
||||
Rejected with the number, each in section 2: per-lane data-dependent branches (divergence costs the card, a chip nothing); reads tied to the shard proof per block (a refresh per block is 0.3 to 1 W on a chip, 1.3 percent of a 4090's hash time); randomised memory topology (a chip's address decoder permutes its lines for nothing; the stride and interleave are already drawn); the VRAM-size ratchet as a lever (a chip buys 24 to 32 GB that the 8, 12 and 16 GB tiers cannot: it retires cards first); proof-carrying hashes sampled by the pool (the chip holds everything the witness proves); prover-gated eligibility (proving is 1.6 kW network-wide at any hash rate, 0.7 percent of the hash's energy at 100 GH/s); time-locked parameter commitments beyond the era VDF (the drawn band is firmware; the 2-hour lead already denies the fixed chip 180 days); a fraction of reads derived from the cache (the 5090 loses about 30 percent of rate, the chip 7 percent of energy); row-straddling reads (the w64 regime, 47 percent of the 5090's rate); a refresh per block (dead by arithmetic, the research file's row 7).
|
||||
|
||||
Per tier, in one line each: a home miner on any card sees no change from anything here today (nothing ships; the devnet pays nothing); the 5090 tier's one number is that the per-load placement costs it LESS than class v4's whole block at the same work (13 to 14 W measured on the 16 x 27 form, the 256 x 1 form's row due about 12:45 UK); the 5070 Ti has no measured row in this lane (the 4070's rows are the proxy, approximate); the Apple tier's open question is the inline footprint of a 4,096-line block per iteration (the 1,024-line block cost the M5 Max 17 percent on 6 October, measured), which decides whether rank 1 needs a block-shape cap for Apple; a pool user sees nothing; a node verifies the per-load forms in the same 8.3 to 8.8 ms as class v4 (measured); a chip maker sees its project forced onto one advanced die by rank 1 and its interposer escape closed by rank 2.
|
||||
Per tier, in one line each: a home miner on any card sees no change from anything here today (nothing ships; the devnet pays nothing); the 5090 tier's one number is that the sound per-load placement costs it 4 percent more watts than class v4's whole block at the same work unlocked and 2 percent at the knee (19 and 6.6 W, measured 12:1x UK; the dead 16 x 27 form had read the other way); the 5070 Ti has no measured row in this lane (the 4070's rows are the proxy, approximate); the Apple tier's open question is the inline footprint of a 4,096-line block per iteration (the 1,024-line block cost the M5 Max 17 percent on 6 October, measured), which decides whether rank 1 needs a block-shape cap for Apple; a pool user sees nothing; a node verifies the per-load forms in the same 8.3 to 8.8 ms as class v4 (measured); a chip maker sees its project forced onto one advanced die by rank 1 and its interposer escape closed by rank 2.
|
||||
|
||||
## 1. The frame, and what a candidate must do
|
||||
|
||||
|
|
@ -66,13 +67,13 @@ Chip row:
|
|||
|---|---|---|
|
||||
| A fixed-function chip's `k` | unchanged (the work is the same ALU mix); its capex: the controller cannot be a 28 nm part with the core elsewhere, so the project moves from USD 5 M (no core) or 30 M (a core on its own die) to about 60 M (one N5-class die or a 2.5D package); break-even cap about USD 200 M in years 1 to 2 (s = 0.30) against about 100 M | modelled (16.2, the mission lane's N3 single-die row; a GDDR7 PHY on N5 is unpriced) |
|
||||
| A GPU-like chip's per-joule edge | unchanged: 2.1x at `k = 1`, 3.5x at `k = 0.3` at the knee; its capex per MH/s 3.0 to 4.3 USD against 2.8 | modelled |
|
||||
| RTX 5090 | the 16 x 27 v2 export: 135.90 MH/s at 448.3 W unlocked against the whole block's 137.51 at 462.2 (the premium 137 against 151 W, -14 W); at the 1,300 lock 126.04 at 282.9 against 126.93 at 295.8 (-13 W); the 256 x 1 and 144 x 3 forms in today's PC 1 job (the hash lane, after the AMD grid, about 12:45 UK) | measured (research file 20.3); the sound forms' rows owed |
|
||||
| RTX 5090 | the sound forms (PC 1, 12:14 to 12:20 UK): `shl2304x3` (class v4's count) 135.85 MH/s at 483.6 W unlocked against the whole block's 137.62 at 464.6 (+19 W, -1.3 percent of rate; the premium over mx8 1.09 against 0.95 microjoules), at the 1,300 lock 125.88 at 303.4 against 126.99 at 296.8 (+6.6 W; 0.72 against 0.66 microjoules); `shl4096x1` (59 percent of the count) 135.99 at 428.6 W unlocked and 126.08 at 271.8 locked (0.68 and 0.47 microjoules over mx8). Per shadow instruction: 19.7 and 20.8 pJ unlocked against the whole block's 17.2, so the placement costs this card 15 to 20 percent more per instruction. The 16 x 27 v2 export (dead as a class) had read 13 to 14 W UNDER the whole block; the sign reverses on the sound form, which is the number the row carries | measured (the hash lane's job; the mx8 control 137.65 at 312.2 W and 127.39 at 212.6) |
|
||||
| RTX 5070 Ti | no row (no card in this lane); the 4070's class v4 premium at its tune point, 30 W for no rate, less the block effect, is the proxy | approximate |
|
||||
| Apple M5 Max | the 16 x 27 v2 export 26.88 MH/s against 27.01 (-0.5 percent, Metal packbench, 7 October); the 256 x 1 form's inline text is 4,096 shadow lines per iteration where the 1,024-line block cost the M5 Max 17 percent (6 October, measured), so its footprint is the open Apple number: OWED (a Mac measurement under the measure lock, which this lane does not run; the hash lane's or the shipper's Metal row) | measured for 16 x 27; the sound form's row owed |
|
||||
| The verifier | 8.28 to 8.55 ms cold with the sibling loaded (256 x 1), 8.44 to 8.82 (144 x 3), against class v4's 8.33 to 8.63 on the same core in the same minutes; the acceptance's dynamic test 35 ms per candidate (1,111 ms for 32), 13.7 candidates per seed on average: about 0.5 s of one core per epoch | measured (section 3.2) |
|
||||
| The acceptance | 0.927 per candidate (256 x 1), P(256 consecutive rejections) 0.927^256 about 4 x 10^-9 per seed; class v4 sub-version 3 reads 0.681 and 2 x 10^-43; the gap is the missing dataflow rule (the per-load class is not the class v4 shape, so (a'), (c') and (c'') do not run on it; the value-level bias test catches the same population: 1,563 of 2,329 bias rejections name index bit 0 at a one-count near 4,096 or 12,288 of 16,384, the product's low-bit law) | measured (section 3.1) |
|
||||
|
||||
Verdict: KEEP as layer 5, the first thing v6 adds beyond the four, because it is the only mechanism found that moves the project cost, it costs the 5090 less than class v4's own block (measured on the 16 x 27 form; the sound form's row today), and its acceptance is now a measured 0.927 with a named fix (the sub-version 3 dataflow fixpoint run over the real execution order, base and sub-blocks interleaved, as the generator's draw rule) that the research file's 20.2 already asked for. What it does not do: move the energy identity by one joule. The founder's "useless as soon as it dropped" is layer 1's and 3's sentence; layer 5's sentence is "the chip that can be built costs twice as much to start".
|
||||
Verdict: KEEP as layer 5, the first thing v6 adds beyond the four, because it is the only mechanism found that moves the project cost (about 2x on the mission lane's model) against a measured cost to the 5090 of 4 percent more watts at the same work unlocked (19 W) and 2 percent at the knee (6.6 W), 1.3 percent of rate: the rule of this file (keep what raises the chip's capex more than every GPU tier's cost) holds by 2x against 2 to 4 percent, but the honest line is that the card pays, not saves, and the Apple footprint is still unread; its acceptance is now a measured 0.927 with a named fix (the sub-version 3 dataflow fixpoint run over the real execution order, base and sub-blocks interleaved, as the generator's draw rule) that the research file's 20.2 already asked for. What it does not do: move the energy identity by one joule. The founder's "useless as soon as it dropped" is layer 1's and 3's sentence; layer 5's sentence is "the chip that can be built costs twice as much to start".
|
||||
|
||||
### 2.2 Layer 6: the register-file width drawn per era, the link tax on layer 5 (KEEP, rank 2)
|
||||
|
||||
|
|
@ -198,15 +199,36 @@ The per-load forms verify in class v4's time within the run's noise (the same in
|
|||
|
||||
The same 2,816 rows with `--era igneum-era-test/<seed mod 16>` (`ERA=era`): every per-load form 0 of 256 seeds accepted, 8,192 candidates per form, rejection 1.000; the class v4 shape 256 of 256. Of the 256 x 1 form's 7,862 bias rejections, 5,536 name index bit 26 or 27 "set in 0 of 16,384" or "set in 16,384 of 16,384" at a load site, which is the era's working-set window (spec 1.13.1: `k_off = below(3)` per site puts the site on the whole dataset, a half or a quarter by fixing the top `k` bits of the index to the drawn offset `o`); the prototype's `BiasedIndexBit` test loops bits 0 to 27 and does not exclude bits at or above `28 - k_off_s`, so under any era it refuses every program with a half- or quarter-window site, which is nearly every program. The research file's 20.2a-close ("the 16 x 27 per-load class accepts 22 of 1,621 candidates over 64 seeds, 1.4 percent; 42 of 64 seeds exhaust the chain's 32 attempts") was read across drawn eras and therefore measured the instrument on most of its rows; the no-era census above is the construction's own figure (the 16 x 27 form 0.989 per candidate, 76 of 256 seeds accepted, which still fails the test of 2.1 and keeps that form dead). Owed to the research file (the Counter ASIC coordinator): the instrument fix (skip the window bits per site) and the 20.2a-close figures re-read with it; neither is made this week by this lane, which changes no code in the crate.
|
||||
|
||||
### 3.5 The uniformity read (`tools/attack/v6-invention/uniform`, 11:5x to 12:0x UK; 64 seeds `igneum-v6inv/0..63`, the first accepted candidate of each, 2^20 nonces, every load's index through the library's `trace_load_indices` on the closed-form dataset at 2^28 words, no era; per site the distinct-index ratio `d_s / E_s` at N = 2^23 evaluations, the cross-hash item histogram's top 0.1 percent share against a uniform SplitMix64 control of the same read count; logs `docs/analysis/class-v6/logs/uniform-*.tsv`)
|
||||
|
||||
| Form | Seeds read (exhausted at the 32 cap) | Min site ratio: min / median / max | Sites under 0.995 (the (c''') floor) | Top 0.1 percent share against the control: min / median / max | Seeds over 1.2x | Heaviest item, reads (the control's max 29) | Reading |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| `mx8+sh256x27`, drawn through the v2/v3 rule only (the crate's `accept` on this spelling runs no (a'), (c') or (c''): the class v4 shape BEFORE sub-version 3) | 64 (0) | 0.093 / 0.540 / 1.00008 | 60 | 0.999 / 7.42 / 36.3 | 41 | 396,564 (seed 39, site 13), 358,161, 350,025 | AP-F8-1's class seen whole: the value-level hot sets the dataflow rule and the floor were added for; the harness's known-failed case fired on real programs, which is what makes the two rows below a reading |
|
||||
| **`mx8+shl4096x1`** (16 x 256 x 1, the sound form) | 60 (4) | 0.99707 / 1.00009 / 1.00013 | 0 | 0.9984 / 1.0003 / 1.0339 | 0 (1 over 1.02x) | 251 (seed 23, site 13; 8.7x the control's max, 0.0002 percent of the reads) | clean on 59 of 60 at the F8 line; one mild hot item on seed 23 that the 0.995 floor admits (0.99707) and the top-0.1-percent share reads at 1.034x: the residual class of the in-house pass (a few-item concentration under the floor's resolution, about 1.0004x to a chip there, under 1.002x here) |
|
||||
| **`mx8+shl2304x3`** (16 x 144 x 3, class v4's instruction count) | 61 (3) | 0.99962 / 1.00009 / 1.00013 | 0 | 0.9984 / 1.0002 / 1.0019 | 0 (0 over 1.02x) | 31 | clean on every seed read: the uniform control's own figures |
|
||||
|
||||
What the three rows say together: the per-load forms, with their draw's redraw rule (a sub-block writer of the next load's source never a product or an `or`) and the value-level bias test, read as clean at 2^20 as the uniform control on 119 of 121 seeds, where the raw class v4 shape through the same rule reads hot on 41 of 64; the chain's class v4 sub-version 3 (the dataflow fixpoint and the (c'') floor) read 60 of 64 under 1.2x on F8's census at 2^24. So the two per-load tests are at least as strong as sub-version 3's on this read, at the price of the 0.93 rejection of 3.1; and the dataflow rule in execution order, when it lands, is expected to move the rejection down and the uniformity not at all. Owed: the same read under drawn eras on the fixed instrument (the research lane's commit), and at 2^24 on the four seeds nearest the line (23, 29, 49 and the first exhausted).
|
||||
|
||||
The box record, stated because it cost the network something: the 24-thread run of this harness on build-1 took 30.8 to 31.7 GB resident (16 hash sets of 2^20 indices and two 2^24-bucket histograms per thread, about 1.2 GB per thread) and the kernel's OOM killer ended its second and third forms at 11:58 and 11:59 UK; the same pressure killed the Devnet 3 seed and node1-dn3 on build-1 in that window (the build-server lane's read, 12:0x UK). The lease holds cores, not memory; the rerun was 8 threads (about 10 GB, released after 684 s with 0 kills); every further run of this lane names its resident memory in the lease label and goes to build-4 (88 GB free at 12:0x UK), never the seed box. The build-server lane carries the memory rule for the lease tool and the hands' `oom_score_adj`.
|
||||
|
||||
### 3.4 The packs
|
||||
|
||||
`igneum-pow export --seed igneum-genesis --day 2026-10-03 --class <form> --out <dir>` on build-1: `mx8_shl4096x1` (attempt 7, id 75ca9547da21b200, OVERALL PASS, kernel.cu 245,267 bytes, 4,308 lines) and `mx8_shl2304x3` (attempt 8, id bbfdfc1dcdda0b46, OVERALL PASS, kernel.cu 142,010 bytes, 2,516 lines), under `/srv/builds/v6-invention/packs/`, tarred as `v6inv-perload-packs.tgz` (sha256 ca1986b7fc5fab20a643fc37151a55e01f91edbfacc6f1a22a7384ae87cc11bc). Handed to the hash lane at 11:1x UK, taken into its v6 PC 1 job (the 5090 alone, the packs beside today's class v3 x8 and x16, the two re-weighted shadow packs, and the controls `mx8-genesis` and `mx8_sh256x27`; self-test, the 2^24 fingerprint, MH/s and W unlocked and at the 1,300 MHz lock), queued after the AMD grid, publish about 12:00 UK, close about 12:45 UK. Nothing of the packs' output goes to a served page or the spec.
|
||||
`igneum-pow export --seed igneum-genesis --day 2026-10-03 --class <form> --out <dir>` on build-1: `mx8_shl4096x1` (attempt 7, id 75ca9547da21b200, OVERALL PASS, kernel.cu 245,267 bytes, 4,308 lines) and `mx8_shl2304x3` (attempt 8, id bbfdfc1dcdda0b46, OVERALL PASS, kernel.cu 142,010 bytes, 2,516 lines), under `/srv/builds/v6-invention/packs/`, tarred as `v6inv-perload-packs.tgz` (sha256 ca1986b7fc5fab20a643fc37151a55e01f91edbfacc6f1a22a7384ae87cc11bc). Handed to the hash lane at 11:1x UK and run in its job `run-ca4-pc1-v6-packs-5090-20261008` (PC 1, the RTX 5090 alone, 12:14 to 12:20 UK, 250 batches of 2^24 per row, nvidia-smi at 1 Hz, the helper's cleared lock sequence; self-test PASS and the pinned fingerprint on every row: `shl4096x1` 180edd33ae32a4ae, `shl2304x3` a209664a9b3b7bf1; raw rows `node tools/jobs.mjs run-ca4-pc1-v6-packs-5090-20261008 --all`). Nothing of the packs' output goes to a served page or the spec.
|
||||
|
||||
| Pack | Shadow instructions per hash | Unlocked (2,842 to 2,865 MHz): MH/s / W / MH per W | Over mx8, unlocked | At the 1,300 MHz lock: MH/s / W / MH per W | Over mx8, locked | pJ per shadow instruction, unlocked / locked |
|
||||
|---|---|---|---|---|---|---|
|
||||
| `mx8-genesis` (class v3, the control) | 0 | 137.65 / 312.2 / 0.441 | | 127.39 / 212.6 / 0.599 | | |
|
||||
| `mx8_sh256x27` (class v4's shape, the whole block) | 55,296 | 137.62 / 464.6 / 0.296 | 152.4 W, 0.95 microjoules | 126.99 / 296.8 / 0.428 | 84.2 W, 0.66 | 17.2 / 12.0 |
|
||||
| **`mx8_shl2304x3`** (the sound per-load form at class v4's count) | 55,296 | 135.85 / 483.6 / 0.281 | 171.4 W, 1.09 | 125.88 / 303.4 / 0.415 | 90.8 W, 0.72 | 19.7 / 13.0 |
|
||||
| **`mx8_shl4096x1`** (one pass of 256 per load) | 32,768 | 135.99 / 428.6 / 0.317 | 116.4 W, 0.68 | 126.08 / 271.8 / 0.464 | 59.2 W, 0.47 | 20.8 / 14.3 |
|
||||
|
||||
What the rows say: on this card the per-load placement pays 15 to 20 percent more per shadow instruction than the whole block at either state (19.7 to 20.8 pJ against 17.2 unlocked; 13.0 to 14.3 against 12.0 locked), with the rate 1.1 to 1.3 percent under the whole block's. The 16 x 27 v2 export's 13 to 14 W saving (research file 20.3) does not carry to the sound form; that export was a 16-instruction block iterated 27 times, a loop the compiler keeps in registers, where the sound form is a 144- or 256-instruction straight segment per load. The chip side does not move with any of this (`k` is the chip's cost per op over the card's at the same work), so the column that changes is the honest card's: layer 5 costs a 5090 19 W unlocked and 6.6 W at the knee over class v4 for the project-cost doubling it buys.
|
||||
|
||||
## 4. The ranked list, every column
|
||||
|
||||
| Rank | Layer | Door (section 1) | Chip: fixed-function `k` / capex | Chip: GPU-like per-joule edge | Cost: RTX 5090 | Cost: RTX 5070 Ti | Cost: Apple M5 Max | Verifier | Harness state |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| 1 | Layer 5: the shadow per load, one pass of a long sub-block | capex and project (door 2) | `k` unchanged; project about USD 60 M against 30 M, cap about 200 M against 100 M (modelled); capex 3.0 to 4.3 USD per MH/s | unchanged (2.1x at `k = 1`) | -13 to -14 W against class v4's block at the same work (16 x 27 form, measured); the sound forms' rows in today's PC 1 job | no row; the 4070's 30 W premium as the proxy (approximate) | -0.5 percent (16 x 27 form, measured); the 4,096-line footprint OWED | 8.28 to 8.82 ms loaded (measured) | acceptance 0.927 measured; the dataflow rule in execution order is the fix (gate plan) |
|
||||
| 1 | Layer 5: the shadow per load, one pass of a long sub-block | capex and project (door 2) | `k` unchanged; project about USD 60 M against 30 M, cap about 200 M against 100 M (modelled); capex 3.0 to 4.3 USD per MH/s | unchanged (2.1x at `k = 1`) | +19 W unlocked, +6.6 W at the knee against class v4's block at the same work, -1.3 percent of rate (the sound form, measured) | no row; the 4070's 30 W premium as the proxy (approximate) | -0.5 percent (16 x 27 form, measured); the 4,096-line footprint OWED | 8.28 to 8.82 ms loaded (measured) | acceptance 0.927 measured; the dataflow rule in execution order is the fix (gate plan) |
|
||||
| 2 | Layer 6: the register-file width drawn per era | capex (door 2), with layer 5 | closes the interposer branch: 4.5 to 9 TB/s of die-to-die traffic (modelled, approximate link figures) | unchanged | about 0 rate (occupancy arithmetic, approximate; the pack measures it) | the same | the same | 4x the register arrays, cost per op unchanged (modelled) | no pack form; a generator constant (gate plan) |
|
||||
| 3 | Layer 7: warp-uniform block selection | life of a bitstream (door 3, the FPGA lane) | B x the shadow's area for a fixed pipeline or an overlay (approximate) | unchanged | about 0 (one uniform branch and 40 shuffles per hash: 0.3 percent of `F`) | the same | the compile footprint caps B (the 1,024-line block cost 17 percent, measured) | B x the dynamic test per candidate | no pack form (gate plan) |
|
||||
| 4 | The reserve's order | life of fixed silicon (door 3) | USD 4 pre-wired | unchanged | under 1 percent at 4 points (measured steps) | the same | the same | 0 | layer 3's gate |
|
||||
|
|
@ -218,7 +240,7 @@ What the list does not contain, and why it is honest to say so: no candidate mov
|
|||
| Tier | What this file means today | What is being done |
|
||||
|---|---|---|
|
||||
| A home miner, one 8, 12 or 16 GB card, any vendor, any OS | nothing changes: no layer here ships this week, no class moves, the devnet pays nothing; if rank 1 lands in v6 the card runs the same shadow work in a different place at the same or lower watts (the 16 x 27 form's measured 13 to 14 W under the whole block on a 5090; a 4070-class card's premium at its tune point is 30 W today, measured) | the sound forms' 5090 rows today; a small-card row (the 4070) by job when the hash lane's queue allows |
|
||||
| One 24 or 32 GB card (5090 class) | the measured rows of section 3; the per-load placement is cheaper for this card than class v4's block at the same work | the PC 1 job, about 12:45 UK |
|
||||
| One 24 or 32 GB card (5090 class) | the measured rows of section 3; the sound per-load placement costs this card 2 to 4 percent more watts than class v4's block at the same work and 1.3 percent of rate; a 5090 owner under layer 5 at the knee pays about 7 W more than under class v4 | the rows are in; the knee tune (rank 1 of the research file) is the lever that pays for it |
|
||||
| RTX 5070 Ti | no card in the project; every row is the 4070's or the 5090's scaled, approximate; the hash lane's default (the stock pair plus the 5090's lock slope) stands | stated as approximate wherever it appears |
|
||||
| Apple (M-series) | the one open number: the inline footprint of a 4,096-line per-load block (the 1,024-line block cost 17 percent on 6 October); if it costs rate, rank 1 takes a block-shape cap for the Apple tier (144 x 3 at 2,516 lines, or a 64-instruction sub-block form) and the synthesis says so | a Metal packbench row under the measure lock by the lane that runs the Mac (not this one) |
|
||||
| A rig | watts per card as the 5090 row; a rig's bill under rank 1 is at or under class v4's | the same rows |
|
||||
|
|
@ -241,7 +263,8 @@ Hours: the dataflow rule in execution order 2 to 3 (the research file's own esti
|
|||
|
||||
## 7. Unverified and owed
|
||||
|
||||
- The sound forms' card rows (the 5090 today through the hash lane; the 4070 and the 9070 XT later; the M5 Max footprint by the lane that runs the Mac).
|
||||
- The uniformity read under drawn eras (the fixed instrument's commit), and at 2^24 on the seeds nearest the line.
|
||||
- The sound forms' card rows on the 4070 and the 9070 XT (the 5090 rows are in, section 3.4); the M5 Max footprint by the lane that runs the Mac.
|
||||
- The 16 x 432 x 1 form itself: bracketed by the 256 x 1 and 144 x 3 rows (0.927 and 0.935) and the flat ladder between 36 and 256; not drawn (the cap).
|
||||
- The instrument fix (the window bits) and the re-read of 20.2a-close: owed to the research file's owner, not made here.
|
||||
- The bits 26 and 27 mild bias (502 rejections at one-counts 7,168 to 7,680 of 16,384): unattributed; a trace of the site's source writers is the next read.
|
||||
|
|
|
|||
65
docs/analysis/class-v6/logs/uniform-mx8_sh256x27.tsv
Normal file
65
docs/analysis/class-v6/logs/uniform-mx8_sh256x27.tsv
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
class seed attempt program_id min_site_ratio min_site top0.1_share control_share ratio_to_control max_item_reads max_item control_max reads
|
||||
mx8+sh256x27 6 0 59f94dd9f119f1fe 0.19558 0 0.047505 0.002380 19.9617 254982 0 28 134217728
|
||||
mx8+sh256x27 1 0 75bf2c3f1f939ece 0.10129 2 0.069935 0.002381 29.3675 350025 0 27 134217728
|
||||
mx8+sh256x27 5 0 c7f73fa4e574a061 0.53753 10 0.018618 0.002379 7.8267 7874 0 28 134217728
|
||||
mx8+sh256x27 7 0 b10475207fb37f74 0.99256 15 0.002381 0.002379 1.0010 29 0 27 134217728
|
||||
mx8+sh256x27 3 0 c57665eab7c1b1ca 0.53024 4 0.017687 0.002380 7.4310 8484 0 28 134217728
|
||||
mx8+sh256x27 0 0 6ba933a7c9b4ddfb 0.53044 15 0.017678 0.002382 7.4199 8504 0 27 134217728
|
||||
mx8+sh256x27 4 0 541c9fc000f62049 0.53755 9 0.017245 0.002377 7.2540 7992 0 29 134217728
|
||||
mx8+sh256x27 2 0 65a3d11943181bec 0.59118 9 0.017105 0.002380 7.1879 7946 0 29 134217728
|
||||
mx8+sh256x27 8 0 c515313506cf6f92 0.53023 13 0.034130 0.002379 14.3473 16662 0 27 134217728
|
||||
mx8+sh256x27 11 0 ce2a79324e8c7863 0.53030 9 0.017686 0.002382 7.4249 8253 0 27 134217728
|
||||
mx8+sh256x27 9 0 98e518813fca319f 0.99988 0 0.002381 0.002380 1.0004 27 0 28 134217728
|
||||
mx8+sh256x27 10 0 3dc9fa7d63f5bf7b 0.98508 9 0.002439 0.002381 1.0241 28 0 27 134217728
|
||||
mx8+sh256x27 15 0 48e40802a9edccd4 0.11667 11 0.053312 0.002380 22.3999 335722 0 27 134217728
|
||||
mx8+sh256x27 13 0 1755e3a1545277d5 0.53742 11 0.033744 0.002383 14.1628 16366 0 27 134217728
|
||||
mx8+sh256x27 14 0 42db57cf012bb876 1.00008 13 0.002379 0.002382 0.9990 27 0 27 134217728
|
||||
mx8+sh256x27 12 0 4740b9f1d6099328 0.56249 15 0.017509 0.002381 7.3529 8319 0 27 134217728
|
||||
mx8+sh256x27 16 0 a428c1329e456049 0.10229 3 0.053492 0.002381 22.4632 340535 0 27 134217728
|
||||
mx8+sh256x27 17 0 60b7eec3d4fa3ca5 0.10127 9 0.069958 0.002380 29.3995 348315 0 27 134217728
|
||||
mx8+sh256x27 18 0 65ac09f5691a9434 0.53030 7 0.050022 0.002381 21.0123 24414 0 27 134217728
|
||||
mx8+sh256x27 22 0 6d21392be96440d5 0.99255 14 0.002380 0.002382 0.9993 27 0 27 134217728
|
||||
mx8+sh256x27 19 0 b66d73c9923a1980 0.53024 0 0.025273 0.002381 10.6155 8567 0 27 134217728
|
||||
mx8+sh256x27 20 0 2a697583a62fc7c3 0.97219 1 0.002385 0.002378 1.0028 26 0 27 134217728
|
||||
mx8+sh256x27 23 0 011448f4c45c2b57 0.99264 14 0.002382 0.002378 1.0018 29 0 28 134217728
|
||||
mx8+sh256x27 21 0 7d95136e82c75b3a 0.99185 6 0.002423 0.002382 1.0171 31 0 28 134217728
|
||||
mx8+sh256x27 24 0 3a06ce07234c1926 0.61005 11 0.013259 0.002380 5.5714 3665 0 28 134217728
|
||||
mx8+sh256x27 25 0 863696571362ecd9 0.19009 1 0.045627 0.002381 19.1663 195471 0 26 134217728
|
||||
mx8+sh256x27 26 0 f90e6a19f77e1ad3 0.11049 4 0.068859 0.002380 28.9316 314307 0 26 134217728
|
||||
mx8+sh256x27 29 0 197bb9f218a5c204 0.53057 9 0.017687 0.002379 7.4340 8315 0 27 134217728
|
||||
mx8+sh256x27 28 0 55f1cea0e6dc5b6b 0.53019 14 0.017679 0.002380 7.4295 8483 0 28 134217728
|
||||
mx8+sh256x27 27 0 57195f71a76b1bc7 0.98675 11 0.002383 0.002381 1.0007 29 0 26 134217728
|
||||
mx8+sh256x27 30 0 cde8e1f729e42daa 0.99258 13 0.002380 0.002381 0.9997 26 0 27 134217728
|
||||
mx8+sh256x27 31 0 4a3435feb3302d75 0.99266 8 0.002385 0.002382 1.0014 27 0 28 134217728
|
||||
mx8+sh256x27 32 0 15272ee7eb43378f 0.59034 4 0.014170 0.002379 5.9559 3755 0 28 134217728
|
||||
mx8+sh256x27 34 0 83d02ec262f3d5c5 0.53038 6 0.017663 0.002381 7.4181 8436 0 27 134217728
|
||||
mx8+sh256x27 33 0 5181fb017cc2feb2 0.99255 1 0.002401 0.002381 1.0088 27 0 28 134217728
|
||||
mx8+sh256x27 35 0 1b13044909e7a39b 0.53031 10 0.017688 0.002381 7.4286 8329 0 28 134217728
|
||||
mx8+sh256x27 37 0 2cfccfd3f29d49fc 0.53055 0 0.017729 0.002380 7.4483 8853 0 27 134217728
|
||||
mx8+sh256x27 38 0 d22450bfb6dc253c 0.99252 8 0.002395 0.002380 1.0063 29 0 27 134217728
|
||||
mx8+sh256x27 36 0 af7b63ce492a2184 0.52959 0 0.066383 0.002380 27.8905 33258 0 28 134217728
|
||||
mx8+sh256x27 39 0 7b3432ca80bb9b1a 0.09324 13 0.070846 0.002382 29.7419 396564 0 27 134217728
|
||||
mx8+sh256x27 41 1 b9d2760ddf67bed5 0.52890 1 0.050664 0.002383 21.2621 25481 0 27 134217728
|
||||
mx8+sh256x27 40 0 c5bbcc04fdbb3aaf 0.53017 5 0.017678 0.002381 7.4233 8264 0 27 134217728
|
||||
mx8+sh256x27 42 0 cd5ae1b7ab486cc8 0.58490 3 0.017253 0.002381 7.2468 7891 0 26 134217728
|
||||
mx8+sh256x27 43 0 aecb18472317e5f9 0.55918 5 0.032408 0.002381 13.6094 14867 0 27 134217728
|
||||
mx8+sh256x27 44 0 109f7b7924e25cea 1.00005 5 0.002382 0.002381 1.0004 26 0 27 134217728
|
||||
mx8+sh256x27 45 0 e93b531865ca58fb 0.53045 15 0.034130 0.002382 14.3280 16632 0 26 134217728
|
||||
mx8+sh256x27 46 0 0cc0e896058fca29 0.99254 4 0.002380 0.002381 0.9997 28 0 28 134217728
|
||||
mx8+sh256x27 47 0 1b1fb9e84a44dc2d 0.53017 14 0.034008 0.002378 14.2984 16999 0 28 134217728
|
||||
mx8+sh256x27 48 0 18a179054742e758 0.54001 0 0.017140 0.002381 7.1981 7732 0 28 134217728
|
||||
mx8+sh256x27 49 0 1fde2a7f6b5eedb7 0.10130 10 0.086438 0.002381 36.3106 358161 0 27 134217728
|
||||
mx8+sh256x27 51 0 e03ce538897560a6 0.50444 7 0.019046 0.002378 8.0084 10546 0 27 134217728
|
||||
mx8+sh256x27 50 0 9488018a92e64c11 0.56237 6 0.017550 0.002379 7.3765 8328 0 27 134217728
|
||||
mx8+sh256x27 52 0 0cfebad92d81f64e 0.53030 4 0.034105 0.002379 14.3331 17053 0 28 134217728
|
||||
mx8+sh256x27 54 0 440fb6a7918bdfc0 0.99043 2 0.002382 0.002380 1.0009 32 0 26 134217728
|
||||
mx8+sh256x27 53 0 faf0fae7e7e3c233 0.99255 14 0.002388 0.002380 1.0032 28 0 27 134217728
|
||||
mx8+sh256x27 55 0 84b4a4fc055bb2e0 0.99899 8 0.002385 0.002380 1.0023 27 0 27 134217728
|
||||
mx8+sh256x27 56 0 272cd6667284d2f6 0.53068 11 0.017680 0.002381 7.4252 8579 0 28 134217728
|
||||
mx8+sh256x27 57 0 0fb23f439801b9b9 0.91309 14 0.002407 0.002382 1.0106 32 0 27 134217728
|
||||
mx8+sh256x27 58 0 c6d31831662f6e35 0.53039 3 0.050358 0.002380 21.1548 24908 0 26 134217728
|
||||
mx8+sh256x27 59 0 e8da19c8686961d7 0.99259 2 0.002385 0.002381 1.0015 27 0 27 134217728
|
||||
mx8+sh256x27 60 1 fc150b874c1c2b26 0.56227 14 0.017555 0.002380 7.3761 8355 0 26 134217728
|
||||
mx8+sh256x27 62 0 c205732373fc4eac 0.96813 9 0.002381 0.002380 1.0004 27 0 27 134217728
|
||||
mx8+sh256x27 63 0 d5e897d32c12e13a 0.98843 4 0.002550 0.002381 1.0711 72 0 26 134217728
|
||||
mx8+sh256x27 61 1 4333461849082c5a 0.99257 8 0.002401 0.002383 1.0076 31 0 29 134217728
|
||||
|
65
docs/analysis/class-v6/logs/uniform-mx8_shl2304x3.tsv
Normal file
65
docs/analysis/class-v6/logs/uniform-mx8_shl2304x3.tsv
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
class seed attempt program_id min_site_ratio min_site top0.1_share control_share ratio_to_control max_item_reads max_item control_max reads
|
||||
mx8+shl2304x3 6 1 9527b9571efc012e 1.00008 7 0.002381 0.002380 1.0007 28 0 28 134217728
|
||||
mx8+shl2304x3 4 11 84944416dac88d57 1.00006 6 0.002382 0.002377 1.0019 29 0 29 134217728
|
||||
mx8+shl2304x3 5 11 1b8ee7a3a1131c03 1.00006 7 0.002379 0.002379 1.0003 27 0 28 134217728
|
||||
mx8+shl2304x3 0 31 a820f7ddd35c02d1 1.00013 14 0.002379 0.002382 0.9984 27 0 27 134217728
|
||||
mx8+shl2304x3 2 0 e61f5dca9abc62d3 1.00008 2 0.002380 0.002380 1.0000 29 0 29 134217728
|
||||
mx8+shl2304x3 9 exhausted
|
||||
mx8+shl2304x3 7 6 ea52f6e08a7d660d 1.00006 15 0.002380 0.002379 1.0005 26 0 27 134217728
|
||||
mx8+shl2304x3 1 21 4b5eeff2deea71bf 1.00013 14 0.002382 0.002381 1.0002 26 0 27 134217728
|
||||
mx8+shl2304x3 3 20 31c63382b2c98865 1.00012 6 0.002384 0.002380 1.0017 27 0 28 134217728
|
||||
mx8+shl2304x3 12 8 16549c7d637fe449 1.00006 10 0.002381 0.002381 0.9997 28 0 27 134217728
|
||||
mx8+shl2304x3 8 20 5d5cc864f3e43db0 1.00008 7 0.002383 0.002379 1.0016 27 0 27 134217728
|
||||
mx8+shl2304x3 10 8 44cbd1628f7cd0b5 1.00010 3 0.002380 0.002381 0.9994 29 0 27 134217728
|
||||
mx8+shl2304x3 13 11 650fcc81e8f6713c 1.00011 2 0.002380 0.002383 0.9989 28 0 27 134217728
|
||||
mx8+shl2304x3 11 8 3a19792efa300ffa 1.00009 6 0.002382 0.002382 1.0001 27 0 27 134217728
|
||||
mx8+shl2304x3 15 12 f90e9d3ce1e3bd48 1.00008 2 0.002381 0.002380 1.0003 27 0 27 134217728
|
||||
mx8+shl2304x3 16 14 233962a9d9480e3f 1.00004 10 0.002383 0.002381 1.0006 27 0 27 134217728
|
||||
mx8+shl2304x3 14 0 331b650531df6209 1.00008 14 0.002380 0.002382 0.9994 28 0 27 134217728
|
||||
mx8+shl2304x3 17 2 5ab27785a8cf57c9 1.00007 12 0.002382 0.002380 1.0012 26 0 27 134217728
|
||||
mx8+shl2304x3 18 18 c4aef3f59d632f1e 1.00010 0 0.002382 0.002381 1.0007 28 0 27 134217728
|
||||
mx8+shl2304x3 20 2 8f03b0d74069d184 0.99962 8 0.002380 0.002378 1.0009 28 0 27 134217728
|
||||
mx8+shl2304x3 19 10 c6157a48ca7b80c4 1.00008 14 0.002382 0.002381 1.0004 28 0 27 134217728
|
||||
mx8+shl2304x3 22 3 c8108af63069637c 1.00011 7 0.002381 0.002382 0.9995 28 0 27 134217728
|
||||
mx8+shl2304x3 23 6 6d76f2cb80e7219a 1.00006 13 0.002381 0.002378 1.0013 31 0 28 134217728
|
||||
mx8+shl2304x3 21 25 011719c4bfbbf91f 1.00009 7 0.002381 0.002382 0.9995 27 0 28 134217728
|
||||
mx8+shl2304x3 24 2 c8ce2560bf46d601 1.00012 3 0.002381 0.002380 1.0003 27 0 28 134217728
|
||||
mx8+shl2304x3 31 exhausted
|
||||
mx8+shl2304x3 25 0 5ee91d5f2ba3f0a4 1.00006 5 0.002379 0.002381 0.9994 26 0 26 134217728
|
||||
mx8+shl2304x3 26 7 beff30e8610da986 1.00006 8 0.002381 0.002380 1.0002 26 0 26 134217728
|
||||
mx8+shl2304x3 28 6 8f66d6d334836cbf 1.00012 7 0.002380 0.002380 1.0001 28 0 28 134217728
|
||||
mx8+shl2304x3 29 18 d8bf4433ed44aaeb 1.00005 9 0.002382 0.002379 1.0010 28 0 27 134217728
|
||||
mx8+shl2304x3 27 23 515a5fe888090db6 1.00008 2 0.002383 0.002381 1.0008 27 0 26 134217728
|
||||
mx8+shl2304x3 30 8 6f25bd4f4aab99ef 1.00009 3 0.002381 0.002381 1.0001 27 0 27 134217728
|
||||
mx8+shl2304x3 32 7 fddd29a75d5305f8 1.00009 0 0.002380 0.002379 1.0005 28 0 28 134217728
|
||||
mx8+shl2304x3 33 25 9131928cb80a747e 1.00009 14 0.002381 0.002381 1.0003 27 0 28 134217728
|
||||
mx8+shl2304x3 34 1 af09f974574a354b 1.00007 4 0.002381 0.002381 0.9998 29 0 27 134217728
|
||||
mx8+shl2304x3 36 1 ac021db7775368e2 1.00010 15 0.002377 0.002380 0.9986 27 0 28 134217728
|
||||
mx8+shl2304x3 35 29 72c2d1dbdf096864 1.00007 10 0.002380 0.002381 0.9995 27 0 28 134217728
|
||||
mx8+shl2304x3 43 exhausted
|
||||
mx8+shl2304x3 37 12 21180cca7fee526e 1.00009 14 0.002381 0.002380 1.0004 29 0 27 134217728
|
||||
mx8+shl2304x3 39 13 aef8a74cd6a789b5 1.00011 12 0.002381 0.002382 0.9997 27 0 27 134217728
|
||||
mx8+shl2304x3 38 1 3512feaa1923cee9 1.00007 2 0.002379 0.002380 0.9994 26 0 27 134217728
|
||||
mx8+shl2304x3 40 21 3b3d6730aa1bed86 1.00005 0 0.002379 0.002381 0.9991 29 0 27 134217728
|
||||
mx8+shl2304x3 41 9 37953c8af2eef1dc 1.00008 10 0.002381 0.002383 0.9991 26 0 27 134217728
|
||||
mx8+shl2304x3 42 4 7963bc66dc5269b6 1.00010 13 0.002379 0.002381 0.9993 27 0 26 134217728
|
||||
mx8+shl2304x3 44 0 0f603ad5e7345c45 1.00010 2 0.002381 0.002381 1.0000 27 0 27 134217728
|
||||
mx8+shl2304x3 45 14 1b0ff5a133de4b73 1.00004 1 0.002380 0.002382 0.9990 27 0 26 134217728
|
||||
mx8+shl2304x3 48 1 e5de4ffa5ff74e5b 1.00009 12 0.002383 0.002381 1.0008 26 0 28 134217728
|
||||
mx8+shl2304x3 47 6 de8dcd1dac65e4df 1.00009 4 0.002380 0.002378 1.0007 27 0 28 134217728
|
||||
mx8+shl2304x3 46 0 bb6c6630f4690b74 1.00007 6 0.002382 0.002381 1.0003 28 0 28 134217728
|
||||
mx8+shl2304x3 50 2 2a0e0aed9270a971 1.00005 2 0.002381 0.002379 1.0006 26 0 27 134217728
|
||||
mx8+shl2304x3 49 27 b88483b1e1e0964a 1.00011 11 0.002378 0.002381 0.9989 27 0 27 134217728
|
||||
mx8+shl2304x3 51 18 2ee1055d1ff42b36 1.00010 0 0.002381 0.002378 1.0013 29 0 27 134217728
|
||||
mx8+shl2304x3 52 3 06e2740b99bbd358 1.00009 9 0.002384 0.002379 1.0019 27 0 28 134217728
|
||||
mx8+shl2304x3 53 8 dd6621b58d8e9777 1.00009 2 0.002379 0.002380 0.9994 28 0 27 134217728
|
||||
mx8+shl2304x3 54 21 d8923d811eb288ef 1.00011 3 0.002383 0.002380 1.0013 27 0 26 134217728
|
||||
mx8+shl2304x3 55 9 cfa772fa29dfebd2 1.00009 13 0.002379 0.002380 0.9997 26 0 27 134217728
|
||||
mx8+shl2304x3 56 26 0cf3506bb52cc03c 1.00012 11 0.002380 0.002381 0.9996 26 0 28 134217728
|
||||
mx8+shl2304x3 57 0 80664c0cbbcf9f04 1.00006 14 0.002381 0.002382 0.9998 28 0 27 134217728
|
||||
mx8+shl2304x3 58 4 73787a50dbf4df0e 1.00011 12 0.002380 0.002380 0.9998 29 0 26 134217728
|
||||
mx8+shl2304x3 59 0 5e60995ec3140606 1.00009 0 0.002382 0.002381 1.0003 26 0 27 134217728
|
||||
mx8+shl2304x3 60 5 2b3db670b6d1b8e7 1.00009 15 0.002379 0.002380 0.9998 27 0 26 134217728
|
||||
mx8+shl2304x3 61 12 9c8106cbccf40cdf 0.99997 0 0.002382 0.002383 0.9996 29 0 29 134217728
|
||||
mx8+shl2304x3 63 7 c647131d75335d5c 1.00008 7 0.002382 0.002381 1.0004 27 0 26 134217728
|
||||
mx8+shl2304x3 62 3 55c3d4c861d94dea 1.00007 13 0.002381 0.002380 1.0005 27 0 27 134217728
|
||||
|
Can't render this file because it has a wrong number of fields in line 7.
|
65
docs/analysis/class-v6/logs/uniform-mx8_shl4096x1.tsv
Normal file
65
docs/analysis/class-v6/logs/uniform-mx8_shl4096x1.tsv
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
class seed attempt program_id min_site_ratio min_site top0.1_share control_share ratio_to_control max_item_reads max_item control_max reads
|
||||
mx8+shl4096x1 3 exhausted
|
||||
mx8+shl4096x1 17 2 b0f95f83c8b9848a 1.00010 14 0.002381 0.002380 1.0006 28 0 27 134217728
|
||||
mx8+shl4096x1 24 2 4f25c8f1d38840d2 1.00007 15 0.002381 0.002380 1.0006 28 0 28 134217728
|
||||
mx8+shl4096x1 9 7 6059f333a16dbf81 1.00009 3 0.002381 0.002380 1.0007 27 0 28 134217728
|
||||
mx8+shl4096x1 0 21 340d3f5acca526f7 1.00006 5 0.002381 0.002382 0.9993 28 0 27 134217728
|
||||
mx8+shl4096x1 20 12 44d5d0a1c21c2c08 1.00008 10 0.002383 0.002378 1.0019 27 0 27 134217728
|
||||
mx8+shl4096x1 4 21 227c9ea969b4f0be 1.00007 8 0.002383 0.002377 1.0023 28 0 29 134217728
|
||||
mx8+shl4096x1 13 11 cc2a38356847026b 1.00005 1 0.002382 0.002383 0.9998 28 0 27 134217728
|
||||
mx8+shl4096x1 1 9 545090fe5d5d48fe 1.00009 1 0.002382 0.002381 1.0003 30 0 27 134217728
|
||||
mx8+shl4096x1 8 20 e857640d0270f30f 1.00011 15 0.002383 0.002379 1.0018 26 0 27 134217728
|
||||
mx8+shl4096x1 16 2 d925a29d984cd513 1.00009 5 0.002384 0.002381 1.0011 27 0 27 134217728
|
||||
mx8+shl4096x1 12 3 ed43bca34cd7c2a2 1.00013 9 0.002379 0.002381 0.9989 29 0 27 134217728
|
||||
mx8+shl4096x1 10 8 5c87a72e42c9de86 1.00011 6 0.002379 0.002381 0.9992 26 0 27 134217728
|
||||
mx8+shl4096x1 6 1 05834442251198a1 1.00009 13 0.002381 0.002380 1.0006 27 0 28 134217728
|
||||
mx8+shl4096x1 23 8 93a81f4565355861 0.99707 13 0.002459 0.002378 1.0339 251 0 28 134217728
|
||||
mx8+shl4096x1 11 6 c416ed8bbe7d4ea0 1.00006 4 0.002379 0.002382 0.9987 27 0 27 134217728
|
||||
mx8+shl4096x1 2 0 6edd24933e170d70 1.00013 8 0.002379 0.002380 0.9999 27 0 29 134217728
|
||||
mx8+shl4096x1 22 3 823529821cdf93ab 1.00010 13 0.002382 0.002382 0.9999 27 0 27 134217728
|
||||
mx8+shl4096x1 18 18 df5d9390d3d83cb1 1.00008 10 0.002381 0.002381 1.0003 27 0 27 134217728
|
||||
mx8+shl4096x1 14 0 f865448dc76d5aca 1.00007 5 0.002378 0.002382 0.9984 27 0 27 134217728
|
||||
mx8+shl4096x1 7 3 470478a4eb187067 0.99964 4 0.002385 0.002379 1.0024 26 0 27 134217728
|
||||
mx8+shl4096x1 5 30 254c9c5fb60381ed 1.00010 14 0.002381 0.002379 1.0011 27 0 28 134217728
|
||||
mx8+shl4096x1 21 18 c52bcee3ca0baa30 1.00010 15 0.002382 0.002382 0.9999 28 0 28 134217728
|
||||
mx8+shl4096x1 19 2 ddab5a93bd139bc8 1.00011 14 0.002378 0.002381 0.9990 28 0 27 134217728
|
||||
mx8+shl4096x1 15 10 08a70d0dbe8faa8c 1.00010 2 0.002379 0.002380 0.9995 27 0 27 134217728
|
||||
mx8+shl4096x1 31 exhausted
|
||||
mx8+shl4096x1 41 exhausted
|
||||
mx8+shl4096x1 25 0 36ab9c36661531c3 1.00011 11 0.002383 0.002381 1.0009 27 0 26 134217728
|
||||
mx8+shl4096x1 26 8 81f861fdce42d06e 1.00011 11 0.002379 0.002380 0.9996 27 0 26 134217728
|
||||
mx8+shl4096x1 29 0 11b231ddd567c9e8 0.99970 15 0.002382 0.002379 1.0012 31 0 27 134217728
|
||||
mx8+shl4096x1 28 9 3b227938c0e2231c 1.00010 11 0.002382 0.002380 1.0008 27 0 28 134217728
|
||||
mx8+shl4096x1 53 exhausted
|
||||
mx8+shl4096x1 27 23 dc1f09a3ef9d2a99 1.00012 12 0.002382 0.002381 1.0004 28 0 26 134217728
|
||||
mx8+shl4096x1 39 4 4e7c182baa1a4a1b 1.00009 9 0.002381 0.002382 0.9994 28 0 27 134217728
|
||||
mx8+shl4096x1 44 0 36953ab1f2180836 1.00007 12 0.002382 0.002381 1.0005 27 0 27 134217728
|
||||
mx8+shl4096x1 43 12 48580e6c2b59439b 1.00011 9 0.002380 0.002381 0.9993 27 0 27 134217728
|
||||
mx8+shl4096x1 37 4 d5013a9522ad5543 1.00008 2 0.002380 0.002380 1.0000 27 0 27 134217728
|
||||
mx8+shl4096x1 34 5 1c5a9cb1f2d42cca 1.00007 14 0.002380 0.002381 0.9996 28 0 27 134217728
|
||||
mx8+shl4096x1 33 2 7c6a199c86313f69 1.00008 14 0.002382 0.002381 1.0004 28 0 28 134217728
|
||||
mx8+shl4096x1 30 19 b783565b6523434c 1.00006 12 0.002380 0.002381 0.9996 26 0 27 134217728
|
||||
mx8+shl4096x1 45 16 628bac1c72879c6d 1.00010 12 0.002382 0.002382 0.9998 27 0 26 134217728
|
||||
mx8+shl4096x1 32 7 36488864cadf6ca7 1.00008 1 0.002381 0.002379 1.0008 28 0 28 134217728
|
||||
mx8+shl4096x1 36 1 3fdecb3b8e921f75 1.00010 11 0.002382 0.002380 1.0009 27 0 28 134217728
|
||||
mx8+shl4096x1 49 5 b77e74a67bb6c771 1.00002 2 0.002380 0.002381 0.9996 32 0 27 134217728
|
||||
mx8+shl4096x1 46 0 5eb5626db2690873 1.00002 13 0.002378 0.002381 0.9990 26 0 28 134217728
|
||||
mx8+shl4096x1 35 7 6c3967bb0b566f09 1.00007 12 0.002381 0.002381 0.9998 26 0 28 134217728
|
||||
mx8+shl4096x1 40 14 e7f5c35cfb86a17c 1.00000 4 0.002381 0.002381 1.0000 27 0 27 134217728
|
||||
mx8+shl4096x1 50 2 549f8dba3fcba122 1.00011 3 0.002381 0.002379 1.0008 27 0 27 134217728
|
||||
mx8+shl4096x1 38 1 4b79b3b55f4764aa 1.00012 3 0.002379 0.002380 0.9995 28 0 27 134217728
|
||||
mx8+shl4096x1 47 3 b3c9b8bac363b4c5 1.00006 10 0.002380 0.002378 1.0008 26 0 28 134217728
|
||||
mx8+shl4096x1 42 4 0428662243e68699 1.00011 7 0.002383 0.002381 1.0009 27 0 26 134217728
|
||||
mx8+shl4096x1 48 14 be0d1e64f5ba21bb 1.00011 1 0.002381 0.002381 0.9997 27 0 28 134217728
|
||||
mx8+shl4096x1 54 21 7d1a5b56479af4ec 1.00013 10 0.002382 0.002380 1.0008 26 0 26 134217728
|
||||
mx8+shl4096x1 52 16 9bc4cf406998d9a2 1.00007 4 0.002381 0.002379 1.0005 27 0 28 134217728
|
||||
mx8+shl4096x1 51 3 26a54134632ad738 1.00012 10 0.002383 0.002378 1.0020 27 0 27 134217728
|
||||
mx8+shl4096x1 55 0 3167b616ff2705fc 1.00002 15 0.002380 0.002380 1.0003 30 0 27 134217728
|
||||
mx8+shl4096x1 56 25 ad1e66ae16b7962f 1.00010 7 0.002380 0.002381 0.9997 27 0 28 134217728
|
||||
mx8+shl4096x1 60 1 2fd619b39ec1cada 1.00004 8 0.002383 0.002380 1.0011 28 0 26 134217728
|
||||
mx8+shl4096x1 57 0 051e980b891b4123 1.00008 11 0.002380 0.002382 0.9992 27 0 27 134217728
|
||||
mx8+shl4096x1 59 26 0bd2c17514f67fd4 1.00009 13 0.002380 0.002381 0.9995 26 0 27 134217728
|
||||
mx8+shl4096x1 58 6 8bc36a3e9c765a1c 1.00006 2 0.002381 0.002380 1.0004 27 0 26 134217728
|
||||
mx8+shl4096x1 63 10 39fab9b0e5f88aa8 1.00008 15 0.002383 0.002381 1.0010 27 0 26 134217728
|
||||
mx8+shl4096x1 62 3 1ccf354dd44307ed 0.99999 1 0.002380 0.002380 1.0002 27 0 27 134217728
|
||||
mx8+shl4096x1 61 30 a6b85d02886ea796 1.00009 10 0.002381 0.002383 0.9992 27 0 29 134217728
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
|
@ -34,9 +34,22 @@
|
|||
"source": "igneum.network/api/checkpoint?index=2127 (dn3_live_certificates), the bytes the chain carried; verified by eth_call before the send (true, 4833, 7164)"
|
||||
}
|
||||
],
|
||||
"interface": "IIgneumCertificateVerifier in contracts/bridge/src/IgneumCertificateVerifier.sol: chainId(), tableId(), verifyCertificate(uint64 index, bytes32 checkpoint, bytes bitmap, bytes signature) view returns (bool ok, uint256 signedWeight, uint256 totalWeight), submitCertificate(...), finalCheckpoint(uint64) view returns (bytes32), isFinal(bytes32) view returns (bool), verifyAccount(bytes32 stateRoot, address account, bytes[] proof) pure returns (bool exists, uint256 nonce, uint256 balance, bytes32 storageRoot, bytes32 codeHash)"
|
||||
"interface": "IIgneumCertificateVerifier in contracts/bridge/src/IgneumCertificateVerifier.sol: chainId(), tableId(), verifyCertificate(uint64 index, bytes32 checkpoint, bytes bitmap, bytes signature) view returns (bool ok, uint256 signedWeight, uint256 totalWeight), submitCertificate(...), finalCheckpoint(uint64) view returns (bytes32), isFinal(bytes32) view returns (bool), verifyAccount(bytes32 stateRoot, address account, bytes[] proof) pure returns (bool exists, uint256 nonce, uint256 balance, bytes32 storageRoot, bytes32 codeHash)",
|
||||
"account_proofs": [
|
||||
{
|
||||
"account": "0x085a7ca7338efaf797f3300fa7c64afa9d2c539b",
|
||||
"devnet3_block": 28462,
|
||||
"state_root": "0x1fd551393d84009c398a9b9747cd296d0fdf1e31f85fa21c10426bc219694561",
|
||||
"balance_wei": "547807747463600000000",
|
||||
"balance_ign": "547.8077",
|
||||
"proof_nodes": 3,
|
||||
"source": "eth_getProof on the reference-apps lane's Devnet 3 reader node (igneum-light-reader on build-1, fork branch light-apps-node), the block's stateRoot equal to the proof's root",
|
||||
"verified": "eth_call verifyAccount on the live contract 13:0x UTC: (true, nonce 0, 547807747463600000000, empty storage root, empty code hash); the suite's test_devnet3_account_balance_proven green on build-3 (10 of 10)",
|
||||
"caveat": "the root is the chain's own but no certificate ties it to a checkpoint (gap 1 in docs/bridge/light-client-bridge.md)"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_deploy_note": "A first creation at 0xD7dd375E14F92A4CE4782040325189e6d6E394b6 (tx 0x4db10565\u2026, block 11869633) ran out of gas at Foundry's Prague-spec estimate of 3,323,884; Sepolia runs Osaka pricing (EIP-7883 modexp), so the test EVM and the deploy now use osaka and the RPC's own estimate. That address holds no code.",
|
||||
"tests": "contracts/bridge/test/Verifier.t.sol: 9 of 9 green on build-3 (Foundry, osaka), 12:3x UTC 8 October 2026; the live contract verified and recorded Devnet 3 checkpoint 2127 at 12:5x UTC"
|
||||
"tests": "contracts/bridge/test/Verifier.t.sol: 10 of 10 green on build-3 (Foundry, osaka), 13:0x UTC 8 October 2026, including one Devnet 3 account under a real Devnet 3 state root"
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -125,11 +125,14 @@ export function createHandler({ env = process.env, sql, evm = evmCall } = {}) {
|
|||
|
||||
// ---- stats ----
|
||||
if (q.has('stats')) {
|
||||
const [chain10, fin] = await Promise.all([
|
||||
const [chain10, fin, paid10] = await Promise.all([
|
||||
sql(`SELECT count(*)::int AS blocks_10m, count(*) FILTER (WHERE is_chain_block)::int AS chain_10m, count(DISTINCT vote_key_hash)::int AS miners_10m, max(daa_score) AS daa, max(number) AS height FROM ${T}live_blocks WHERE received_at > now() - interval '10 minutes'`),
|
||||
Promise.resolve(s && s.finality ? s.finality : null),
|
||||
// payments landing in the window for blocks of any age (the observer's shards_paid_10m counts only blocks of the last 10 minutes, which reads 0 while the lag runs to 500 DAA)
|
||||
sql(`SELECT count(*)::int AS n, count(DISTINCT prover)::int AS provers, sum(payout_wei::numeric)::text AS payout_wei FROM ${T}live_proofs WHERE state = 'paid' AND updated_at > now() - interval '10 minutes'`).catch(() => [{ n: null, provers: null, payout_wei: null }]),
|
||||
]);
|
||||
const c = chain10[0] || {};
|
||||
const p10 = paid10[0] || {};
|
||||
const w = fin && fin.weights ? fin.weights : null;
|
||||
const activations = params ? Object.entries(params).filter(([k, v]) => /_activation_daa$/.test(k) && Number.isFinite(Number(v))).map(([k, v]) => ({ name: k.replace(/_activation_daa$/, ''), daa: Number(v) })) : [];
|
||||
return res.status(200).json({
|
||||
|
|
@ -140,6 +143,7 @@ export function createHandler({ env = process.env, sql, evm = evmCall } = {}) {
|
|||
miners_10m: num(c.miners_10m),
|
||||
finality: fin ? { active: !!fin.finality_active, voters: w ? num(w.voters) : null, total_weight: w ? num(w.total_weight) : null, active_weight: w ? num(w.active_weight) : null, keys: w && Array.isArray(w.keys) ? w.keys.length : null, latest_locked_index: num(fin.latest_locked_index), latest_locked_blue_score: num(fin.latest_locked_blue_score), params: fin.params || null } : null,
|
||||
proving: s && s.proving ? s.proving : null,
|
||||
paid_10m_any_age: { shards: num(p10.n), provers: num(p10.provers), payout_wei: p10.payout_wei || '0', note: 'shards paid in the last 10 minutes for blocks of any age' },
|
||||
class: classAt(num(c.daa), params), activations, digest: ix && ix.node_info ? ix.node_info.digest : null, genesis: ix && ix.node_info ? ix.node_info.genesis : null,
|
||||
budgets: null,
|
||||
});
|
||||
|
|
@ -147,7 +151,7 @@ export function createHandler({ env = process.env, sql, evm = evmCall } = {}) {
|
|||
|
||||
// ---- proving view ----
|
||||
if (q.has('proving')) {
|
||||
const [blocks, provers24, provers1, lat, totals] = await Promise.all([
|
||||
const [blocks, provers24, provers1, lat, totals, paid10] = await Promise.all([
|
||||
sql(`SELECT b.hash, b.number, b.daa_score, b.blue_score, b.timestamp_ms, b.vote_key_hash, b.evm_miner, b.tx_count, b.proof_records,
|
||||
count(p.shard)::int AS total, count(*) FILTER (WHERE p.state = 'planned')::int AS planned, count(*) FILTER (WHERE p.state = 'proving')::int AS proving,
|
||||
count(*) FILTER (WHERE p.state = 'verified')::int AS verified, count(*) FILTER (WHERE p.state = 'paid')::int AS paid,
|
||||
|
|
@ -161,6 +165,7 @@ export function createHandler({ env = process.env, sql, evm = evmCall } = {}) {
|
|||
sql(`SELECT count(*)::int AS paid_1h, percentile_cont(0.5) WITHIN GROUP (ORDER BY lag_daa) AS p50, percentile_cont(0.9) WITHIN GROUP (ORDER BY lag_daa) AS p90, max(lag_daa) AS max_lag, min(lag_daa) AS min_lag
|
||||
FROM ${T}live_proofs WHERE state = 'paid' AND updated_at > now() - interval '1 hour'`),
|
||||
sql(`SELECT state, count(*)::int AS n, sum(payout_wei::numeric)::text AS payout_wei FROM ${T}live_proofs WHERE received_at > now() - interval '24 hours' GROUP BY state`),
|
||||
sql(`SELECT count(*)::int AS n, count(DISTINCT prover)::int AS provers, sum(payout_wei::numeric)::text AS payout_wei FROM ${T}live_proofs WHERE state = 'paid' AND updated_at > now() - interval '10 minutes'`).catch(() => []),
|
||||
]);
|
||||
const hour = new Map(provers1.map(p => [p.prover, p]));
|
||||
return res.status(200).json({
|
||||
|
|
@ -169,6 +174,7 @@ export function createHandler({ env = process.env, sql, evm = evmCall } = {}) {
|
|||
provers: provers24.map(p => ({ id: p.prover, shards_24h: num(p.shards), payout_wei_24h: p.payout_wei || '0', median_lag_24h: p.median_lag === null ? null : Number(p.median_lag), shards_1h: hour.has(p.prover) ? num(hour.get(p.prover).shards) : 0, payout_wei_1h: hour.has(p.prover) ? hour.get(p.prover).payout_wei || '0' : '0', last_paid: p.last_paid })),
|
||||
latency_1h: lat[0] ? { paid: num(lat[0].paid_1h), p50_daa: lat[0].p50 === null ? null : Number(lat[0].p50), p90_daa: lat[0].p90 === null ? null : Number(lat[0].p90), min_daa: num(lat[0].min_lag), max_daa: num(lat[0].max_lag), note: 'lag in DAA score from the proven block to the block whose coinbase paid the shard; Devnet 3 targets one DAA step per second' } : null,
|
||||
totals_24h: Object.fromEntries(totals.map(t => [t.state, { shards: num(t.n), payout_wei: t.payout_wei || '0' }])),
|
||||
paid_10m_any_age: paid10[0] ? { shards: num(paid10[0].n), provers: num(paid10[0].provers), payout_wei: paid10[0].payout_wei || '0' } : null,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -360,14 +360,14 @@ const id = decodeURIComponent(location.pathname.split('/').pop() || '');
|
|||
const query = /^\d{1,12}$/.test(id) ? 'height=' + id : 'block=' + encodeURIComponent(id.replace(/^0x/i, ''));
|
||||
async function recheck(index, blockHash, isCheckpoint) {
|
||||
// the verified badge: this browser fetches the certificate that covers the block and checks it with the site's light client
|
||||
const el = $('recheck'); el.innerHTML = `<p class="note" id="rc-line">Re-checking certificate ${int(index)} in this browser.</p>`;
|
||||
const el = $('recheck'); el.innerHTML = `<p class="note" id="rc-line">Re-checking certificate ${int(index)} in this browser. The STARK proofs of the shards are not re-run here; the node's verdict on them is shown in the shard table as the node's.</p>`;
|
||||
const badge = document.createElement('span'); badge.className = 'badge wait'; badge.textContent = 'checking the certificate'; $('chips').appendChild(badge);
|
||||
try {
|
||||
const { fetchCheckpoint, verify } = await import('/verify/verify.js');
|
||||
const data = await fetchCheckpoint('/api/checkpoint?index=' + index);
|
||||
const r = verify(data);
|
||||
if (r.verified) {
|
||||
badge.className = 'badge ok'; badge.textContent = isCheckpoint ? 'verified in this browser' : `verified under lock ${int(index)} in this browser`;
|
||||
badge.className = 'badge ok'; badge.textContent = "certificate re-checked in this browser; the node's verdict on the STARK";
|
||||
$('rc-line').innerHTML = `Certificate ${int(index)} re-checked in this browser in ${r.ms} ms: ${int(r.headers_checked)} header hashes recomputed, ${int(r.signers)} of ${int(r.voters)} voters' BLS keys aggregated, the signature verifies over ${(r.weight_fraction_total * 100).toFixed(1)}% of all weight. ${isCheckpoint ? 'This block is the certified checkpoint.' : 'This block sits under that lock on the selected chain.'} The light client is <a href="/verify/core.js">/verify/core.js</a>; the data it checked is <a href="/api/checkpoint?index=${index}">/api/checkpoint?index=${index}</a>.`;
|
||||
} else { badge.className = 'badge bad'; badge.textContent = 'certificate did not verify'; $('rc-line').textContent = `Certificate ${int(index)} did not verify in this browser: ${r.error || 'unknown reason'}.`; }
|
||||
} catch (e) { badge.className = 'badge wait'; badge.textContent = 're-check unavailable'; $('rc-line').textContent = 'The re-check could not run: ' + (e.message || e); }
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin
|
|||
<div class="cell"><div class="k">Chain rate, 10 min</div><div class="v" id="st-rate">0<small>blocks/s</small></div><div class="s" id="st-rate-s">DAG blocks per second; chain blocks per second</div></div>
|
||||
<div class="cell"><div class="k">Finality</div><div class="v" id="st-fin">n/a</div><div class="s" id="st-fin-s">voters and weight</div></div>
|
||||
<div class="cell"><div class="k">Program class</div><div class="v" id="st-class">v4</div><div class="s" id="st-class-s">the hash program family at the tip</div></div>
|
||||
<div class="cell"><div class="k">Proving</div><div class="v" id="st-prov">0<small>paid</small></div><div class="s" id="st-prov-s">shards paid in 10 min</div></div>
|
||||
<div class="cell"><div class="k">Proving</div><div class="v" id="st-prov">0<small>paid</small></div><div class="s" id="st-prov-s">shards paid in the last 10 min for blocks of any age</div></div>
|
||||
</div>
|
||||
<div class="card" aria-label="The DAG">
|
||||
<div class="viz-head"><h2>The DAG</h2><div class="eyebrow" id="dag-eyebrow">the newest 150 blocks, one lane per miner</div></div>
|
||||
|
|
@ -460,9 +460,9 @@ async function loadStats() {
|
|||
$('st-class').textContent = s.class ? s.class.class : 'v4';
|
||||
const next = s.class && s.class.floors ? s.class.floors.find(x => x.daa > (s.daa || 0)) : null;
|
||||
$('st-class-s').textContent = next ? `${next.class} from DAA ${int(next.daa)}` : (s.class && s.class.floors && s.class.floors.length ? `since DAA ${int(s.class.floors[s.class.floors.length - 1].daa)}` : 'the hash program family at the tip');
|
||||
const p = s.proving || {};
|
||||
$('st-prov').innerHTML = esc(int(p.shards_paid_10m ?? 0)) + '<small>paid</small>';
|
||||
$('st-prov-s').textContent = p.supported === false ? 'the node reports no proving layer' : `shards paid in 10 min, ${int(p.provers_10m ?? 0)} provers, ${int(p.open_blocks ?? 0)} open blocks`;
|
||||
const p = s.proving || {}, pa = s.paid_10m_any_age || {};
|
||||
$('st-prov').innerHTML = esc(int(pa.shards ?? 0)) + '<small>paid</small>';
|
||||
$('st-prov-s').textContent = p.supported === false ? 'the node reports no proving layer' : `shards paid in the last 10 min for blocks of any age, ${int(pa.provers ?? 0)} provers, ${int(p.open_blocks ?? 0)} open blocks`;
|
||||
}
|
||||
async function loadProving() {
|
||||
const j = await fetch('/api/explorer?proving=1').then(r => r.json()); if (!j.ok) throw new Error(j.error);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -40,7 +40,9 @@ try {
|
|||
const cp = await get(`${API}/checkpoint`);
|
||||
// a transaction to prove: the first in a chain block below the checkpoint
|
||||
let tx = q.get('tx');
|
||||
if (!tx) { const cb = await rpc('eth_getBlockByHash', ['0x' + cp.hash, false]); const n = parseInt(cb.number, 16); for (let k = n - 1; k > n - 200 && !tx; k--) { const b = await rpc('eth_getBlockByNumber', ['0x' + k.toString(16), false]); if (b && b.transactions.length) tx = b.transactions[0]; } }
|
||||
// the public RPC allows 20 requests a second: walk at most 40 blocks below the checkpoint, 80 ms apart
|
||||
if (!tx) { const cb = await rpc('eth_getBlockByHash', ['0x' + cp.hash, false]); const n = parseInt(cb.number, 16); for (let k = n - 1; k > n - 40 && !tx; k--) { const b = await rpc('eth_getBlockByNumber', ['0x' + k.toString(16), false]); if (b && b.transactions.length) tx = b.transactions[0]; await new Promise(r => setTimeout(r, 80)); } }
|
||||
if (!tx) throw new Error('no transaction found in the 40 chain blocks below the checkpoint; pass ?tx=');
|
||||
const rr = await get(`${API}/receipt?tx=${tx}&checkpoint=${cp.hash}&index=${cp.index}`);
|
||||
const receipt = { format: 'igneum-receipt-v1', ...rr, checkpoint: { ...rr.checkpoint, certificate: rr.checkpoint.certificate || cp } };
|
||||
const R = [
|
||||
|
|
|
|||
|
|
@ -205,26 +205,26 @@
|
|||
{
|
||||
"card": "AMD Radeon RX 9070 XT (16 GB)",
|
||||
"generator": "v2",
|
||||
"mh_s": 18.92,
|
||||
"watts": 202,
|
||||
"mh_per_w": 0.093,
|
||||
"mh_s": 18.96,
|
||||
"watts": 149.3,
|
||||
"mh_per_w": 0.127,
|
||||
"miner": "igneum-worker-opencl bench (installed worker), class v3 control",
|
||||
"date": "2026-10-08",
|
||||
"source": "Counter ASIC 3.0 status: the 9070 XT Ember tune (run-ca3-pc1-ember-9070-20261007, 06:11Z, app 0.3.20) for the watts; item 8's RX 9070 XT rows (the G1 ladder, 6 October 2026) for the rate",
|
||||
"source": "Counter ASIC 3.0 status: the RX 9070 XT's first measured grid on the AMD knob (job run-ca3-pc1-amd-grid-9070-20261008-b, 24 of 24 points, 8 October 2026) for the rate and the watts; the 9070 XT Ember tune row (run-ca3-pc1-ember-9070-20261007) for the app's own stock reading",
|
||||
"by": "measured by the team",
|
||||
"note": "the watts are the app's own power reading at the stock point, no external sampler (8 October 2026, the status row): the Ember tune on this card measured the stock point and stopped, 0.3.20 having no AMD knob (power_pct 0, clock_cap 0, limit 0.0 W)",
|
||||
"note": "the grid's stock point reads 3,292 MHz, 195.8 W, 0.097 MH per watt (the app's own stock reading of 7 October was 202 W); the clock offset alone reaches 2,924 MHz at 159.2 W and the power limit alone 184.4 W; the best point is both together. The knob ships in 0.3.25, so until that cut serves the figure reads \"with the 0.3.25 knob\". Against the 5090 at its class v4 1,200 MHz lock (133.8 MH/s at 305 W, 0.43 MH per watt) the 9070 XT at its best point sits 3.5x behind per watt; against the 5090 at its 1,300 MHz knee (134.6 at 223 W, 0.60) about a fifth",
|
||||
"v4_cost": "+2 percent of rate (19.29 against 18.92 MH/s) at 102,100 ops per hash, watts owed, measured 6 October 2026",
|
||||
"tuned": "no lever: the app has no AMD knob today (an AMD core-clock knob through rocm-smi or ADL is the path, a morning item)",
|
||||
"tuned": "core -500 MHz, power -30 percent, with the 0.3.25 knob: 2,921 MHz, 149.3 W at 18.96 MH/s, a 24 percent saving at the same rate (the rate flat at 18.93 to 18.98 MH/s on all 24 points, the knob moves watts only); measured 8 October 2026",
|
||||
"driver_os": "Adrenalin 26.9.2, Windows 11",
|
||||
"hive": {
|
||||
"core_mhz": null,
|
||||
"mem_mhz": null,
|
||||
"pl_w": null,
|
||||
"label": "stock (no lever on AMD in 0.3.20; no measured tune point)"
|
||||
"label": "the AMD knob is the 0.3.25 app's (core -500 MHz, power -30 percent); no Hive flight-sheet values yet"
|
||||
},
|
||||
"group": "buy",
|
||||
"mh_s_display": "18.9 (18.8 to 19.2 on the G1 ladder)",
|
||||
"watts_display": "202 stock"
|
||||
"mh_s_display": "19.0 stock (19.0 with the 0.3.25 knob)",
|
||||
"watts_display": "149.3 with the 0.3.25 knob (195.8 stock)"
|
||||
},
|
||||
{
|
||||
"card": "Apple M5 Max (40 GPU cores, Metal)",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -252,9 +252,10 @@
|
|||
<h2 id="deployed">On Sepolia</h2>
|
||||
<div class="kv" data-oracle-kv>
|
||||
<div class="k">Oracle</div><div class="mono" data-oracle-address>0xefe9879de29c401eeff195d5bf71c86b9caaa1b2 <small>IgneumStateOracle, deployed 8 October 2026 (tx 0xb8650f5b…d644, block 11869608)</small></div>
|
||||
<div class="k">Verifier</div><div class="mono" data-verifier-address>0xa197ef31d5d5613125779179668e2482ac69a6f6 <small>StubCertificateVerifier, the stand-in: it records any well-formed certificate and does not check the BLS signature; the shared IgneumCertificateVerifier replaces it through setVerifier the day it lands</small></div>
|
||||
<div class="k">Verifier</div><div class="mono" data-verifier-address>0xAf74f3F512081291D663Bb1d6b6d37E99e37D744 <small>the shared IgneumCertificateVerifier (the DEX lane's, a real BLS12-381 check on chain through the EIP-2537 precompiles, voter table installed at checkpoint 2127), set by setVerifier on 8 October 2026 (tx 0xd679bb65…db8e); the stand-in 0xa197ef31…a6f6 served until then</small></div>
|
||||
<div class="k">Chain</div><div>Sepolia, chain id 11155111; Devnet 3 (igneum-devnet-3), no value</div>
|
||||
<div class="k">First proven root</div><div class="mono">Devnet 3 chain block 26631, post_root 0xf567a84f…a82fd, stored 8 October 2026 (tx 0xf360e54c…224b, 404,376 gas); provenBalance read 92.029323 IGN for 0x636de2dc…44ea on Sepolia, equal to the Devnet 3 node's eth_getProof</div>
|
||||
<div class="k">Proven roots</div><div class="mono">Under the shared verifier: certificate 2232 (0xf056c26e…, 29 voters, signed weight 4,988 of 7,164) recorded with a real BLS check, tx 0x1794b785…1e8a, 792,677 gas; Devnet 3 chain block 28439, post_root stored with a 6-header path, tx 0x3629525e…b2d3, 1,624,984 gas; provenBalance read 721.451608 IGN for 0xcaed79d8…c087 on Sepolia, equal to the Devnet 3 node's eth_getProof. Earlier, under the stand-in: block 26631 (tx 0xb3875bbd…, 642,331 gas; 92.029323 IGN for 0x636de2dc…44ea).</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="note">How to read a balance from another contract: <code>IIgneumStateOracle(oracle).provenBalance(number, account, accountProof)</code>, where <code>number</code> is a Devnet 3 chain block whose state root the oracle holds and <code>accountProof</code> is the <code>eth_getProof</code> account proof at that block. A storage slot: <code>provenStorage(number, account, slot, accountProof, storageProof)</code>. Both revert on any mismatch.</p>
|
||||
</section>
|
||||
|
|
@ -266,7 +267,7 @@
|
|||
<li>The coinbase transaction under the carrier's <code>hash_merkle_root</code>, and the segment record parsed out of its extra data: the record's <code>post_root</code> for its block is stored under the certificate's index.</li>
|
||||
<li>Every read: a keccak-keyed Merkle Patricia proof against the stored root, verified on chain.</li>
|
||||
</ol>
|
||||
<p class="note">Said plainly, on the contract too (<code>trust()</code>): the aggregator's BLS signature on the record is not checked on chain in this slice, and while the stand-in verifier is installed no certificate signature is checked on chain either; the voter table the shared verifier holds is installed by its deployer. Gas on Sepolia, measured 8 October 2026: a 62-header path 13.3 million (about 215,000 per header, 15 precompile blocks each), a 10-header path about 2.2 million, the state-root store 177,000, a balance read 153,000. The negative cases in <code>test.mjs</code> are a flipped proof node, a wrong block number, a header removed from the path, a merkle sibling altered, a record with its <code>post_root</code> altered, a header with its nonce altered: each reverts.</p>
|
||||
<p class="note">Said plainly, on the contract too (<code>trust()</code>): the aggregator's BLS signature on the record is not checked on chain in this slice; the certificate's BLS signature is checked by the shared verifier against the voter table its deployer installed at checkpoint 2127 (a later table that drifts past the rule's margin needs a new table). Gas on Sepolia, measured 8 October 2026: a 62-header path 13.3 million (about 215,000 per header, 15 precompile blocks each), a 10-header path about 2.2 million, the state-root store 177,000, a balance read 153,000. The negative cases in <code>test.mjs</code> are a flipped proof node, a wrong block number, a header removed from the path, a merkle sibling altered, a record with its <code>post_root</code> altered, a header with its nonce altered: each reverts.</p>
|
||||
<p class="asof">Devnet 3, no value. Sepolia, no value. A demonstration of the verification path, not a product.</p>
|
||||
</main>
|
||||
<!-- footer:start -->
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin
|
|||
</div>
|
||||
<div class="strip" aria-live="polite">
|
||||
<div class="cell status"><div class="k">Proving</div><div class="v"><span class="dot"></span><span id="p-status">OFFLINE</span></div><div class="s" id="p-status-s">the node's proving layer</div></div>
|
||||
<div class="cell"><div class="k">Paid, 10 min</div><div class="v" id="p-paid10">0</div><div class="s" id="p-paid10-s">shards</div></div>
|
||||
<div class="cell"><div class="k">Paid, 10 min</div><div class="v" id="p-paid10">0</div><div class="s" id="p-paid10-s">shards, for blocks of any age</div></div>
|
||||
<div class="cell"><div class="k">Paid, 24 h</div><div class="v" id="p-paid24">0</div><div class="s" id="p-paid24-s">shards, IGN to provers</div></div>
|
||||
<div class="cell"><div class="k">Open blocks</div><div class="v" id="p-open">0</div><div class="s" id="p-open-s">chain blocks with unpaid shards</div></div>
|
||||
<div class="cell"><div class="k">Provers, 24 h</div><div class="v" id="p-provers">0</div><div class="s" id="p-provers-s">vote keys paid for a shard</div></div>
|
||||
|
|
@ -382,7 +382,8 @@ async function load() {
|
|||
document.body.classList.toggle('on', on); document.body.classList.toggle('off', !on);
|
||||
$('p-status').textContent = j.stale ? 'OFFLINE' : (p.supported === false ? 'NO LAYER' : (p.active ? 'ACTIVE' : 'INACTIVE'));
|
||||
$('p-status-s').textContent = j.stale ? 'observer stale' : `read ${stamp(j.now)}, tip DAA ${int(p.tip_daa)}${p.paused_since_ms ? ', paused' : ''}`;
|
||||
$('p-paid10').textContent = int(p.shards_paid_10m ?? 0); $('p-paid10-s').textContent = `shards; ${int(p.blocks_fully_proven_10m ?? 0)} of ${int(p.blocks_10m ?? 0)} blocks of the window fully proven`;
|
||||
const pa = j.paid_10m_any_age || {};
|
||||
$('p-paid10').textContent = int(pa.shards ?? 0); $('p-paid10-s').textContent = `shards paid in the last 10 min for blocks of any age, ${ignFromWei(pa.payout_wei || '0', 2)} IGN; ${int(p.blocks_fully_proven_10m ?? 0)} of ${int(p.blocks_10m ?? 0)} blocks of the window fully proven`;
|
||||
$('p-paid24').textContent = int(t.paid ? t.paid.shards : 0); $('p-paid24-s').textContent = `shards, ${ignFromWei(t.paid ? t.paid.payout_wei : '0', 2)} IGN to provers`;
|
||||
$('p-open').textContent = int(p.open_blocks ?? 0); $('p-open-s').textContent = `chain blocks with unpaid shards, ${int(p.pending_plans ?? 0)} plans not read yet`;
|
||||
$('p-provers').textContent = int(j.provers.length); $('p-provers-s').textContent = `vote keys paid for a shard; ${int(p.provers_10m ?? 0)} in the last 10 min`;
|
||||
|
|
|
|||
|
|
@ -265,6 +265,7 @@ dt{color:var(--ash)}dd{margin:0;font-family:var(--f-mono);font-size:13px;overflo
|
|||
<input id="amount-out" name="amount-out" readonly placeholder="0.0">
|
||||
<select id="token-out" aria-label="Token to receive"></select>
|
||||
</div>
|
||||
<p class="small">The Igneum Wallet is found on this machine through 127.0.0.1; Chrome asks once per site to allow local network access, and the wallet asks once to connect igneum.network. Nothing on this page asks for a seed or a key.</p>
|
||||
<p class="small" id="quote-line">Enter an amount for a quote. Slippage limit 1 percent, deadline 10 minutes.</p>
|
||||
<button class="btn" id="go" type="submit" disabled>Swap</button>
|
||||
<div class="status" id="status" role="status" aria-live="polite"></div>
|
||||
|
|
|
|||
15
tools/attack/v6-invention/README.md
Normal file
15
tools/attack/v6-invention/README.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Class v6 invention lane harnesses (8 October 2026)
|
||||
|
||||
Research harnesses over the `igneum-pow` crate of branch `counter-asic-4` (the experimental per-load shadow class
|
||||
`+shl<S>x<R>` lives there, not on master): build them from a worktree of that branch with `tools/build-remote.sh`
|
||||
and run them on the boxes under `/srv/builds/_bin/lease`. Nothing here is consensus code or a chain class.
|
||||
|
||||
- `v6inv-census.sh`: the acceptance census of a list of load classes over N seeds (`igneum-v6inv/<i>`), with or without
|
||||
a drawn era, one TSV row per (form, seed): candidates, accepted, the first accepted attempt, the first failing parts.
|
||||
- `uniform/`: the F8-form uniformity read for any class the crate draws, through the library's own `trace_load_indices`
|
||||
(the class's execution order): per site the distinct-index ratio at 2^20 nonces, the cross-hash item histogram's top
|
||||
0.1 percent share against a uniform control of the same size.
|
||||
- `v6_window_bits.rs.offered`: a known-failed test for the per-load bias test's era-window fault (offered to the
|
||||
counter-asic-4 crate's suite; not built here).
|
||||
|
||||
The record: `docs/analysis/class-v6/invention.md`.
|
||||
15
tools/attack/v6-invention/uniform/Cargo.toml
Normal file
15
tools/attack/v6-invention/uniform/Cargo.toml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "v6inv-uniform"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[[bin]]
|
||||
name = "v6inv-uniform"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
igneum-pow = { path = "../../../../igneum-pow" }
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
95
tools/attack/v6-invention/uniform/src/main.rs
Normal file
95
tools/attack/v6-invention/uniform/src/main.rs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
//! v6inv-uniform (class v6 invention lane, 8 October 2026): the F8-form uniformity read for any load class the crate can
|
||||
//! draw, the per-load shadow forms included, through the library's own `trace_load_indices` (the execution order the
|
||||
//! class defines, not a mirror). Per seed: the first accepted candidate of `attempts_class`, then over `nonces` nonces
|
||||
//! (warps of 32) every load's index; per site the distinct-index ratio `d_s / E_s` with `E_s = N - N^2 / (2 W)` at
|
||||
//! W = 2^log2 (no era: every site on the whole dataset), and the cross-hash item histogram's top 0.1 percent share
|
||||
//! against a uniform SplitMix64 control of the same size (the F8 harness's null without an era). One TSV row per seed.
|
||||
//!
|
||||
//! v6inv-uniform --class mx8+shl4096x1 --seeds 64 --nonces 1048576 --threads 48 [--log2 28] [--day 2026-10-03]
|
||||
use igneum_pow::generator::{attempts_class, LoadClass};
|
||||
use igneum_pow::seed::{seed_words_from_bytes, SplitMix64};
|
||||
use igneum_pow::verify::{trace_load_indices, DatasetMode, DatasetSource};
|
||||
use std::collections::HashSet;
|
||||
use std::io::Write;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Mutex;
|
||||
|
||||
fn arg(args: &[String], k: &str, d: &str) -> String {
|
||||
args.iter().position(|a| a == k).and_then(|i| args.get(i + 1).cloned()).unwrap_or_else(|| d.to_string())
|
||||
}
|
||||
|
||||
fn top_share(counts: &mut Vec<u32>, frac: f64) -> (f64, u32) {
|
||||
let total: u64 = counts.iter().map(|&c| c as u64).sum();
|
||||
counts.sort_unstable_by(|a, b| b.cmp(a));
|
||||
let k = ((counts.len() as f64) * frac) as usize;
|
||||
let top: u64 = counts[..k].iter().map(|&c| c as u64).sum();
|
||||
(top as f64 / total as f64, counts[0])
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let class_name = arg(&args, "--class", "mx8+shl4096x1");
|
||||
let seeds: u32 = arg(&args, "--seeds", "64").parse().unwrap();
|
||||
let nonces: u32 = arg(&args, "--nonces", "1048576").parse().unwrap();
|
||||
let threads: usize = arg(&args, "--threads", "16").parse().unwrap();
|
||||
let log2: u32 = arg(&args, "--log2", "28").parse().unwrap();
|
||||
let day = arg(&args, "--day", "2026-10-03");
|
||||
let prefix = arg(&args, "--prefix", "igneum-v6inv");
|
||||
let class = LoadClass::parse(&class_name).expect("class");
|
||||
let ds = DatasetSource::new(&day, DatasetMode::ClosedForm, log2);
|
||||
let items = 1usize << (log2 - 4);
|
||||
let w = (1u64 << log2) as f64;
|
||||
let n = (nonces as f64) * (igneum_pow::generator::ITERATIONS as f64); // evaluations per site
|
||||
let e_s = n - n * n / (2.0 * w);
|
||||
let next = AtomicUsize::new(0);
|
||||
let out = Mutex::new(std::io::stdout());
|
||||
println!("class\tseed\tattempt\tprogram_id\tmin_site_ratio\tmin_site\ttop0.1_share\tcontrol_share\tratio_to_control\tmax_item_reads\tmax_item\tcontrol_max\treads");
|
||||
std::thread::scope(|s| {
|
||||
for _ in 0..threads {
|
||||
s.spawn(|| loop {
|
||||
let i = next.fetch_add(1, Ordering::Relaxed) as u32;
|
||||
if i >= seeds {
|
||||
break;
|
||||
}
|
||||
let label = format!("{prefix}/{i}");
|
||||
let tries = attempts_class(&label, label.as_bytes(), class);
|
||||
let Some((p, _)) = tries.into_iter().find(|(_, r)| r.is_ok()) else {
|
||||
let mut o = out.lock().unwrap();
|
||||
writeln!(o, "{class_name}\t{i}\texhausted").unwrap();
|
||||
continue;
|
||||
};
|
||||
let seed = seed_words_from_bytes(label.as_bytes());
|
||||
let sites = p.instrs.iter().filter(|x| x.op.is_load()).count();
|
||||
let mut distinct: Vec<HashSet<u32>> = (0..sites).map(|_| HashSet::with_capacity(nonces as usize)).collect();
|
||||
let mut counts = vec![0u32; items];
|
||||
let mut reads: u64 = 0;
|
||||
let mut base = 0u32;
|
||||
while base < nonces {
|
||||
let rows = trace_load_indices(&p, &seed, base, &ds);
|
||||
for (k, row) in rows.iter().enumerate() {
|
||||
let site = k % sites;
|
||||
for &idx in row.iter() {
|
||||
distinct[site].insert(idx);
|
||||
counts[(idx >> 4) as usize] += 1;
|
||||
reads += 1;
|
||||
}
|
||||
}
|
||||
base += 32;
|
||||
}
|
||||
let (min_ratio, min_site) = distinct.iter().enumerate().map(|(s, d)| (d.len() as f64 / e_s, s)).fold((f64::MAX, 0usize), |a, b| if b.0 < a.0 { b } else { a });
|
||||
let (share, max_reads) = top_share(&mut counts, 0.001);
|
||||
let max_item = 0u32; // the heaviest item's index is not kept (the sort loses it); the count is the number
|
||||
// the uniform control: the same number of reads over the same items
|
||||
let mut ctrl = vec![0u32; items];
|
||||
let mut rng = SplitMix64::new(0x9e37_79b9_7f4a_7c15 ^ i as u64);
|
||||
for _ in 0..reads {
|
||||
let x = rng.next() as usize & (items - 1);
|
||||
ctrl[x] += 1;
|
||||
}
|
||||
let (cshare, cmax) = top_share(&mut ctrl, 0.001);
|
||||
let mut o = out.lock().unwrap();
|
||||
writeln!(o, "{class_name}\t{i}\t{}\t{:016x}\t{min_ratio:.5}\t{min_site}\t{share:.6}\t{cshare:.6}\t{:.4}\t{max_reads}\t{max_item}\t{cmax}\t{reads}", p.attempt, p.program_id(), share / cshare).unwrap();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
46
tools/attack/v6-invention/v6_window_bits.rs.offered
Normal file
46
tools/attack/v6-invention/v6_window_bits.rs.offered
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//! Class v6 invention lane (8 October 2026): the per-load acceptance's value-level bias test must not judge the era
|
||||
//! window's fixed top index bits. Known-failed first: at counter-asic-4 5984ffab every per-load form under every drawn
|
||||
//! era was refused with "index bit 26 (or 27) at load site s set in 0 (or 16,384) of 16,384" (0 of 256 seeds on 11
|
||||
//! forms, build-1, 11:0x UK); with the window bits skipped the sound form accepts under an era as it does without one.
|
||||
use igneum_pow::accept::Reject;
|
||||
use igneum_pow::generator::{attempts_class, LoadClass};
|
||||
use igneum_pow::seed::seed_words_from_bytes;
|
||||
|
||||
fn era_class(name: &str, n: u32) -> LoadClass {
|
||||
let era_seed = seed_words_from_bytes(format!("igneum-era-test/{n}").as_bytes());
|
||||
let mut bytes = Vec::new();
|
||||
for w in era_seed {
|
||||
bytes.extend_from_slice(&w.to_le_bytes());
|
||||
}
|
||||
LoadClass::era(LoadClass::parse(name).unwrap(), &bytes, &igneum_pow::generator::V3_ALLOWED)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn per_load_bias_test_skips_the_era_window_bits() {
|
||||
let mut accepted = 0usize;
|
||||
let mut window_bit_rejections = 0usize;
|
||||
for i in 0..8u32 {
|
||||
let class = era_class("mx8+shl4096x1", i);
|
||||
let label = format!("igneum-v6inv/{i}");
|
||||
for (_, verdict) in attempts_class(&label, label.as_bytes(), class) {
|
||||
match verdict {
|
||||
Ok(()) => accepted += 1,
|
||||
Err(Reject::BiasedIndexBit { bit, ones, .. }) if bit >= 26 && (ones == 0 || ones == 16_384) => window_bit_rejections += 1,
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_eq!(window_bit_rejections, 0, "a window's fixed top bit was judged as biased");
|
||||
assert!(accepted >= 4, "the sound per-load form accepted on {accepted} of 8 seeds under drawn eras (0 before the fix)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn per_load_bias_test_still_refuses_a_biased_real_bit_without_an_era() {
|
||||
// the no-era census: every rejection on the real address bits stands (bit 0 at a one-count near 4,096 is the
|
||||
// product's low-bit law); the known-pass of the fix is that no era-free verdict moves
|
||||
let class = LoadClass::parse("mx8+shl4096x1").unwrap();
|
||||
let label = "igneum-v6inv/3";
|
||||
let v = attempts_class(label, label.as_bytes(), class);
|
||||
assert!(v.iter().all(|(_, r)| r.is_err()), "seed 3 exhausted the cap on the no-era census (0 of 32) and must still");
|
||||
assert!(v.iter().any(|(_, r)| matches!(r, Err(Reject::BiasedIndexBit { bit: 0, .. }))), "a bit-0 refusal on seed 3 stands");
|
||||
}
|
||||
|
|
@ -14,6 +14,11 @@
|
|||
# .json, .jsonl, .out, .err, .pid, .csv, .md, .toml, .yml) is flagged: a file name is a redirect or an argument, and a
|
||||
# redirect is never on a command line.
|
||||
# 3. `ps ... | grep <literal>` without the bracket form is flagged (the same self-match).
|
||||
# 4. (8 October 2026, 12:4x UK: twice in one day a merge gate died to signal 15 from another lane's kill pattern) `killall` with any
|
||||
# pattern, and `pkill`/`pgrep` (with or without -f, -x) whose pattern is a generic tool or a gate's name (bash, sh, node, cargo,
|
||||
# python, ssh, git, pre-push, merge-to-master, build-remote, remote-run, gate, igneum-gate, igneum-merge) are flagged: such a
|
||||
# pattern can match a gate or a merge run of another lane. A gate is killed by its pid file only
|
||||
# (.git/igneum-gate.pid, .git/igneum-merge.pid under the worktree: `kill "$(cut -d' ' -f1 <pidfile>)"`).
|
||||
#
|
||||
# tools/ci/kill-by-name-check.sh # exit 1 with file:line and the reason
|
||||
# tools/ci/kill-by-name-check.sh --self-test # fires on each banned shape, passes each allowed one
|
||||
|
|
@ -24,6 +29,20 @@ check_line() { # <line> -> prints the reason, returns 1, when the line carrie
|
|||
code="${line%%#*}" # a comment is not code (a line that starts with // or * is a comment too)
|
||||
[[ "$code" =~ ^[[:space:]]*(//|\*|/\*) ]] && return 0
|
||||
[[ "$line" =~ ^[[:space:]]*(//|\*|/\*) ]] && return 0
|
||||
# rule 4: killall, and any pkill/pgrep whose pattern could match a gate or a merge run of another lane (kills are by pid file only)
|
||||
if [[ "$code" =~ (^|[^A-Za-z0-9_./-])killall[[:space:]]+(-[A-Za-z0-9]+[[:space:]]+)*(\"[^\"]*\"|\'[^\']*\'|[^[:space:]|;\)]+) ]]; then
|
||||
echo "killall ${BASH_REMATCH[3]}: killall matches by name across every lane's processes; a gate or a merge run dies with it; kill by pid file only"; return 1
|
||||
fi
|
||||
local gp="$code"
|
||||
while [[ "$gp" =~ (^|[^A-Za-z0-9_./-])(pgrep|pkill)([[:space:]]+-[A-Za-z0-9]+)*[[:space:]]+(\"[^\"]*\"|\'[^\']*\'|[^[:space:]|;\)-][^[:space:]|;\)]*) ]]; do
|
||||
local gpat="${BASH_REMATCH[4]}"; gpat="${gpat#\"}"; gpat="${gpat%\"}"; gpat="${gpat#\'}"; gpat="${gpat%\'}"
|
||||
local core="${gpat#^}"; core="$(printf '%s' "$core" | sed -E 's/^\[([A-Za-z])\]/\1/')" # the bracket form [p]re-push reads as pre-push
|
||||
case "$core" in
|
||||
bash|sh|zsh|node|cargo|python|python3|ssh|git|perl|gate|igneum|*pre-push*|*merge-to-master*|*build-remote*|*remote-run*|*igneum-gate*|*igneum-merge*)
|
||||
echo "pkill/pgrep on a pattern that can match a gate or a merge run of another lane ($gpat): kill by pid file only (.git/igneum-gate.pid, .git/igneum-merge.pid)"; return 1 ;;
|
||||
esac
|
||||
gp="${gp#*${BASH_REMATCH[2]}}"
|
||||
done
|
||||
# every pgrep/pkill -f on the line, not only the first (`pkill -f "[i]gneum-prove-host"; pkill -f prove-shard.sh` hid its second)
|
||||
local rest="$code" m
|
||||
while [[ "$rest" =~ (^|[^A-Za-z0-9_./-])(pgrep|pkill)([[:space:]]+-[A-Za-z0-9]+)*[[:space:]]+-[A-Za-z]*f[A-Za-z]*[[:space:]]+(\"[^\"]*\"|\'[^\']*\'|[^[:space:]|;\)]+) ]]; do
|
||||
|
|
@ -52,6 +71,14 @@ check_line() { # <line> -> prints the reason, returns 1, when the line carrie
|
|||
if [ "${1:-}" = "--self-test" ]; then
|
||||
fails=0
|
||||
bad=(
|
||||
'killall node'
|
||||
'killall -9 igneum-miner'
|
||||
'pkill -f bash'
|
||||
'pkill -x node'
|
||||
'pkill -f "[p]re-push.sh"'
|
||||
'pgrep -f merge-to-master'
|
||||
'pkill -f "^igneum-gate:"'
|
||||
'pkill cargo'
|
||||
'pkill -f igneum-roll.log'
|
||||
'pkill -f "fleet-wave-3.log" || true'
|
||||
'pgrep -f igneumd >/dev/null && exit 0'
|
||||
|
|
@ -65,6 +92,10 @@ if [ "${1:-}" = "--self-test" ]; then
|
|||
"pgrep -fl 'igneumd --' | grep -v Wallet"
|
||||
)
|
||||
good=(
|
||||
'kill "$(cut -d" " -f1 .git/igneum-gate.pid)"'
|
||||
'pkill -F /srv/x/run.pid'
|
||||
'pkill -P "$keeper"'
|
||||
'pkill -x igneumd'
|
||||
'pgrep -f "[i]gneumd" >/dev/null'
|
||||
"pkill -f '[n]ode tools/fleet/wave.mjs'"
|
||||
'pgrep -x igneumd'
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@
|
|||
# unless --fixes-master, none pushes the branch, pending waits then goes
|
||||
set -euo pipefail
|
||||
ROOT=$(git rev-parse --show-toplevel); cd "$ROOT"
|
||||
# kill-proof by rule (8 October 2026): a unique title per run and a pid file under the worktree's git directory, removed at exit; a merge
|
||||
# run is stopped by `kill "$(cut -d' ' -f1 .git/igneum-merge.pid)"` and never by a name pattern (tools/ci/kill-by-name-check.sh)
|
||||
if [ -z "${IGNEUM_MERGE_TITLE:-}" ] && [ "${IGNEUM_GATE_NO_TITLE:-0}" != 1 ]; then export IGNEUM_MERGE_TITLE="igneum-merge:$$-$(date +%s)"; exec -a "$IGNEUM_MERGE_TITLE" bash "$0" "$@"; fi
|
||||
MERGE_PID_FILE="$(git rev-parse --git-dir)/igneum-merge.pid"
|
||||
printf '%s %s %s\n' "$$" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "${IGNEUM_MERGE_TITLE:-untitled}" > "$MERGE_PID_FILE" 2>/dev/null || true
|
||||
trap 'rm -f "$MERGE_PID_FILE"' EXIT
|
||||
. tools/ci/gh-env.sh # every gh call here reads Igneum's own gh directory, never the founder's (8 October 2026)
|
||||
BRANCH="$(git rev-parse --abbrev-ref HEAD)"; TRIES=6; CI_WAIT_MIN="${CI_WAIT_MIN:-25}"; FIXES_MASTER=0; SELF_TEST=0; REMOTE="${MERGE_REMOTE:-origin}"
|
||||
while [ $# -gt 0 ]; do case "$1" in --tries) TRIES="$2"; shift 2 ;; --ci-wait) CI_WAIT_MIN="$2"; shift 2 ;; --fixes-master) FIXES_MASTER=1; shift ;; --remote) REMOTE="$2"; shift 2 ;; --self-test) SELF_TEST=1; shift ;; -*) echo "unknown option $1" >&2; exit 2 ;; *) BRANCH="$1"; shift ;; esac; done
|
||||
|
|
|
|||
|
|
@ -27,8 +27,19 @@ cd "$(git rev-parse --show-toplevel)" || exit 1
|
|||
unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_PREFIX GIT_COMMON_DIR GIT_OBJECT_DIRECTORY GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_QUARANTINE_PATH GIT_PUSH_OPTION_COUNT
|
||||
MODE="${1:-local}"; MODE="${MODE#--}"
|
||||
GATE_ROOT="$(pwd -P)"
|
||||
# Kill-proof by rule (8 October 2026, 12:4x UK: twice in a day a gate died to signal 15 from another lane's kill pattern): every gate run
|
||||
# carries a unique process title (igneum-gate:<pid>-<start>, set by re-exec through `exec -a`) and writes its pid, start and mode to
|
||||
# .git/igneum-gate.pid under the worktree (removed at exit); a gate is stopped by that file only (`kill "$(cut -d' ' -f1 <file>)"`), and
|
||||
# tools/ci/kill-by-name-check.sh refuses any pkill/pgrep/killall pattern that could match a gate. IGNEUM_GATE_NO_TITLE=1 skips the re-exec.
|
||||
if [ -z "${IGNEUM_GATE_TITLE:-}" ] && [ "${IGNEUM_GATE_NO_TITLE:-0}" != 1 ] && [ "$MODE" != self-test ]; then
|
||||
export IGNEUM_GATE_TITLE="igneum-gate:$$-$(date +%s)"
|
||||
exec -a "$IGNEUM_GATE_TITLE" bash "$0" "$@"
|
||||
fi
|
||||
GATE_PID_FILE="$(git rev-parse --git-dir 2>/dev/null || echo .git)/igneum-gate.pid"
|
||||
printf '%s %s %s %s\n' "$$" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$MODE" "${IGNEUM_GATE_TITLE:-untitled}" > "$GATE_PID_FILE" 2>/dev/null || true
|
||||
[ "${IGNEUM_GATE_HOLD:-0}" = 1 ] && sleep 4 # the self-test's window to read the file and the title
|
||||
. "$GATE_ROOT/tools/ci/gh-env.sh" # every gh call under the gate reads Igneum's own gh directory, never the founder's (8 October 2026) # the readers below are called from fixture repositories in the self-test, so by absolute path
|
||||
RED=0; N=0; LOG="$(mktemp)"; trap 'rm -rf "$LOG" "${SITE_TMP:-}"' EXIT
|
||||
RED=0; N=0; LOG="$(mktemp)"; trap 'rm -rf "$LOG" "${SITE_TMP:-}"; rm -f "$GATE_PID_FILE"' EXIT
|
||||
T0=$(date +%s)
|
||||
|
||||
run() {
|
||||
|
|
@ -271,6 +282,14 @@ case "$MODE" in
|
|||
MODE=ci GITHUB_ACTIONS= site_in_place && { echo "self-test failed: --ci outside GitHub Actions chose the in-place build"; fails=1; }
|
||||
MODE=ci GITHUB_ACTIONS=true site_in_place || { echo "self-test failed: --ci inside GitHub Actions did not choose the in-place build"; fails=1; }
|
||||
declare -f tree_checks | grep -q 'never_push_checks' || { echo "self-test failed: the full gate does not run the never-push checks"; fails=1; }
|
||||
# kill-proof: a running gate writes its pid, start and mode to .git/igneum-gate.pid and removes it at exit; the title re-exec is in the script
|
||||
pf="$(mktemp -d)"; ( cd "$pf" && git init -q -b master . )
|
||||
# a gate that is held open (IGNEUM_GATE_HOLD=1 sleeps 3 s after writing the file) names its own pid and mode in the file; the file is gone after it
|
||||
( cd "$pf"; IGNEUM_GATE_HOLD=1 bash "$GATE_ROOT/tools/ci/pre-push.sh" --list >/dev/null 2>&1 & p=$!; sleep 2; f="$pf/.git/igneum-gate.pid"
|
||||
if [ ! -f "$f" ]; then echo "self-test failed: no pid file at $f while the gate runs"; else read -r pid start mode title < "$f"; [ "$pid" = "$p" ] || echo "self-test failed: the pid file names $pid, the gate is $p"; [ "$mode" = list ] || echo "self-test failed: the pid file's mode is $mode"; case "$title" in igneum-gate:*) ;; *) echo "self-test failed: the pid file carries no title: $title" ;; esac; [ "$(ps -o command= -p "$p" | cut -d' ' -f1)" = "$title" ] || echo "self-test failed: the process title is $(ps -o command= -p "$p" | cut -d' ' -f1), the file says $title"; fi
|
||||
wait $p 2>/dev/null; [ -f "$f" ] && echo "self-test failed: the pid file outlived the gate"; true ) | grep 'self-test failed' && fails=1
|
||||
rm -rf "$pf"
|
||||
grep -q 'exec -a "\$IGNEUM_GATE_TITLE" bash "\$0" "\$@"' "$0" || { echo "self-test failed: the gate does not re-exec under its unique title"; fails=1; }
|
||||
# the overlap sweep's wall clock runs the command with GNU timeout where it exists and plainly where it does not (bash 3.2 under set -u included)
|
||||
[ "$(wall_clock 5 /bin/echo clocked 2>&1)" = clocked ] || { echo "self-test failed: wall_clock did not run its command"; fails=1; }
|
||||
[ "$(PATH=/nonexistent wall_clock 5 /bin/echo plain 2>&1)" = plain ] || { echo "self-test failed: wall_clock without a timeout binary did not run its command plainly"; fails=1; }
|
||||
|
|
|
|||
1
tools/reference-apps/fixtures/dn3-account-proof.json
Normal file
1
tools/reference-apps/fixtures/dn3-account-proof.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"request":{"method":"eth_getProof","params":["0x085a7ca7338efaf797f3300fa7c64afa9d2c539b",[],"0x6f2e"]},"block":{"number":"0x6f2e","hash":"0xa75c5624c1d5be04a126712c4dfbf30091336bc21107278795341358e3ac9d19","stateRoot":"0x1fd551393d84009c398a9b9747cd296d0fdf1e31f85fa21c10426bc219694561"},"result":{"accountProof":["0xf90211a035a5663e80bde9c005c3f519613b5c3ff2add9bb9310908d4b6478ddfdd42b09a0628c3663581b1c12c36c5103080474c8f1503dc78e498e290e0ce309ee5dd580a048442259307de1a1ddc270914b19054e914a59f7ad1992c88fe9e5eeb91b91d3a0e72f8245f6bfe8fe9356e186352dc55a7f16e4eaf8bebfa8950625f0185ea699a0c8cf4b30c816ffbc8fc615de2e87ff7fe7ff384e22286b5cbb8aa29f126d2688a06819cfcddf29f3b1c72b4df680105c393217282d22439e204bfaf42eb5dfc3e0a0eafc7b7ab68e87b1574ce1c0a383b876ca03eb851e6d4074a6faa11583f8938fa0077c5575ade9c4657ef3094d44b493452279890fdd2028cbc46d7d7b260bfdf4a0f56e310ad31c53de3dd63db5823d99375f0ebed359d81efc13bc48e0fec734baa0a3a9b96516f395397fc8f86ada0e75c6b56fb56f26686b0de9b994828e7050a3a0f721a95427f32ec9105a8b6ae61ea87d68409f005eb4bb1bce08f8682de0f23aa08a09b8aba440e829c5b75680940ab07f7af7de4d5b784a7ebb4a9a55d5482686a072fed18995aede9d7cd457a87f58abb19b16d2794d7197e8808d049aa81fe4b1a058f1fadf00854cbe3d7b9fc0bdd2e38fe6c25bd944bc5b55f916c394282ba527a01e2b4f50116b9f85ef2b704b4e0858317961a715ff891e996eef10e4856c9d09a0588251a542d92fd21df94204ef0e7eb19224979273f6fa25a276ded6eca00b2080","0xf8b180808080a0420981c3d36f89ff245988aee9cf67b0852aa20aac3c0dd683b6441b8325ee6680a077d4821f911305b34d67a0f25372b5102b157ed8a3bcbcca278d663f41c2740ba0ca001aa786bbd28c50b735599b74b883185be98a9ea6118b519720fbed7720b9808080a04ea6a6815f895cbcf98aab72a2db87a197fd077953c650a9d74782dd1ca064df808080a025c2908da5906b49a3da3c07e84912f3428889a96f91da09057604c4bf189ab880","0xf872a0200f6ca86de6ec8bae815e435db88eb1e3ccc026af0d2049dc0299f37ac21622b84ff84d80891db25c13e886c5cc00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"],"address":"0x085a7ca7338efaf797f3300fa7c64afa9d2c539b","balance":"0x1db25c13e886c5cc00","blockHash":"0xa75c5624c1d5be04a126712c4dfbf30091336bc21107278795341358e3ac9d19","blockNumber":"0x6f2e","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","nonce":"0x0","stateRoot":"0x1fd551393d84009c398a9b9747cd296d0fdf1e31f85fa21c10426bc219694561","storageHash":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","storageProof":[]}}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -117,6 +117,37 @@
|
|||
"gasUsed": 404376,
|
||||
"calldataBytes": 5701,
|
||||
"headers": 1
|
||||
},
|
||||
{
|
||||
"at": "2026-10-08T11:36:17.204Z",
|
||||
"what": "setVerifier",
|
||||
"verifier": "0xAf74f3F512081291D663Bb1d6b6d37E99e37D744",
|
||||
"tx": "0xd679bb6581d7bf11fefa5cf78e06c3942a7da508d9fca74da976bd08013fdb8e",
|
||||
"block": 11869902,
|
||||
"gasUsed": 31170
|
||||
},
|
||||
{
|
||||
"at": "2026-10-08T11:36:26.812Z",
|
||||
"what": "submitCertificate (shared verifier)",
|
||||
"verifier": "0xAf74f3F512081291D663Bb1d6b6d37E99e37D744",
|
||||
"index": "2232",
|
||||
"checkpoint": "0xf056c26ef290dbaf79045441dd0c976181e25fb7c51d702fcdd331bce877cff8",
|
||||
"tx": "0x1794b785f9d3d3251edcec01e08e5a9cd0f41ea6c9143d8099256653a2801e8a",
|
||||
"block": 11869903,
|
||||
"gasUsed": 792677
|
||||
},
|
||||
{
|
||||
"at": "2026-10-08T11:36:40.002Z",
|
||||
"what": "submitStateRoot",
|
||||
"vector": "devnet-3",
|
||||
"number": "28439",
|
||||
"postRoot": "0x6e6d2fc8993db13220d84f39ca9cbc08a8c6975ce2932a4289a1d6ef4cef60c8",
|
||||
"certIndex": "2232",
|
||||
"tx": "0x3629525e57eae4483ef40c7ee61f7364b4a9ff8adc3336d89ff6018427e1b2d3",
|
||||
"block": 11869904,
|
||||
"gasUsed": 1624984,
|
||||
"calldataBytes": 24391,
|
||||
"headers": 6
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
88
tools/reference-apps/oracle/real-verifier.mjs
Normal file
88
tools/reference-apps/oracle/real-verifier.mjs
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
// Points the oracle at the shared IgneumCertificateVerifier on Sepolia and runs the real path through it (8 October 2026):
|
||||
// 1. setVerifier(<the shared verifier>) on the oracle (owner only), when it is not set yet
|
||||
// 2. a fresh balance proof from the light service (the newest paid segment record and the earliest certificate above
|
||||
// its carrier), its certificate encoded for the precompiles (bitmap bytes as carried; the 96-byte compressed G2
|
||||
// aggregate signature decompressed to the EIP-2537 256-byte form) and checked with verifyCertificate by eth_call
|
||||
// 3. submitCertificate on the shared verifier (a real BLS check on chain), then submitStateRoot on the oracle,
|
||||
// then provenBalance read back beside the node's eth_getProof balance
|
||||
// The proof body is written to ../fixtures/dn3-balance.json so test.mjs part C and demo.mjs run against the same vector.
|
||||
// node real-verifier.mjs [--verifier 0x...] [--address 0x...] [--api https://rpc.devnet.igneum.network/light]
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { bls12_381 } from '../light-service/node_modules/@noble/curves/bls12-381.js';
|
||||
import * as L from './lib.mjs';
|
||||
|
||||
const arg = (k, d) => { const i = process.argv.indexOf(k); return i > 0 ? process.argv[i + 1] : d; };
|
||||
const VERIFIER = arg('--verifier', '0xAf74f3F512081291D663Bb1d6b6d37E99e37D744');
|
||||
const API = arg('--api', 'https://rpc.devnet.igneum.network/light').replace(/\/$/, '');
|
||||
const here = path.dirname(new URL(import.meta.url).pathname);
|
||||
const fixtures = path.join(here, '..', 'fixtures');
|
||||
const strip = s => String(s).replace(/^0x/, '');
|
||||
const hex = b => '0x' + Array.from(b, x => x.toString(16).padStart(2, '0')).join('');
|
||||
const be = (n, len) => { const out = new Uint8Array(len); let v = BigInt(n); for (let i = len - 1; i >= 0; i--) { out[i] = Number(v & 0xffn); v >>= 8n; } return out; };
|
||||
const fe = n => { const out = new Uint8Array(64); out.set(be(n, 48), 16); return out; };
|
||||
const concat = parts => { const n = parts.reduce((a, p) => a + p.length, 0); const out = new Uint8Array(n); let o = 0; for (const p of parts) { out.set(p, o); o += p.length; } return out; };
|
||||
|
||||
// the aggregate signature: 96 bytes compressed (the chain's form) to x.c0 || x.c1 || y.c0 || y.c1, 64 bytes each
|
||||
export function g2Uncompressed(compressedHex) {
|
||||
const G2 = bls12_381.G2.Point || bls12_381.G2.ProjectivePoint;
|
||||
const p = G2.fromHex(strip(compressedHex)); const a = p.toAffine();
|
||||
return hex(concat([fe(a.x.c0), fe(a.x.c1), fe(a.y.c0), fe(a.y.c1)]));
|
||||
}
|
||||
|
||||
const verifierAbi = [
|
||||
{ type: 'function', name: 'chainId', stateMutability: 'view', inputs: [], outputs: [{ type: 'string' }] },
|
||||
{ type: 'function', name: 'tableId', stateMutability: 'view', inputs: [], outputs: [{ type: 'bytes32' }] },
|
||||
{ type: 'function', name: 'verifyCertificate', stateMutability: 'view', inputs: [{ type: 'uint64' }, { type: 'bytes32' }, { type: 'bytes' }, { type: 'bytes' }], outputs: [{ type: 'bool' }, { type: 'uint256' }, { type: 'uint256' }] },
|
||||
{ type: 'function', name: 'submitCertificate', stateMutability: 'nonpayable', inputs: [{ type: 'uint64' }, { type: 'bytes32' }, { type: 'bytes' }, { type: 'bytes' }], outputs: [] },
|
||||
{ type: 'function', name: 'finalCheckpoint', stateMutability: 'view', inputs: [{ type: 'uint64' }], outputs: [{ type: 'bytes32' }] },
|
||||
{ type: 'function', name: 'isFinal', stateMutability: 'view', inputs: [{ type: 'bytes32' }], outputs: [{ type: 'bool' }] },
|
||||
];
|
||||
|
||||
const pub = L.publicClient(); const account = L.deployerAccount(); const wallet = L.walletClient(account);
|
||||
const d = L.deployment(); const oracleAbi = L.artifact('IgneumStateOracle').abi;
|
||||
const read = (fn, args = []) => pub.readContract({ address: d.oracle.address, abi: oracleAbi, functionName: fn, args });
|
||||
|
||||
// 1. the verifier on the oracle
|
||||
let current = await read('verifier');
|
||||
console.log(L.ukTime(), 'UK oracle', d.oracle.address, 'verifier now', current, 'shared', VERIFIER, 'chainId', await pub.readContract({ address: VERIFIER, abi: verifierAbi, functionName: 'chainId' }), 'tableId', await pub.readContract({ address: VERIFIER, abi: verifierAbi, functionName: 'tableId' }));
|
||||
if (current.toLowerCase() !== VERIFIER.toLowerCase()) {
|
||||
const hash = await wallet.writeContract({ address: d.oracle.address, abi: oracleAbi, functionName: 'setVerifier', args: [VERIFIER] });
|
||||
const r = await pub.waitForTransactionReceipt({ hash, timeout: 180_000 });
|
||||
if (r.status !== 'success') throw new Error('setVerifier reverted in ' + hash);
|
||||
L.recordWrite({ what: 'setVerifier', verifier: VERIFIER, tx: hash, block: Number(r.blockNumber), gasUsed: Number(r.gasUsed) });
|
||||
current = await read('verifier');
|
||||
console.log(L.ukTime(), 'UK setVerifier done: tx', hash, 'block', Number(r.blockNumber), 'gas', Number(r.gasUsed), 'verifier now', current);
|
||||
}
|
||||
|
||||
// 2. a fresh proof and its certificate, checked by eth_call
|
||||
const cp = await (await fetch(API + '/checkpoint')).json();
|
||||
if (!cp.ok) throw new Error('checkpoint: ' + cp.error);
|
||||
const tipBlock = await fetch('https://rpc.devnet.igneum.network', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_getBlockByNumber', params: ['latest', false] }) }).then(r => r.json());
|
||||
const address = arg('--address', tipBlock.result.igneum.rewards[0].miner);
|
||||
const proof = await (await fetch(`${API}/balance?address=${address}&checkpoint=${cp.hash}&index=${cp.index}`)).json();
|
||||
if (!proof.ok) throw new Error('balance: ' + proof.error);
|
||||
const cert = proof.checkpoint_certificate || cp;
|
||||
if (Number(cert.index) !== Number(proof.checkpoint.index)) throw new Error('the proof and its certificate disagree on the index');
|
||||
const bitmap = '0x' + strip(cert.certificate.bitmap_hex);
|
||||
const signature = g2Uncompressed(cert.certificate.aggregate_signature_hex);
|
||||
const checkpoint = '0x' + strip(cert.hash);
|
||||
const [ok, signed, total] = await pub.readContract({ address: VERIFIER, abi: verifierAbi, functionName: 'verifyCertificate', args: [BigInt(cert.index), checkpoint, bitmap, signature] });
|
||||
console.log(L.ukTime(), `UK certificate ${cert.index} (${checkpoint.slice(0, 14)}, ${cert.certificate.voter_count} voters, signers bitmap ${bitmap}) verifyCertificate by eth_call: ok=${ok} signed=${signed} total=${total}`);
|
||||
if (!ok) throw new Error('the shared verifier refuses this certificate (its installed table is at index 2127; a later table drifted past the rule, or a signer is not in it)');
|
||||
|
||||
// 3. record it, store the root, read the balance
|
||||
const already = (await pub.readContract({ address: VERIFIER, abi: verifierAbi, functionName: 'finalCheckpoint', args: [BigInt(cert.index)] })).toLowerCase() === checkpoint.toLowerCase();
|
||||
if (!already) {
|
||||
const hash = await wallet.writeContract({ address: VERIFIER, abi: verifierAbi, functionName: 'submitCertificate', args: [BigInt(cert.index), checkpoint, bitmap, signature] });
|
||||
const r = await pub.waitForTransactionReceipt({ hash, timeout: 180_000 });
|
||||
if (r.status !== 'success') throw new Error('submitCertificate reverted in ' + hash);
|
||||
L.recordWrite({ what: 'submitCertificate (shared verifier)', verifier: VERIFIER, index: String(cert.index), checkpoint, tx: hash, block: Number(r.blockNumber), gasUsed: Number(r.gasUsed) });
|
||||
console.log(L.ukTime(), 'UK submitCertificate on the shared verifier: tx', hash, 'block', Number(r.blockNumber), 'gas', Number(r.gasUsed));
|
||||
} else console.log(L.ukTime(), 'UK certificate', cert.index, 'already final on the shared verifier');
|
||||
writeFileSync(path.join(fixtures, 'dn3-balance.json'), JSON.stringify({ ...proof, checkpoint_certificate: { ok: true, ...cert } }));
|
||||
const v = L.vectorFromBalanceFixture({ ...proof, checkpoint_certificate: { ok: true, ...cert } });
|
||||
const s = await L.ensureStateRoot(pub, wallet, d, v);
|
||||
console.log(L.ukTime(), 'UK state root for block', v.number, s.already ? 'already stored' : `stored: tx ${s.tx} block ${s.block} gas ${s.gasUsed} (${s.headers} headers, ${s.calldataBytes} B calldata)`);
|
||||
const bal = await read('provenBalance', [v.number, address, proof.account.accountProof]);
|
||||
console.log(L.ukTime(), `UK provenBalance(${v.number}, ${address}) on Sepolia = ${bal} wei; the node's eth_getProof says ${BigInt(proof.account.balance)} wei: ${bal === BigInt(proof.account.balance) ? 'MATCH' : 'MISMATCH'}`);
|
||||
|
|
@ -52,9 +52,14 @@ const cp = '0x' + L.strip(f.checkpoint.hash);
|
|||
}
|
||||
|
||||
// ---- Part B: the synthetic vector -----------------------------------------------------------------------------
|
||||
// The synthetic certificate is accepted by the stub verifier only; with the shared verifier installed (a real BLS check)
|
||||
// part B's positive case cannot be recorded, so the part is skipped and part C (the real proof) carries the positive.
|
||||
const S = L.buildSynthetic();
|
||||
const wallet = L.walletClient(L.deployerAccount());
|
||||
{
|
||||
const installedVerifier = String(await read('verifier')).toLowerCase();
|
||||
const stubAddress = String((d.stub && d.stub.address) || (d.verifier && d.verifier.address) || '').toLowerCase();
|
||||
if (installedVerifier !== stubAddress) console.log(' Part B skipped: the installed verifier', installedVerifier, 'is not the stub (synthetic certificates are refused by a real BLS check)');
|
||||
else {
|
||||
const c = await L.ensureCertificate(pub, wallet, d, S.certIndex, L.hex0x(L.hexToBytes(S.checkpoint)));
|
||||
console.log(' stub certificate', S.certIndex, c.already ? 'already recorded' : 'recorded in ' + c.tx + ' block ' + c.block + ' gas ' + c.gasUsed);
|
||||
const args = L.proofArgs(S);
|
||||
|
|
|
|||
Loading…
Reference in a new issue