Merge enforced-proving 9e6b3f02 into master (gate: green on 9e6b3f02, recorded by tools/ci/pre-push.sh; landed on the box mirror)

This commit is contained in:
igneum-labs 2026-10-08 16:12:28 +00:00
commit 33ffe78c0d
2 changed files with 16 additions and 1 deletions

View file

@ -1810,7 +1810,7 @@ Round 2 (5 October 2026, night): the public text now carries the v0 fact, labell
### P22. The rewards and payouts are inputs to the shard proof, not outputs
"The shard guest takes the segment's rewards and the prover payouts as data and commits the post-root after them. A host can feed any list and the proof still verifies."
Status: Open, staged (8 October 2026, the enforced-proving lane; `docs/spec/proving-enforcement.md` section 7 carries the staging table): the closure is four explicit stages, each a claim about one input with the native check that holds it until the next stage, never a self-contained proof of the whole state. Stage 0 (today): rewards and payouts are data in the shard statement and every node's native derivation vetoes a statement that differs; enforced proving adds that the record's proof must verify for that statement (ledger P21). Stage 1: the rewards list checked against a commitment the aggregator carries in its public values, the commitment itself recomputed natively from the mergeset. Stage 2: the payouts derived inside the aggregator guest from the carried records it verifies, `carried_payouts` the native check of the same derivation. Stage 3: the rewards derived inside the aggregator guest from the headers and blue sets it verifies, the consensus proof proper; only here do rewards stop being an input anywhere. Stages 1 to 3 are the phase 2 consensus-proof work (Nov 2026 to Jan 2027 per the litepaper roadmap); no served text says "the rewards and payouts are proven" before stage 3. Was: Open, blocked on the phase 2 consensus proof (design 7: the aggregator derives the rewards and payouts from consensus data it verifies, so they become outputs of the proof): next step that consensus-proof work, in phase 2 (Nov 2026 to Jan 2027 per the litepaper roadmap), no earlier date. Was: Open, stated in spec 7.7 item 6 (4 October 2026). Sweep (5 October 2026): stated; nothing runnable.
Status: Open, staged (8 October 2026, the enforced-proving lane; `docs/spec/proving-enforcement.md` section 7 carries the staging table): the closure is four explicit stages, each a claim about one input with the native check that holds it until the next stage, never a self-contained proof of the whole state. Stage 0 (today): rewards and payouts are data in the shard statement and every node's native derivation vetoes a statement that differs; enforced proving adds that the record's proof must verify for that statement (ledger P21). Stage 1: the rewards list checked against a commitment the aggregator carries in its public values, the commitment itself recomputed natively from the mergeset. Stage 2: the payouts derived inside the aggregator guest from the carried records it verifies, `carried_payouts` the native check of the same derivation. Stage 3: the rewards derived inside the aggregator guest from the headers and blue sets it verifies, the consensus proof proper; only here do rewards stop being an input anywhere. Stages 1 to 3 are the phase 2 consensus-proof work (Nov 2026 to Jan 2027 per the litepaper roadmap); no served text says "the rewards and payouts are proven" before stage 3. The 2.0 plan's negative test (6) (incorrect rewards or consensus inputs: derivation authenticated) is PENDING in that sense: the executor test `enforced_a_statement_over_altered_rewards_or_payouts_is_vetoed_native_derivation_is_the_check` holds the native veto (every node's own derivation), and the proof-side closure is stage 3. Boundary sentence for every served text: a proof of execution is not a proof of authenticated consensus inputs, canonical history or data availability. Was: Open, blocked on the phase 2 consensus proof (design 7: the aggregator derives the rewards and payouts from consensus data it verifies, so they become outputs of the proof): next step that consensus-proof work, in phase 2 (Nov 2026 to Jan 2027 per the litepaper roadmap), no earlier date. Was: Open, stated in spec 7.7 item 6 (4 October 2026). Sweep (5 October 2026): stated; nothing runnable.
Answer: Correct, and already true of the rewards since devnet v4 (`BlockFixture.rewards`, `proving_pool_credit`): the shard statement is "from this pre-root, these transactions, these rewards and payouts, the post-root is X". The node checks the statement against its own execution, which used the rewards and payouts consensus derived, so a proof over a different list does not match any node's statement and pays nothing. Closing it in the proof itself means the aggregator deriving the rewards and payouts from consensus data it verifies (the mergeset's blue blocks and the carried records), which is the consensus-proof work of design section 7.

View file

@ -58,6 +58,21 @@ Known-failed first: the two tests that encode the new condition (the "pays nothi
Results: section 6.
## 3a. The plan's six negative tests, mapped
The Igneum 2.0 plan (p. 16) names six negative tests every validator must pass. The map, each with its test name and the tree it is green on (the 0.3.25 node line at 019a12b1, on release-2.0.0-node as dd84ed6a and f6cd2f00; the proving-payment branch eaddbf83 for the last row):
| Plan test | Covered by | Where | State |
|---|---|---|---|
| (1) a correct statement with an invalid proof: rejected, no reward | `enforced_a_record_whose_proof_fails_to_verify_invalidates_the_block` (the block refused); `enforced_an_unverified_proof_pays_nothing_and_the_verified_honest_record_pays_once` (no payment, the honest proof pays once) | consensus; executor | green 16:15 UK |
| (2) a wrong program or verifier identity under the pinned release configuration | `enforced_a_proof_for_another_program_id_invalidates_the_block` (the verdict); `nativeverify::tests::a_real_proof_verifies_and_a_wrong_statement_is_refused` (a real proof under the other pinned key: "pinned id"); `the_embedded_keys_match_the_manifest` (the release's keys are the manifest's); the daemon's start refusal when the embedded keys are not the object's pinned ids (exit 3, a process check, not a unit test) | consensus; executor; the daemon | green 16:15 UK; the start refusal stated |
| (3) a wrong chain, epoch or statement binding, replayed or misbound work | `enforced_a_record_signed_for_another_network_pays_nothing` (the chain); `enforced_a_replayed_record_pays_nothing_the_second_time` (replay); `assignment_follows_the_window_and_records_check_against_native_execution` (a wrong block, a wrong shard, a stale record outside the window, a wrong statement); the epoch binds through the sortition's epoch seed and the chain block in the statement | executor | green 16:15 UK |
| (4) a changed payout identity | `enforced_an_altered_payout_address_pays_nothing` (altered after signing: the signature; re-signed: the statement binds the payout) | executor | green 16:15 UK |
| (5) a duplicate proof reward: exactly the permitted payment outcome | `enforced_a_duplicate_of_a_paid_record_by_another_key_pays_nothing`; the honest record paid once in (1)'s test | executor | green 16:15 UK |
| (6) incorrect rewards or consensus inputs: derivation authenticated, not only execution over supplied inputs | `enforced_a_statement_over_altered_rewards_or_payouts_is_vetoed_native_derivation_is_the_check` (a statement whose post-root came from execution over other rewards or payouts is not the native statement and pays nothing: the native veto, every node's own derivation) | executor (proving-payment branch, on build-2 at 17:06 UK) | PENDING as the plan means it: the derivation is authenticated by every node's own execution, not inside the proof; the proof-side closure is P22's stages 1 to 3 (section 7), phase 2 |
The boundary sentence of the plan, carried in every served text that names the rule: a proof of execution is not a proof of authenticated consensus inputs, canonical history or data availability. What the rule proves today is that the carried record's statement is the native statement of this node's own execution and that an SP1 proof of that statement verifies; what consensus inputs the execution used, which history is canonical and whether the data is available are each the node's own reading, not the proof's.
## 4. The cost
The verifier's time per record on the node, measured on build-2 under the lease tool (section 6 carries the RESULT lines). The budget per block: at most 8 shard records and 2 segment records per block (`MAX_RECORDS_PER_BLOCK`, `MAX_SEGMENT_RECORDS_PER_BLOCK`), verified in parallel on the body processor's thread pool, each verdict cached by proof hash, so a proof verified at relay time costs the block nothing. Measured (section 6, build-2, one EPYC 9454P core at nice 19 under the lease tool, the box loaded): 0.668 to 0.710 s per record and about 30 MB per concurrent verify. What the switch costs a block, from those figures: nothing for a block that carries no records; nothing for a proof the relay verified before its block (the cached verdict); the worst case is a block whose ten proofs all arrive cold with it, about 0.7 s wall on ten cores of the body processor's pool (7 s of CPU) and about 300 MB peak. At the hold's rate of one block a second, a producer that fills every block with cold proofs costs a validator 0.7 s of wall per block on ten cores, which the pool absorbs; a validator with fewer cores serialises the ten verifies (7 s a block) and falls behind, which is why the relay-time verify is the design's budget and the block-time verify its backstop. Per tier: every node class holds the 300 MB (8 GB rig, 12 and 16 GB card nodes, pool nodes); a Windows node verifies through `igneum-prove-host` and the daemon refuses to start with the rule set and no host. The 10 ms gate of the overview is the hash's per-warp CPU-verify gate, not this check's: an SP1 compressed proof verify is 70x it, a different class of check, and the cache above is what keeps it off the block's critical path.