Skip to content

Serial epoch refunds and simplifications - #286

Merged
GCdePaula merged 6 commits into
mainfrom
feature/serial-epoch-refunds
Sep 10, 2026
Merged

GCdePaula merged 6 commits into
mainfrom
feature/serial-epoch-refunds

Conversation

@GCdePaula

@GCdePaula GCdePaula commented Sep 7, 2026 •

Copy link
Copy Markdown
Member

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:

  • Removes unused ruler abstractions and isolates toy-machine support in test code.
  • Keeps transition positioning, proof generation, and pre/post-state checks together in the engine.
  • Makes Advance preparation read its original context instead of copying and revalidating match state.

Computation-hash and proof semantics are unchanged.

@GCdePaula
GCdePaula marked this pull request as ready for review September 7, 2026 13:41
@GCdePaula GCdePaula self-assigned this Sep 7, 2026
@GCdePaula
GCdePaula requested a review from stephenctw September 7, 2026 19:11
stephenctw
stephenctw previously approved these changes Sep 8, 2026

@stephenctw stephenctw left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Completion blocks on any TOURNAMENT_RUNNING in 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 in docs/node-architecture.md next to the existing
    "recovery may delay another action" caveat, so the assumption stays
    reviewable.
  2. The other => arm also sets complete = false, so an unexpected
    BondDisposition would 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 run just check or
    the multi_sybil e2e that this PR touches.

@GCdePaula
GCdePaula merged commit 79874c0 into main Sep 10, 2026
9 checks passed
@GCdePaula
GCdePaula deleted the feature/serial-epoch-refunds branch September 10, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants