Mining epochs: per-epoch currency units and reward-triggered rotation (tracking) #13

Open
opened 2026-08-12 18:07:44 +01:00 by vnprc-agent · 0 comments
Collaborator

Complete hashpool's mining epoch mechanics: every epoch gets its own currency unit and keyset, and the mint closes the old epoch and opens a new one when a block reward lands at its receive address. This is the tracking issue for the milestone; the canonical design is docs/EPOCH_DESIGN.md (PR #12), with the upstream CDK change designed in docs/pr/cdk-dynamic-payment-processors.md. Marked passages of docs/SETTLEMENT_DESIGN.md are superseded by the same PR.

Primary goals:

  • Per-epoch currency units — epoch = period between rewards at the mint's address; unit hash_<height>, named by the block height that opened the epoch; one epoch per height, ever; the mint owns epoch identity and the pool stays oblivious.
  • Reward-triggered rotation — the mint detects the reward by watching the chain (not a pool message: proxy-built blocks, no acceptance ack, and lossy delivery all argue against pool-side detection).
  • Correct under reorgs — boundaries are provisional until D confirmations; provisional-epoch quotes are created unpaid (existing quote-state machinery is the gate, no custom guards); dissolve re-stamps never-paid quotes to the previous epoch and pays them; same-height re-mines reuse the epoch; finalized epochs never reopen.
  • Bounded mint growth — the previous epoch's payment-processor entry and mint-info settings retire at the new boundary's finality; old quotes still mint, no new quotes for old epochs.
  • Milestone scope is mechanics only — settlement/redemption of old ehash, unit end-of-life, epoch-aware wallet UX, and authenticated quote/asset creation are all explicitly out.

Build order

Dependency spine: #15 gates #16; #16's first real rotation breaks the sweeper unless #17 lands with it; #18 turns on only once #16 and #17 hold; #14 lands first because everything is tested with it; #19 is parallel once the design doc merges.

  • #14 dev stack controls (on-demand miner, configurable reward destination)
  • #15 CDK dynamic payment processor registration (fork commit, upstream PR, repin)
  • #16 mint epoch mechanics (open/close, genesis, records, manual lever)
  • #17 proxy wallet sweeps across per-epoch units
  • #18 reward trigger (chain watcher, reorg-safe boundaries)
  • #19 educational explainer (epoch lifecycle, learnmeabitcoin style)

Key decisions (recorded from the design session)

decision ruling
epoch identity block height of the reward that opened it; height in the name, block hash in the record
unit naming hash_<pool>_<height> — pool = full compressed pubkey, lowercase hex (anon set, self-authenticating, no truncation-grinding surface); deterministic suffix on derivation-index collision
who owns epochs the mint; pool keeps sending HASH, mint stamps the current unit at quote creation
trigger mint-side chain watcher over node RPC; BlockFound demoted to future announce-then-verify; trigger is an abstraction so a lightning-paid upstream reward can slot in later
reorg handling rotate immediately (provisional), finalize at D confirmations, gate the only irreversible act (minting) on finality via quote states: unpaid → paid at finality → issued at sweep
receive address configured script for now (dev: regtest harness wallet); custody arrives with settlement; not cdk-bdk for detection (quote-bound, drops block height, no coinbase awareness)
genesis first boot grabs current height, opens the first epoch, final immediately; clean slate, existing test data blown away
dev/test network regtest, not signet (signet can never carry pool-built coinbases); control rewards-to-mint, not blocks

Scope

In: the six child issues. Out (tracked by docs/SETTLEMENT_DESIGN.md and existing issues): settlement and redemption, old-unit expiry windows, epoch-aware wallet/UI display, authenticated quote and asset creation, pool→mint block announcement, keyset id in the coinbase, block template validation (#20) — noting that the deferred-pay hook built here is exactly where its result will plug in (pay = boundary final AND template valid).

Complete hashpool's mining epoch mechanics: every epoch gets its own currency unit and keyset, and the mint closes the old epoch and opens a new one when a block reward lands at its receive address. This is the tracking issue for the milestone; the canonical design is `docs/EPOCH_DESIGN.md` (PR #12), with the upstream CDK change designed in `docs/pr/cdk-dynamic-payment-processors.md`. Marked passages of `docs/SETTLEMENT_DESIGN.md` are superseded by the same PR. Primary goals: - **Per-epoch currency units** — epoch = period between rewards at the mint's address; unit `hash_<height>`, named by the block height that opened the epoch; one epoch per height, ever; the mint owns epoch identity and the pool stays oblivious. - **Reward-triggered rotation** — the mint detects the reward by watching the chain (not a pool message: proxy-built blocks, no acceptance ack, and lossy delivery all argue against pool-side detection). - **Correct under reorgs** — boundaries are provisional until D confirmations; provisional-epoch quotes are created unpaid (existing quote-state machinery is the gate, no custom guards); dissolve re-stamps never-paid quotes to the previous epoch and pays them; same-height re-mines reuse the epoch; finalized epochs never reopen. - **Bounded mint growth** — the previous epoch's payment-processor entry and mint-info settings retire at the new boundary's finality; old quotes still mint, no new quotes for old epochs. - **Milestone scope is mechanics only** — settlement/redemption of old ehash, unit end-of-life, epoch-aware wallet UX, and authenticated quote/asset creation are all explicitly out. ### Build order Dependency spine: #15 gates #16; #16's first real rotation breaks the sweeper unless #17 lands with it; #18 turns on only once #16 and #17 hold; #14 lands first because everything is tested with it; #19 is parallel once the design doc merges. - [ ] #14 dev stack controls (on-demand miner, configurable reward destination) - [ ] #15 CDK dynamic payment processor registration (fork commit, upstream PR, repin) - [ ] #16 mint epoch mechanics (open/close, genesis, records, manual lever) - [ ] #17 proxy wallet sweeps across per-epoch units - [ ] #18 reward trigger (chain watcher, reorg-safe boundaries) - [ ] #19 educational explainer (epoch lifecycle, learnmeabitcoin style) ### Key decisions (recorded from the design session) | decision | ruling | |---|---| | epoch identity | block height of the reward that opened it; height in the name, block hash in the record | | unit naming | `hash_<pool>_<height>` — pool = full compressed pubkey, lowercase hex (anon set, self-authenticating, no truncation-grinding surface); deterministic suffix on derivation-index collision | | who owns epochs | the mint; pool keeps sending `HASH`, mint stamps the current unit at quote creation | | trigger | mint-side chain watcher over node RPC; `BlockFound` demoted to future announce-then-verify; trigger is an abstraction so a lightning-paid upstream reward can slot in later | | reorg handling | rotate immediately (provisional), finalize at D confirmations, gate the only irreversible act (minting) on finality via quote states: unpaid → paid at finality → issued at sweep | | receive address | configured script for now (dev: regtest harness wallet); custody arrives with settlement; not cdk-bdk for detection (quote-bound, drops block height, no coinbase awareness) | | genesis | first boot grabs current height, opens the first epoch, final immediately; clean slate, existing test data blown away | | dev/test network | regtest, not signet (signet can never carry pool-built coinbases); control rewards-to-mint, not blocks | ### Scope In: the six child issues. Out (tracked by `docs/SETTLEMENT_DESIGN.md` and existing issues): settlement and redemption, old-unit expiry windows, epoch-aware wallet/UI display, authenticated quote and asset creation, pool→mint block announcement, keyset id in the coinbase, block template validation (#20) — noting that the deferred-pay hook built here is exactly where its result will plug in (pay = boundary final AND template valid).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
vnprc/hashpool#13
No description provided.