Serial epoch refunds and simplifications - #286
Conversation
stephenctw
left a comment
There was a problem hiding this comment.
Approve.
The core fix is sound: recovery now walks the whole tournament tree at a
finalized head and drives one tryRecoveringBond at a time, so a validator
with bonds locked in several tournaments no longer starves. Pairing it with a
durable completion cursor (storage/completion.rs) is the right call - the
epoch is only retired once settlement and refunds have both been observed at a
finalized head, so a restart mid-recovery resumes instead of forgetting.
I like that plan_recovery derives everything from bondRecovery() and needs
no join history. The engine/Hero cleanup (folding ProvingStf into Stf,
dropping ToyFactory) is a clear simplification and reads as behavior-
preserving.
Two non-blocking notes:
- Completion blocks on any
TOURNAMENT_RUNNINGin the tree, including
tournaments where no bond is ours. That is the conservative reading of an
answer the contract has not yet given, and avoiding it would cost the
no-join-history property, so I would keep it - but it is worth naming the
inner-still-running case indocs/node-architecture.mdnext to the existing
"recovery may delay another action" caveat, so the assumption stays
reviewable. - The
other =>arm also setscomplete = false, so an unexpected
BondDispositionwould stall the cursor behind a warning rather than fail
loudly. The ordinal mirror test should catch drift at build time, so this is
belt-and-braces - just flagging that it fails closed on the liveness side.
Review scope: diff, surrounding code, and docs. I did not runjust checkor
themulti_sybile2e that this PR touches.
Fixes bond refunds being starved as the node moves into new tournaments. The epoch manager now follows a durable completion cursor and waits for finalized settlement and recovery of its winning root and inner-tournament bonds before participating in the next epoch.
Each tick batches dispute/settlement work with eligible refunds through the existing stateless transaction lane. Restart resumes the same unfinished epoch, and snapshot collection respects both completion and machine-runner progress.
Also simplifies the engine/Hero boundary:
Computation-hash and proof semantics are unchanged.