FHEVM Relayer 自托管部署完整指南:打造权限无关的 FHE 网络接入节点
【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm
本文是一份面向开发者和节点运营者的 FHEVM Relayer 自托管实战指南,覆盖从环境准备、主网/测试网一键式引导、数据库与迁移、私钥安全管理,到生产级配置调优与监控的全流程。读完本文,你将掌握如何在 fhevm 仓库的relayer/模块下独立部署一个可处理公开解密(public decryption)、用户解密(user decryption)、输入证明校验(input proof verification)与 FHE 密钥材料分发(key material distribution)的 Relayer 服务,并理解其底层实现原理与配置项的源码依据。
Relayer 是什么:FHEVM 主机链与 Zama Gateway 之间的桥梁
FHEVM Relayer 桥接了两类网络:
- FHEVM 主机链(host chain),例如 Ethereum L1,负责托管 FHEVM 智能合约;
- Zama Gateway(Gateway 链),负责执行 FHE 计算、解密与密钥管理。
Relayer 对外提供的核心能力包括:
- 公开解密(Public Decryption):转发 HTTP 公开解密请求并返回明文响应;
- 用户解密(User Decryption):将用户解密请求转发,在密文句柄访问控制(ciphertext-handle access control)的前提下,将数据用用户提供的公钥重新加密后返回;
- 输入证明校验(Input Proof Verification):转发输入证明校验请求并返回有效性证明;
- 密钥材料(Key Material):对外暴露 FHE 公钥与 CRS 的 URL(
/v2/keyurl)。
从事件驱动架构看,Relayer 由 Orchestrator 统一协调事件流,Gateway 监听器(WSS 订阅)接收链上事件,HTTP Handler 处理 V2 API 请求,SQL Repository 持久化请求状态并支持状态轮询,Transaction Engine 配合 Throttler 负责可靠的交易发送与背压控制,Metrics/Tracing 提供运行时可观测性。详细架构图见 relayer/README.md。
权限无关(Permissionless):任何人只要自托管一个 Relayer,即可获得对 FHEVM 网络的独立接入能力,无需依赖第三方基础设施。
为什么需要自托管
运行自己的 Relayer 的核心价值在于:
- 获得对 FHEVM 网络的权限无关、独立访问能力;
- 不依赖任何第三方的公共节点或服务可用性;
- 对请求队列、超时策略、交易节流(throttling)、数据保留策略拥有完全控制权;
- 可自主扩缩容,按需调整数据库连接池、监听器数量等资源参数。
环境准备
自托管前需要准备以下环境:
| 依赖 | 说明 |
|---|---|
| Rust 工具链 + Cargo | 通过 rustup 安装,用于编译并运行fhevm-relayer二进制 |
| Docker + Docker Compose v2 | 用于启动本地 PostgreSQL(端口 5433) |
Foundry(cast) | 仅用于网络接入引导流程(make preflight-*、make mint-zama-*、make approve-payment-*),负责钱包地址推导、余额查询与授权交易 |
| 已注资的钱包 | 同时持有 ETH(Gas)与 $ZAMA 代币 |
所有部署命令均在仓库的relayer/目录下执行。执行make help可查看全部可用的 Make 目标。
主网(Mainnet)自托管
前置条件
- Gateway 链上的 ETH(用于 Gas):从 Arbitrum One 通过 Zama Bridge 跨链到 Gateway 主网(chain id
261131); - Gateway 链上的 $ZAMA 代币:购买 $ZAMA 后,通过 Zama Bridge 从 Ethereum L1 跨链到 Gateway 主网;
- 一个 Ethereum L1 RPC 端点:
config/local.mainnet.yaml.example中默认使用公共节点https://ethereum-rpc.publicnode.com,可用于测试但有速率限制,生产环境建议替换为自有的 L1 RPC。
Step 1:启动数据库
make db-start该命令通过 dev/docker-compose.yaml 启动一个本地 PostgreSQL 实例,容器内端口5432映射到宿主机5433(避免与常见本地 PostgreSQL 冲突)。数据库名为relayer_db,默认用户/密码为postgres/postgres。Makefile 中定义的连接串为:
DATABASE_URL := postgresql://postgres:postgres@localhost:5433/relayer_db启动后_db-wait会探测容器内的pg_isready,最长等待 30 秒,直到 PostgreSQL 就绪。
Step 2:应用数据库迁移
make db-migrate该目标运行独立的relayer-migratecrate(见 relayer/relayer-migrate/),以MAX_ATTEMPTS=20在连接失败时自动重试,并将 13 个 SQL 迁移文件按序应用到数据库:
DATABASE_URL="postgresql://postgres:postgres@localhost:5433/relayer_db" MAX_ATTEMPTS=20 \ cargo run --manifest-path relayer-migrate/Cargo.toml --bin relayer-migrateStep 3:运行预检引导(Preflight)
make preflight-mainnet这是一个交互式接入向导,其内部逻辑实现在 relayer/Makefile 的_preflight目标中,具体执行:
- 若
config/local.mainnet.yaml不存在,则从config/local.mainnet.yaml.example模板复制生成(通过init-mainnet),并交互式提示输入钱包私钥,写入gateway.tx_engine.private_key字段; - 使用
cast wallet address --private-key "$pk"推导出钱包地址; - 通过
cast balance向主网 RPC(https://rpc.mainnet.zama.org/)查询Gateway ETH 余额; - 通过
cast call调用 ZAMA 代币合约的balanceOf(address)(uint256)查询$ZAMA 余额(主网与测试网代币合约地址均为0xcE762c7FDaac795D31a266B9247F8958c159c6d4); - 通过
cast call调用代币合约的allowance(address,address)(uint256)检查钱包是否已授权 ProtocolPayment 合约花费 $ZAMA; - 若余额或授权缺失,向导会提示操作指引:ETH 不足时提示跨链地址,$ZAMA 不足时提示购买与跨链,授权缺失时提示运行
make approve-payment-mainnet(在获得你确认后也可自动执行)。
ProtocolPayment 合约地址由 Makefile 定义:
| 网络 | ProtocolPayment 地址 |
|---|---|
| Mainnet | 0x7E179E45E5fe0a21015Be25185363B4F2F2F7e89 |
| Testnet | 0xAA1d9D4927A62f842F0DE5AD6b8dFDB074Fa62f2 |
make approve-payment-mainnet会发送一笔approve(address,uint256)交易,将MAX_UINT256(即115792089237316195423570985008687907853269984665640564039457584007913129639935)作为最大授权额度授予 ProtocolPayment 合约,并回读确认授权结果。向导还支持通过YES=1/NO=1环境变量自动接受或拒绝交互提示,便于脚本化。
Step 4:启动 Relayer
make run-mainnet以主网配置启动服务,实际执行的命令为:
cargo run --bin fhevm-relayer -- --config-file config/local.mainnet.yaml启动前会校验配置文件存在且private_key非空。运行前必须保证本地 PostgreSQL 已启动(make run-mainnet依赖_check-postgres)。
Step 5:验证健康状态
make health该目标通过curl依次检查以下端点:
GET http://localhost:3000/liveness—— 存活探针;GET http://localhost:3000/healthz—— 就绪/健康检查;GET http://localhost:3000/version—— 构建版本信息;GET http://localhost:3000/metrics—— Prometheus 指标(打印前 10 行)。
若服务不可达,会提示 "Relayer is not reachable at localhost:3000"。
测试网(Testnet)自托管
测试网的流程与主网完全一致,仅代币来源不同:
- ETH:通过测试网桥从 Arbitrum Sepolia 跨链到 Gateway 测试网(chain id
10901); - $ZAMA:测试网不提供自助获取,需要向 Relayer 团队申请发放到你的钱包地址。
make db-start make db-migrate make preflight-testnet make run-testnet make health其中make run-testnet实际执行为cargo run --bin fhevm-relayer -- --config-file config/local.testnet.yaml,RPC 为https://rpc.testnet.zama.org/。注意:测试网配置模板中的 KMS 公钥与 CRS URL 指向kms-public.testnet.zama.org,主网模板则指向kms-public.mainnet.zama.org,二者的data_id与链 ID 也不同。
私钥管理与安全最佳实践
配置文件将私钥存放在gateway.tx_engine.private_key字段中。安全实践要点:
- 切勿将
config/local.mainnet.yaml或config/local.testnet.yaml提交到版本控制(它们已被加入.gitignore); - 环境变量覆盖:设置
APP_GATEWAY__TX_ENGINE__PRIVATE_KEY=0x...可以完全避免把私钥写入配置文件。这一机制源于 relayer/src/config/settings.rs 中基于configcrate 的加载逻辑:配置按YAML 文件 → 环境变量(APP_前缀、__表示层级嵌套)→ CLI 参数的优先级合并; - 使用专用钱包运行 Relayer,避免与主钱包混用,降低私钥泄露风险面。
此外,配置文件还支持 AWS KMS 签名器替代方案(gateway.tx_engine.signer.type: "aws_kms"),可在生产环境将私钥托管在云端 KMS 中,避免明文私钥落盘。
配置参考:可调字段详解
relayer/docs/SELF_HOSTING.md 给出了运维人员最常调整的字段清单(默认值来自代码与配置模板):
| 字段 | 说明 | 默认值 |
|---|---|---|
http.endpoint | API 监听地址 | 0.0.0.0:3000 |
log.format | 日志格式(compact、pretty、json) | pretty |
gateway.tx_engine.tx_throttlers.*.per_seconds | 每种操作类型的交易节流速率 | 20 |
storage.app_pool.max_connections | 应用连接池最大数据库连接数 | 10 |
storage.cron.timeout_cron_interval | 超时 Worker 的运行频率 | 60s |
storage.cron.public_decrypt_timeout | 公开解密请求超时 | 30m |
storage.cron.user_decrypt_timeout | 用户解密请求超时 | 30m |
storage.cron.input_proof_timeout | 输入证明请求超时 | 30m |
storage.cron.expiry_enabled | 是否启用自动数据清理 | false |
storage.cron.public_decrypt_expiry | 公开解密记录保留期 | 365d |
storage.cron.user_decrypt_expiry | 用户解密记录保留期 | 7d |
storage.cron.input_proof_expiry | 输入证明记录保留期 | 7d |
http.retry_after.max_seconds | Retry-After响应头的最大值 | 300 |
http.enable_admin_endpoint | 是否启用/admin/config运行时配置(见下方安全说明) | false |
配置层级:YAML → 环境变量 → CLI 参数
配置是分层级的:先加载 YAML 文件,再用带APP_前缀、__嵌套分隔的环境变量覆盖,最后 CLI 参数(如--config-file)优先级最高。示例:
APP_GATEWAY__BLOCKCHAIN_RPC__HTTP_URL=https://rpc.example.org等价于修改 YAML 中的gateway.blockchain_rpc.http_url。完整的主网/测试网/本地配置模板分别见:
- relayer/config/local.mainnet.yaml.example
- relayer/config/local.testnet.yaml.example
- relayer/config/local.yaml.example
值得注意的实现细节:配置在加载后会经过GatewayConfig::validate()校验(见 relayer/src/config/settings.rs),例如http_url/read_http_url必须以http://或https://开头,否则启动失败并返回明确的错误信息。
关键底层机制:超时 Worker 与数据保留
超时 Worker(始终启用):后台任务周期性地把在receipt_received状态停留超过配置时长的请求标记为timed_out。其实现位于 relayer/src/store/sql/repositories/timeout_repo.rs,对user_decrypt_req、public_decrypt_req、input_proof_req三张表分别执行UPDATE ... FOR UPDATE SKIP LOCKED的原子更新,错误原因为 "Gateway chain did not respond within the expected timeframe",并同时记录状态流转指标。
数据保留(默认关闭):清理 Worker 会按保留窗口删除已完结(成功或失败)的旧记录,实现位于 relayer/src/store/sql/repositories/expiry_repo.rs。默认不启用,如需启用请设置expiry_enabled: true,并确保数据库用户对相关表拥有DELETE权限;也可以手动执行等价的DELETESQL 完成清理。
Admin 端点安全
/admin/config(GET/POST)主要用于测试与压测场景,可在运行时调整节流器 TPS 与Retry-After字段。它默认关闭,且刻意不提供应用层认证——启用时必须通过网络层手段限制可达性:
- 将
http.endpoint绑定到回环地址(127.0.0.1:3000)或仅内部子网,或 - 将端点置于认证层(如 API 网关)之后。
监控与可观测性
- Prometheus 指标:
:9898端口,GET /metrics; - 应用健康:
:3000端口,/liveness(存活)、/healthz(就绪); - 指标与 Grafana 面板:参见 relayer/src/metrics/docs_and_dashboards/http_metrics.md 等文档,包含 HTTP 请求量、错误率、延迟分位数等 R.E.D. 指标的完整定义与 PromQL 查询示例。
HTTP 层核心指标包括:
relayer_http_requests_total(CounterVec:endpoint、method、version);relayer_http_responses_total(CounterVec:按status分类);relayer_http_request_duration_seconds(HistogramVec:请求延迟,桶由http.metrics.histogram_buckets配置)。
请求超时、交易发送耗时、队列深度等也在relayer/src/metrics/下按模块拆分暴露。完整的 V2 API 语义(异步 POST + GET 轮询、Retry-After动态计算、统一响应信封、请求去重等)可参考 relayer/docs/http-api-design.md。
故障排查
主 README 的 Troubleshooting 章节 总结了常见问题,这里列举与自托管强相关的几条:
- PostgreSQL 使用 5433 而非 5432:本地开发库映射到 5433 以避免端口冲突。出现 "connection refused" 时,请确认目标端口是 5433;
- 配置模板包含 localhost/mock URL:
config/local.yaml.example内置localhost:8757RPC 与0.0.0.0:3001密钥 URL,只适用于本地 mock 栈。接入测试网/主网时必须使用make preflight-testnet/make preflight-mainnet,它们会自动复制对应的正确示例配置; - Docker 内存:在本地完整栈上运行
./fhevm-cli deploy需要至少 12 GB 的 Docker 内存配额; - Git worktree 破坏 Docker 构建:Relayer 的 Dockerfile 会挂载
.git/HEAD、.git/objects、.git/refs用于版本信息嵌入,而 worktree 中.git是文件而非目录,会导致挂载失败,请在主克隆中构建。
小结
自托管 FHEVM Relayer 是一条完整可控的接入路径:通过make db-start、make db-migrate、make preflight-*、make run-*、make health五个命令即可完成从数据库、引导检查到服务运行与健康验证的全流程。在接入之后,通过配置表中的节流速率、超时窗口、连接池与保留策略等字段,可以针对实际流量对服务进行精细化调优;结合:9898的 Prometheus 指标与源码级的超时/保留 Worker 实现,运营者可以完全掌握请求生命周期中的每一个状态流转。
【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考