Skip to content

Repository files navigation

leafage-evm

中文文档

leafage-evm is a lightweight EVM executor built with alloy and revm. It focuses on state queries (eth_call, eth_estimateGas, etc.) and does not store transaction data. State updates are received via Kafka + S3, rather than P2P synchronization.

Features

  • Two Node Modes:
    • State Node: Only retains recent block states (default 64 blocks), ~90GB for ETH mainnet (as of 2025.1)
    • Archive Node: Retains complete historical state, ~360GB for ETH mainnet (as of 2025.1)
  • Multi-chain Support: Ethereum mainnet, Optimism, BSC, Cosmos EVM
  • Multiple Database Backends: RocksDB (default), MDBX
  • Data Migration: Import initial state from Geth snapshots

Supported Write Node Repositories

Any EVM-compatible chain can potentially be supported. The following chains are currently supported:

Chain Repository
ETH, Linea Chaintable/go-ethereum
AVAX Chaintable/coreth
OP Stack op-geth: OP, opBNB, Celo, B2, BOB, DBK, Hemi, Katana, Manta, Mantle, Mode, Orderly, Soneium, Unichain, X Layer, Swell Chaintable/op-geth
Base Chaintable/base-reth
OP Stack op-reth: HSK, Ink, Lisk, Zora, Cyber Chaintable/optimism
Arb, Gravity, Plume, Hood Chaintable/nitro
Gnosis Chaintable/erigon
Bitlayer Chaintable/bitlayer-l2
Oasys Chaintable/oasys-validator
Kava Chaintable/kava
IoTeX Chaintable/iotex-core-x
Scrl Chaintable/go-ethereum-scrl
Bera Chaintable/bera-geth
Story Chaintable/story-geth
Tac Chaintable/tacchain
Mitosis Chaintable/reth-mitosis
XDC Chaintable/XDPoSChain
Citrea Chaintable/citrea
ZKsync: Lens, Era, Abstract, Sophon Chaintable/zksync-era @ debank
Cronos zkEVM (Croze) Chaintable/zksync-era @ chain/croze
Fraxtal Chaintable/frax-op-reth
Ronin Chaintable/conduit-op-reth
World Chain Chaintable/world-chain
Plasma, Botanix Chaintable/reth-x
BSC Chaintable/bsc-x
Core Chaintable/core
Chiliz Chaintable/chiliz-chain-v2
Morph Chaintable/go-ethereum-morph-x
Taiko Chaintable/taiko-geth
Metis Chaintable/mvm-x
0G Chaintable/0g-geth
Immutable zkEVM Chaintable/immutable-geth
Kite Chaintable/subnet-evm-kite
Merlin Chaintable/cdk-erigon
Flare Chaintable/go-flare-x
Moonbeam / Moonriver Chaintable/moonbeam-x
Conflux Chaintable/conflux-rust-x
Kaia (Klaytn) Chaintable/kaia
WEMIX Chaintable/go-wemix
Polygon PoS Chaintable/bor
Sonic Chaintable/sonic

Supported JSON-RPC Methods

eth_*

Method Description
eth_call Execute a contract call
eth_multiCall Batch contract calls
eth_blockNumber Get current block number
eth_getBalance Get account balance
eth_getBlockByNumber Get block by number
eth_getBlockByHash Get block by hash
eth_getCode Get contract code
eth_getStorageAt Get storage slot data
eth_getTransactionCount Get account nonce
eth_chainId Get chain ID
eth_baseFee Get base fee

DeBankApi (no namespace prefix)

Method Description
version Get version info
getAddressNonce Get account nonce
getAddressBalance Get account balance
getAddressCode Get contract code
getStorageAt Get storage slot data
contractMultiCall Batch contract calls
simulateTransactions Simulate transaction execution
estimateGas Estimate gas
getLatestBlock Get latest block
getBlockByHeight Get block by height
getBlockById Get block by hash
blockIsValid Validate block

Note: Block query methods (eth_getBlockByNumber, eth_getBlockByHash, getLatestBlock, getBlockByHeight, getBlockById) return header only - transactions and uncles are always empty. leafage-evm does not store transaction data.

pre_*

Method Description
pre_traceCall Pre-execute call trace
pre_traceMany Batch pre-execute traces

Build

Requirements: Rust 1.79+

cargo build --release

Docker build:

docker build -t leafage-evm .

Usage

Start Server

RUST_LOG=info ./target/release/leafage-evm standalone \
  --db-path /path/to/db \
  --listen-addr 0.0.0.0:8545 \
  --rpc-addr http://geth:8545 \
  --evm-type mainnet \
  --chain-cfg 1

Main Parameters

Parameter Default Description
--db-path - Database path (required)
--listen-addr 0.0.0.0:8545 RPC listen address
--rpc-addr - Geth RPC address (for HTTP mode state updates)
--evm-type mainnet EVM type: mainnet/op/bsc/cosmos
--chain-cfg 1 Chain ID
--db-type rocksdb Database type: rocksdb/mdbx
--db-cache 2048 Database cache size (MB)
--diff-depth-limit 64 Block diff depth retained in memory
--catchup-safe-depth 0 S3 catch-up reorg buffer: blocks below the Kafka head backfilled via the exact parent-hash chain instead of the by-number index. 0 disables it (legacy behavior); set above the chain's max reorg depth (e.g. 64 for Moonriver)
--archive false Enable archive mode
--prometheus-addr - Prometheus metrics address
--kafka-s3-config - Path to Kafka + S3 config JSON file
--max-connections 5000 Maximum concurrent RPC connections
--rpc-timeout 10000 RPC request timeout (ms)
--iterator-timeout-secs 0 Iterator timeout for archive mode (0 = disabled)
--historical-rpc - Historical RPC endpoint for pre-fork queries (e.g., OP pre-bedrock)
--historical-height - Fork height threshold for historical RPC forwarding

Kafka + S3 Configuration

When using Kafka + S3 mode, provide a JSON config file:

{
  "topic": "block-notifications",
  "brokers": "kafka1:9092,kafka2:9092",
  "partition": 0,
  "bucket_name": "state-diffs-bucket",
  "outer_bucket_name": "block-info-bucket",
  "offset_dir": "/path/to/offset",
  "s3_chain_id": "1",
  "version": "v1"
}

Data Migration

Migrate initial data from Geth snapshot:

# 1. Export snapshot from Geth
./geth snapshot dump2 --dumpdb /nodex_backup --datadir /eth/state/geth/

# 2. Import to leafage-evm
RUST_LOG=info ./target/release/leafage-evm file-migrate \
  --source-path /nodex_backup \
  --db-path /path/to/leafage/db

Benchmark

leafage-bench is a CLI tool for benchmarking eth_call performance between leafage-evm and geth.

Build

cargo build --release -p leafage-bench

Corpus

The benchmark corpus (bin/leafage-bench/corpus/corpus.json) is tracked via Git LFS. Pull it after cloning:

git lfs pull

Subcommands

run — Run the benchmark

./target/release/leafage-bench run \
  --corpus bin/leafage-bench/corpus/corpus.json \
  --target http://leafage-evm:8545 \
  --compare http://geth:8545
Parameter Default Description
--corpus / -c - Path to the corpus JSON file (required)
--target - Primary RPC endpoint URL (leafage-evm) (required)
--compare - Comparison RPC endpoint URL (geth)
--label all Only run cases with this complexity label: L1, L2, L3
--concurrency 10 Number of concurrent requests per endpoint
--requests corpus size Total requests per endpoint per round
--rounds 1 Number of benchmark rounds
--seed - Shuffle seed for corpus ordering
--output-dir - Directory for export files (summary.json, verbose.json)
--verbose false Write per-request details to verbose.json (requires --output-dir)

inspect — Inspect the corpus

Print summary statistics of the corpus without running any benchmark:

./target/release/leafage-bench inspect \
  --corpus bin/leafage-bench/corpus/corpus.json

Documentation

Document Description
Architecture.md System architecture, crate structure, key traits
StateManage.md In-memory state tree, fork handling, finalization
StateUpdater.md Kafka + S3 and HTTP update modes
Database.md RocksDB storage layout for state and archive nodes
DataSpec.md Data format specification for state updates
Deploy Deployment guide with Docker Compose

Architecture

State Management

leafage-evm manages state using a linked-list structure:

Latest Block (Head)
    ↓
Block N-1 diff
    ↓
   ...
    ↓
Block N-63 diff
    ↓
Base State (RocksDB)
  • Recent 64 block diffs are kept in memory for fast access
  • State queries search from top to bottom, falling back to RocksDB
  • On new block: push new diff to head, persist oldest diff to RocksDB when exceeding depth limit

State Update

leafage-evm supports two modes for receiving state updates:

  • Kafka + S3 (Primary): Receives block change notifications via Kafka, fetches block info and state diffs from S3
  • HTTP (Fallback): Polls trace_debankBlock RPC from a modified Geth instance

Project Structure

leafage-evm/
├── bin/leafage-evm/           # CLI entry point
├── crates/
│   ├── leafage-evm-types/     # Type definitions
│   ├── leafage-evm-storage/   # Storage layer (RocksDB/MDBX, StateTree)
│   ├── leafage-evm-rpc/       # JSON-RPC implementation
│   └── leafage-evm-chains/    # Chain-specific logic (BSC/Cosmos precompiles)
└── docs/                      # Documentation

License

MIT OR Apache-2.0

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

2 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages