Skip to content

feat(bench-tps): add deposit & withdraw e2e load testing flows#89

Merged
dev-jodee merged 4 commits intomainfrom
feat/deposit-n-withdrawal-load-testing
Apr 3, 2026
Merged

feat(bench-tps): add deposit & withdraw e2e load testing flows#89
dev-jodee merged 4 commits intomainfrom
feat/deposit-n-withdrawal-load-testing

Conversation

@Huzaifa696
Copy link
Copy Markdown
Collaborator

@Huzaifa696 Huzaifa696 commented Apr 2, 2026

Summary

Extends contra-bench-tps with two new subcommands — deposit and withdraw — that load-test the full cross-chain flows end-to-end.

New flows

Deposit (Solana -> Contra)

Sends Deposit instructions to the escrow program on the Solana validator. Setup funds each depositor account with SOL and Solana tokens, creates the escrow instance PDA, registers the mint, and seeds the instance ATA. During the load phase, each transaction transfers tokens from a depositor's Solana ATA into the escrow instance ATA. Measures solana_landed (validator confirmations via getTransactionCount) and contra_minted (e2e Contra mints confirmed by operator-solana via contra_operator_mints_sent_total{escrow}).

The CLI final summary prints sent, solana_landed, contra_minted, drop (solana_landed - contra_minted) and TPS. The Grafana dashboard shows four panels in order: Solana Sent TPS → Indexer Solana events indexed → Operator fetch rate + backlog depth → Contra Mint Rate.

Deposit flow dashboard

<img width="1477" height="664" alt="Screenshot from 2026-04-02 16-46-29" src="https://github.com/user-attachments/assets/f5ce0ea7-77df-4924-986b-54451dca2468" />

Withdraw (Contra → Solana)

Sends WithdrawFunds (burn) transactions to the Contra write-node. Setup initialises the same escrow infrastructure on Solana, creates Contra ATAs funded with tokens, and creates Solana ATAs for each withdrawer. During the load phase, each transaction burns tokens from the withdrawer's Contra ATA. Measures contra_burned (Contra confirmations via getTransactionCount) and solana_released (e2e Solana releases confirmed by operator-contra via contra_operator_mints_sent_total{withdraw}).

The CLI final summary prints sent, contra_burned, solana_released, drop (contra_burned - solana_released) and TPS. The Grafana dashboard shows four panels in order — Contra Sent/Landed TPS → Indexer Contra events indexed → Operator fetch rate + backlog depth → Solana Release Rate.

Withdraw flow dashboard

<img width="1477" height="664" alt="Screenshot from 2026-04-02 16-48-38" src="https://github.com/user-attachments/assets/a25912d8-128d-45ea-92f5-d311c02cdf80" />

Changes outside bench-tps

docker-compose.devnet.ymloperator-contra was missing COMMON_SOURCE_RPC_URL, which is the Contra gateway URL the operator uses to read withdrawal burn events. Without it, operator-contra cannot process any withdrawals. METRICS_PORT also added to all indexer/operator services for observability.

bench-tps/.env.sample.devnet — New env sample for devnet deployments

scripts/devnet/config/operator-contra.toml — Added source_rpc_url field

indexer/config/local/operator-contra.toml — Added source_rpc_url = "http://localhost:8898" so the local operator-contra reads from the Contra gateway.

indexer/config/local/operator-solana.toml — Fixed rpc_url, should be Contra gateway 8898 for reading mint events and added source_rpc_url = "http://localhost:18899" for Solana.

grafana/dashboards/contra-bench.json — Restructured dashboard into separate Deposit Flow (Solana → Contra) and Withdraw Flow (Contra → Solana) sections. This makes it straightforward to see which stage is the bottleneck during a run.

bench-tps/scripts/run.sh — Cleanup now calls docker compose down and made sure that the containers' teardown fires exactly once regardless of how the script exits.

Docs

README.md and BOTTLENECK_ANALYSIS.md updated with per-flow sections covering how to run, what each metric means, and a panel-by-panel bottleneck guide.

Test plan

  • ./bench-tps/scripts/run.sh deposit — verify solana_landed and contra_minted appear in final summary
  • ./bench-tps/scripts/run.sh withdraw — verify contra_burned and solana_released are non-zero
  • Grafana dashboard loads without errors; Deposit and Withdraw sections show data during respective bench runs
  • Ctrl+C mid-run triggers docker compose down and all containers stop

Coverage Report

Component Lines Hit Lines Total Coverage Artifact
Core 7,104 8,411 84.5% rust-unit-coverage-reports
Indexer 12,101 14,180 85.3% rust-unit-coverage-reports
Gateway 952 1,076 88.5% rust-unit-coverage-reports
Auth 541 596 90.8% rust-unit-coverage-reports
Withdraw Program 118 230 51.3% unit-coverage-reports
Escrow Program 1,170 1,957 59.8% unit-coverage-reports
E2E Integration 7,678 11,026 69.6% e2e-coverage-reports
Total 29,664 37,476 79.2%  

Last updated: 2026-04-02 12:53:41 UTC by E2E Integration

## Summary

Extends contra-bench-tps with two new subcommands — deposit and withdraw — that load-test the full cross-chain flows end-to-end.

New flows

Deposit (Solana -> Contra)

Sends Deposit instructions to the escrow program on the Solana validator. Setup funds each depositor account with SOL and Solana tokens, creates the escrow instance PDA, registers the mint, and seeds the instance ATA. During the load phase, each transaction transfers tokens from a depositor's Solana ATA into the escrow instance ATA. Measures solana_landed (validator confirmations via getTransactionCount) and contra_minted (e2e Contra mints confirmed by operator-solana via contra_operator_mints_sent_total{escrow}).

The CLI final summary prints sent, solana_landed, contra_minted, drop (solana_landed - contra_minted) and TPS. The Grafana dashboard shows four panels in order: Solana Sent TPS → Indexer Solana events indexed → Operator fetch rate + backlog depth → Contra Mint Rate.

Deposit flow dashboard

Screenshot from 2026-04-02 16-46-29

Withdraw (Contra → Solana)

Sends WithdrawFunds (burn) transactions to the Contra write-node. Setup initialises the same escrow infrastructure on Solana, creates Contra ATAs funded with tokens, and creates Solana ATAs for each withdrawer. During the load phase, each transaction burns tokens from the withdrawer's Contra ATA. Measures contra_burned (Contra confirmations via getTransactionCount) and solana_released (e2e Solana releases confirmed by operator-contra via contra_operator_mints_sent_total{withdraw}).

The CLI final summary prints sent, contra_burned, solana_released, drop (contra_burned - solana_released) and TPS. The Grafana dashboard shows four panels in order — Contra Sent/Landed TPS → Indexer Contra events indexed → Operator fetch rate + backlog depth → Solana Release Rate.

Withdraw flow dashboard

Screenshot from 2026-04-02 16-48-38

Changes outside bench-tps

docker-compose.devnet.ymloperator-contra was missing COMMON_SOURCE_RPC_URL, which is the Contra gateway URL the operator uses to read withdrawal burn events. Without it, operator-contra cannot process any withdrawals. METRICS_PORT also added to all indexer/operator services for observability.

bench-tps/.env.sample.devnet — New env sample for devnet deployments

scripts/devnet/config/operator-contra.toml — Added source_rpc_url field

indexer/config/local/operator-contra.toml — Added source_rpc_url = "http://localhost:8898" so the local operator-contra reads from the Contra gateway.

indexer/config/local/operator-solana.toml — Fixed rpc_url, should be Contra gateway 8898 for reading mint events and added source_rpc_url = "http://localhost:18899" for Solana.

grafana/dashboards/contra-bench.json — Restructured dashboard into separate Deposit Flow (Solana → Contra) and Withdraw Flow (Contra → Solana) sections. This makes it straightforward to see which stage is the bottleneck during a run.

bench-tps/scripts/run.sh — Cleanup now calls docker compose down and made sure that the containers' teardown fires exactly once regardless of how the script exits.

Docs

README.md and BOTTLENECK_ANALYSIS.md updated with per-flow sections covering how to run, what each metric means, and a panel-by-panel bottleneck guide.

Test plan

  • ./bench-tps/scripts/run.sh deposit — verify solana_landed and contra_minted appear in final summary
  • ./bench-tps/scripts/run.sh withdraw — verify contra_burned and solana_released are non-zero
  • Grafana dashboard loads without errors; Deposit and Withdraw sections show data during respective bench runs
  • Ctrl+C mid-run triggers docker compose down and all containers stop

Coverage Report

Component Lines Hit Lines Total Coverage Artifact
Core 7,103 8,411 84.4% rust-unit-coverage-reports
Indexer 12,100 14,180 85.3% rust-unit-coverage-reports
Gateway 952 1,076 88.5% rust-unit-coverage-reports
Auth 541 596 90.8% rust-unit-coverage-reports
Withdraw Program 118 230 51.3% unit-coverage-reports
Escrow Program 1,170 1,957 59.8% unit-coverage-reports
E2E Integration 7,679 11,026 69.6% e2e-coverage-reports
Total 29,663 37,476 79.2%

Last updated: 2026-04-03 14:05:37 UTC by E2E Integration

Comment thread bench-tps/src/setup_withdraw.rs Outdated
Comment thread bench-tps/src/load_deposit.rs
Comment thread bench-tps/src/setup_deposit.rs
Comment thread core/src/bin/node.rs
  Adds two new bench-tps subcommands for end-to-end load testing:

  - `deposit`: sets up L1 escrow instance, mints tokens, runs deposit
    load against the escrow program, and tracks l2_minted via
    operator-solana metrics.

  - `withdraw`: sets up L1 escrow + L2 withdrawer accounts (including
    L1 ATAs for recipients), runs WithdrawFunds burn load on L2, and
    tracks l1_released via operator-contra metrics.

  Key fix: create L1 ATAs for withdrawer keypairs during setup.
  validate_ata() in the escrow program returns InvalidInstructionData
  when the recipient ATA is empty, causing all ReleaseFunds calls to
  fail silently with "invalid instruction data".

  Also fixes docker-compose: add COMMON_ESCROW_INSTANCE_ID passthrough,
  METRICS_PORT=9103, and port mapping to operator-contra so the bench
  can scrape l1_released from outside the Docker network.
  - Add deposit flow: L1 escrow Deposit load test with e2e measurement via
    operator-solana mints (contra_operator_mints_sent_total{escrow})
  - Add withdraw flow: L2 WithdrawFunds burn + L1 ReleaseFunds e2e path;
    setup creates L1 ATAs for withdrawers to fix InvalidInstructionData on
    ReleaseFunds; memo nonce added to ensure unique tx signatures
  - Add COMMON_SOURCE_RPC_URL to operator-contra in docker-compose.devnet.yml
    and scripts/devnet/config/operator-contra.toml
  - Add bench-tps/.env.sample.devnet with devnet-specific placeholders
  - Restructure Grafana dashboard: separate Deposit and Withdraw flow sections
    each showing pipeline stages in order (sent → indexer → operator → confirmed);
    remove Mixed Load panels
  - Improve run.sh cleanup: use `down` instead of `stop`, trap EXIT INT TERM ERR
    with a deduplication guard to ensure teardown on all exit paths
  - Update README and BOTTLENECK_ANALYSIS with per-flow run/measure/debug guides
  - Fix clippy: remove redundant serde_json imports, fix over-indented doc comment
@Huzaifa696 Huzaifa696 force-pushed the feat/deposit-n-withdrawal-load-testing branch from a5bfa6e to 9b64c5e Compare April 2, 2026 11:07
@Huzaifa696 Huzaifa696 changed the title Feat/deposit n withdrawal load testing feat(bench-tps): add deposit & withdraw e2e load testing flows Apr 2, 2026
Comment thread bench-tps/src/setup_withdraw.rs Outdated
@Huzaifa696 Huzaifa696 requested review from amilz and dev-jodee April 2, 2026 13:20
Copy link
Copy Markdown
Collaborator

@dev-jodee dev-jodee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 small nits + what we discussed on slack

Comment thread bench-tps/src/bench_metrics.rs Outdated
Comment thread bench-tps/src/args.rs Outdated
@solana-foundation solana-foundation deleted a comment from Huzaifa696 Apr 3, 2026
@solana-foundation solana-foundation deleted a comment from greptile-apps Bot Apr 3, 2026
@solana-foundation solana-foundation deleted a comment from greptile-apps Bot Apr 3, 2026
@dev-jodee dev-jodee merged commit 16b8b3e into main Apr 3, 2026
10 checks passed
@dev-jodee dev-jodee deleted the feat/deposit-n-withdrawal-load-testing branch April 3, 2026 14:28
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.

2 participants