状态根怎么送到以太坊:Polygon PoS 检查点的提议、投票与回执 图 1
状态根怎么送到以太坊:Polygon PoS 检查点的提议、投票与回执 · 图 1

以太坊一侧的合约要确认 Polygon 链上某个余额或某笔跨链取款有真实依据时,它不会去实时读取 Polygon 的每一个区块,而是核对一份被称为检查点的快照:某个区块区间的状态根,加上验证者对这个根的签名集合。这份快照由 Polygon 的第二层共识客户端 Heimdall 组织产生。官方文档把这条链路拆成提议、验证、提交、回执四段,每一段都有独立的消息类型和失败处理。本文按 Heimdall-v2 的文档逐段拆。

谁在管检查点

Heimdall-v2 是 Polygon 网络里的共识客户端,官方说明它基于 Cosmos SDK 的一个分支和 CometBFT 的一个分支重写,负责验证者与质押管理、为 Bor 执行层挑选出块者、管理 span 与命名空间,以及编排以太坊与 Polygon 之间的状态同步。检查点是它众多职责里最容易被外部观察到的一项:文档的表述是,检查点代表 Bor 链状态的快照,先由验证者集合中的多数作出证明,再到以太坊合约上验证和提交。也就是说,检查点不是把区块数据搬去以太坊,而是把一个区间的状态承诺连同投票证据送过去;以太坊合约后续只需要用这棵树做成员证明。

提议:从 Bor 合约取根

每个检查点都有一个验证者作为提议者,流程由 bridge processor 组件启动:它生成一条 MsgCheckpoint 消息并广播。提议者从 Bor 链的合约里导出根哈希,消息字段包含区间起止区块号、root_hashaccount_root_hash、Bor 链的 chain id。文档提醒了一点:受 Bor 最终性时间的影响,这个根未必总是反映最新的链尖——检查点覆盖的区间天然滞后于最新出块,这是设计使然而非故障。下一任提议者由 Heimdall 使用 CometBFT 的领导者选择算法决定,并且会根据上一轮检查点在以太坊上的成败被调整,构成一种失败让位式的轮换。

投票:ABCI++ 里的干跑与扩展

MsgCheckpoint 被打包进 Heimdall 区块后,按 ABCI++ 的钩子流程处理。提议阶段,只有干跑这笔交易不报错,它才会被放进候选块;验证阶段,每个验证者节点拿消息里的 Bor 根哈希与自己的本地 Bor 链独立比对;在 ExtendVote 阶段,验证者执行一笔侧交易复核检查点,通过就在投票扩展里附上确认。到下一个区块的 Finalize 环节,处理完的投票汇总,达到足够多数的检查点被视为通过,preBlocker 触发后置处理,把它存进待桥接缓冲区。这一串设计的要点是把状态根的对错判断分摊到每个验证者自己的 Bor 节点上,而不是信任提议者自说自话。

示意:检查点从提议到回执的流水线

提交与回执:ACK 与 No-ACK

检查点进缓冲区时发出事件,监听事件的桥系统把数据和验证者签名提交到以太坊根链。成功上链后,bridge processor 向 Heimdall 回送 MsgCpAck,经过同一套 ABCI++ 流程更新状态、把已处理的检查点从缓冲区清除,并递增用于跟踪确认次数的计数器。如果提交在以太坊上失败——官方文档点名的原因是 gas 上限、网络拥堵或高 gas 费——多阶段流程就是为这些失败准备的:回执更新提议者选择,让下一任接手。还有一种更别扭的情况:检查点可能已经转去以太坊但迟迟拿不到回执,此时由提议者广播 MsgCpNoAck。文档说明后台例程会定期检查距上一次检查点创建和上一次 No-ACK 的时间,只有回执超期才会触发 No-ACK,避免它被高频刷出。

检查点不是唯一的最终性刻度

读 Heimdall-v2 的职责清单还会看到 milestones:用投票扩展在 2 到 5 秒内提供确定性最终性的机制。两者构成粗细两把尺子——milestone 管近期区块的快速确认,检查点管把状态根连同证据沉淀到以太坊这件事。核对一笔跨链资产时,先弄清楚你要查的是哪一把尺子:Bor 区块被 milestone 盖章,不等于对应检查点已经在以太坊上被确认;桥的安全边界通常以后者为准。哪些字段能证明到哪一步,建议对照当时版本的官方文档和链上合约状态核验,本文只按文档描述机制,不构成对任何具体桥部署安全性的判断,也不构成投资建议。