Skip to content

Latest commit

 

History

History
312 lines (247 loc) · 10.4 KB

File metadata and controls

312 lines (247 loc) · 10.4 KB

Load Blaster - Specification

High-performance load testing tool for EVM-compatible testnets

1. Overview

load-blaster is a Rust-based load testing tool designed to stress-test EVM-compatible testnets with high transaction throughput and blob data rates.

Target Metrics

Metric Target Range Notes
TPS (transactions/second) 10k - 100k Regular EIP-1559 transactions
Blob throughput 16 - 100 MB/s EIP-4844 blob transactions
Latency P99 < 5s Submission to inclusion

Non-Goals (v1)

  • Distributed coordinator/worker architecture (future)
  • Smart contract interaction (just transfers)
  • Cross-chain testing

2. Architecture

2.1 Component Diagram

┌─────────────────────────────────────────────────────────────────┐
│                          load-blaster                           │
│                                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐  │
│  │ AccountPool  │  │  Generator   │  │    RateController    │  │
│  │ - HD wallet  │  │ - EIP-1559   │  │ - target_tps         │  │
│  │ - Nonce mgmt │  │ - EIP-4844   │  │ - target_blob_mbps   │  │
│  │ - Backpress. │  │ - BlobRing   │  │ - governor limiter   │  │
│  └──────┬───────┘  └──────┬───────┘  └──────────┬───────────┘  │
│         │                 │                      │              │
│  ┌──────▼─────────────────▼──────────────────────▼───────────┐  │
│  │                      RpcClientPool                         │  │
│  │  - HTTP/1.1 keep-alive                                     │  │
│  │  - JSON-RPC batching (eth_sendRawTransaction[])            │  │
│  │  - Round-robin endpoint selection                          │  │
│  └────────────────────────┬──────────────────────────────────┘  │
│                           │                                     │
│  ┌────────────────────────▼──────────────────────────────────┐  │
│  │                      Metrics                               │  │
│  │  - Prometheus exporter (:9091)                             │  │
│  │  - Console reporter                                        │  │
│  │  - Confirmation sampling                                   │  │
│  └───────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
                    Target RPC nodes

2.2 Data Flow

  1. AccountPool provides next available account (with backpressure)
  2. Generator creates signed transaction (EIP-1559 or EIP-4844 with blobs)
  3. RateController enforces target TPS / blob MB/s
  4. RpcClientPool batches and sends transactions
  5. Metrics tracks submitted/errors/latency

3. Core Components

3.1 AccountPool

Purpose: Manage test accounts with HD derivation and per-account backpressure.

Requirements:

  • Derive accounts from mnemonic (BIP-39 / BIP-44)
  • Track pending transactions per account
  • Enforce max pending limit (default: 16, matches reth txpool)
  • Support 1000+ accounts for high TPS

Interface:

pub struct AccountPool {
    pub fn new(mnemonic: &str, count: usize, max_pending: u32) -> Result<Self>;
    pub fn acquire(&self) -> Option<AccountHandle>;  // None = backpressure
    pub fn release(&self, handle: AccountHandle);
    pub fn get_nonce(&self, index: usize) -> u64;
    pub fn increment_nonce(&self, index: usize);
}

3.2 Generator

Purpose: Create signed transactions (EIP-1559 and EIP-4844).

Requirements:

  • Reuse patterns from ultramarine/crates/utils/src/tx.rs
  • EIP-4844: Use ring buffer of pre-computed blobs (64 blobs, ~50MB)
  • KZG proofs computed once at startup
  • Support configurable blobs_per_tx (1-32)

Interface:

pub struct Generator {
    pub fn new(chain_id: u64, blobs_per_tx: usize) -> Result<Self>;
    pub async fn create_eip1559(&self, signer: &Signer, nonce: u64, to: Address) -> Result<Bytes>;
    pub async fn create_eip4844(&self, signer: &Signer, nonce: u64, to: Address) -> Result<Bytes>;
}

3.3 RpcClientPool

Purpose: Efficient transaction submission with batching.

Requirements:

  • Multiple reqwest clients per endpoint (default: 4)
  • HTTP/1.1 with keep-alive (not HTTP/2)
  • JSON-RPC batch arrays (default: 20 txs per batch)
  • Round-robin across endpoints
  • Timeout handling (default: 10s)

Interface:

pub struct RpcClientPool {
    pub fn new(endpoints: Vec<String>, config: RpcConfig) -> Self;
    pub async fn send_batch(&self, txs: Vec<Bytes>) -> Vec<Result<TxHash, RpcError>>;
    pub async fn get_nonce(&self, address: Address) -> Result<u64>;
}

3.4 RateController

Purpose: Enforce target TPS and blob throughput.

Requirements:

  • Token bucket algorithm (governor crate)
  • Separate limiters for regular TPS and blob MB/s
  • Calculate blob_tx_rate from target_blob_mbps and blobs_per_tx
  • Support burst mode for stress testing

Interface:

pub struct RateController {
    pub fn new(target_tps: u64, target_blob_mbps: f64, blobs_per_tx: usize) -> Self;
    pub async fn wait_for_regular(&self);
    pub async fn wait_for_blob(&self);
    pub fn blob_tx_rate(&self) -> f64;  // txs/sec for blobs
}

3.5 Metrics

Purpose: Observability and reporting.

Requirements:

  • Prometheus metrics on configurable port
  • Console reporter with 1s interval
  • Confirmation sampling (default: 1% of txs)

Metrics:

Name Type Description
load_blaster_txs_submitted_total Counter Total transactions submitted
load_blaster_txs_errors_total Counter Submission errors (by type)
load_blaster_blobs_submitted_total Counter Total blobs submitted
load_blaster_bytes_submitted_total Counter Total bytes submitted
load_blaster_tps_current Gauge Current TPS (1s window)
load_blaster_blob_mbps_current Gauge Current blob throughput
load_blaster_nonce_resyncs_total Counter Nonce resync operations
load_blaster_confirmation_latency_seconds Histogram Sampled confirmation latency

4. Configuration

4.1 Config File (load-blaster.toml)

[target]
endpoints = ["http://localhost:8545"]
chain_id = 16384

[accounts]
count = 1000
max_pending = 16

[connections]
clients_per_endpoint = 4
keepalive_secs = 30
timeout_secs = 10
batch_size = 20

[blobs]
ring_buffer_size = 6
blobs_per_tx = 6
max_blobs_per_tx = 32

[metrics]
prometheus_addr = "127.0.0.1:9091"
console_interval_secs = 1
confirmation_sample_rate = 0.01

[sanity]
max_tps = 50000
max_blob_mbps = 200

4.2 Scenario File (scenarios/example.toml)

[scenario]
name = "example"

[[phases]]
type = "ramp_up"      # or "constant", "burst", "ramp_down"
duration = "30s"
from_tps = 1000
to_tps = 10000
from_blob_mbps = 0
to_blob_mbps = 50

[blobs]
blobs_per_tx = 6

[criteria]
min_success_rate = 0.95
max_p99_latency_ms = 5000

5. CLI Interface

load-blaster 0.1.0
High-performance load testing for EVM-compatible networks

USAGE:
    load-blaster <COMMAND>

COMMANDS:
    run         Run a load test
    accounts    Manage test accounts
    help        Print help

OPTIONS:
    -c, --config <FILE>    Config file [default: load-blaster.toml]
    -v, --verbose          Verbose output

5.1 run

load-blaster run [OPTIONS]

OPTIONS:
    --target-tps <N>           Target regular TPS [default: from config]
    --target-blob-mbps <N>     Target blob throughput MB/s [default: 0]
    --duration <DURATION>      Test duration (e.g., 60s, 5m) [default: 60s]
    --scenario <FILE>          Scenario file (overrides other options)
    --blobs-per-tx <N>         Blobs per blob transaction [default: 6]
    --mnemonic-stdin           Read mnemonic from stdin

5.2 accounts

load-blaster accounts <SUBCOMMAND>

SUBCOMMANDS:
    generate    Generate addresses for external funding
    check       Verify accounts are funded

6. Security Considerations

  1. No keys in repo: Mnemonic loaded from env var or stdin only
  2. Sanity checks: Prevent impossible TPS/MB/s configurations
  3. Rate limiting: Respect network capacity, don't DoS nodes
  4. Graceful backpressure: Don't exhaust account nonces

7. Dependencies

Crate Version Purpose
alloy-consensus 1.0.37 Transaction types
alloy-eips 1.0.37 EIP-4844 blob types
alloy-signer-local 1.1.2 HD wallet signing
c-kzg 1.0 KZG proof generation
tokio 1.46 Async runtime
reqwest 0.12 HTTP client
governor 0.8 Rate limiting
prometheus 0.13 Metrics
clap 4.5 CLI
serde 1.0 Serialization
toml 0.8 Config parsing

8. Testing Strategy

Unit Tests

  • Config parsing and validation
  • Rate calculations (blob_tx_rate)
  • Ring buffer correctness
  • Account pool backpressure

Integration Tests

  • JSON-RPC batching against mock server
  • Transaction generation and signing
  • Nonce management

System Tests (manual)

  • Local devnet: 1000 txs, verify inclusion
  • Remote testnet: 10k TPS sustained load
  • Blob stress: 50 MB/s, monitor memory

9. Future Work (v2+)

  • Distributed coordinator/worker mode for 100k+ TPS
  • Smart contract call load testing
  • WebSocket subscription for real-time block monitoring
  • Grafana dashboard generator
  • Benchmark regression tests in CI