Conversation
Greptile SummaryThis PR delivers three interconnected throughput improvements: (1) rewrites the bench-tps load phase as fully async using tokio mpsc +
Confidence Score: 4/5Safe to merge after addressing the block_in_place gap in the parallel SVM path; all other changes are well-structured and well-tested. One P1 finding: execute_parallel blocks a tokio worker thread via std::thread::scope without block_in_place, which can starve the async pipeline under sustained load. The fix is a one-line change. All remaining findings are P2 style/robustness suggestions. The bulk of the PR is solid. core/src/stages/execution.rs — the execute_parallel call site in execute_batch needs tokio::task::block_in_place Important Files Changed
Sequence DiagramsequenceDiagram
participant RPC as RPC Handler
participant Dedup as Dedup (async_channel bounded)
participant SigV as Sigverify Pool (async_channel bounded)
participant Seq as Sequencer (mpsc bounded)
participant Exec as Executor (tokio task)
participant SVM as SVM Workers (std::thread::scope)
participant Settle as Settler (tick-driven)
participant PG as Postgres (bulk UNNEST)
RPC->>Dedup: SanitizedTransaction
Dedup->>SigV: forward (bounded, backpressure)
SigV->>Seq: verified tx (unbounded mpsc)
Seq->>Seq: deadline batch collection
Seq->>Exec: ConflictFreeBatch (bounded channel)
Exec->>SVM: execute_parallel (blocks tokio thread)
SVM-->>Exec: merged LoadAndExecuteOutput
Exec->>Settle: (output, txs) via unbounded mpsc
Settle->>Settle: accumulate until blocktime tick
Settle->>PG: write_batch (bulk UNNEST upsert)
Settle->>Dedup: settled_blockhash
Settle->>Exec: settled_accounts (BOB update)
Reviews (1): Last reviewed commit: "perf(throughput): async bench, bulk-SQL ..." | Re-trigger Greptile |
- execution: wrap execute_parallel in block_in_place to avoid
stalling the tokio worker during thread::scope.
- bench-tps: swap Arc<Mutex<mpsc::Receiver>> for async_channel so
cancellation hits every sender task directly.
- accounts: add explicit ::bytea[] cast to bulk DELETE query.
- Rewrite bench-tps load phase as async (tokio mpsc + join_all) - Replace per-row account/tx writes with bulk UNNEST upserts - Drop settler's in-memory tx_count; same-tx read-modify-write - Expose CONTRA_PG_MAX_CONNECTIONS (32, cap 256), CONTRA_BATCH_DEADLINE_MS, CONTRA_MAX_SVM_WORKERS - Raise container nofile soft/hard to 65536 - Mirror new env vars and ulimits in docker-compose.devnet.yml
- execution: wrap execute_parallel in block_in_place to avoid
stalling the tokio worker during thread::scope.
- bench-tps: swap Arc<Mutex<mpsc::Receiver>> for async_channel so
cancellation hits every sender task directly.
- accounts: add explicit ::bytea[] cast to bulk DELETE query.
async_channel guarantees no fairness, so the /2 floor flaked on CI. Assert each consumer received >0 — enough to prove MPMC fan-out.
The SVM's AccountLoader treats cached accounts with lamports=0 as deallocated and returns None on subsequent loads in the same batch. BOB's system_program and rent sysvar precompiles, plus admin-created mints, all had lamports=0 — breaking ATA creation when multiple txs landed in one batch (exposed by batch_deadline_ms coalescing).
d1617c8 to
41ea473
Compare
Summary
Raises sustained end-to-end TPS by adding a deadline-driven sequencer flush, parallelizing SVM execution over non-conflicting chunks, tightening dedup/sigverify under load, and collapsing the settler's per-row SQL writes into bulk upserts. The same knobs are exposed as env vars so operators can tune the pipeline without code changes. No behavioral changes outside perf + configuration.
Also rewrites the bench load loop as async.
Core
merge_svm_outputsreassembles results and accumulatesTransactionErrorMetrics/ExecuteTimingsacross chunks. Single-worker setting collapses back to the sequential path.write_batch.rsreplaced with bulk upserts; settlerselect!made biased so shutdown and blocktime ticks win over result draining.PostgresAccountsDBnow resolves pool size from config with a ceiling.Configuration
New knobs:
CONTRA_BATCH_DEADLINE_MS(sequencer flush deadline),CONTRA_MAX_SVM_WORKERS(executor parallelism),CONTRA_PG_MAX_CONNECTIONS(pool size, default 32, ceiling 256) — mirrored in.env.*anddocker-compose*.yml.bench-tps
mpsc+join_all) so a single driver saturates the RPC endpoint instead of blocking per-tx.args.rs/main.rswire the new async flow;run.shand.env.sample(.devnet)pick up the new knobs.Infra
docker-compose.ymlanddocker-compose.devnet.ymlraise containernofilesoft/hard limits to 65536 and mirror the new env vars.Result
TPS Before: ~1600

TPS After: ~7000
Coverage Report