Skip to content

Concurrent Transaction Submission, Throughput Measurement & Sequence Number Conflict Resolution #80

Description

@grantfox-oss

Overview

A developer tuning a high-throughput Stellar application — a payment processor, a batch settlement system, or a DEX bot — needs to know how many transactions per second they can submit before hitting sequence number conflicts, fee bumps, or Horizon rate limits. No tool exists for this. SaviTools must implement a network stress tester that submits N concurrent transactions from a single account (requiring sequence number management), measures actual throughput and error rates, automatically resolves tx_bad_seq errors via sequence number refresh, and produces a latency distribution report.

What needs to be built

apps/api/src/modules/network/stress.service.ts

  • POST /network/stress/run — accepts { sourcePublicKey, sourceSecretKey (encrypted transit), targetPublicKey, assetCode, assetIssuer, amountPerTx, concurrency: number (1–50), totalTxCount: number (1–500), feeStrategy: 'fixed' | 'p90' | 'p99' }:

    • Fetches current account sequence number from Horizon
    • Builds totalTxCount transactions with incrementing sequence numbers in memory before submission begins
    • Submits all transactions concurrently in batches of concurrency using Promise.allSettled
    • For any transaction that returns tx_bad_seq: re-fetches the current sequence number, rebuilds from that point, and re-submits — records this as a "sequence conflict event"
    • Tracks per-transaction: submission timestamp, confirmation timestamp, latency, result code
    • Returns a StressRunResult: { totalSubmitted, confirmed, failed, conflictsResolved, throughputTps, latencyP50, latencyP95, latencyP99, errorBreakdown: { [resultCode]: count } }
  • GET /network/stress/runs — list of previous stress run results for the authenticated user

  • Secret key is accepted as AES-256-GCM encrypted ciphertext using the user's session key — never stored in plaintext
    apps/web/src/app/network/stress/

  • Configuration form: source account, target account, amount, concurrency slider (1–50), total transactions (1–500), fee strategy selector

  • Warning banner: "This will submit real transactions on the selected network. Use testnet for load testing."

  • "Run Test" button — streams progress via WebSocket:

    • Live counter: submitted / confirmed / failed
    • Running throughput (TPS) gauge
    • Real-time latency histogram (recharts bar chart, updated every second)
  • Results panel post-run:

    • Summary cards: Total Submitted, Confirmed, Failed, Conflicts Resolved, Avg TPS
    • Latency distribution: P50, P95, P99 in ms
    • Error breakdown table: result code, count, percentage
    • Timeline chart: submissions and confirmations plotted over time

Acceptance criteria

  • 50 concurrent transactions from a single account all submitted successfully with no sequence number gaps — confirmed by checking the account's final sequence number equals initial + 50
  • tx_bad_seq errors are automatically resolved and the conflicting transactions resubmitted — zero manual intervention required
  • P99 latency measurement is accurate within ±100ms (validated by comparing against independently timed submissions)
  • Secret key never appears in any API response, log line, or database row
  • WebSocket progress updates arrive within 200ms of each batch completing
  • Stress test correctly blocks submission if the network toggle is set to mainnet and the user has not explicitly confirmed

Metadata

Metadata

Assignees

No one assigned

    Labels

    Third CampaignCampaign: Third CampaignbackendBackend / API workblockchainStellar / blockchain work

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions