同步进度条快 100% 却还没好:verificationprogress 是怎么估出来的 图 1
同步进度条快 100% 却还没好:verificationprogress 是怎么估出来的 · 图 1

一、先分清两个高度

getblockchaininfo 里有两个最容易被混的字段:blocks 是当前已经完整验证并落库的区块高度,headers 是已经从对端收下、尚未验证的区块头高度。同步初期你会看到 headers 冲得飞快、blocks 在后面慢慢追——先把整条链的目录(区块头链)拿到手,再逐块重放内容,这是初始同步的标准节奏。判断进度的第一步,就是看这两个数字差多少。

同步进度条快 100% 却还没好:verificationprogress 是怎么估出来的 图 2
同步进度条快 100% 却还没好:verificationprogress 是怎么估出来的 · 图 2

二、进度条不是字节比

verificationprogress 的官方定义写得很清楚:初始同步期间对验证进度的估算,取值介于 0 和 1 之间,依据是对全链交易总数的一个估计值。也就是说,它统计的不是下载了多少字节,而是重放了多少笔交易相对一个模型总量的比例。为什么用交易数而不是字节数?因为验证成本的大头在脚本执行与未花费输出集读写,交易数量比文件大小更接近真实工作量。也正因为它是模型估算,你看到的一切怪现象都由此而来。

三、为什么总卡在 0.999

模型需要知道全链历史上一共发生过多少笔交易,这个总数本身也是估出来的。越接近链的末端,未处理的新交易笔数越少,估算噪声相对越大,进度自然越走越慢。当节点的统计模型更新时,进度数字甚至可能小幅回退——这不是链出了问题,只是估算被修正。把验证跳过的场景(例如高区块之前的脚本校验被 assumevalid 类机制略过)叠加进来,感知进度和真实完成点之间的错位会更明显。

四、更可靠的完成信号

比进度数字更硬的信号有两个。其一是 initialblockdownload 布尔字段:为真说明节点仍处于初始同步状态,会调整对等连接和数据请求策略;为假表示已追平。其二是 blocks 与 headers 是否相等且贴近对端时间。两个条件同时满足,同步就算完成,不用等 verificationprogress 真的变成 1。

五、快照同步下的特例

如果节点加载过未花费输出集快照(快照同步功能自 v26 起进入核心,主网参数在 v28 加入),节点内部会同时存在两条链状态:一条从快照起步快速追链,另一条在后台从头验证。这种状态下只看一个进度字段意义有限,应当结合查询链状态的工具分别查看,后台验证完成前,快照带来的信任假设仍然成立。

六、实用口径

给自己定三条观察线:headers 是否贴近当前链头、blocks 是否追平 headers、initialblockdownload 是否转假。三条全绿,进度条显示多少都不重要。

七、进度字段的两个历史怪癖

早期版本里,进度估算依赖内置的链上交易计数器,当统计口径修正(例如重新校准交易数据打包点)时,进度会突然跳变,社区有过不少虚惊。另一类来自剪枝节点:剪枝改变的是原始文件的保留范围,不改变 blocks 高度语义,有人误以为剪枝”加快验证”会反映到进度上,实际上二者互不相干。记住口径的粗糙性,能省掉很多不必要的重头同步。

八、网络层面的干扰

进度停在某个值不动时,先排除比模型更常见的原因:连接对端全部是低版本或异网节点,块源饥饿让验证自然停摆;headers 若同时不再增长,问题在头同步而不是验证。这类场景 progress 表面安静,实际是断粮——所以前文的三条观察线里,headers 贴近链头排在第一位,它比进度数字更早暴露网络问题。

一句话收束:把 verificationprogress 当作仪表盘上一支会抖动的指针就好,真正给同步盖章的是那两个高度与一个布尔值。

风险提示:本文仅为技术机制科普,不构成任何投资建议。