Skip to content

feat: caller-supplied idempotency key for place_bets batch#769

Merged
greatest0fallt1me merged 1 commit into
Predictify-org:masterfrom
Keengfk:feat/place-bets-idempotency-key
Jun 29, 2026
Merged

feat: caller-supplied idempotency key for place_bets batch#769
greatest0fallt1me merged 1 commit into
Predictify-org:masterfrom
Keengfk:feat/place-bets-idempotency-key

Conversation

@Keengfk

@Keengfk Keengfk commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

feat: caller-supplied idempotency key for place_bets batch

Summary

place_bets previously had no per-batch deduplication token. A client retry
after a partial failure could double-submit bets. This PR adds a
caller-supplied BytesN<32> idempotency key consumed atomically on the first
successful call.

Changes

storage.rs

  • Added DataKey::PlaceBetsIdem(Address, BytesN<32>) — keyed per user so keys
    from different users never collide
  • Added PLACE_BETS_IDEM_TTL_LEDGERS = 7 * LEDGERS_PER_DAY (≈ 7 days at 5
    s/ledger); documented inline

err.rs

  • Added Error::IdempotentBatchAlreadyApplied = 509

bets.rs

  • Added idempotency_key: BytesN<32> parameter to BetManager::place_bets
  • Guard checks for existing key before any validation; rejects with typed error
  • Key is written to persistent storage with TTL only after all bets succeed
    (atomic)

lib.rs

  • Updated place_bets entrypoint signature to forward the new parameter

place_bets_idempotency_tests.rs (new)

  • 5 tests: fresh key accepted, duplicate key rejected, different key accepted,
    key scoped per user, key reusable after TTL

Acceptance criteria

┌───────────┬────────┐
│ Criterion │ Status │
├──────────────────────────────────────────────────────────┼────────┤
│ Repeated key rejected with IdempotentBatchAlreadyApplied │ ✅ │
├──────────────────────────────────────────────────────────┼────────┤
│ TTL documented in storage.rs constants │ ✅ │
├──────────────────────────────────────────────────────────┼────────┤
│ No unwrap() introduced │ ✅ │
├──────────────────────────────────────────────────────────┼────────┤
│ Key scoped to (user, key) — no cross-user collisions │ ✅ │
└──────────────────────────────────────────────────────────┴────────┘

Testing

cargo test -p predictify-hybrid place_bets_idempotency -- --nocapture
cargo test -p predictify-hybrid batch_operations_tests -- --nocapture
closes #621

- Add DataKey::PlaceBetsIdem(Address, BytesN<32>) to storage.rs
- Add PLACE_BETS_IDEM_TTL_LEDGERS = 7 * LEDGERS_PER_DAY constant
- Add Error::IdempotentBatchAlreadyApplied = 509 to err.rs
- Add idempotency_key: BytesN<32> param to BetManager::place_bets
- Guard: reject reuse within TTL with IdempotentBatchAlreadyApplied
- Consume key atomically after successful batch (persistent + TTL)
- Update lib.rs entrypoint and all existing call sites
- Add place_bets_idempotency_tests.rs: 5 tests covering happy path,
  duplicate key rejection, different key acceptance, per-user key
  scoping, and post-TTL re-use
@drips-wave

drips-wave Bot commented Jun 28, 2026

Copy link
Copy Markdown

@Keengfk 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

@greatest0fallt1me greatest0fallt1me merged commit 74dde59 into Predictify-org:master Jun 29, 2026
1 check failed
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.

Add idempotency token to place_bets batch to prevent partial double-submission

2 participants