Reward trigger: mint-side chain watcher with reorg-safe epoch boundaries #18
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
vnprc/hashpool#18
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Build the trigger: the mint watches the chain, and a block reward landing on its receive script closes the current epoch and opens the next — provisionally at detection, final at D confirmations, correct under reorgs. Design:
docs/EPOCH_DESIGN.md(reward detection and reorg sections).Primary goals:
roles/roles-utils/rpc): on each new block, match coinbase outputs against the mint's configured receive script (script comparison, not address strings). Persist the last processed block and the last ~D hashes; on restart, re-scan forward — rewards seen during downtime open and close epochs in sequence, empty epochs allowed; dedupe reward events by height.open_epoch(provisional; new quotes unpaid). At H+D with the boundary still canonical: mark final, bulk-pay the epoch's quotes, retire the previous epoch's registration. Reorg before finality with no replacement payment: dissolve — re-stamp the never-paid quotes to the previous epoch and pay them, splice the record, assert the dissolved keyset issued nothing (nonzero is a critical invariant violation). Same-height re-mine that pays us: keep the epoch, swap the recorded block hash, restart the confirmation clock. Never reopen a final epoch.Current state and specifics
The mint has zero bitcoin connectivity today; jd-server's
MiniRpcClientand its regtest RPC config are the reuse points. Not cdk-bdk: its detection is quote-bound, it drops the funding block height epochs are named by, and it has no coinbase awareness (custody can move to a CDK wallet in the settlement milestone; the trigger needs only a script to watch). Not pool-announced: proxy-built blocks bypass the pool, the pool gets no acceptance ack, and a lost message loses the event, while a payment on-chain waits for a re-scan.Witness
The five regtest scenarios from the design doc: deterministic trigger (node+mint only,
generatetoaddress 1 <mint address>→ exactly one rotation, quotes flip paid at D); full-stack (pool coinbase pointed at the mint via #14, brief miner burst → the pool's own winning block rotates the epoch, epoch heights monotonic); catch-up (rewards mined while the mint is down); dissolve (invalidate the boundary block, extend the other branch → quotes re-stamped and paid, record spliced); same-height re-mine (epoch reused, new block hash, clock restarted). Reward assertions compute the subsidy from height (regtest halves every 150 blocks).Scope
In: watcher, event abstraction, boundary state machine, config, the five scenarios. Out: pool→mint announce-then-verify, keyset id in the coinbase, settlement-side maturity handling, lightning source.
Part of #13. Gated on #16 and #17.