Skip to content

feat(contract): implement bounded resumable settlement and void refunds (closes #359) - #372

Open
ranjeet150 wants to merge 1 commit into
Sub-Rosa-Issue:mainfrom
ranjeet150:feat/issue-359-bounded-resumable-settlement
Open

ranjeet150 wants to merge 1 commit into
Sub-Rosa-Issue:mainfrom
ranjeet150:feat/issue-359-bounded-resumable-settlement

Conversation

@ranjeet150

Copy link
Copy Markdown

Summary

Closes #359.

Implements a bounded, resumable settlement and void refund protocol on the Soroban contract and updates client/orchestration tooling. Rounds supporting up to 500 bidders can now be settled or voided incrementally across bounded transaction batches without exceeding Soroban execution and memory limits.

Architectural Changes

  1. Explicit Payout Progress & Invariant Conservation:

    • Added PayoutProgress struct: tracking cursor, total_bidders, paid_amount, remaining_obligations, and completed.
    • After each batch, the aggregate escrow invariant strictly holds:
      2076271\text{total_escrow} = \text{paid_amount} + \text{remaining_obligations}2076271
    • Status transition to Settled or Voided occurs if and only if all obligations are 100% completed (remaining_obligations == 0).
  2. Frozen Clearing & Idempotency:

    • Clearing outcome (winning bidder, winning value, operator address) remains frozen across batches.
    • Payout state is tracked per bidder using the settled flag on BidState.
    • Repeated and overlapping batch calls are fully idempotent: operator payout, winner surplus, and loser refunds are never duplicated.
  3. Resumable Keeper Orchestration:

    • Added settle_batch(round_id, cursor, limit), void_batch(round_id, cursor, limit), and get_payout_progress(round_id).
    • Backwards compatible single-call settle and void delegate to batch execution.
    • SDK client extended with settleBatch, voidBatch, getPayoutProgress, settleAll, voidAll, and preflight simulations.
    • If an off-chain keeper halts or crashes between batches, any subsequent keeper can resume from on-chain confirmed cursor.
  4. Error Handling & Drift Guarding:

    • Added error variant InvalidCursor = 40 (code 40 in 30-49 data/input range).
    • Documented in ERRORS.md and synchronized with TypeScript bindings and automated drift checks.

Verification & Testing Proof

  • Rust Contract Tests: 95/95 passed green (cargo test -p sub-rosa-round).
    • max_500_bidder_bounded_settlement_resource_regression: Verified bounded settlement of 500 bidders across 10 batches with recorded instruction budgets well within Stellar Protocol 20/21/22 single-transaction limits (100M CPU, 40MB memory).
    • bounded_settlement_multi_batch_conservation_and_short_batch
    • bounded_settlement_repeated_and_overlapping_batches
    • bounded_settlement_invalid_cursors_and_limits
    • bounded_settlement_zero_surplus
    • bounded_void_multi_batch_and_conservation
    • resumable_settlement_interrupted_keeper_simulation
  • Linter & Formatting:
    • cargo clippy -p sub-rosa-round -- -D warnings: 0 warnings, 0 errors.
    • cargo fmt --check: 100% clean formatting.
  • TypeScript Packages:
    • packages/round-bindings: 17/17 tests pass; tsc --noEmit clean.
    • packages/sdk: 213/213 tests pass; tsc --noEmit clean.
    • services/keeper: 73/73 tests pass.
    • packages/tlock: 67/67 tests pass.
    • scripts/check-round-errors: 5/5 tests pass.

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.

feat(contract): implement bounded resumable settlement and void refunds

1 participant