Skip to content

验证者守护(Validator Guard)

validator_guard 插件为验证者账户自动化签名密钥恢复。当验证者的签名密钥被重置为 null(禁用区块生产)时,插件检测到此变化并广播 validator_update_operation 以恢复密钥——无需手动干预。


何时使用此插件

  • 您的验证者账户的签名密钥可能被紧急共识主节点、安全协议或手动操作清空。
  • 没有此插件,您必须手动监控链上密钥并在计划槽位到来前恢复它。
  • 有了此插件,节点每 N 个区块监视一次 null 密钥并自动恢复。

启用插件

ini
plugin = validator_guard

配置

选项默认值描述
validator-guard-enabledtrue全局启用或禁用插件。
validator-guard-interval20检查间隔,以区块为单位(按 3 秒/区块计约 60 秒)。
validator-guard-validatorJSON 三元组 [name, signing_wif, active_wif]。可重复。
validator-guard-disable5同一验证者连续生产的区块数,超过后自动禁用。0 = 禁用。
validator-guard-disable-on-shutdowntrue优雅关闭时,将每个仍在链上启用的已配置验证者的签名密钥清空,使网络在本节点离线期间停止调度它。
validator-guard-shutdown-grace10持续重新广播关闭禁用交易的秒数,以便对等节点有时间接收并转发它们。请保持低于容器/进程的终止超时。

插件还从验证者插件配置中读取 enable-stale-production

示例

ini
plugin = validator_guard

# 监控一个验证者
validator-guard-validator = ["alice", "5K_SIGNING_WIF", "5K_ACTIVE_WIF"]

# 监控第二个验证者
validator-guard-validator = ["alice.backup", "5J_SIGNING_WIF", "5J_ACTIVE_WIF"]

# 每 10 个区块检查一次
validator-guard-interval = 10

安全说明: 活跃私钥以明文存储在 config.ini 中。限制文件权限(chmod 600 config.ini),避免将文件暴露给不受信任的进程。


工作原理

启动

  1. 解析并验证所有配置的 WIF 密钥。
  2. 如果 enable-stale-production = true,自动恢复启动时处于禁用状态(参见安全机制)。
  3. 链数据库打开后,针对链上权限验证每个配置的活跃密钥。账户未找到或密钥不匹配的验证者将从监控中删除并发出警告。
  4. 运行立即检查;缓存结果以与周期性计划对齐。

每区块处理程序

每个区块时:

  1. 连续区块自动禁用:如果被监控的验证者连续生产了 validator-guard-disable 个区块,广播带 null 密钥的 validator_update_operation 以禁用它,并将该验证者标记为自动禁用。其他验证者的任何区块都会重置所有连续计数器。
  2. 交易确认:扫描区块中待处理的恢复交易 ID。匹配时,将恢复标记为已确认并清除跟踪状态。
  3. 前瞻调度:如果任何被监控的验证者在接下来的 3 个槽位内有安排,触发立即检查,以便在槽位到来前恢复密钥。
  4. 周期性检查:否则,每 validator-guard-interval 个区块运行核心检查。节点启动后仍在追赶时,每 10 个区块检查一次。

核心检查

每次检查(按顺序):

  1. 过时生产防护:如果 enable-stale-production 激活且网络参与度 < 33%,跳过所有恢复。参与度达到 ≥ 33% 时自动清除。
  2. 同步检查:如果头块时间比系统时钟落后超过 2 个区块间隔,则跳过。
  3. 长 fork 安全:如果 LIB 超过 200 秒,则跳过。
  4. 过期清理:清理过期的进行中恢复尝试,以便可以重试。
  5. 每验证者密钥检查:读取链上签名密钥。
    • 密钥存在 → 清除待处理恢复状态和自动禁用标志。
    • 密钥为 null + 验证者已自动禁用 → 跳过自动恢复(操作员必须调查)。
    • 密钥为 null + 无进行中的恢复 → 调用 send_witness_update

恢复交易

  1. 构建 validator_update_operation,保留当前链上 URL,并将签名密钥设置为配置的公钥。
  2. 包装为 signed_transaction,30 秒到期时间,引用当前头块。
  3. 使用配置的活跃私钥签名。
  4. 通过 P2P 广播。
  5. _pending_confirmations 中跟踪交易 ID 以防止重复发送。

优雅关闭

节点关闭时,插件会禁用每个仍在链上启用(签名密钥非 null)的已配置验证者,使网络在本节点离线期间停止调度它,从而不漏出区块。这是启动恢复的逆操作:干净关闭会清空密钥,而下次启动通过周期性检查自动恢复它们。

plugin_shutdown 时(由 validator-guard-disable-on-shutdown 控制,默认开启):

  1. 首先断开每区块处理程序,使连续区块防护不会并行触发。
  2. 在读锁下,为每个已启用的验证者构建并签名一个带 null 密钥的 validator_update_operation(到期时间 = validator-guard-shutdown-grace + 120 秒,使交易在传播期间保持有效)。在广播之前释放锁,以避免与 P2P 线程死锁。
  3. 如果没有已连接的对等节点,记录警告并停止——没有可传播的对象。
  4. 广播每笔交易。broadcast_transaction 会阻塞,直到字节写入每个活跃对等节点的套接字。
  5. 在最多 validator-guard-shutdown-grace 秒内,每 3 秒重新广播这些(幂等)交易,使它们在转发偶发丢失时仍能存活并有时间传播。若所有对等节点断开则提前停止。

运维提示: grace 窗口只有在进程确实获得了那么长的退出时间时才有用。在 Docker 中,容器会在其停止超时(默认 10 秒)后被 SIGKILL,因此请用匹配的窗口停止节点——docker stop -t 30 vizd(或 compose 中的 stop_grace_period: 30s)。发布的镜像将 runit 服务的 KILL_PROCESS_TIMEOUT / KILL_ALL_PROCESSES_TIMEOUT 设置为 30 秒。


安全机制

机制行为
过时生产enable-stale-production = true 时,自动恢复被禁用以避免在少数派 fork 上广播。参与度 ≥ 33% 时自动清除。
紧急模式紧急共识期间,过时生产防护被绕过——密钥恢复可能是恢复所需的。
同步检查仅在节点同步时运行。
长 fork 检测如果 LIB 超过 200 秒则跳过。
权限验证启动时针对链上权限验证活跃密钥。
连续区块自动禁用同一验证者连续生产 N 个区块后自动清空签名密钥。操作员手动修复密钥前,自动恢复被抑制。
优雅关闭禁用关闭时清空已启用验证者的签名密钥,并在 grace 窗口内重新广播交易,使对等节点在节点离线前收到它们。无已连接对等节点时跳过。
重复防护进行中的恢复以过期方式跟踪;不发送重复交易。

日志消息

消息含义
monitoring validator 'alice' (signing key: VIZ...)插件已为此验证者启动
enable-stale-production detected — auto-restore is DISABLED过时生产模式激活;恢复被抑制
network is healthy (XX%), auto-clearing stale production override过时生产防护已解除
'alice' has null signing key on-chain — initiating restore检测到 null 密钥,即将广播
broadcasting validator_update [ID: ...] for 'alice' — restoring key to VIZ...恢复交易已发送
CONFIRMED restoration for 'alice' in block #N恢复已在链上确认
POTENTIAL LONG FORK DETECTED! LIB #N is Xs old. Skipping restoration.由于 LIB 过期而跳过恢复
validator 'alice' produced N consecutive blocks — auto-disabling连续区块阈值已达到
'alice' was auto-disabled (consecutive block limit), skipping auto-restore自动禁用后抑制自动恢复
graceful shutdown — disabling N enabled validator(s) across P peer(s)关闭禁用已开始
broadcasting shutdown disable for 'alice' [ID: ...]关闭禁用交易已发送
shutting down with NO connected peers — disable transactions ... cannot be propagated关闭时无对等节点;禁用已跳过
validator_update FAILED for 'alice': [error]广播失败

故障排除

问题检查
恢复未触发验证 validator-guard-enabled = true;确保节点已同步;确认账户是已注册的验证者
enable-stale-production = true 时禁用预期行为——等待网络参与度 ≥ 33%
交易失败验证 active_wif 是否与账户的活跃权限匹配。检查启动时关于密钥不匹配的警告
配置解析错误每个条目必须是有效的 3 元素 JSON 数组:["name", "signing_wif", "active_wif"]
验证者已自动禁用且未恢复连续区块阈值已触发。调查原因,手动在链上恢复签名密钥;一旦密钥检测为非 null,自动禁用标志将清除
启动时权限警告WARNING: Configured active key ... does NOT have authority on-chain — 在配置中更新密钥

参见:验证者节点 — 签名密钥设置;验证者插件 — 生产循环内部机制。