A Go-based tool for testing and comparing transaction latency performance between different Flashblocks-enabled Base node endpoints.
Flashblocks are sub-blocks issued by the block builder every 200ms, allowing for early confirmation times and making Base 10x faster for real-time applications.
For synchronous transaction sending testing, the node endpoints must support the eth_sendRawTransactionSync RPC method. See EIP-7966: eth_sendRawTransactionSync Method.
For asynchronous transaction sending testing, the node endpoints do not have to support the eth_sendRawTransactionSync RPC method and will rely on separate polling for confirmed transactions.
Chainstack Base nodes for Mainnet & Testnet support both the synchronous one with eth_sendRawTransactionSync and the asynchronous one.
Create a .env file based on .env.example:
PRIVATE_KEY=your_private_key_here
TO_ADDRESS=0xc2F695613de0885dA3bdd18E8c317B9fAf7d4eba
# If you are going with the asynchronous method and poll for the transaction receipts separately
POLLING_INTERVAL_MS=100
BASE_NODE_ENDPOINT_1=https://your-node-endpoint-1.com
BASE_NODE_ENDPOINT_2=https://your-node-endpoint-2.com
# This a simple label for the resulting filename to remember where you sent the test transactions from. Not used in any node routing.
REGION=singapore
NUMBER_OF_TRANSACTIONS=10
# With `true`, the synchronous eth_sendRawTransactionSync method is used. With `false`, the asynchronous method is used with POLLING_INTERVAL_MS=100
SEND_TXN_SYNC=true
RUN_ENDPOINT2_TESTING=trueSEND_TXN_SYNC=true:
- Uses
eth_sendRawTransactionSyncmethod - Provides instant confirmation receipt when transaction is included in a Flashblock
- Transactions wait for immediate inclusion confirmation
SEND_TXN_SYNC=false:
- Uses standard
eth_sendTransactionmethod - Polls for transaction receipts using
POLLING_INTERVAL_MS - Traditional async transaction sending
POLLING_INTERVAL_MS:
- Used only when
SEND_TXN_SYNC=false - Defines how frequently (in milliseconds) to check for transaction receipts
- Default: 100ms
- Lower values = more frequent polling = faster detection but higher load
- Not used when
SEND_TXN_SYNC=truesince confirmations are immediate
BASE_NODE_ENDPOINT_1: Primary endpoint (e.g., a Flashblocks-enabled)
BASE_NODE_ENDPOINT_2: Secondary endpoint (e.g., a standard non-Flashblocks endpoint)
The tool will:
- Send transactions to
BASE_NODE_ENDPOINT_1first - Then send transactions to
BASE_NODE_ENDPOINT_2(ifRUN_ENDPOINT2_TESTING=true) - Compare performance between both endpoints
# Build the container
docker build -t transaction-latency .
# Run the test
docker run -v $(pwd)/data:/data --env-file .env --rm -it transaction-latencyAfter completion, results are saved to the ./data/ directory:
endpoint1-{region}.csv: Results fromBASE_NODE_ENDPOINT_1endpoint2-{region}.csv: Results fromBASE_NODE_ENDPOINT_2(if enabled)
Each CSV contains:
sent_at: Timestamp when transaction was senttxn_hash: Transaction hashincluded_in_block: Block number where transaction was includedinclusion_delay_ms: Time from sending to confirmation (milliseconds)
Flashblocks are produced at 200ms intervals, but actual confirmation times will be higher due to network latency:
- Standard endpoint: ~2000ms (2-second block time)
- Flashblocks endpoint: ~300-500ms (200ms Flashblock interval + network travel time)
The actual confirmation time depends on:
- Network latency to/from the Base node
- Transaction processing time
- Time until next Flashblock (up to 200ms)
- Network travel time for confirmation response