Make the epoch store durable and fail loudly on a missing or unreadable one #36
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#36
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?
Make the epoch store durable and make a missing or unreadable store fail loudly, so a crash or a deleted file cannot silently discard epoch history.
Primary goals:
Current state and specifics
EpochStoreinroles/mint/src/lib/epoch/store.rspersists the epoch records as JSON beside the mint database, written by atomic rename. Three gaps follow.The rename is not fsynced, so a power loss can leave a truncated or zero-length
epochs.json. On the next start the mint cannot parse it.That failure mode is worse than it looks, because an absent or unreadable store is indistinguishable from a first boot: the mint opens a genesis epoch at the current height and carries on. Every earlier epoch is then forgotten, which means their outstanding quotes lose the processor registration that keeps them resolvable, and their holders can never issue. The same happens if someone deletes the file to "reset" something. A loud failure is the correct behaviour; the operator can then choose to re-genesis deliberately.
The store's write also happens inside the async rotation mutex, so a slow disk blocks rotation rather than just that write.
Scope
In scope: fsync the record file and its directory on write; distinguish "no store exists and the operator asked for a fresh start" from "the store is missing or unreadable", failing loudly on the latter; and move the blocking filesystem work off the async lock.
Decide and state how a deliberate fresh start is expressed, since
just clean cashualready removes the store as the documented clean-slate step and must keep working.Out of scope: moving epoch records into the mint database, which is a larger change and would want its own issue.
Validation
Truncate
epochs.jsonto zero length and confirm the mint refuses to start rather than re-genesising. Remove it entirely and confirm the same, then confirm the documented clean-slate path still produces a working fresh mint. For durability, confirm the fsync is actually issued rather than asserting it from the code; a deliberate test that the file survives a simulated interrupted write is better than reading the call site.Superseded by a decision on vnprc/hashpool#37 (2026-10-09): the epoch store moves out of
epochs.jsonand into the mint database's key-value store, written in the same transaction as the cdk state it describes. That meets this issue's three goals by construction rather than by code: durability is sqlite's (no fsync of our own), a missing or unreadable store cannot exist separately from the database (there is one file;just clean cashuremoves it and that is the clean slate), and writes go through cdk's async database layer, off the rotation lock's executor thread. The fsync, fresh-start and mismatch work built on the earlier shape is dropped. #37 will carry the closing reference once the move is on its branch.