Skip to content

fix(round): reject seals outside the committed Drand reveal window (#… - #464

Merged
karagozemin merged 3 commits into
Sub-Rosa-Issue:mainfrom
CollinsKRO:fix/376-seal-round-commit-window
Oct 1, 2026
Merged

karagozemin merged 3 commits into
Sub-Rosa-Issue:mainfrom
CollinsKRO:fix/376-seal-round-commit-window

Conversation

@CollinsKRO

Copy link
Copy Markdown
Contributor

Closes #376

Goal

Refuse a bid seal — both off-chain and in the round contract — when its Drand quicknet round is not the round the auction committed to open.

Contract (contracts/round)

  • commit gains a seal_round: u64 argument. The allowed reveal round is always the stored Round::reveal_round, never a caller-supplied value. Mismatched seals are rejected before the escrow transfer, so a seal for a different round can never lock funds.
  • New stable errors mirroring the issue's requirements:
    • SealRoundTooEarly = 40 — seal round before the auction's round
    • SealRoundTooLate = 41 — seal round after the auction's round
    • InvalidSealRoundZero = 42 — zero/malformed rounds; also returned by create_round for zero or overflowing reveal rounds via the new drand::checked_time_of_round (replaces the saturating placeholder that could map an absurd round into the far future and strand the round past the void window).
  • Bookkeeping kept in lock-step per repo guards: ERRORS.md (new 40–42 section), DOCUMENTED_ERROR_CODES, variant_name, ERROR_PATH_REGISTRY (27→30), scripts/check-round-errors test counts. errors:check / errors:test PASS; 63 contract call snapshots regenerated with the new argument.

TypeScript (packages/tlock, sdk, services)

  • New packages/tlock/src/window.ts: assertSealRoundWindow(sealRound, revealRound) throws SealRoundError with stable reasons (seal-round-too-early / seal-round-too-late / invalid-seal-round-zero) mirroring the contract codes. Wired into sealBid and sealPayload before any encryption/network call.
  • SealedBid now carries sealRound; the SDK forwards it to commit as seal_round (typed config error if missing). All e2e/smoke/agent call sites updated (lifecycle-e2e, keeper-e2e, live-smoke, mainnet-micro, sealed-auction, agent bidder).
  • services/drand-tools timeOfRound now throws on zero/unsafe/overflowing rounds instead of returning a garbage product.

Acceptance criteria

  • A seal for a different Drand round cannot be committed (error_path_seal_round_too_early / ..._too_late, asserting no bid state / no escrow)
  • The contract and the TypeScript helper reject the same fixture set — both sides run vectors built from the repo's quicknet chain parameters (genesis 1692803367, period 3, frozen chain hash; real BLS fixture VEC_ROUND on-chain)
  • Overflowing or zero round numbers fail before any escrow lock (error_path_invalid_seal_round_zero, create_round_rejects_overflowing_reveal_round)
  • Existing happy-path seal tests still pass (live quicknet round trips unchanged apart from the new explicit revealRound argument)

Validation

  • cargo test -p sub-rosa-round: 91 passed, 0 failed
  • pnpm tlock:test: 79 passed (incl. new window.test.ts vectors)
  • pnpm sdk:test 211, keeper:test 73, agent:test 38, bindings:test 17, drand-tools:test 5 — all green
  • All affected workspaces typecheck (tlock, sdk, round-bindings, keeper, agent, auction-template)

…ub-Rosa-Issue#376)

A bid seal is only meaningful for the Drand round the auction committed to
open. The contract now stores that rule: `commit` takes the seal's round and
rejects, before any escrow is locked, any value that differs from the stored
`reveal_round` — with stable errors SealRoundTooEarly (40), SealRoundTooLate
(41), and InvalidSealRoundZero (42), the last also covering zero/overflowing
reveal rounds at `create_round` via the new checked_time_of_round.

Off-chain, @sub-rosa/tlock enforces the same window in sealBid/sealPayload
through assertSealRoundWindow (SealRoundError with matching stable reasons),
so the TS helper and the contract reject the same fixture set built from the
repo's quicknet chain parameters. The SDK forwards sealed.sealRound as
seal_round, bindings are regenerated, drand-tools' timeOfRound rejects
rounds the chain can never publish, and ERRORS.md plus all error registry
guards stay in lock-step.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@drips-wave

drips-wave Bot commented Sep 30, 2026

Copy link
Copy Markdown

@CollinsKRO Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@karagozemin
karagozemin merged commit df3e368 into Sub-Rosa-Issue:main Oct 1, 2026
Hustler490 pushed a commit to Hustler490/sub-rosa-issue that referenced this pull request Oct 4, 2026
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.

Reject seals whose Drand round falls outside the commit window

2 participants