If the client the new chain uses is already in the list of adapted clients (for example, yet another OP Stack chain), the write side usually only needs a new deployment; no code changes are required.
Write side: integrate pipeline into the execution client
Choose an adaptation path
The three adaptation guides are in the pipeline repository:
standard,
legacy,
Reth.
What to change
Using a standard Geth fork as an example:1
Extend the tracing hooks
Add
OnCommit and OnBlockDBStart in core/tracing/hooks.go.2
Export the state diff
Add
StateDiff() in core/state/statedb.go to convert the commit set into pipeline’s types.3
Distribute the hooks
Call the new hooks on the block processing path in
core/blockchain.go, and compute the reorg and publish the Kafka notification when the canonical head is determined.4
Register the live tracer
Create
eth/tracers/live/pipeline.go and register the pipeline tracer in LiveDirectory.5
Add the RPC
Implement
trace_debankBlock and register the trace namespace in eth/backend.go.6
Validate
Once
go build ./... passes, run a real chain and compare the output of trace_debankBlock with the objects on S3.Adapting with Claude Code
The pipeline repository ships with adaptation skills that detect the client type automatically and guide you stage by stage:Cargo.toml, go.mod, tracing.Hooks, and vm.EVMLogger to determine the client type, checks whether an integration already exists, and then routes to the corresponding specialized skill: /adapt-pipeline-geth, /adapt-pipeline-legacy, or /adapt-pipeline-reth.
The flow for each stage is: probe the code structure → consult the guide → generate the changes → run go build or cargo check to validate.
Read side: add an executor to leafage-evm
If the new chain’s EVM behavior is identical to a chain that is already supported, just start with the corresponding--evm-type and the correct --chain-cfg (chain ID). A new executor is only needed when the behavior differs.
What to change:
A typical configuration branch:
disable_* settings are standard for state queries: eth_call does not need to check balances, the base fee, or the block gas limit.
Historical ranges without data
Some chains have historical ranges where block diffs cannot be obtained (typically OP pre-bedrock). Use--historical-rpc to specify an external RPC and --historical-height to specify the fork height; queries below the threshold are forwarded out.
Validation
1
Compare state
For the same batch of addresses and storage slots, compare the
eth_getBalance, eth_getStorageAt, and eth_getCode return values from leafage-evm and the chain’s official full node.2
Compare call results
Use
leafage-bench to send the same corpus to both leafage-evm and a full node, and compare the eth_call return values and latency.3
Watch reorgs
Watch the
changeType: 2 notifications for a while and confirm that leafage-evm’s chain head follows correctly. Chains with deeper reorgs need a correspondingly larger --catchup-safe-depth.Deployment
Deploying a new chain is identical to existing chains; only thechainID differs: Kafka topics, S3 prefixes, and etcd keys all start with the chain ID, so they are naturally isolated. nodex-proxy does not need a restart; it discovers the new chain’s nodes through etcd.
See the deployment guide for the specific steps.