Skip to content

Client Load Testing: simulate and send transactions #12

@sreuland

Description

@sreuland

Add support for the interactive transaction endpoints: simulateTransaction and sendTransaction. These endpoints require sophisticated request generation strategies based on transaction construction capabilities and leveraging the vegeta custom targeters to achieve parameter injections.

Related to: Client load testing tool Feature - #4
Related to: Client load testing Epic - #2

Prerequisite

Depends on #3, #6, and #11 to be done first. Create the CLI tool 'generate' and 'run' commands with data-dependent read-only endpoint support first.

Implementation Details

Use vegeta custom targets for injecting request data for the http client requests. Refer to this chat session for a vibe coded PoC of using vegeta against getTransaction.

Abstract away account creation so that we can plug in pubnet funding later.

Endpoint - simulateTransaction

Request Generation Strategy:

  • doesn't require seeded request data from bootstrap.dat from generate phase, request payload can be built during run
  • Mix of valid transactions:
    • 85% of requests should use well-formed valid transaction
    • 10% of requests should use transaction with invalid parameters
    • 5% of requests should use transaction with insufficient resources
  • Support both XDR and JSON format requests
  • At init time, pre-generate the XDR for three transactions: (1)well-formed, (2)invalid, and (3)insufficient resource
    • Transaction envelopes built with single InvokeHostFn op to invoke contract 'transfer' function
    • Can use zero contract ID since simulation doesn't validate on-chain existence
    • Can use zero account ID for account to/from references

Endpoint - sendTransaction

Request Generation Strategy:

  • Transaction submission pattern:

    • transactions will be done for 'transfer' operations on classic and soroban.
    • At worker thread init time:
      • generate a keypair for pub/private keys for the signer which is also used as the source and the transfer from accoun.
      • generate keypairss for transfer 'to' accounts, one or many, your choice.
      • fund the signer account public key with Friendbot
    • worker constructs and sign all transactions with signer account keypair, and set the 'source' on tx to the signer public key and correctly incrementing the account sequence number,
    • Handle transaction lifecycle (async submission, poll on getTransaction, result tracking)
  • if sendTransaction endpoint load testing is enabled in loadtest_config.toml, it should Include warnings about network impact on console from run.

    • if enabled, should the cli tool validate if pubnet is specified as network passphrase and fail the test on console with reason?
  • doesn't require seeded request data from bootstrap.dat from generate phase, request payload can be built during run

  • Perform the 'transfer' type transactions for both classic and contracts based on the classic_ratio configuration:

    Classic Stellar Payments (XLM transfers):

    • Percentage of transactions submitted determined by sendTransaction.classic_ratio (0-100)
    • Use generated 'from' and 'to' accounts
    • Transfer XLM as the asset

    Soroban SEP-41 Token Transfers:

    • Percentage of transactions submitted determined by 100 - sendTransaction.classic_ratio
    • Invoke 'transfer' method on SEP-41 compliant token contract
    • Use generated 'from' and 'to' accounts
    • at worker init, mint tokens to 'from' accounts
    • Token contract specified by sendTransaction.soroban_sep41_token_contract (WASM file path or hex contract ID). If it's wasm, then test should deploy the contract to network at init time.
    • Leverage the SEP-41 compliant token interface so invocation is just for the standardized 'transfer' function and the contract instance can be an SAC or a custom token contract.

Configuration Updates

Update TOML configuration to include new endpoints with transaction-specific parameters:

[endpoints]
# Existing endpoints...
# getHealth.rps = 5.0
# ...

# Transaction simulation endpoint
simulateTransaction.enabled = true
simulateTransaction.rps = 3.0
simulateTransaction.concurrency = 2

# Transaction sending endpoint
sendTransaction.enabled = true
sendTransaction.rps = 1.0
sendTransaction.concurrency = 1

# Transaction type distribution (0-100, remainder is Soroban)
sendTransaction.classic_ratio = 50

# SEP-41 token contract
# Can be any SAC or SEP-41 compliant token contract
# expressed as file path to a wasm, which would be deployed by test first to network
sendTransaction.soroban_sep41_token_contract = "./contracts/token.wasm"
# or as strkey encoded contract address for a contract already on chain
sendTransaction.soroban_sep41_token_contract = "CDABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF"

Metrics

Update metrics collection to include transaction-specific measurements:

New Metrics:

  • rpc_loadtest_simulate_result{type="success|fail"} - Simulation response counter
  • rpc_loadtest_send_transaction_type{type="classic|soroban"} - Transaction type counter
  • rpc_loadtest_send_transaction_result{type="success|fail"} - Submission response counter

Update console output to include:

[00:32 / 05:00] 
simulateTransaction: 180 req (153 success, 27 errors) | 3.0 RPS | p50: 85ms, p95: 220ms, p99: 450ms
  └─ Avg CPU: 1.2M, Avg Memory: 45KB, Success Rate: 85%
sendTransaction: 60 req (58 success, 2 errors) | 1.0 RPS | p50: 120ms, p95: 380ms, p99: 650ms
  └─ Classic: 30 (50%), Soroban: 30 (50%) | Validation Rate: 97%

Metadata

Metadata

Assignees

Labels

performance-pod-scrumBoard items for performance pod work (anything related to load testing or adjacent work)

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions