Epic: RPC — ETH Compliance, Performance & Correctness Testing
- Dominant language
- Rust
- Stars
- 4
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Goal
Make Evolve's JSON-RPC layer fully Ethereum-compliant, high-performance, and rigorously tested. The end state: MetaMask and all standard Ethereum wallets/tooling (ethers.js, viem, wagmi, Foundry, Hardhat) work out of the box with zero quirks, and the RPC is never the bottleneck for transaction submission or query throughput.
## Current State
- **Implemented methods**: `eth_chainId`, `eth_blockNumber`, `eth_getBalance`, `eth_getTransactionCount`, `eth_getBlockByNumber/Hash`, `eth_getTransactionByHash`, `eth_getTransactionReceipt`, `eth_call`, `eth_estimateGas`, `eth_gasPrice`, `eth_sendRawTransaction`, `eth_getLogs`, `eth_syncing`, `eth_protocolVersion`, `eth_getCode`, `eth_getStorageAt`, `eth_feeHistory`, `eth_maxPriorityFeePerGas`, `eth_getBlockTransactionCountByNumber/Hash`, `web3_clientVersion`, `web3_sha3`, `net_version`, `net_listening`, `net_peerCount`
- **Subscriptions**: `newHeads`, `logs`, `newPendingTransactions`, `syncing` via WebSocket
- **Observability**: Prometheus metrics endpoint, health endpoint
- **Missing methods**: Several methods required by wallets (see below)
- **No compliance test suite**: No automated verification against the ETH JSON-RPC spec
- **No load testing**: No benchmarks for RPC throughput or latency
- **Stub implementations**: `fee_history` returns zero fees, `net_peerCount` returns 0
## Scope
### 1. ETH JSON-RPC Compliance — Missing Methods
Methods required by MetaMask and common tooling that are not yet implemented:
- [ ] `eth_accounts` — Returns list of addresses owned by client (return empty for non-custodial)
- [ ] `eth_sign` / `eth_signTransaction` — Return proper "not supported" errors (MetaMask expects these to exist)
- [ ] `eth_getTransactionByBlockHashAndIndex` — Required by block explorers
- [ ] `eth_getTransactionByBlockNumberAndIndex` — Required by block explorers
- [ ] `eth_getBlockReceipts` — Batch receipt fetching (used by indexers)
- [ ] `eth_getUncleCountByBlockHash` / `eth_getUncleCountByBlockNumber` — Return 0 (no uncles, but wallets call these)
- [ ] `eth_getUncleByBlockHashAndIndex` / `eth_getUncleByBlockNumberAndIndex` — Return null
- [ ] `eth_newFilter` / `eth_newBlockFilter` / `eth_newPendingTransactionFilter` / `eth_getFilterChanges` / `eth_getFilterLogs` / `eth_uninstallFilter` — HTTP polling filter API (MetaMask uses these when WebSocket is unavailable)
- [ ] `eth_createAccessList` — Used by wallets for EIP-2930 tx optimization
- [ ] `eth_getProof` — Merkle proof for account/storage (used by bridges and light clients)
- [ ] `debug_traceTransaction` / `debug_traceBlockByNumber` — Optional but needed for debugging tooling (Tenderly, Foundry)
### 2. ETH Compliance Correctness Testing
- [ ] **Ethereum JSON-RPC spec conformance suite**: Automated tests that verify every implemented method returns spec-compliant responses (correct field names, correct hex encoding, correct types)
- [ ] **MetaMask connection test**: Automated end-to-end test that simulates the MetaMask handshake sequence:
1. `eth_chainId`
2. `net_version`
3. `eth_blockNumber`
4. `eth_getBalance`
5. `eth_gasPrice` / `eth_maxPriorityFeePerGas` / `eth_feeHistory`
6. `eth_getTransactionCount` (nonce)
7. `eth_estimateGas`
8. `eth_sendRawTransaction`
9. `eth_getTransactionReceipt` (polling)
- [ ] **ethers.js / viem integration tests**: Send real transactions using ethers.js and viem clients against a running node, verify end-to-end correctness
- [ ] **Foundry compatibility test**: `forge script` and `cast` against a running Evolve node
- [ ] **Block/receipt/log field correctness**: Verify all RPC response fields match Ethereum expectations:
- Block: `baseFeePerGas` present, `mixHash`/`nonce` correct defaults, `size` non-zero
- Receipt: `status`, `cumulativeGasUsed`, `effectiveGasPrice`, `type` field present
- Transaction: `v`/`r`/`s` fields correct, `type` field present, `accessList` when applicable
- Logs: `logIndex`, `transactionIndex`, `blockNumber` all populated
- [ ] **Error code compliance**: Verify JSON-RPC error codes match the spec (-32700 parse error, -32600 invalid request, -32601 method not found, -32602 invalid params, -32603 internal error, -32000 execution reverted with revert data)
- [ ] **Edge case testing**: `earliest`/`latest`/`pending`/`safe`/`finalized` block tags, zero address, empty data, max u256 values, nonexistent blocks/txs return null not error
### 3. Performance Testing & Optimization
- [ ] **Load testing harness**: Build or integrate a load testing tool (e.g., custom Rust tool, vegeta, k6) that hammers the RPC with realistic workloads
- [ ] **Throughput benchmarks**:
- `eth_sendRawTransaction` submissions/sec (target: RPC should not be the bottleneck — must exceed block gas consumption rate)
- `eth_getBalance` / `eth_getTransactionCount` queries/sec (read-heavy wallet workload)
- `eth_getBlockByNumber` with full transactions (large response serialization)
- `eth_getLogs` with broad filters (index query performance)
- `eth_call` execution (dry-run throughput)
- [ ] **Latency benchmarks**: p50/p95/p99 latency for each method category (read, write, subscription)
- [ ] **Concurrent connection limits**: Test with 100, 1000, 10000 concurrent WebSocket connections
- [ ] **WebSocket subscription throughput**: Measure event delivery latency for `newHeads` and `logs` under load
- [ ] **Serialization performance**: Profile JSON serialization/deserialization — consider `simd-json` if it's a bottleneck
- [ ] **Connection pooling**: Verify jsonrpsee handles connection reuse efficiently
- [ ] **Batch request support**: Verify JSON-RPC batch requests work and benchmark batch vs. individual call performance
- [ ] **CI performance regression tests**: Track key latency/throughput metrics across commits
### 4. Fee/Gas Correctness
The current `fee_history` and gas-related methods return hardcoded zeros. This breaks wallet UX.
- [ ] **`eth_feeHistory`**: Return actual base fee history from indexed blocks (wallets use this to suggest gas prices)
- [ ] **`eth_gasPrice`**: Return a meaningful gas price (even if fixed/low, MetaMask uses this to populate the tx form)
- [ ] **`eth_maxPriorityFeePerGas`**: Return a sensible default (wallets add this to base fee)
- [ ] **`eth_estimateGas`**: Verify accuracy — should return gas that is sufficient but not wildly over-estimated
- [ ] **EIP-1559 fee fields**: Ensure block responses include correct `baseFeePerGas` and receipts include `effectiveGasPrice`
### 5. Subscription Correctness
- [ ] **`newHeads` delivers all blocks**: No gaps under high block production
- [ ] **`logs` filtering**: Verify address and topic filters match Ethereum semantics exactly (OR within position, AND across positions)
- [ ] **Subscription backpressure**: Test behavior when subscriber can't keep up (current: lagged messages dropped with warning — verify this is acceptable)
- [ ] **Reconnection handling**: Test that clients can reconnect and resubscribe without losing data
- [ ] **`newPendingTransactions`**: Verify hash is emitted when tx enters mempool, not on execution
### 6. RPC Server Hardening
- [ ] **Request size limits**: Cap incoming request body size to prevent OOM
- [ ] **Rate limiting**: Per-IP or per-connection rate limiting for public deployments
- [ ] **Timeout configuration**: Request execution timeouts to prevent slow queries from blocking the server
- [ ] **CORS configuration**: Configurable CORS headers (MetaMask needs this for browser dApps)
- [ ] **Batch request limits**: Cap the number of requests in a JSON-RPC batch
- [ ] **`eth_getLogs` result limits**: Cap the number of logs returned per query to prevent memory exhaustion
- [ ] **Connection limits**: Max concurrent HTTP and WebSocket connections
## Success Criteria
1. MetaMask connects, displays balance, sends a transaction, and shows the receipt — zero errors, zero workarounds.
2. ethers.js, viem, and Foundry (`cast`, `forge script`) work against Evolve without custom provider configuration.
3. Automated compliance test suite passes on every PR, covering all implemented methods against the ETH JSON-RPC spec.
4. `eth_sendRawTransaction` throughput exceeds 10,000 submissions/sec (RPC layer only, excluding STF execution).
5. p99 latency for read methods (`eth_getBalance`, `eth_blockNumber`) under load is <10ms.
6. All fee/gas methods return meaningful values that wallets can use without user confusion.
Contributor guide
Assessment
This issue has not been assessed yet.