Skip to main content
Leafage 是一套 EVM 状态查询与区块数据分发架构。它把传统全节点里耦合在一起的四件事拆开:同步执行状态存储RPC 服务数据导出

为什么要拆

在生产规模下,用“多部署几个 Geth”来扩展查询能力会遇到几个硬性问题: Leafage 的答案是:只让一个节点执行区块,其余节点消费执行结果。

组件职责

写节点

执行客户端加上 pipeline 集成,在执行区块时导出状态变更、调用追踪和事件。

pipeline

分发库。序列化执行数据,双桶写 S3,Leader 节点向 Kafka 发布区块变更通知。

leafage-evm

查询节点。消费 Kafka + S3 重建状态,用 revm 执行 eth_call,不做 P2P、不存交易。

consistency-checker

校验层。等待副本收敛、标记分叉块、维护 etcd 中的节点健康状态、向外部 Kafka 发布确认通知。

nodex-proxy

网关。通过 etcd 发现节点,按区块上下文路由到 State / Archive / Native 节点池。

运行拓扑

数据面与控制面

理解 Leafage 的关键是把两条通路分开看。它们使用不同的中间件,故障影响范围也不同。

数据面:Kafka + S3

区块数据只走一个方向,从写节点流向消费者。
  • Kafka(内部 topic) 只传通知,不传数据体。消息里是区块哈希、父哈希、高度、时间戳,以及 reorg 时被丢弃的区块列表。
  • S3(内部桶) 存 Header 和 StateDiff,是 leafage-evm 重建状态的数据源。
  • S3(外部桶) 存 BlockFile(交易、追踪、事件)和 BlockValidation,供外部消费者和分析平台使用。
  • Kafka(外部 topic) 由 consistency-checker 发布,是外部消费者应当订阅的入口,带一致性保障。
数据面故障时,leafage-evm 停止追块但仍可服务已有状态的查询。

控制面:etcd

etcd 是所有运行时状态的事实来源,三个组件在上面协作: 完整键空间见接口契约
控制面这条闭环容易被忽略:leafage-evm 只把自己注册进 etcd 并标记为 Delay,真正判断它是否健康、是否追上链头的是 consistency-checker;nodex-proxy 只是这份状态的消费者。要理解“为什么某个节点没有流量”,应当从 consistency-checker 的轮询结果查起。

节点类型

nodex-proxy 按请求携带的区块参数在三个节点池之间路由,规则见 nodex-proxy 组件文档

部署单元

一条链是一个独立的部署单元,各链之间不共享 Kafka topic、S3 前缀或 etcd 前缀(都以 chainID 开头)。一个典型的单链部署包含:
nodex-proxy 是多链的:同一个进程按路径里的 chainId 管理多条链的节点池,因此通常整个集群只部署一组 proxy。

多链支持

写侧和读侧分别适配:
  • 写侧:pipeline 需要嵌入目标链的执行客户端。已适配 40+ 条链的客户端分叉,列表见 leafage-evm README。适配方式见接入新链
  • 读侧:leafage-evm 通过 --evm-type 选择执行器,当前支持 mainnetarbitrumopbasebsccosmosmantlev2tempocitreaiotexmoonbeammoonriverpolygonhemi

设计取舍

eth_call 只需要账户状态(balance、nonce、code、storage),交易体、收据和日志都可以丢弃。代价是区块查询接口(eth_getBlockByNumber 等)只返回 header,transactionsuncles 恒为空。需要交易数据的消费者应当读 S3 外部桶或订阅外部 Kafka topic。
最近 64 块的状态以差异层链表形式留在内存,超出深度的层被刷写到 RocksDB。这个窗口同时是 reorg 的处理能力上限:更深的重组需要走 S3 回补路径。窗口大小由 --diff-depth-limit 控制。
所有查询节点消费同一个 Kafka 分区,按相同顺序应用相同区块,因此不存在 P2P 的非确定性。但“副本是否都追上了”这件事由 consistency-checker 判断,并只在达到 ready_ratio(默认 0.8)后才向外部通知。
通知消息很小,Kafka 只承担顺序和低延迟;大体积的 StateDiff 和 BlockFile 走 S3,消费者可以并行拉取,也便于冷启动时按需回补历史。

下一步

数据链路

跟着一个区块走完执行、分发、摄入、终结化、查询五个阶段。

接口契约

Kafka、S3、etcd 和 RPC 的精确格式定义。