> ## Documentation Index
> Fetch the complete documentation index at: https://docs.leafage.chaintable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 部署

> 从单机验证到生产集群的部署形态、资源规划与常见运维操作

一条链是一个独立的部署单元。本页给出三种形态：单机验证、单链生产、多链集群。

## 基础设施

生产部署需要三样共享基础设施：

| 组件      | 要求                                                            |
| ------- | ------------------------------------------------------------- |
| Kafka   | 内部 topic 必须**单分区**（承载全序区块流）；外部 topic 可按需分区                    |
| S3      | 两个桶：内部桶（Header + StateDiff）、外部桶（BlockFile + Validation），可跨链共用 |
| etcd v3 | 建议 3 节点；承载节点注册、Leader 选举、链高度和路由配置                             |

多条链共用同一套基础设施：所有 Kafka topic、S3 键、etcd 键都以 `chainID` 开头。

## 形态一：单机验证

不需要 Kafka 和 S3。写节点开放 `trace` 命名空间，leafage-evm 用 HTTP 模式轮询。适合本地开发和适配新链时的验证。

```bash theme={null}
geth --http --http.api=eth,debug,trace --http.addr=0.0.0.0 --http.port=8545

leafage-evm standalone \
  --db-path /tmp/leafage \
  --listen-addr 0.0.0.0:8659 \
  --chain-cfg 1 \
  --rpc-addr http://127.0.0.1:8545
```

## 形态二：单链生产

```yaml theme={null}
services:
  beacon:
    image: sigp/lighthouse:v8.0.1
    command:
      - lighthouse
      - beacon_node
      - --network=mainnet
      - --datadir=/var/data/lighthouse
      - --execution-endpoint=http://geth:8551
      - --execution-jwt=/var/data/geth/jwtsecret
      - --checkpoint-sync-url=https://mainnet.checkpoint.sigp.io

  geth:
    image: public.ecr.aws/b2h7a5c4/chaintable/ethereum-writer:v1.17.3-debank-3
    ports: ["8666:8545"]
    entrypoint:
      - /app/geth
      - --datadir=/var/data/geth
      - --syncmode=full
      - --gcmode=archive
      - --authrpc.addr=0.0.0.0
      - --authrpc.jwtsecret=/var/data/geth/jwtsecret
      - --http
      - --http.addr=0.0.0.0
      - --http.api=net,web3,eth,admin,debug,txpool,engine,trace
      - --vmtrace=pipeline
      - '--vmtrace.jsonconfig={"region":"ap-northeast-1","node_x_bucket":"nodex-internal","chain_table_bucket":"chaintable-pipeline","brokers":["kafka-1:9092"],"etcd_endpoints":["http://etcd:2379"]}'

  leafage-evm:
    image: public.ecr.aws/b2h7a5c4/chaintable/leafage-evm-x:v1.2.31
    ports: ["8659:8659"]
    environment: ["RUST_LOG=info"]
    command:
      - standalone
      - --db-path=/nodex-eth
      - --listen-addr=0.0.0.0:8659
      - --chain-cfg=1
      - --kafka-s3-config=/etc/leafage/kafka_s3.json
      - --prometheus-addr=0.0.0.0:9100

  consistency-checker:
    image: consistency-checker:latest
    command: ["-config", "/config/config.yml"]
```

nodex-proxy 通常独立部署，覆盖所有链：

```bash theme={null}
./node-proxy -config config.yaml -listen 8663
```

### 资源规划（ETH 主网）

| 服务                        | CPU | 内存    |
| ------------------------- | --- | ----- |
| beacon（Lighthouse）        | 4 核 | 12 GB |
| geth（full sync + archive） | 4 核 | 24 GB |
| leafage-evm               | 4 核 | 16 GB |

leafage-evm 的 QPS 与 CPU 核数近似线性。要提高查询吞吐，只扩这一个服务的 CPU 和内存即可。

| 磁盘                     | 容量       |
| ---------------------- | -------- |
| beacon + geth（archive） | \~850 GB |
| leafage-evm（archive）   | \~450 GB |
| leafage-evm（state）     | \~150 GB |

至少 3000 IOPS，推荐 SSD。AWS 上 gp3 的默认 3000 IOPS / 125 MB/s 足够稳态运行（12 秒一个区块），但首次启动的两个阶段压力更高：快照解压受顺序写吞吐限制，快照恢复后的追赶受随机读写 IOPS 限制。预留 20–30% 容量余量。

<Note>
  写节点开启 `--ancient.prune` 可以显著降低磁盘占用：历史区块体和收据在离开最近 90000 块窗口后被裁剪。下游消费者读 S3，不依赖写节点保留历史区块体。需要 `--syncmode full`。
</Note>

## 形态三：多链集群

```text theme={null}
每条链：
  1 × 共识客户端（PoS 链）
  1–2 × 写节点（pipeline etcd 选举决定谁发 Kafka）
  1 × consistency-checker
  N × leafage-evm（State 为主，按需加 Archive）

全局共享：
  1 组 nodex-proxy（多实例，按 chainId 管理多条链）
  Kafka / S3 / etcd
  Prometheus + Grafana
```

写节点可以部署两个：都上传 S3，只有 Leader 发 Kafka。备节点在主节点故障时接管，避免数据链路中断。

## 常见运维操作

<AccordionGroup>
  <Accordion title="新增一个查询节点">
    1. 从 S3 下载 RocksDB 快照并解压到 `--db-path`
    2. 启动 leafage-evm，它会自动从 Kafka offset 或 S3 追赶到链头
    3. 启动时自注册到 etcd，consistency-checker 确认追上后把 `stateType` 改为 `1`
    4. nodex-proxy watch 到变更，健康检查通过后加入负载均衡池

    整个过程通常在分钟级完成，不需要人工干预 proxy。
  </Accordion>

  <Accordion title="下线一个查询节点">
    停止进程即可。leafage-evm 退出时删除自己的 etcd 键；即使异常退出，consistency-checker 也会在轮询失败后把它标记为离线并删除。
  </Accordion>

  <Accordion title="切换写节点 Leader">
    通过 nodex-proxy 的管理接口：

    ```bash theme={null}
    curl -X POST http://proxy:8663/1/writers/switchLeader -d '{...}'
    curl http://proxy:8663/1/writers/leader
    ```

    也可以直接改 etcd 的 `{chainID}/writers/leader`。切换后新 Leader 会等待 `grace_period` 再开始发布。
  </Accordion>

  <Accordion title="版本切换">
    版本模式下，修改 etcd 的 `{chainID}/version`：

    * consistency-checker 检测到版本变化后释放或争抢 singleton topic 的发布锁，并把 topic 对齐到新版本的进度
    * nodex-proxy 把基础链 ID 的请求改写到 `{chainId}-{version}` 的节点池

    客户端不需要改动。
  </Accordion>

  <Accordion title="回退并重新同步">
    leafage-evm 的状态出现异常时，可以把链头回退到更早的区块，再从 S3 重新同步：

    ```bash theme={null}
    leafage-evm rewind --db-path /nodex-eth --to-block 12345
    ```
  </Accordion>
</AccordionGroup>

## 排查

| 现象           | 检查顺序                                                                                                     |
| ------------ | -------------------------------------------------------------------------------------------------------- |
| 查询节点不追块      | Kafka 消费是否正常 → S3 拉取是否报错（`RUST_LOG=info` 看 `updater` target）→ offset 是否过期触发了全量追赶                         |
| 外部消费者收不到通知   | checker 的 `pipeline_replica_ready_timeouts_total` 是否增长 → 副本是否有节点长期落后拉低了 ready 比例 → 版本模式下是否持有 singleton 锁 |
| proxy 报无可用节点 | etcd 里节点键是否存在 → `stateType` 是否为 3 → 健康检查是否通过（用 `/{chainId}/getAllNodes` 查看）                              |
| 历史查询失败       | 是否有 Archive 节点在池中 → 请求高度是否落在 `--historical-height` 以下但未配置 `--historical-rpc`                             |
| S3 上有重复高度对象  | 正常，reorg 会留下分叉块；确认 checker 把非规范的标记成了 `is_fork: true`（看 `pipeline_fork_scan_rewrites_total`）              |
| 写节点磁盘增长过快    | 是否开启 `--ancient.prune`；pipeline 的 `s3_temp_dir` 是否有残留未上传文件                                               |

## 参考

* [leafage-evm 部署指南](https://github.com/Chaintable/leafage-evm/blob/main/docs/deploy/Deploy.md) — 含一键脚本、快照下载、目录结构
* [nodex-proxy 部署指南](https://github.com/Chaintable/nodex-proxy/blob/main/docs/deployment_cn.md) — Docker Compose、Kubernetes、systemd 与生产调优
* [consistency-checker 部署说明](https://github.com/Chaintable/consistency-checker/tree/main/deploy)
