news 2026/9/13 1:14:16

FHEVM Relayer 自托管部署完整指南:打造权限无关的 FHE 网络接入节点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FHEVM Relayer 自托管部署完整指南:打造权限无关的 FHE 网络接入节点

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 id261131);
  • 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-migrate

Step 3:运行预检引导(Preflight)

make preflight-mainnet

这是一个交互式接入向导,其内部逻辑实现在 relayer/Makefile 的_preflight目标中,具体执行:

  1. config/local.mainnet.yaml不存在,则从config/local.mainnet.yaml.example模板复制生成(通过init-mainnet),并交互式提示输入钱包私钥,写入gateway.tx_engine.private_key字段;
  2. 使用cast wallet address --private-key "$pk"推导出钱包地址
  3. 通过cast balance向主网 RPC(https://rpc.mainnet.zama.org/)查询Gateway ETH 余额
  4. 通过cast call调用 ZAMA 代币合约的balanceOf(address)(uint256)查询$ZAMA 余额(主网与测试网代币合约地址均为0xcE762c7FDaac795D31a266B9247F8958c159c6d4);
  5. 通过cast call调用代币合约的allowance(address,address)(uint256)检查钱包是否已授权 ProtocolPayment 合约花费 $ZAMA;
  6. 若余额或授权缺失,向导会提示操作指引:ETH 不足时提示跨链地址,$ZAMA 不足时提示购买与跨链,授权缺失时提示运行make approve-payment-mainnet(在获得你确认后也可自动执行)。

ProtocolPayment 合约地址由 Makefile 定义:

网络ProtocolPayment 地址
Mainnet0x7E179E45E5fe0a21015Be25185363B4F2F2F7e89
Testnet0xAA1d9D4927A62f842F0DE5AD6b8dFDB074Fa62f2

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 id10901);
  • $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.yamlconfig/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.endpointAPI 监听地址0.0.0.0:3000
log.format日志格式(compactprettyjsonpretty
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_secondsRetry-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_reqpublic_decrypt_reqinput_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/configGET/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:endpointmethodversion);
  • 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 章节 总结了常见问题,这里列举与自托管强相关的几条:

  1. PostgreSQL 使用 5433 而非 5432:本地开发库映射到 5433 以避免端口冲突。出现 "connection refused" 时,请确认目标端口是 5433;
  2. 配置模板包含 localhost/mock URLconfig/local.yaml.example内置localhost:8757RPC 与0.0.0.0:3001密钥 URL,只适用于本地 mock 栈。接入测试网/主网时必须使用make preflight-testnet/make preflight-mainnet,它们会自动复制对应的正确示例配置;
  3. Docker 内存:在本地完整栈上运行./fhevm-cli deploy需要至少 12 GB 的 Docker 内存配额;
  4. Git worktree 破坏 Docker 构建:Relayer 的 Dockerfile 会挂载.git/HEAD.git/objects.git/refs用于版本信息嵌入,而 worktree 中.git是文件而非目录,会导致挂载失败,请在主克隆中构建。

小结

自托管 FHEVM Relayer 是一条完整可控的接入路径:通过make db-startmake db-migratemake 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 1:13:16

ESP32-S3 N16R8开发实战:环境搭建与项目组织全指南

ESP32-S3这颗芯片最近热度确实高,尤其是N16R8这个配置版本,在AI图像、离线语音、音频处理这些场景里几乎成了首选。我手里这块N16R8开发板已经用了快半年,从最初搭环境到跑通完整项目,中间踩了不少坑,也积累了一些实际…

作者头像 李华
网站建设 2026/9/13 1:12:02

基于群智能优化算法的光伏组件参数辨识:GWO、DBO与DOA对比实践

先说结论:用群智能优化算法做光伏组件参数辨识,这件事的本质就是在一个高维、非线性、多峰值的参数空间里找全局最优解。你手里拿到的I-V曲线数据是“果”,而单二极管/双二极管模型里的那些参数(光生电流、串联电阻、并联电阻、二…

作者头像 李华
网站建设 2026/9/13 1:10:29

红黑树C++实现全解析:旋转、插入删除修复与调试验证

先聊个很多人都在经历的尴尬瞬间:红黑树的五个性质背得滚瓜烂熟,面试前能默写,可一到真要自己用C实现一棵能跑的、插入删除都不崩的红黑树,就变成大型翻车现场。这个问题我太有体会了,前前后后写了三版,每一…

作者头像 李华