运行 Wormhole Guardian 节点
本文档详细介绍了如何运行 Wormhole Guardian 节点,包括连接的链、所需节点的要求(如 Solana、以太坊、Terra 等)、wormchain 的配置和使用。强调了安全性,建议从源代码构建 guardiand 二进制文件,并详细说明密钥生成、部署、监控、原生代币转账(NTT)及跨链查询(CCQ)的配置步骤,同时鼓励 Guardian 节点公开 API 端点以提高协议的鲁棒性。
运行 Wormhole Guardian 节点
连接的链
除了 Wormhole 本身,你需要为你所连接的每个链运行你自己的验证节点,除了通过 Wormhole Gateway 集成的新 IBC 连接的链。请参考 常量参考 获取 Wormhole 连接的所有链。
对于任何链,不要使用第三方 RPC 服务提供商! 你会完全信任他们,他们可能会在事件是否被实际观察到这件事上对你撒谎。 Wormhole 的全部意义在于不依赖中心化节点!
我们强烈建议为测试网和主网(如果适用)运行你自己的完整节点,这样你可以测试主网完整节点的更改并获得操作经验。
Solana 节点要求
参考 Solana 文档 了解如何运行 RPC(完整)节点。Solana 的 Discord 服务器 是一个很好的资源,可以解答有关操作的问题。
#rpc-server-operators 频道对于设置 Solana RPC 节点尤其有用。
你的 Solana RPC 节点需要启用以下参数:
--enable-rpc-transaction-history
--enable-cpi-and-log-storage
--enable-rpc-transaction-history 允许通过 getConfirmedBlock API 检索历史交易,这是 Wormhole 查找交易所需的。
--enable-cpi-and-log-storage 存储关于 CPI 调用的元数据。
请注意,这些需要额外的磁盘空间!
账户索引
如果你为 Wormhole v1 使用相同的 RPC 节点,你还需要以下附加参数来加速 getProgramAccount 查询:
<!-- cspell:disable -->
[... 请参阅上面其他必需的参数 ...]
--account-index program-id
--account-index-include-key WormT3McKhFJ2RkiGpdw9GKvNCrB2aB54gb2uV9MfQC # 用于主网
--account-index-include-key 5gQf5AUhAgWYgUCt9ouShm9H7dzzXUsLdssYwe5krKhg # 用于测试网
<!-- cspell:enable -->
或者,如果你想运行一个通用 RPC 节点,该节点具有所有程序(而不仅仅是 Wormhole)的索引,请忽略过滤:
--account-index program-id
在主网上,我们强烈建议将 KIN 和 token 程序列入黑名单,以加快追赶速度:
<!-- cspell:disable -->
--account-index-exclude-key kinXdEcpDQeHPEuQnqmUgtYykqKGVFq6CeVX5iAHJq6 # 仅限主网
--account-index-exclude-key TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA # 仅限主网
<!-- cspell:enable -->
请注意,这些索引需要额外的磁盘空间,并且可能会减慢追赶速度。 添加这些参数后的首次启动将很慢,因为 Solana 需要重建所有索引。
Ethereum 节点要求
为了观察以太坊链上的事件,你需要访问以太坊 RPC 端点。 最常见的选择是 geth,但为了多样性,你可能想运行一些不是 geth 的东西。
使用 Alchemy、Infura 等 RPC 提供商,你信任这些运营商为你提供未被篡改的链数据,并且无法验证正确性。 因此,Wormhole 需要以太坊完整节点或轻客户端。 该节点可以在完整、快速或轻模式下运行,而不会影响桥接软件的安全性或性能。 只要该节点支持以太坊 JSON RPC API,它就与桥接兼容,因此所有主要实现都可以正常工作。
通常,完整节点比轻客户端工作得更好、更可靠,因为轻客户端容易受到 DoS 攻击,因为只有极少数节点支持轻客户端协议。
运行完整节点通常需要 ~500G 的 SSD 存储、8G 的 RAM 和 4-8 个 CPU 线程(取决于时钟频率)。 轻客户端的硬件要求要低得多。
Terra
Terra 有时也称为 Terra 2,但正确的名称只是“Terra”。 先前版本已重命名为“Terra Classic”。
参考 Terra 文档 了解如何运行完整节点。
Terra Classic
参考 Terra Classic 文档 了解如何运行完整节点。
Wormchain
所有守护者必须为 wormchain 运行验证器,这是 Wormhole Gateway 的代号。
前提条件
- 确保你已安装 Go >= 1.23.3。
构建 wormchaind 二进制文件
没有可用的预构建二进制文件。 你需要检出 repo 并从源代码构建 wormchaind 二进制文件:
首先,检出你要部署的 Wormhole repo 的版本:
git clone https://github.com/wormhole-foundation/wormhole && cd wormchain
然后,以非特权构建用户身份编译发布二进制文件:
make build/wormchaind
你将在 wormchain/build/wormchaind 中找到 wormchaind 二进制文件。
初始化环境
使用必要的配置初始化 Wormchain 环境。
/path/to/wormchain/bin/wormchaind init <你的节点名称> --chain-id wormchain --home /path/to/wormchain/directory
此命令将生成私有验证器密钥。 该密钥应该备份。 此密钥在 config.toml 文件中的 priv_validator_key_file 字段下设置。
生成配置文件
guardian 节点的 --wormchainURL 参数应指向 <validator address>:9090,这是 app.toml 中的 grpc 端口。
示例端口设置:
<!-- cspell:disable -->
config.toml:
[rpc]
laddr = "tcp://0.0.0.0:26657"
grpc_laddr = ""
pprof_laddr = "localhost:6060"
[p2p]
laddr = "tcp://0.0.0.0:26656"
external_address = ""
app.toml:
[grpc]
address = "0.0.0.0:9090"
[grpc-web]
address = "0.0.0.0:9091"
<!-- cspell:enable -->
对于签名,请考虑设置远程阈值签名器,例如 horcrux,并采用在 wormchain 验证器前使用哨兵节点的哨兵节点架构。
检索 Genesis 文件
从 wormhole 存储库下载 genesis 文件。
wget -O /path/to/wormchain/config/genesis.json https://raw.githubusercontent.com/wormhole-foundation/wormhole/main/wormchain/<network>/genesis.json
生成 wormchain 密钥
要生成 wormchain 密钥,请运行以下命令:
/path/to/wormchain/bin/wormchaind keys add <key-name> --keyring-backend file --home /path/to/wormchain/directory
此命令将创建一个 <key-name>.info 文件。 要提取密钥,请运行以下命令:
wormchaind keys export <key_name> --home /path/to/wormchain/directory --keyring-dir . --keyring-backend file
此命令将要求为其创建一个密码。 以下 guardiand 标志将使用 wormchain.key 和 passphrase:
--accountantKeyPath--accountantKeyPassPhrase
注意
这些步骤可以直接在 guardiand 节点上执行,前提是之前已经构建了 wormchaind 二进制文件。
Wormchain 实用命令
检查最新的守护者集合:
<!-- cspell:disable -->
$ wormchaind query wormhole latest-guardian-set-index
latestGuardianSetIndex: 4
<!-- cspell:enable -->
升级守护者集合(使用有效的治理 vaa):
<!-- cspell:disable -->
wormchaind tx wormhole execute-governance-vaa <以十六进制格式表示的 guardian_set_upgrade_VAA>
<!-- cspell:enable -->
查看验证器信息:
<!-- cspell:disable -->
$ wormchaind q staking validators
... snipped ...
- commission:
commission_rates:
max_change_rate: "0.020000000000000000"
max_rate: "0.200000000000000000"
rate: "0.000000000000000000"
update_time: "2024-04-16T19:13:45.210176030Z"
consensus_pubkey:
'@type': /cosmos.crypto.ed25519.PubKey
key: T+hsVX52EarrsL+mOwv3mL0byWa2EctsG6XmikUMFiQ=
delegator_shares: "0.000000000000000000"
description:
details: ""
identity: 11A4103C4BCBD2B4
moniker: RockawayX
security_contact: ""
website: https://rockawayx.com/infrastructure
jailed: false
min_self_delegation: "0"
operator_address: wormholevaloper1thl5syhmscgnj7whdyrydw3w6vy80044278fxp
status: BOND_STATUS_BONDED
tokens: "0"
unbonding_height: "0"
unbonding_time: "1970-01-01T00:00:00Z"
<!-- cspell:enable -->
EVM 节点要求
一些非以太坊 EVM 兼容的区块链需要以存档模式运行,以便 查询 能够正常运行。 默认情况下,在 geth 中,历史状态仅在内存中保留 128 个区块。 128 块之后,较旧的状态将被垃圾回收。 这些链中的许多都是 geth 的分支,它们保持了这种历史限制。
- Arbitrum
- Base
- Optimism
较新的执行客户端(例如 reth)没有这种限制,一旦稳定,值得研究。
此外,如果由于硬分叉或某些不可预见的情况,网络未能就 EVM 兼容链达成共识,则可能需要临时为这些链运行存档节点,以确保可以重新观察到这些交易。
Cosmos / IBC 连接的节点
所有现代 Cosmos 集成都是通过 Wormhole 观察 Gateway(wormchain)上的 IBC 交易来实现的。 Guardian 节点运营商不需要为这些网络运行完整节点。 对于在此功能之前添加的基于 Cosmos 的链,仍然需要完整节点。
以下基于 Cosmos 的节点是在 Gateway 之前添加的,守护者需要运行完整节点:
- Injective
- Terra
- Terra Classic
- XPLA
注意:所有守护者必须为 wormchain 运行验证器。
构建 guardiand
出于安全原因,我们不提供预构建的二进制文件。 你需要检出 repo 并从源代码构建 guardiand 二进制文件。 Git 存储库比发布二进制文件更难篡改。
要构建 Wormhole 节点,你需要 Go >= 1.23.3
首先,检出你要部署的 Wormhole repo 的版本:
git clone https://github.com/wormhole-foundation/wormhole && cd wormhole
然后,以非特权构建用户身份编译发布二进制文件:
make node
你最终会在 build/ 中得到一个 guardiand 二进制文件。
考虑这些建议,而不是盲目遵循的教程。 你需要将其与你现有的构建管道集成。 如果你需要 Dockerfile 示例,可以查看我们的开发网络部署。
如果你想在本地编译和部署,可以运行 sudo make install 将二进制文件安装到 /usr/local/bin。
如果你使用自定义管道进行部署,则需要在二进制文件上设置 CAP_IPC_LOCK 功能(例如,执行等效于 sudo setcap cap_ipc_lock=+ep 的操作),以允许它锁定其内存页,以防止它们被换出。 请参阅下文,了解原因 - 这是一种通用的深度防御缓解措施,可确保进程内存永远不会交换到磁盘。 如果此额外功能代表运营或合规性问题,请创建一个 GitHub issue。
密钥生成
要生成 guardian 密钥,请先安装 guardiand。 如果你在单独的机器上生成密钥,你可能只想编译 guardiand 而不安装它:
make node
sudo setcap cap_ipc_lock=+ep ./build/bin/guardiand
否则,请使用你使用上述常规说明编译的相同 guardiand 二进制文件。
使用 keygen 子命令生成一个新密钥:
guardiand keygen --desc "Testnet key foo" /path/to/your.key
密钥文件包括一个人类可读的部分,其中包括公钥哈希和描述。
部署
我们强烈建议为 Wormhole 服务使用单独的用户和 systemd 服务。
请参阅单独的 wormhole-networks 存储库,以获取有关如何为特定网络设置 guardiand 单元的示例。
你需要在防火墙中打开端口 8999/udp 用于 P2P 网络,8996/udp 用于 跨链查询。 如果你不运行公共 RPC,则无需在外部公开其他任何内容。
journalctl 可以使用 -a 标志显示 guardiand 的彩色输出以进行二进制输出,即:journalctl -a -f -u guardiand。
Kubernetes
完全支持 Kubernetes 部署。
请参阅 devnet/,以获取示例 k8s 部署,作为你自己的生产部署的起点。 你必须构建自己的容器。 除非你已经在生产中运行 Kubernetes,否则我们强烈建议在专用实例上进行传统部署 - 这样更容易理解和排除故障。
在 kubernetes 中运行或在任何类型的 NAT 之后运行时,将 --gossipAdvertiseAddress=external.ip.address 传递给 guardiand 节点进程,以确保在 p2p 中公布外部地址。 如果不这样做,重新观察请求和 CCQ 将无法按预期运行。
监控
Wormhole 公开了一个状态服务器,用于就绪状态和指标。 默认情况下,它在 localhost 上的端口 6060 上侦听。 你可以使用命令行参数公开它:--statusAddr=[::]:6060。
注意: 不建议解析日志输出进行监控。 日志输出供人们使用,不被视为稳定的 API。 日志消息可能会在没有通知的情况下被添加、修改或删除。 使用指标 :-)
/readyz
一旦 Wormhole 节点准备好为请求提供服务,此端点将返回 200 OK 状态代码。 只要节点成功连接到所有链并开始处理请求,该节点就被认为已准备就绪。
这仅用于启动信号 - 它不会告诉你在稍后的某个时间点是否 停止 处理请求。 一旦它为真,它就一直为真! 使用指标来找出答案。
/metrics
此端点提供 Prometheus 指标,用于警报和自省。 我们建议使用 Prometheus 和 Alertmanager,但任何可以使用标准化 Prometheus 公开格式提取指标的监控工具都可以工作。
一旦我们获得了更多关于 Wormhole 的运营经验,此处将记录关于基于症状的适当警报的具体建议。
请参阅 Wormhole.json,以获取 Grafana 仪表板示例。
Wormhole 仪表板
有一个 仪表板,它显示了网络的整体健康状况,并具有关于各个守护者的指标。
注意: 不建议解析日志输出进行监控。 日志输出供人们使用,不被视为稳定的 API。 日志消息可能会在没有通知的情况下被添加、修改或删除。 使用指标 :-)
Wormhole Fly 健康检查
在 wormhole-dashboard 存储库中,有一个小的 健康检查应用程序,它验证守护者是否正在 gossiping 出心跳信号,是否正在提交链观察,并且是否有一个可用的工作心跳信号 API。 这是验证特定守护者是否按预期运行的非常好的方法。
你可以克隆 repo 并针对 MCF Guardian 运行检查:
git clone https://github.com/wormhole-foundation/wormhole-dashboard
cd wormhole-dashboard/fly/cmd/healthcheck
## 运行 fly
$ go run main.go --pubKey 0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811 --url https://wormhole-v2-mainnet-api.mcf.rocks
✅ 收到 guardian 心跳信号 {12D3KooWDZVv7BhZ8yFLkarNdaSWaB43D6UbQwExJ8nnGAEmfHcU: [/ip4/185.188.42.109/udp/8999/quic-v1]}
✅ 收到 44 次观察结果
✅ /v1/heartbeats
如果未公开 guardian 公共 RPC,则可以省略 --url 标志:
$ go run main.go --pubKey 0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811
✅ 收到 guardian 心跳信号 {12D3KooWDZVv7BhZ8yFLkarNdaSWaB43D6UbQwExJ8nnGAEmfHcU: [/ip4/185.188.42.109/udp/8999/quic-v1]}
✅ 收到 41 次观察结果
ℹ️ --url 未定义,跳过 Web 检查
引导节点和网络默认为 mainnet,这些值可以在 网络常量 中找到。
它也可以用于测试特定的引导节点:
$ go run main.go --pubKey 0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811 --bootstrap /dns4/wormhole.mcf.rocks/udp/8999/quic/p2p/12D3KooWDZVv7BhZ8yFLkarNdaSWaB43D6UbQwExJ8nnGAEmfHcU
✅ 收到 guardian 心跳信号 {12D3KooWDZVv7BhZ8yFLkarNdaSWaB43D6UbQwExJ8nnGAEmfHcU: [/ip4/185.188.42.109/udp/8999/quic-v1]}
✅ 收到 44 次观察结果
ℹ️ --url 未定义,跳过 Web 检查
原生 Token 转移
NTT 是 wormhole 的一项令人兴奋的功能,它构建在核心桥之上,以允许铸造/销毁风格转移。 确保它正确运行需要将其与 NTT Accountant 集成。 要启用此功能,请创建一个新的 wormchain 密钥。 不要重用现有的全局 accountant 密钥,并添加以下参数:
<!-- cspell:disable -->
## 你可能已经拥有这些。
--wormchainURL URL_TO_YOUR_WORMCHAIN_NODE
--accountantWS HTTP_URL_OF_YOUR_WORMCHAIN_NODE
## 这是主网合约。
--accountantNttContract wormhole1mc23vtzxh46e63vq22e8cnv23an06akvkqws04kghkrxrauzpgwq2hmwm7
--accountantNttKeyPath PATH_TO_YOUR_NTT_ACCOUNTANT_KEY_FILE
--accountantNttKeyPassPhrase YOUR_NTT_ACCOUNTANT_KEY_PASS_PHRASE
<!-- cspell:enable -->
请记住允许将新的 NTT Accountant 密钥用于 Wormchain! 有关如何执行此操作的说明,请与 Wormhole Foundation 的某人联系。
跨链查询
CCQ 也称为 Wormhole 查询,是一种允许以跨链方式提取 attestation 的功能。 要运行 ccq,需要在 guardian 节点上启用一些附加标志:
<!-- cspell:disable -->
--ccqEnabled=true \
--ccqAllowedPeers="[ALLOWED,PEERS,GO,HERE]" \
--ccqAllowedRequesters="[ALLOWED,REQUESTORS,GO,HERE" \
<!-- cspell:enable -->
要测试查询功能,请按照 node/hack/query/ccqlistener/ccqlistener.go 中的说明进行操作。
运行公共 API 端点
Wormhole v2 不再使用 Solana 作为数据可用性层(请参阅 设计文档)。 而是依赖于 Guardian 节点公开一个 API,Web 钱包和其他客户端可以使用该 API 来检索给定交易的已签名 VAA 消息。
强烈建议 Guardian 节点公开一个公共 API 端点以提高协议的稳健性。
guardiand 附带一个内置的 REST 和 grpc-web 服务器,可以使用 --publicWeb 标志启用:
--publicWeb=[::]:443
为了与 Web 钱包一起使用,需要支持 TLS。 guardiand 具有内置的 Let's Encrypt 支持:
--tlsHostname=wormhole-v2-mainnet-api.example.com
--tlsProdEnv=true
或者,你可以使用像 CloudFlare 这样的托管反向代理来终止 TLS。
在签名节点上公开 publicWeb 端口是安全的。 为了更好地抵御拒绝服务攻击,未来的 guardiand 版本将包括仅侦听模式,这样可以在负载均衡器后面运行多个没有 guardian 密钥的 guardiand 实例。
启用遥测
(可选)guardian 可以将遥测数据发送到 Grafana Cloud Logs,也称为 "loki"。 要启用此功能,请添加以下标志:
--telemetryLokiURL=$PER_GUARDIAN_LOKI_URL_WITH_TOKEN
新的 guardian 应该与 Wormhole Foundation 联系以获取 Loki url。
绑定到特权端口
如果你想将 --publicWeb 绑定到 <1024 的端口,你需要分配 CAP_NET_BIND_SERVICE 功能。 这可以通过将该功能添加到二进制文件(如在非 systemd 环境中)来完成:
sudo setcap cap_net_bind_service=+ep guardiand
...或者通过扩展 guardiand.service 中的功能集来完成:
AmbientCapabilities=CAP_IPC_LOCK CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE
密钥管理
你必须管理以下密钥:
-
guardian 密钥,它是桥共识密钥。 此密钥非常重要 - 你的节点使用它来验证 VAA 消息。 公钥的哈希存储在所有连接链上的 guardian 集合中。 它不会累积奖励。 它是保护 Wormhole 网络的 multisig 机制的份额。 如果大多数 guardian 同意签名并发布新的 guardian 集合,则可以替换 guardian 集合。
-
节点密钥,它在 gossip 网络上识别它,类似于 Solana 的节点身份或 Tendermint 节点密钥。 它被对等网络用于路由和传输层加密。 攻击者可能会使用它来审查你在网络上的消息。 除此之外,它不是很重要,可以轮换。 如果你指定的路径中不存在节点密钥,该节点将自动创建节点密钥。 虽然节点密钥可以被替换,但我们建议使用持久节点密钥。 这将使你更容易在监控数据中识别你的节点,并提高 p2p 连接性。
对于生产环境,我们强烈建议你加密你的磁盘,并且/或者注意不要让热 guardian 密钥接触磁盘。 实现此目的的一种方法是将密钥存储在内存 ramfs 上,该 ramfs 无法换出,并在每次节点重启时从冷存储或 HSM/vault 恢复它。 你可能想要完全禁用交换。 这些都不是 Wormhole 特有的 - 这适用于任何热密钥。
我们的节点软件会格外小心地使用 mlock(2) 锁定内存,以防止密钥被交换到磁盘,这就是为什么它需要额外的功能。 是的,其他链可能也想这样做 :-)
将密钥存储在 HSM 上或使用远程签名者只能部分缓解服务器被入侵的风险 - 这意味着密钥不会被盗,但攻击者仍然可能导致 HSM 签署恶意负载。 Wormhole 的未来迭代可能会包括对远程签名的支持。
引导对等点
支持的引导对等点的列表在 node/pkg/p2p/network_consts.go 中定义。 该文件还提供了用于根据环境(主网或测试网)获取网络参数(网络 ID 和引导对等点)的 golang 函数。
常见的 Wormhole 应用程序(guardiand、spy 和查询代理服务器)使用这些函数,因此无需在其配置中指定实际的引导参数。 强烈建议任何新应用程序的开发人员也这样做,并且不要扩散可能随时间变化的引导对等点列表。
运行 Guardian Spy
间谍连接到 wormhole guardian 对等网络并侦听新的 VAA。 它通过套接字和 websocket 发布这些 VAA,应用程序可以订阅这些 VAA。 如果你想运行从源代码构建的间谍,请在构建 guardian 映像后将 ghcr.io/wormhole-foundation/guardiand:latest 更改为 guardian。
针对测试网 wormhole guardian 启动间谍:
<!-- cspell:disable -->
docker run \
--pull=always \
--platform=linux/amd64 \
-p 7073:7073 \
--entrypoint /guardiand \
ghcr.io/wormhole-foundation/guardiand:latest \
spy --nodeKey /node.key --spyRPC "[::]:7073" --env testnet
<!-- cspell:enable -->
要对 mainnet 运行间谍:
<!-- cspell:disable -->
docker run \
--pull=always \
--platform=linux/amd64 \
-p 7073:7073 \
--entrypoint /guardiand \
ghcr.io/wormhole-foundation/guardiand:latest \
spy --nodeKey /node.key --spyRPC "[::]:7073" --env mainnet
<!-- cspell:enable -->
Guardian 配置
支持配置文件、环境变量和标志。
配置文件
位置/命名:默认情况下,配置文件应位于 node/config 目录中。 配置文件的标准名称是 guardiand.yaml。 目前尚不支持自定义目录或文件名。
格式:我们支持 Viper 支持的任何格式。 但通常首选 YAML 格式。
示例:
<!-- cspell:disable -->
ethRPC: "ws://eth-devnet:8545"
ethContract: "0xC89Ce4735882C9F0f0FE26686c53074E09B0D550"
solanaRPC: "http://solana-devnet:8899"
solanaContract: "Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o"
<!-- cspell:enable -->
环境变量
前缀:与 Guardian 节点相关的所有环境变量应以 GUARDIAND_ 为前缀。
用法:环境变量可用于覆盖配置文件中的设置。 尤其适用于不应存储在配置文件中的敏感数据(如 API 密钥)。
示例:
export GUARDIAND_ETHRPC=ws://eth-devnet:8545
命令行标志
用法:标志提供最高优先级,可用于临时覆盖或用于频繁更改的设置。
示例:
./guardiand node --ethRPC=ws://eth-devnet:8545
优先级顺序
配置设置按以下优先级顺序应用:
- 命令行标志:最高优先级,覆盖任何其他设置。
- 环境变量:覆盖配置文件设置,但可以被标志覆盖。
- 配置文件:最低优先级。
- 原文链接: github.com/wormhole-foun...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~