Skip to content

Resolve concurrent-submission account-sequence races in TxService #32

Description

@Ehonrie

Difficulty: Research-Required
Category: Edge Case

Context: When a user has the dapp open in two tabs (or votes from two devices), both can independently simulate a transaction successfully against the same source account, then both submit — one will fail at the ledger with a sequence-number conflict after the user has already seen a successful simulation/confirmation UI. TxService.ts doesn't appear to guard against this class of race.

// dapp/src/service/TxService.ts
export async function submitWithSequenceConflictRecovery(
  buildAndSign: () => Promise<StellarSdk.Transaction>,
  options: { maxRebuildAttempts?: number },
): Promise<StellarSdk.rpc.Api.GetSuccessfulTransactionResponse> {
  // !todo: Detect account-sequence-number conflict responses from Soroban RPC submission
  //        and transparently rebuild+resimulate+resubmit with the correct next sequence,
  //        rather than surfacing a raw sequence error to the user.
  // !todo: Must cap rebuild attempts and distinguish "someone else's concurrent tx won"
  //        from "our own stale local sequence cache" to avoid infinite rebuild loops.
  // !todo: Research: how do other Soroban dapps/SDKs handle this? Document findings before implementing.
  // !todo: Edge case: the conflicting transaction may have been this SAME user's other tab —
  //        surfacing "your other tab already did this" is better UX than a generic error.
  throw new Error("Not implemented");
}

What contributors need to know:

  • Problem: no explicit handling found in TxService.ts (304 lines) for sequence-number races between simulate-success and submit-time.
  • Related code: dapp/src/components/stellar-wallets-kit.ts, walletService.ts.
  • Suggested approach: research needed into Soroban RPC's specific error shape for sequence conflicts, and the safe rebuild protocol (re-fetch account sequence, rebuild tx, re-simulate, re-sign).
  • Acceptance criteria: a test harness simulating two overlapping submissions from the "same" wallet demonstrates one succeeding and the other recovering gracefully with a clear user-facing message, not a raw RPC error dump.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    edge-caseError recovery, concurrency, race conditionsresearch-requiredDifficulty: Research-Required

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions