BIP 9 状态机解读:defined、started、locked_in、active、failed 各意味着什么 图 1
BIP 9 状态机解读:defined、started、locked_in、active、failed 各意味着什么 · 图 1

软分叉需要一台状态机

比特币的升级大多是软分叉:旧节点眼中仍然合法的规则收紧。问题是如何让成千上万个独立升级的节点就“新规则何时开始强制生效”达成一致。答案不在任何中央服务器上,而是写死在每台节点代码里的一个状态机,这就是 BIP 9 版本位机制。节点每次选链、每次出块模板计算时都会走一遍这台状态机,因此全网的判断由区块数据本身驱动,天然一致。

五个状态和它们的含义

每个部署(deployment)在任意时刻处于五种状态之一:DEFINED 尚未开始;STARTED 进入信号期,矿工可以投票但新规则未生效;LOCKED_IN 信号达标,进入强制预备期,新版本节点会拒绝不符合新规则的块,但旧规则在共识层继续有效直到激活;ACTIVE 新规则正式成为共识;FAILED 超时未达标,部署作废。查询入口是 getdeploymentinfo(Bitcoin Core v24.0 引入)与 getblockchaininfo 的 deployments 字段。对主网大多数历史部署,信号窗口取一个难度调整周期,即两千零一十六块;达标门槛九百五成,即两千零一十六块中的一千九百一十六块由新版本签发。状态由每个周期的实际区块统计出来,不存在人工宣布环节。

区块头怎么投出这一票

投票不用额外消息,就在区块版本号里:前三位固定为一零零(BIP 9 的身份证),其余低位里每个部署占一个比特,置位即赞成。钱包或节点收到版本号带有未识别置位的区块时,会提示 unknown new version bits,这只是“有我没装的升级在投票”,不代表网络异常。周期起止按 MTP(前十一块时间戳中位数)划窗,投票只在状态为 STARTED 的周期内计数。多套 BIP 共享同一段版本号位时,必须保证同一周期内至多一个部署处于 STARTED,这是 BIP 9 对并行部署的约束,也是节点提示 unknown new version bits 频发的另一层原因:某段时间同时存在多个信号尝试,或某个部署的位被其他用途占用。

机制的演化:从九百五成到 Speedy Trial

高门槛有被少数算力卡住的历史教训。2021 年的 Taproot(BIP 340、341、342)改用 Speedy Trial 变体:阈值降为九成,窗口限制在约三个月(四个周期)内,起算高度六十八万三千一百三十六,从第二个周期的末尾——第六十八万七千二百八十四块达到锁定条件,随后经历较长的强制预备期,于第七十万九千六百三十二块(2021 年 11 月 14 日)正式激活。若窗口内未达标,部署平静过期,不留任何网络分裂。对比 2017 年 SegWit 用 BIP 9 加 BIP 91、BIP 148 双重压力才走完全程的历史,Speedy Trial 的设计目标就是把“僵持”从协议里删掉。

读懂状态比读懂新闻更重要

社区讨论升级时,“信号通过了”“已经锁定”“已激活”经常被混用,对应的是 LOCKED_IN 之前的信号比例、LOCKED_IN、ACTIVE 三个阶段,用户可见的行为完全不同:LOCKED_IN 后,升级过的节点已拒绝旧规则区块,但旧节点仍能跟随最长链;ACTIVE 后,任何不遵守新规则的块都会被全网拒绝。如果你经营节点服务,关注 LOCKED_IN 出现的瞬间即可安排升级,而无需在 STARTED 阶段抢跑;如果经营接收系统,判断某笔交易是否风险,看的是所在链当前处于哪个状态,而不是媒体标题。

常见误区

“矿工投票通过=软件已升级”——投票只在区块版本号上,与节点软件版本无关。“FAILED 意味着攻击或灾难”——多数 FAILED 只是无人推进,网络照常出块。“状态是中心化的开关”——每个节点独立重放区块重算状态,没有管理员。

风险提示

本文描述的是协议机制,不构成对任何升级前景或资产价格的预测。部署参数以对应 BIP 与节点文档为准。