evstack / evstack/ev-rs

Epic: RPC — ETH Compliance, Performance & Correctness Testing

Open
#7 0 comments 0 reactions 0 assignees View on GitHub
enhancement
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.