A mint restart strands every outstanding quote in non-current epochs #30
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#30
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?
A mint restart permanently strands every outstanding quote in every non-current epoch. The resume path re-registers only the current epoch's payment processor, so all earlier epochs — including ones still holding paid-but-unissued quotes — become unresolvable and their value can never be collected.
This is the same failure the
retireversusderegisterwork was introduced to prevent, reappearing by a different route.retirekeeps the processor map entry, but that map lives only in memory; nothing rebuilds it for retired epochs on startup.Observed on a live dev stack: integration of vnprc/hashpool#21, #23 and #24, cdk pinned at
ed7657c3, with the vnprc/hashpool#29 fix applied.Evidence
Three epochs existed in
epochs.json— 17 (genesis), 122 and 127 (both manual) — and unit 122 still held 5 unissued quotes. The mint was then restarted. Its log shows exactly one registration:One
Starting payment wait task, for epoch 127 alone. Epochs 17 and 122 are not registered. The sweeper's very next pass:The current epoch mints normally. The retired epoch returns
Unit unsupported—Error::UnsupportedUnit— for its 5 outstanding quotes, and will do so forever.Before the restart, those same 5 quotes did not produce
Unit unsupported: across every pass they reported only a wallet-sideQuote already in use by another operation, confirming the mint still resolved the retired unit while the process lived. The regression is introduced by the restart, not by retirement.Where it comes from
roles/mint/src/lib/epoch/mod.rsresume path registers a processor for the current epoch only. An earlier review of vnprc/hashpool#24 caught the adjacent case — a restart failing to re-register the resumed epoch at all, fixed in922637e9— but that fix covers the current epoch, and nothing covers epochs that are closed yet still referenced by live quotes.The in-memory nature of the map is the crux.
retire_payment_processordeliberately keeps the map entry while dropping the NUT-04/NUT-05 settings, which is what makes a closed epoch resolvable but not quotable. A restart rebuilds the map from configuration and the resumed epoch, so that carefully preserved entry is simply absent.Scope
In scope: on resume, restore every non-dissolved epoch's processor, not just the current one. The semantics already exist and compose cleanly — register each epoch's processor, then retire every one except the current. That reproduces the intended post-rotation state exactly: all epochs resolvable for outstanding quotes, only the current epoch quotable.
Deciding which epochs are worth restoring is part of the work. Restoring every record retains a map entry per epoch forever, which grows without bound; restoring only those with outstanding unissued quotes is tighter but requires the mint to ask that question at startup. Either is defensible; the choice should be explicit rather than incidental.
Out of scope: the wallet-side reservation leak noted on vnprc/hashpool#29, and the
unit hash: failed to refresh keysets on first sight: Unknown Keysetwarning the sweeper emits for the retired static base unit, which is noise rather than a fault but will mislead a reader of these logs.Validation
With several epochs recorded and outstanding unissued quotes in a non-current one, restart the mint and confirm the sweeper's batch status check for that epoch does not return
Unit unsupported, and that its quotes go on to mint. Then confirm new quote creation for that retired epoch still fails, so restoring resolvability has not accidentally reopened a closed epoch for issuance.