name: debug-validator-checkpoint-inconsistency description: 调试验证器检查点不一致,其中一些验证器落后于其他验证器。当警报提到“检查点不一致”、“验证器落后”或“不一致的最新检查点”时使用,或当被要求调试验证器集、调查验证器延迟或解决链的元数据获取失败时使用。如果未指定,默认为 default_ism 应用上下文。
调试验证器检查点不一致
何时使用
-
基于警报的触发:
- 警报提到“检查点不一致”、“验证器不一致”或“验证器落后”
- 警报名称如“验证器集中不一致的最新检查点”
- 警报名称包含“检查点不一致”并带有阈值(例如“> 20”)
- 任何引用验证器签名延迟或检查点间隙的警报
-
用户请求触发:
- “在[链]上调试验证器集”(如果未指定,使用
default_ism应用上下文) - “检查[链]的验证器检查点状态”
- “为什么在[链]上验证器不一致?”
- “为[链]上的[应用上下文]调查验证器延迟”
- “为什么[链]的元数据获取失败?”(通常与验证器相关)
- “在[链]上调试验证器集”(如果未指定,使用
输入参数
| 参数 | 必填 | 默认值 | 描述 |
|---|---|---|---|
origin_chain |
是 | - | 验证器正在签署检查点的原始链(例如 hyperevm、ethereum、arbitrum) |
app_context |
否 | default_ism |
ISM/应用上下文(例如 default_ism、EZETH/renzo-prod) |
time_range |
否 | 1h |
回溯调查的时间范围 |
environment |
否 | mainnet3 |
仅可能的值为 mainnet3 或 testnet4。如果被告知是主网或测试网,请选择适当的可能值。 |
validator |
否 | * |
可选 |
evaluation_timestamp |
否 | 现在 | 被视为当前时间的时间戳。可以使用过去的时间戳来评估先前场景。将此时间戳视为所有工具请求的当前时间,例如查询 Prometheus 指标时。永远不要查询 evaluation_timestamp 之后的任何指标。 |
关于指标的说明
关键:使用中继器的视角查看所有验证器(包括外部验证器):
使用 Grafana MCP 服务器查询 Prometheus 指标。使用数据源 uid grafanacloud-prom 与 Prometheus 指标交互。
如果提供了特定的 evaluation_timestamp 不是现在,请始终表现得如同 evaluation_timestamp 是当前时间。这意味着:
- 所有查询的 Prometheus 指标应至少在
evaluation_timestamp时——永远不要查询此时间之后的任何内容 - 获取最新的 Prometheus 指标意味着在
evaluation_timestamp时查询 - 在查询任何 Prometheus 指标时,始终使用
evaluation_timestamp作为结束时间,而不是开始时间。
存在以下指标,显示中继器视角下所有验证器:
hyperlane_observed_validator_latest_index{
origin="[origin_chain]",
destination="[destination_chain]",
hyperlane_deployment="[environment]",
app_context="[APP_CONTEXT]",
validator="[validator_address]",
hyperlane_context="hyperlane" # 始终使用此值
}
该指标显示验证器签署的最新最高索引,由中继器观察到。仅当中继器尝试处理从该原始链到该目标链的给定应用上下文的消息时更新。这有以下含义:
- 指标值可能非常陈旧,指示误报
- 如果您想查看该验证器集中每个验证器的最新值,应该对指标使用
max by (origin, validator, app_context) - 不同的原始链验证器集可能注册在不同的目标链上。这通常不是故意的,可能反映进行中的验证器集轮换,但也可能表示问题。如果通过使用
max by (origin, validator, app_context)忽略目标链,请记住这一点 - 可能一些验证器是健康的,只是比其他人落后几秒钟,因此指标可能显示它们稍微落后。在这种情况下,它们并未停滞,只是中继器在验证器签署检查点前不久尝试传递消息。
永远不要忽略这些指标中的负值。-1 值表示验证器签名无法被中继器访问。将此视为与验证器完全宕机一样严重。注意,根本原因可能是以下之一:
- 验证器配置不正确
- 验证器根本没有运行
- 中继器因某种原因无法访问验证器的签名
调试工作流程
步骤 0:选择应用上下文
如果明确指定了 app_context,则跳过此步骤。如果未指定 app_context,即使有默认值,也继续此步骤。
如果未指定特定 validator,则跳过此步骤。
如果指定了任何 validator,首先使用 hyperlane_observed_validator_latest_index 指标找到要关注的 app_context。查找该指标的 app_context 标签值:
hyperlane_observed_validator_latest_index{origin="[origin_chain]", validator="[validator]"}
如果应用上下文列表包括 default_ism,我们将 app_context 设置为 default_ism 供将来使用。否则,选择返回的任意一个值作为 app_context。
步骤 1:检查 hyperlane_observed_validator_latest_index 以查看哪些验证器可能落后
首先,查看原始链上每个验证器的最高值:
查看过去 time_range 的以下指标值,每分钟一个数据点。
max_over_time(
max by (validator) (
hyperlane_observed_validator_latest_index{hyperlane_context="hyperlane", hyperlane_deployment="[environment]", origin="[origin_chain]", app_context=~"[app_context]"}
)[3h:]
)
停滞的验证器将同时满足:
- 最新的检查点索引落后于其他验证器(> 5 个落后)
- 在其他验证器增加时未增加
注意 如果验证器满足以上点被视为停滞验证器,即使只落后几个索引,也视为停滞。不要因为只落后 5 个索引而视为“稍微落后”——如果停滞,就是停滞。
如果没有停滞验证器,则跳至步骤 2。
然后,确认验证器确实落后
如果验证器根据我们刚获取的指标似乎停滞,下一步是确保验证器注册到所有目标链,并且我们不是遇到验证器只注册到一些不常发送消息的目标链的情况,因此它只是长时间未更新。
注意 验证器可能确实停滞,并且只注册到目标链的子集。即使它们不应该仍然注册,我们同样关心这些停滞的验证器。
对于每个可能停滞的验证器:
- 查看
hyperlane_observed_validator_latest_index{origin="[origin_chain]", validator="[stalled_validator]}的destination标签值列表 - 将该目标链列表与 任意 验证器的目标链列表比较:
hyperlane_observed_validator_latest_index{origin="[origin_chain]"}。如果目标链没有差异,此验证器是 确实停滞。 - 如果目标链有任何差异,无论验证器是否确实停滞,都向用户报告。如果链有任何差异,您可以通过执行步骤 1 但限制
destination=~"[停滞验证器注册的目标链列表,以 promql 兼容格式]"来确认可能停滞的验证器是否确实落后。一旦我们过滤只针对停滞验证器注册的目标链,如果没有验证器似乎落后,那么实际上没有停滞!
步骤 2:发现验证器的人类友好身份
对原始链上的所有验证器执行此操作,无论是否停滞:
对于每个验证器地址:
- 打开
typescript/sdk/src/consts/multisigIsm.ts - 在
defaultMultisigConfigs中找到原始链的条目。这是原始链相关验证器集的最新真实来源。 - 查看原始链的验证器列表,找到与停滞验证器地址相关的别名。
- 如果无法找到匹配项:有时可能发生无法在此找到匹配项——可能是停滞验证器本应从 ISM 中移除,因此不再反映在 multisigIsm.ts 配置中,但它仍然在链上存在。在这种情况下,需要向用户报告。如果您能在文件的其他地方看到验证器地址,可能仍然能找到验证器的别名——同一个验证器地址可能用于不同链,因此如果验证器地址匹配,别名也匹配。
此外,记下原始链的阈值和验证器集大小。
步骤 3:向用户报告
始终报告 整个 验证器地址(从不截断)、别名、最新签署的检查点、与最高最新签署检查点的差异、状态(例如健康、停滞)。
首先,在表格中显示 multisigIsm.ts 配置中存在的所有验证器。清晰地显示任何停滞的验证器,其他非停滞验证器为健康。
其次,在表格中显示任何观察到的验证器,它们不在 multisigIsm.ts 文件中,但仍然似乎为某些目标链注册。将此作为警告报告,并包括它们仍然注册的目标链列表。清晰地显示任何停滞的验证器,其他非停滞验证器为健康。将这与默认 ISM 的任何差异视为可能的错误配置,即使您认为可能故意使用自定义 ISM。
然后总结关键发现:
- 是否有任何停滞?
- 报告阈值和验证器集大小。法定人数意味着我们至少有
threshold个健康验证器。如果停滞验证器的数量意味着我们不再满足健康验证器的阈值,这极其令人担忧,是 高 优先级!如果接近(即如果再有一个宕机),视为 中 优先级。否则,视为 低 优先级,除非以下指令与此冲突。 - 任何停滞验证器都表示当前存在健康风险。即使我们仍有法定人数,也应 ping 停滞验证器并解决此问题。
- 如果我们仍有法定人数(或不确定是否仍有法定人数),报告以下优先级:
- 正好 1 个验证器宕机 - 高 优先级(显示警告表情)
- 正好 2 个验证器宕机 - 中 优先级(显示警告错误表情)
- 3 个或更多验证器宕机 - 高 优先级(显示错误表情)
- 如果失去法定人数(活跃验证器数量 < 阈值)
- 高 优先级(显示错误表情)