Skip to content

#752 getAccount uses deduplicateRequest but dedup key does not include sequence number — stale results on rapid retries - #823

Merged
k-deejah merged 1 commit into
Sorokit:mainfrom
jotel-dev:fix/752-getAccount-dedup-stale-sequence
Oct 18, 2026
Merged

k-deejah merged 1 commit into
Sorokit:mainfrom
jotel-dev:fix/752-getAccount-dedup-stale-sequence

Conversation

@jotel-dev

Copy link
Copy Markdown
Contributor

Summary

Fixes #752

Ensures getAccount deduplication does not return stale sequence numbers on rapid retries or concurrent transaction submissions.

How Sequence Is Invalidated or Refreshed After Submission

  1. Sequence & Version-Aware Deduplication Key:

    • The deduplication key in src/account/getAccount.ts has been updated to include per-account mutation version tracking and optional sequence parameters: getAccount:${horizonUrl}:${publicKey}:v${version}${seqSuffix}.
    • Callers can also supply sequence, expectedSequence, or forceRefresh via GetAccountOptions to isolate concurrent requests expecting distinct ledger states.
  2. Automatic Post-Submission Invalidation:

    • In src/transaction/submitTransaction.ts, successful transaction submissions (and submission attempts) automatically invoke invalidateSubmittedTxAccounts(tx, horizonUrl).
    • Resolves source accounts for both standard Transaction and FeeBumpTransaction (including inner transaction source and fee source), demuxes muxed addresses to Ed25519 public keys, and calls invalidateAccount(sourceKey, horizonUrl).
  3. In-Flight Cache Eviction:

    • Added invalidateInflightRequests and removeInflightRequest to src/shared/utils.ts.
    • When invalidateAccount is called, the mutation version is bumped and all matching in-flight deduplicated promises are evicted from _inflightRequests. Any concurrent or subsequent fetch initiates a fresh Horizon query rather than returning the stale sequence number.
  4. Public Invalidation APIs:

    • Exported invalidateAccount, invalidateAccountCache, refreshAccountSequence, clearAccountDeduplication, and GetAccountOptions from src/account/index.ts for direct lifecycle control.

Acceptance Criteria Covered

  • Rapid concurrent fetches of the same account share the deduplicated request and receive the same correct sequence.
  • After a transaction is submitted using that sequence, the next fetch reflects the incremented sequence rather than a cached old value.
  • Concurrent fetch + mid-flight mutation invalidation scenarios correctly evict in-flight promises and fetch fresh state.
  • Comprehensive test coverage in src/tests/getAccountDeduplication.test.ts.

…tion (Sorokit#752)

Ensure getAccount deduplication does not return stale sequence numbers on rapid concurrent fetches and retries. Includes sequence in the deduplication key when provided, tracks per-account mutation version, clears in-flight deduplicated requests on account invalidation, and automatically invalidates source account sequence state upon transaction submission.
@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

@jotel-dev 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

@k-deejah
k-deejah merged commit b8700a0 into Sorokit:main Oct 18, 2026
4 of 5 checks passed
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.

getAccount uses deduplicateRequest but dedup key does not include sequence number — stale results on rapid retries

2 participants