# Pool v0: what it does, what it does not, what was measured, and the listing checklist 5 October 2026, branch `pool-v0` (main worktree `../igneum-wt-pool`, fork worktree `vendor/igneum-node-pool` on the fork's `pool-v0` from `release-0.3.6` a24ab01a). REBASED 6 October 2026 (section 9): branch `pool-v0-rebase` on master, fork branch `pool-v0-rebase` on `release-0.3.14-node` 4c6b129d (worktree `../igneum-wt-pool-rebase`, fork worktree `vendor/igneum-node-pr`); the share re-check hashes the template's program class, never a fixed one. The founder's ask: a public mining pool with the stats API WhatToMine and HiveOS read, "the biggest step toward being listable". Built against `docs/spec/09-pool-protocol.md`, the miner's template subscription and worker protocol (`igneum/miner/src/main.rs`), the Hive package's `local` mode (`packaging/hive`), ledger F10 and G6 (pools and votes), and `docs/plans/explorer.md` section 6. Nothing is deployed. ## 1. Rust, and why Spec 9.3 fixes the member protocol as newline-delimited JSON over TLS, not the node's gRPC. The miner is Rust and talks gRPC to its node; the pool must verify every share on the CPU warp verifier (spec 9.8 item 5), which is the node's own `IgneumEngine` in `consensus/pow/src/igneum.rs` (same program, cache and init words as block validation), and it must build templates and submit blocks over the node's gRPC. Both are Rust crates by path. A Node service would have had to reimplement the verifier or shell out per share; the Rust pool calls it in process at 0.44 ms per share (measured, section 5). JSON lines are three serde derives. So: Rust, `pool/`, its own Cargo workspace reading the fork by path. The miner side is a module in the fork (`igneum/miner/src/pool.rs`), because the identity, voter, template and worker code it reuses lives there. ## 2. What v0 does | Area | v0 | Spec section | |---|---|---| | Transport | newline JSON over plain TCP on 4463 (devnet), 4462, 4461; one object per line, `"t"` names the type, unknown fields ignored, 4 MiB line cap | 9.3, 9.5 | | Session | `hello` / `welcome` (version, chain id, pool address, modes, `vote_mode: member`, `share_scheme` with fee, window and min payout), `authorize` with the member's BLS pubkey and proof of possession (verified with `verify_pop`), payout address and worker name / `authorized` | 9.3, 9.5 | | Templates | mode A, one template per member per tip (NewBlockTemplate subscription, 1 s refresh, on demand): the member's `vote_key_hash` in the header, its key reveal and the pool's `IGNA` payout address in the coinbase extra data; sent as the node's `RpcRawBlock` JSON so a member with a node can submit it there | 9.4, 9.4.1 items 1 and 2, 9.6 item 2 | | Seeds | `seeds` on connection and on every change, from the template's `pow_epoch` (current and next epoch seed, boundary DAA, day, the schedule; since 6 October 2026 also `program_class`, `next_program_class`, `era_seed`, `era_index`, `genesis_day_index`, `genesis_dataset_log2`, `program_class_v3_activation_daa`, so a member without a node builds the same program and day cache as the pool's node) | 9.9 | | Jobs | `job` with prehash, `target64`, `share_target64`, a random 2^32 nonce space, the seed pair, `program_class` and `era_seed` (6 October 2026: the member refuses a job without a class, code `seeds`, and never hashes a guessed one), `clean` on a tip change | 9.5 | | Shares | `share` = a lane hash at or below `share_target64`; the pool evaluates the lane on the CPU and answers `share_result` with `ok`, `stale` (superseded job past the 2,000 ms grace), `duplicate`, `above_target`, `wrong_hash`, `unknown_job`; a share at or below `target64` is a block, submitted to every node | 9.8 items 1, 5, 7 | | Vardiff | per member, one share per 10 s, shift `s` with `share_target = target64 << s` never saturated; first correction sized from the measured rate (up to 8 steps), then one step per 30 s at most; idle members eased one step per 3 intervals | 9.8 items 2 and 4 (one deviation: the sized first step, below) | | Weight | `2^-s` of a block per share | 9.8 item 3 | | Payment | PPLNS over a window of N blocks of weight (default 2); the split is snapshotted when a block is found and credited when it is confirmed blue (a chain block or in a chain block's mergeset blues, the set the execution layer pays); orphans pay nobody; fee (default 1%) off the top | 9.8 item 8 | | Payouts | EIP-1559 transfers from the pool's coinbase address through the node's eth_ JSON-RPC, one per payee at or above the minimum, at most 16 per round, receipts checked, a failed receipt re-credits; `--dry-run` records and sends nothing | design 1.1 (execution layer rewards) | | The 20% | untouched: the execution layer credits the proving escrow by rule from consensus data (`executor.rs`); the pool's templates name only its own address and receive the 80% | 2.5, 5.3 | | Votes | the member votes through its own node with its own key, as in solo mode; the pool holds no key and names each member's key in its header | 9.6, 9.7 items 1 and 2 | | Member checks | own key in the header, the pool's address and own key reveal in the coinbase (refused with `vote_key`, `payout`, `reveal`); the pool's epoch seed, program class and era seed against the member's node (`seeds`; the class and era joined the check on 6 October 2026); a custodial pool (`vote_mode` not `member`) refused by default | 9.4.1 items 1 and 2, 9.9 item 2, 9.6 item 5 | | Found blocks | the member submits to its own node and sends `solution`; the pool submits to every node | 9.2 | | API | `/api/stats`, `/api/blocks`, `/api/miners/
`, `/api/payments`, `/api/pool-stats` (Hive-style flat object); field contracts in `pool/src/api.rs`, fixtures from the measured run | explorer.md section 6 | | Page | `pool/web/index.html` under the site's tokens: tiles, connect card with the exact miner flags, address lookup, blocks, payments | | | Persistence | `state.json` snapshot every 15 s and at shutdown (balances, blocks, payments, PPLNS window, lifetime counters) | | | Miner | `igneum-miner mine