diff --git a/docs/benchmarks/proving-e2e.md b/docs/benchmarks/proving-e2e.md index b501ba7ec..7f1f9691a 100644 --- a/docs/benchmarks/proving-e2e.md +++ b/docs/benchmarks/proving-e2e.md @@ -76,7 +76,7 @@ Mining compatibility and proving compatibility are reported separately, because | Card | Memory | Mining: lottery hash | Proving: this standard | |---|---|---|---| -| NVIDIA RTX 5090 | 32 GB | Measured: 229 Mhash/s at 1 GiB, bit-exact (bench-log, 3 October 2026) | Not run | +| NVIDIA RTX 5090 | 32 GB | Measured: 229 Mhash/s at 1 GiB, bit-exact (bench-log, 3 October 2026) | Not run as a standard run. A 1,488-pgas block proven 4 October 2026 (core 1.4 s, compressed 2.7 s); the shard at `S_p` and the two- and four-shard blocks are the PROVE-SHARD.bat run, pending | | NVIDIA RTX 4090 | 24 GB | Not run | Not run | | NVIDIA RTX 4070 | 12 GB | Not run | Not run; the design's reference card class ("a 12 GB card") | | NVIDIA RTX 3060 12 GB | 12 GB | Not run | Not run; the phase 2 gate names a "3060-class card" (ledger P1) | @@ -84,7 +84,7 @@ Mining compatibility and proving compatibility are reported separately, because | AMD RX 7900 XTX | 24 GB | Not run (discrete AMD never run, O-1.15) | Not run | | AMD RX 6700 XT | 12 GB | Not run | Not run | | AMD gfx1036 (Ryzen 7 9800X3D integrated) | shared | Measured: 4.38 Mhash/s on 1 compute unit, bit-exact (bench-log) | Not eligible: shared system memory | -| Apple M5 Max (40 GPU cores) | 64 GB unified | Measured: 45.2 Mhash/s at 1 GiB, bit-exact (bench-log) | Not run | +| Apple M5 Max (40 GPU cores) | 64 GB unified | Measured: 45.2 Mhash/s at 1 GiB, bit-exact (bench-log) | Not run as a standard run. CPU only, 4 October 2026 (bench-log, "proving: devnet v4 shards"): one shard at `S_p` executes in 60 M SP1 cycles; a 200-pgas shard proven core 83 s, compressed 272 s, on a machine at load 40 | | Apple M-series, 16 GB unified | 16 GB unified | Not run | Not run | | Intel Arc A770 | 16 GB | Not run | Not run | @@ -145,8 +145,8 @@ An operator declares each row in their report and signs it with the vote key tha | Item | What closes it | |---|---| -| The workload files and `tools/bench-e2e/` | Written with the phase 2 SP1 implementation (execution engineer) | -| The provisional `B_p` and `S_p` | The project's own first run, published before the external runs | +| The workload files and `tools/bench-e2e/` | Written with the phase 2 SP1 implementation (execution engineer). First step taken 4 October 2026: `proving/fixtures/block-{338,341,344}` are one, two and four shards at `S_p` from `tools/prove-fixtures`, with the shard plan and every shard's witness; they are fixtures for the shard measurement, not W1 to W3 | +| The provisional `B_p` and `S_p` | The project's own first run, published before the external runs. `B_p` = 30 M (devnet v4), `S_p` = 7.5 M = `B_p / 4` provisional since 4 October 2026 (spec 7.4, 7.6), to be set from the PROVE-SHARD.bat shard times | | The wrapped-proof stage on consumer hardware | O-10.7, measured in the same campaign | | The reproduction reward and who pays it | `docs/plans/funding.md`, challenge reward row | | Whether a 10 GB card can prove W3 at all | The RTX 3080 row of section 6 | diff --git a/docs/fud-ledger.md b/docs/fud-ledger.md index 7e6043c63..32e92bc9e 100644 --- a/docs/fud-ledger.md +++ b/docs/fud-ledger.md @@ -1183,7 +1183,7 @@ Evidence: the two sections. Review id R3.9. ### P12. An aggregator can name itself as every prover "`ProofRecord.provers` is who is paid and nothing in a shard proof's statement says who proved it. I aggregate eight gossiped shard proofs and write my key eight times." -Status: Open, format fix named. +Status: Fixed in the proving code (4 October 2026, `proving/igneum-prove`): every shard proof's public values carry the prover's payout address (`ShardOutput.prover`), the aggregated block proof commits keccak over the provers in shard order and the shard program's verifying-key hash (`BlockOutput.provers`, `BlockOutput.shard_vk`), and the host verifier checks both before it accepts a claim. Still to do in the node: `ProofRecord.provers` must hash to `BlockOutput.provers` or the record is invalid (acceptance test A5); records are not on devnet v4 yet. Was: Open, format fix named. Answer: Correct. Section 5.1's shard statement (pre-root, transactions, post-root, receipts) and the `ProofSystem` trait of 5.6 carry no prover identity; 4.4 credits the pool to the record's `provers`. Fix: each shard proof's public input includes the prover's payout key, aggregation carries the keys as public outputs, and a record whose list does not match them is invalid; acceptance test A5 checks the match, not only the credit. @@ -1463,7 +1463,7 @@ Evidence: `docs/bench-log.md`, 4 October 2026 "execution layer attack fixes" (be ### P20. The SP1 GPU client panics on shutdown and the compressed stage waited ten minutes "Your first GPU proof run aborted with a core dump. What else aborts?" -Status: Open, found by the team (4 October 2026, morning, first RTX 5090 run through WSL2, SP1 6.8.1). +Status: Fixed in the host, to be confirmed on the PC (4 October 2026, afternoon). (1) `igneum-prove-host` holds a Tokio runtime for the whole run (`main` enters it before anything else) and drops the proof system inside it, then shuts the runtime down with a 10-s grace, so `sp1-cuda`'s `tokio::spawn` in `Drop` finds a runtime. (2) Every stage prints a `STAGE ... start` line and a `RESULT` line with a UTC timestamp, and the setup line splits client creation from the two key setups (on the Mac CPU the client creation alone is 30 to 50 s of a 40 to 60 s setup; bench-log 4 October 2026, shards). The next PC run (PROVE-SHARD.bat) shows whether the gap sits before the first compressed stage and how long it is on the card. Was: Open, found by the team (4 October 2026, morning, first RTX 5090 run through WSL2, SP1 6.8.1). Answer: Two separate things, neither in the proof. (1) After every proof was written, verified and uploaded, `sp1-cuda`'s client dropped its session key outside a Tokio runtime and panicked in its destructor (`sp1-cuda-6.8.1/src/pk.rs:63`, `client.rs:221`), so the host exited 134 with the results already on disk. Fix in our host: hold a runtime for the client's lifetime or drop the proof system inside one. (2) Between the core proof (08:49:10 UTC) and "Proving with mode: Compressed" (08:59:02 UTC) the host was silent for ten minutes while the card was idle; the compressed mode's recursion setup on first use is the suspect, and the second run must time it. Both go on the proving e2e benchmark standard as fixed overheads to measure, not hide. diff --git a/docs/spec/07-execution.md b/docs/spec/07-execution.md index d78a7138a..5de392507 100644 --- a/docs/spec/07-execution.md +++ b/docs/spec/07-execution.md @@ -71,6 +71,8 @@ Nothing in consensus changes for any of this: the segment claim already commits | Per-transaction pgas cap | the including block's remaining `B_p`, metered incrementally, halt before the crossing opcode or precompile | Decided 4 October 2026 (ledger P19), 7.5 | | Over-cap transaction | executed as out of gas: charged for gas and pgas consumed to the abort, status 0, nonce advanced, never skipped | Decided 4 October 2026 (ledger P19), 7.5 | | Mempool bounds | `gas_limit <= B_e`; estimated pgas `<= B_p`; template packs by the estimate | Designed, node policy (ledger P18, P19), 7.5 | +| Shard budget `S_p` | 7,500,000 pgas (`B_p / 4`), provisional: the specification carried no number before 4 October 2026; set from the shard-time measurements, never from the fixtures | Implemented (`proving/igneum-prove/core/src/config.rs`), value Designed, 7.6 | +| Shard statement carry | a link hash between consecutive shards (transaction index, including block, block gas and pgas, cumulative gas, running transaction commitment) | Implemented, 7.6 | ## 7.5 Proving gas per transaction: the cap and the abort @@ -82,3 +84,11 @@ Decided 4 October 2026 (ledger P18 and P19, closed by this section; `docs/bench- 4. **The pgas dimension is visible.** `eth_estimateGas` folds the proving charge into the quoted gas limit (7.1) and fails, naming the pgas metered and `B_p`, for a call that hits the cap; `eth_call` fails the same way. `igneum_estimateGas` returns both dimensions for the same simulation: `gasUsed`, `pgas`, the folded `gas`, `provingGasLimit`, both base fees and `exceedsProvingLimit`, so a wallet or tool can show the proving side. What the rule gives, measured (bench-log, 4 October 2026, `B_p` 30 M, modexp loop of 9,000 calls): before, 10.85 ms of native execution per inclusion, nothing charged, the nonce stuck and the sender's later transactions never includable; after, the mempool refuses it, a hostile miner's inclusion is cut at 29,998,593 pgas after 4,680,437 gas in 11.4 ms, the sender pays 0.0394 IGN, the nonce advances, a second inclusion is skipped in 35 us, and the next nonce executes in the following blocks. + +## 7.6 Shard statement and block proof, as implemented + +Added 4 October 2026 because the implementation (`proving/igneum-prove`, devnet v4) needed three definitions the specification did not give. They are Implemented; nothing else in this section changes. + +1. **Carry between shards.** Section 7.2 cuts a segment at transaction boundaries, but a transaction's outcome depends on more than the state: the including block's running gas and pgas (the budgets of 7.5), the receipts' cumulative gas, and the position in the segment. Shard i therefore starts from a carry (transaction index, including-block index, block gas, block pgas, cumulative gas, running transaction commitment) and ends with the carry shard i+1 starts from; each shard proof commits the hash of both (`link_in`, `link_out`), and the block proof is invalid unless every `link_in` equals the previous `link_out` and the first is the empty carry. A shard whose single transaction exceeds `S_p` is a shard of its own (`over_budget`); the zkVM's own continuations prove it (approximate). +2. **Transaction commitment.** The block's transaction commitment is a running keccak over the transactions in sequence order (`acc = keccak(acc, miner, blue, length, raw)`), carried in the link, so it is the same whatever the cut. The block proof's `tx_commitment` is the final accumulator. +3. **Receipts.** A shard commits the ordered trie root of its own receipts (cumulative gas running across the whole segment); the block proof commits keccak over the shard receipts roots in order. This is what a proof record's `receipts` (design 5.4) means under this implementation, and what the native-execution veto of 7.2 item 5 compares. The provers are committed the same way (keccak over the shards' payout addresses, ledger P12), beside the shard program's verifying-key hash and, when the proof chains to the previous segment's proof, the aggregator's own. diff --git a/proving/README.md b/proving/README.md index a8f1b6820..01b6caed8 100644 --- a/proving/README.md +++ b/proving/README.md @@ -1,18 +1,21 @@ # proving -Igneum proving v0 (3 October 2026): the first SP1 proof of an Igneum block. Plan and scope: `docs/plans/proving-v0.md`. +Igneum proving: v0 (3 October 2026, one SP1 proof per block) and the devnet v4 shards (4 October 2026). Plan, status and measurements: `docs/plans/proving-v0.md`; numbers: `docs/bench-log.md`. -- `igneum-prove/`: Cargo workspace. `core` (the block statement, a port of the execution layer's executor), `program` (the SP1 guest), `host` (execute, core, compressed modes; the versioned `ProofSystem` trait with the stub and the SP1 implementation in `host/src/proof_system.rs`), `export` (cuts a real block out of an `igneum_exportSegments` dump and checks the port against the node's state roots). -- `fixtures/`: real simnet blocks, `block-78-increment.json` (the Counter `increment(5)` call) and `block-56-transfers.json` (three transfers). -- `windows-wsl2/`: SETUP-PROVER.bat, PROVE-BLOCK.bat and the Linux scripts for the project lead's PC; `make-package.sh` builds the zip. +- `igneum-prove/`: Cargo workspace. `core` (the port of the execution layer's executor at b7fca5a0; the cutter `plan.rs`, the partial-trie witnesses `trie.rs` and `witness.rs`, the shard statement `shard.rs`, the block statement `agg.rs`), `program` (the shard guest), `aggregator` (the aggregator guest, SP1 deferred proofs of the shard program), `host` (modes native, execute, shard, block, all; the versioned `ProofSystem` trait with the stub and the SP1 implementation in `host/src/proof_system.rs`), `export` (cuts a real block out of an `igneum_exportSegments` dump, checks the port against the node's state roots, plans the shards and checks every witness). +- `fixtures/`: `block-338-shard1`, `block-341-shards2`, `block-344-shards4` (one, two and four shards at `S_p` = 7.5 M pgas, from the private simnet of `tools/prove-fixtures`), `block-78-increment` and `block-56-transfers` (the v0 blocks, one shard each), `block-56-transfers-3shards` (a test cut at 200 pgas for the CPU multi-shard check). +- `windows-wsl2/`: SETUP-PROVER.bat, PROVE-SHARD.bat (the shard at `S_p` and the two- and four-shard blocks on the GPU), PROVE-BLOCK.bat (the small block) and the Linux scripts for the project lead's PC; `make-package.sh` builds the zip. Build and run on a machine with the SP1 toolchain (`curl -L https://sp1up.succinct.xyz | bash && sp1up`): ``` cd proving/igneum-prove -cargo build --release -p igneum-prove-export -./target/release/igneum-prove-export ../../tools/evm-smoke/seq.json 78 ../fixtures/block-78-increment.json -cargo build --release -p igneum-prove-host # add --features igneum-prove-host/cuda on Linux x86_64 with an NVIDIA card -./target/release/igneum-prove-host ../fixtures/block-78-increment.json --mode execute # native check + cycle count -SP1_PROVER=cuda ./target/release/igneum-prove-host ../fixtures/block-78-increment.json --mode all --out results.json +cargo build --release -p igneum-prove-export -p igneum-prove-host # add --features igneum-prove-host/cuda on Linux x86_64 with an NVIDIA card +./target/release/igneum-prove-export ../../tools/prove-fixtures/seq.json 344 ../fixtures/block-344-shards4.json # replay, plan, witnesses; --budget for a test cut +./target/release/igneum-prove-host ../fixtures/block-344-shards4.json --mode native # cut, witnesses, chain and sums, tamper checks +./target/release/igneum-prove-host ../fixtures/block-344-shards4.json --mode execute # SP1 cycles per shard and for the aggregator +./target/release/igneum-prove-host ../fixtures/block-338-shard1.json --mode shard --shard 0 --out results.json # execute, core, compressed, verified +SP1_PROVER=cuda ./target/release/igneum-prove-host ../fixtures/block-344-shards4.json --mode block --out results.json # shard proofs plus aggregation ``` + +Fixtures of real size: `tools/prove-fixtures/net.sh start` (a one-node simnet on ports 29300+), `node tools/prove-fixtures/gen.mjs` (bursts of modexp calls, transfers and Counter increments landed in one block, then the export), then the exporter per block.