diff --git a/docs/analysis/pool/pool-pair-2026-10-08.md b/docs/analysis/pool/pool-pair-2026-10-08.md new file mode 100644 index 000000000..e79c28d8b --- /dev/null +++ b/docs/analysis/pool/pool-pair-2026-10-08.md @@ -0,0 +1,54 @@ +# The devnet-4 pool pair, 8 October 2026 (UX-05, UX-04 evidence; the night's record) + +Pool seat, 8 October 2026, 20:0x to 21:4x UK. Binaries: the node /srv/artefacts/200-12424341/node-lane/igneumd on +build-2 (successor-2.0.1's gate build), the pool daemon from pool-2.0 (8106ba27 then e063fdcd; igneum-pow fingerprint +cbc5bd0aa10585c8, the freeze 1c420786), two CPU members from the fork at 2b1a247a (the same fingerprint; a test +binary, never shipped). Two Vast hosts rented for the pair (i7-5820K, Xeon E5-2609 v3, Haswell) died with Illegal +instruction at the class v5 catch-up on every node build and were destroyed; the pair ran on build-2 under lease +pool class measure and was brought down by pid file at 21:3x UK (0 leases, 0 processes left). + +## UX-05 Keep voting keys with the miner through pooling: PASS in the crate + +| Test (pool crate, build-2) | Known-pass | Known-fail | Result | +|---|---|---|---| +| `verify::tests::a_share_under_another_key_is_refused_before_the_hash` | the member's key on job and share: ok | another key on the share, and a job naming another key: `vote_key`, hash 0, under a tenth of an evaluation | ok (51 of 51 at e063fdcd, 52 of 52 at 986252e7) | +| `sidechain::tests::a_share_whose_keys_disagree_is_refused_before_its_pow` | make_share | the claim swapped, the header's key swapped, a foreign reveal | ok | +| `the same nonce on another template hashes differently` | | a nonce moved to another template: `wrong_hash` | ok | +| the TLS binding (replay refused), the admission bounds, the intents (review B) | | | ok | +| `an_unsynced_node_hands_the_pool_no_state_and_no_job` (986252e7) | a synced node: leaves served, jobs issued | synced false: no leaves, no job | red against 8106ba27 on build-6, green with the guard | + +The live pair reached: authorise with the members' own keys (the pool log names each key beside its payout address), +class v5 seeds issued (epoch 1a87e870..., day 20734, era 7c36b833...), jobs issued with `vote_key_hash` the +member's, shares sent. Every share read `wrong_hash`. + +## The wrong_hash cause, from the retained logs (not a generator skew) + +The node, the pool and the member carry the same igneum-pow (fingerprint cbc5bd0aa10585c8, the freeze; pool-2.0's +tree 93c36844 byte-identical to 1c420786, read back by the pool lane from the mirror and from the binaries). The pool +and the members hashed the identical epoch seed, day, class and era. Build-2's node never reached synced on devnet-4 +(its log loops on "class v5 execution catch-up" against peers that close the connection; `synced=false` on every +read), so the class v5 state leaves the pool and the members fetched by `igneum_getPowStateLeaves` for the epoch's +seed block were the still-settling catch-up state, not the node's state at template time; a class v5 lane hash over +unsettled leaves does not match the node's. The class kept: a class v5 pool needs its node fully synced before it +verifies shares, because the dataset is keyed on settled execution state. The guard by construction is pool-2.0 +986252e7 (the provider refuses leaves while `igneum_getExecStatus` reads unsynced, blocked or reexecuting; the feed +issues no job; the STATUS line says so). + +## Two 2.0 gaps closed by the pair (both on pool-2.0, in the 2.0.2 take) + +1. The pool daemon had no class v5 day-state source and issued no job on a class v5 chain (8ff7a0f4: + `state_provider.rs`, `--exec-rpc` defaulting to `--evm-rpc`). +2. The daemon read amounts at 8 decimals and refused every 18-decimal template as a high-word amount (8106ba27: the + base unit installed from the node's network before any amount is read). + +## UX-04 Pay small operators without hidden custody + +PPLNS distribution, the payout key round trip and the signed transfer decode: PASS in the crate. The live payout path +(a member earns, is paid at the minimum, reconnects, a redirection attempt) is NOT RUN: it needs the pair on a +fully-synced devnet-4 node with the 2.0.2 kit, tomorrow. + +## Consequences per tier + +A home miner on a pool: the key stays theirs on every job and share and a pool naming another key is refused before +the hash; a pool operator: the daemon refuses to issue jobs until its node is synced, so an unsynced start costs idle +minutes, never a wrong_hash storm; the network: no change to consensus from any of this. diff --git a/docs/plans/igneum-2.0-test-registry.json b/docs/plans/igneum-2.0-test-registry.json index c8ca528f2..67760214f 100644 --- a/docs/plans/igneum-2.0-test-registry.json +++ b/docs/plans/igneum-2.0-test-registry.json @@ -9461,30 +9461,30 @@ "manual_page": 58, "owner_lane": "pool design seat (a3832b1c3b274b310)", "run_status": "NOT RUN", - "evidence_path": "build-1:/srv/artefacts/tas/pool-review-b-20261008-01/pool-suite-build-6.log", - "run_id": "pool-review-b-20261008-01", - "updated": "2026-10-08T19:58:33.370Z", + "evidence_path": "docs/analysis/pool/pool-pair-2026-10-08.md", + "run_id": "pool-2.0-20261008-03", + "updated": "2026-10-08T20:41:26.619Z", "evidence_record": { - "cell": "suite:pool", - "manifest_sha": "7cfa422a", - "coverage": { - "UX-05": "partial: the vote-key commitment on the wire (verify::tests::a_share_under_another_key_is_refused_before_the_hash: known-pass the member's key, known-fail another key on the share and a job naming another key, refused with code vote_key before the hash), the open pool's sidechain::check_key (the claimed key, the header's key and the reveal are one key), the same-nonce-other-template wrong_hash test, the TLS binding test; the malicious-pool run and the leave-and-retain run on the devnet-4 pair are the UX-05 batch's other evidence; review B INT-15 (8 October 2026): server::authorise_tests::a_replayed_proof_of_possession_is_not_an_authorisation (a public PoP replayed into another session, payout, pool or chain, or under another key, refused; only the challenge-bound binding v2 admits on a public network) and the_binding_policy_follows_the_network", - "UX-04": "partial: PPLNS distribution tests (fee first, never overpays, late joiner), the payout key file round trip, the signed transfer decode; the live payout path on the devnet-4 pair is the UX-04 batch's evidence; review B F12 and INT-03/INT-04 (8 October 2026): payout::intent_tests (a restart from the pre-broadcast snapshot, a lost send response, a crash on either side of the broadcast, a stuck transaction replaced under the same intent, a reorged receipt and a finality pause, a failed transaction, a ledger that cannot be written: never a duplicate or a lost obligation, finalised only under the chain's final lock) and state::ledger_tests (an unreadable ledger is refused or restored, never emptied); F13/INT-16: frame, admission and pool::share_tests (the frame bound while reading, the bounded outgoing queue, one membership per session, the nonce and in-flight bounds, the share and connection budgets)" - }, - "at": "2026-10-08T19:58:33.370Z", - "method": "native", "requirement_id": "UX-04", "decision": "NOT RUN", - "reviewer": "", - "claim_impact": "", + "method": "native", + "cell": "suite:pool", + "manifest_sha": "986252e73", + "run_id": "pool-2.0-20261008-03", + "evidence": "docs/analysis/pool/pool-pair-2026-10-08.md", + "in_progress": true, + "coverage": "partial: PPLNS distribution tests (fee first, never overpays, late joiner), the payout key file round trip, the signed transfer decode; the live payout path on the devnet-4 pair is the UX-04 batch's evidence; review B F12 and INT-03/INT-04 (8 October 2026): payout::intent_tests (a restart from the pre-broadcast snapshot, a lost send response, a crash on either side of the broadcast, a stuck transaction replaced under the same intent, a reorged receipt and a finality pause, a failed transaction, a ledger that cannot be written: never a duplicate or a lost obligation, finalised only under the chain's final lock) and state::ledger_tests (an unreadable ledger is refused or restored, never emptied); F13/INT-16: frame, admission and pool::share_tests (the frame bound while reading, the bounded outgoing queue, one membership per session, the nonce and in-flight bounds, the share and connection budgets); the devnet-4 pair's class (8 October 2026 21:24 UK): state_provider::tests::an_unsynced_node_hands_the_pool_no_state_and_no_job (no job on a node whose igneum_getExecStatus reads synced false, blocked or re-executing; known-failed first against the 8ff7a0f4 provider; pool-synced-guard-202 f3e99e9c on release-2.0.2, 986252e7 on pool-2.0, 52 of 52 on build-6)", "release_identity": { - "commit": "7cfa422a", + "commit": "986252e73", "lockfile": "", "binary": "", "network_object": "", "activation": "", "profile_hashes": "" - } + }, + "claim_impact": "", + "reviewer": "", + "at": "2026-10-08T20:41:26.619Z" }, "in_progress_since": "2026-10-08T19:58:33.370Z", "approvals": { @@ -9495,29 +9495,26 @@ }, "evidence_records": { "suite:pool": { - "cell": "suite:pool", - "manifest_sha": "7cfa422a", - "coverage": { - "UX-05": "partial: the vote-key commitment on the wire (verify::tests::a_share_under_another_key_is_refused_before_the_hash: known-pass the member's key, known-fail another key on the share and a job naming another key, refused with code vote_key before the hash), the open pool's sidechain::check_key (the claimed key, the header's key and the reveal are one key), the same-nonce-other-template wrong_hash test, the TLS binding test; the malicious-pool run and the leave-and-retain run on the devnet-4 pair are the UX-05 batch's other evidence; review B INT-15 (8 October 2026): server::authorise_tests::a_replayed_proof_of_possession_is_not_an_authorisation (a public PoP replayed into another session, payout, pool or chain, or under another key, refused; only the challenge-bound binding v2 admits on a public network) and the_binding_policy_follows_the_network", - "UX-04": "partial: PPLNS distribution tests (fee first, never overpays, late joiner), the payout key file round trip, the signed transfer decode; the live payout path on the devnet-4 pair is the UX-04 batch's evidence; review B F12 and INT-03/INT-04 (8 October 2026): payout::intent_tests (a restart from the pre-broadcast snapshot, a lost send response, a crash on either side of the broadcast, a stuck transaction replaced under the same intent, a reorged receipt and a finality pause, a failed transaction, a ledger that cannot be written: never a duplicate or a lost obligation, finalised only under the chain's final lock) and state::ledger_tests (an unreadable ledger is refused or restored, never emptied); F13/INT-16: frame, admission and pool::share_tests (the frame bound while reading, the bounded outgoing queue, one membership per session, the nonce and in-flight bounds, the share and connection budgets)" - }, - "at": "2026-10-08T19:58:33.370Z", - "method": "native", "requirement_id": "UX-04", "decision": "NOT RUN", - "reviewer": "", - "claim_impact": "", + "method": "native", + "cell": "suite:pool", + "manifest_sha": "986252e73", + "run_id": "pool-2.0-20261008-03", + "evidence": "docs/analysis/pool/pool-pair-2026-10-08.md", + "in_progress": true, + "coverage": "partial: PPLNS distribution tests (fee first, never overpays, late joiner), the payout key file round trip, the signed transfer decode; the live payout path on the devnet-4 pair is the UX-04 batch's evidence; review B F12 and INT-03/INT-04 (8 October 2026): payout::intent_tests (a restart from the pre-broadcast snapshot, a lost send response, a crash on either side of the broadcast, a stuck transaction replaced under the same intent, a reorged receipt and a finality pause, a failed transaction, a ledger that cannot be written: never a duplicate or a lost obligation, finalised only under the chain's final lock) and state::ledger_tests (an unreadable ledger is refused or restored, never emptied); F13/INT-16: frame, admission and pool::share_tests (the frame bound while reading, the bounded outgoing queue, one membership per session, the nonce and in-flight bounds, the share and connection budgets); the devnet-4 pair's class (8 October 2026 21:24 UK): state_provider::tests::an_unsynced_node_hands_the_pool_no_state_and_no_job (no job on a node whose igneum_getExecStatus reads synced false, blocked or re-executing; known-failed first against the 8ff7a0f4 provider; pool-synced-guard-202 f3e99e9c on release-2.0.2, 986252e7 on pool-2.0, 52 of 52 on build-6)", "release_identity": { - "commit": "7cfa422a", + "commit": "986252e73", "lockfile": "", "binary": "", "network_object": "", "activation": "", "profile_hashes": "" }, - "run_id": "pool-review-b-20261008-01", - "evidence": "build-1:/srv/artefacts/tas/pool-review-b-20261008-01/pool-suite-build-6.log", - "in_progress": true + "claim_impact": "", + "reviewer": "", + "at": "2026-10-08T20:41:26.619Z" } } }, @@ -9548,25 +9545,12 @@ "manual_page": 58, "owner_lane": "pool design seat (a3832b1c3b274b310)", "run_status": "NOT RUN", - "evidence_path": "build-1:/srv/artefacts/tas/pool-review-b-20261008-01/pool-suite-build-6.log", - "run_id": "pool-review-b-20261008-01", - "updated": "2026-10-08T20:10:24.556Z", + "evidence_path": "docs/analysis/pool/pool-pair-2026-10-08.md", + "run_id": "pool-2.0-20261008-03", + "updated": "2026-10-08T20:41:26.619Z", "evidence_record": { "reason": "voting keys through pooling is the pool lane's row", - "at": "2026-10-08T20:10:24.556Z", - "method": "static", - "requirement_id": "UX-05", - "decision": "NOT RUN", - "reviewer": "", - "claim_impact": "", - "release_identity": { - "commit": "", - "lockfile": "", - "binary": "", - "network_object": "", - "activation": "", - "profile_hashes": "" - } + "at": "2026-10-08T20:41:26.619Z" }, "in_progress_since": "2026-10-08T19:58:33.370Z", "approvals": { @@ -9577,29 +9561,26 @@ }, "evidence_records": { "suite:pool": { - "cell": "suite:pool", - "manifest_sha": "7cfa422a", - "coverage": { - "UX-05": "partial: the vote-key commitment on the wire (verify::tests::a_share_under_another_key_is_refused_before_the_hash: known-pass the member's key, known-fail another key on the share and a job naming another key, refused with code vote_key before the hash), the open pool's sidechain::check_key (the claimed key, the header's key and the reveal are one key), the same-nonce-other-template wrong_hash test, the TLS binding test; the malicious-pool run and the leave-and-retain run on the devnet-4 pair are the UX-05 batch's other evidence; review B INT-15 (8 October 2026): server::authorise_tests::a_replayed_proof_of_possession_is_not_an_authorisation (a public PoP replayed into another session, payout, pool or chain, or under another key, refused; only the challenge-bound binding v2 admits on a public network) and the_binding_policy_follows_the_network", - "UX-04": "partial: PPLNS distribution tests (fee first, never overpays, late joiner), the payout key file round trip, the signed transfer decode; the live payout path on the devnet-4 pair is the UX-04 batch's evidence; review B F12 and INT-03/INT-04 (8 October 2026): payout::intent_tests (a restart from the pre-broadcast snapshot, a lost send response, a crash on either side of the broadcast, a stuck transaction replaced under the same intent, a reorged receipt and a finality pause, a failed transaction, a ledger that cannot be written: never a duplicate or a lost obligation, finalised only under the chain's final lock) and state::ledger_tests (an unreadable ledger is refused or restored, never emptied); F13/INT-16: frame, admission and pool::share_tests (the frame bound while reading, the bounded outgoing queue, one membership per session, the nonce and in-flight bounds, the share and connection budgets)" - }, - "at": "2026-10-08T19:58:33.370Z", - "method": "native", "requirement_id": "UX-05", "decision": "NOT RUN", - "reviewer": "", - "claim_impact": "", + "method": "native", + "cell": "suite:pool", + "manifest_sha": "986252e73", + "run_id": "pool-2.0-20261008-03", + "evidence": "docs/analysis/pool/pool-pair-2026-10-08.md", + "in_progress": true, + "coverage": "partial: the vote-key commitment on the wire (verify::tests::a_share_under_another_key_is_refused_before_the_hash: known-pass the member's key, known-fail another key on the share and a job naming another key, refused with code vote_key before the hash), the open pool's sidechain::check_key (the claimed key, the header's key and the reveal are one key), the same-nonce-other-template wrong_hash test, the TLS binding test; the malicious-pool run and the leave-and-retain run on the devnet-4 pair are the UX-05 batch's other evidence; review B INT-15 (8 October 2026): server::authorise_tests::a_replayed_proof_of_possession_is_not_an_authorisation (a public PoP replayed into another session, payout, pool or chain, or under another key, refused; only the challenge-bound binding v2 admits on a public network) and the_binding_policy_follows_the_network", "release_identity": { - "commit": "7cfa422a", + "commit": "986252e73", "lockfile": "", "binary": "", "network_object": "", "activation": "", "profile_hashes": "" }, - "run_id": "pool-review-b-20261008-01", - "evidence": "build-1:/srv/artefacts/tas/pool-review-b-20261008-01/pool-suite-build-6.log", - "in_progress": true + "claim_impact": "", + "reviewer": "", + "at": "2026-10-08T20:41:26.619Z" } } }, diff --git a/tools/ci/batches/pool-2.0-20261008-03.json b/tools/ci/batches/pool-2.0-20261008-03.json new file mode 100644 index 000000000..f0fce2d7b --- /dev/null +++ b/tools/ci/batches/pool-2.0-20261008-03.json @@ -0,0 +1,14 @@ +{ + "run_id": "pool-2.0-20261008-03", + "manifest_sha": "986252e73", + "method": "native", + "evidence_dir": "docs/analysis/pool", + "cells": [ + { + "cell": "suite:pool", + "status": "RUNNING", + "method": "native", + "evidence": "docs/analysis/pool/pool-pair-2026-10-08.md" + } + ] +} \ No newline at end of file