协议演进 / BIP/比特币改进提案 / BIP-8
BIP-8
BIP-9 的替代部署机制:用区块高度代替时间戳计时,并增加 lockinontimeout 参数,使软分叉可以在超时前被强制锁定、保证激活。本 BIP 目前处于已完成状态。
一、档案卡
| 编号 | BIP-8 |
|---|---|
| 标题 | Version bits with lock-in by height |
| 作者 | Shaolin Fry <[email protected]>, Luke Dashjr <[email protected]> |
| 指定日期 | 2017-02-01 |
| 类型 | Informational(信息类) |
| 状态 | Complete(已完成) |
| 阅读版 | https://bips.dev/8 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0008.mediawiki |
二、放在哪一族
软分叉部署机制族,是 BIP-9(version bits)的替代设计。两者共用同一套基本思路——把区块头 nVersion 当作位向量、每个 bit 跟踪一次部署、每个难度调整周期(2016 个区块)统计一次信号——分歧只在两点:用什么计时,以及超时时能不能强制锁定。
理解 BIP-8,关键是把它与 BIP-9 对照读:BIP-9 里没有的东西(按高度计时、lockinontimeout、minimum_activation_height、MUST_SIGNAL 状态),正是 BIP-8 认为前者做错或缺失的地方。
三、它要解决什么
原文列出对 BIP-9 的几项不满:
- 激活依赖近乎一致的算力信号:BIP-9 的高阈值可能难以达到,一小部分不信号的算力就能行使否决。另一方面,超级多数算力先行强制新规则、替全节点“加速激活”也有其做法。原文的立场是:一切共识规则最终由全节点执行,软分叉最终会被经济体执行——本提案把两方面结合:既可由算力多数在旗日之前加速激活,也可在合理时间后以可选的旗日方式激活。
- 用时间戳计时不可靠:区块时间本身不甚可靠、还可能被有意或无意地写错;且 BIP-9 以“给定时间之后的第一次难度调整”为触发点,不直观。若算力突然大量流失,还可能干扰临近尾声的激活。
- 高度是更可靠的单调时钟:每个新区块高度必加一,以高度为阈值可以精确地对准难度调整边界计算。
四、规则本身
4.1 参数
每次部署由以下逐链参数定义(比 BIP-9 多三个):
- name:部署的简短标识;同一 BIP 描述的部署建议用 “bipN”。
- bit:nVersion 中用于信号的位,取 0–28;并发部署不得共用同一 bit。
- startheight:该 bit 开始有意义的区块高度。
- timeoutheight:矿工信号结束的高度;到达此高度仍未锁定(不含本块的 bit 状态),部署即告失败。
- threshold:一个调整周期内表示锁定的最少信号区块数;建议 1815(2016 的 90%),测试网 1512(75%)。
- minimum_activation_height:软分叉最早可激活的高度;可设为 0,此时 LOCKED_IN 只持续一个调整周期。它把“升级窗口”从信号开始之前,挪到 LOCKED_IN 期间,给节点留出在已锁定后再升级的时间。
- lockinontimeout:布尔参数;设为 true 时,最后一个周期进入强制信号,确保部署在 timeoutheight 前必然锁定。
选参指南要点:timeoutheight 建议至少在 startheight 之后约一年(52416 个区块、26 个调整周期);startheight、timeoutheight、minimum_activation_height 都必须是 2016 的整数倍(落在调整边界上),且 timeoutheight 至少比 startheight 晚 4032 个区块。预计或已发现有不可忽略比例矿工政治性反对的软分叉,lockinontimeout 应设为 true;它可以后加,但一旦设定不可清除。
4.2 状态机
状态比 BIP-9 多一个 MUST_SIGNAL:
DEFINED(初始,创世块对每次部署都处于此态)→ STARTED(到达 startheight)→ MUST_SIGNAL(仅当 lockinontimeout 为 true、尚未锁定且距超时只剩一个调整周期时进入)→ LOCKED_IN(某周期内至少 threshold 个区块置位;保持到达到 minimum_activation_height)→ ACTIVE(新共识规则开始对每个区块执行);若超时仍未锁定则 FAILED。
要点:同一调整周期内所有区块状态相同;某块的状态只取决于其祖先的 nVersion,不取决于它自己。MUST_SIGNAL 期间有强制性:若本周期已有 (2016 − threshold) 个区块未信号,其后再出现未信号的区块即为无效——以此保证周期结束必然转入 LOCKED_IN。lockinontimeout 为 true 时,LOCKED_IN 最迟在 timeoutheight 到达;一旦锁定,ACTIVE 在一个调整周期后或 minimum_activation_height(取较晚者)到达。
4.3 位与版本范围
nVersion 按 32 位小端整数解释,bit 位的值为 (1 « N)。处于 STARTED 的区块,其 nVersion 最高 3 位必须为 001,即取值范围 [0x20000000…0x3FFFFFFF],共 29 个可用 bit(与 BIP-9 相同);最高 3 位不是 001 的区块,对所有部署按全 0 处理。矿工在 LOCKED_IN 阶段应继续置位以便观察采用情况,但这不影响共识规则。
4.4 配套机制
- 未知升级警告:与 BIP-9 相同,用“隐含 bit”掩码(nVersion 与期望版本有意外差异)跟踪未知部署,检出 LOCKED_IN 时大声警告,进入 ACTIVE 后警告更强。
- getblocktemplate 变更:与 BIP-9 基本相同(rules、vbavailable、vbrequired 等字段);服务器必须把 MUST_SIGNAL 状态部署的 bit 放进 vbrequired,以保证产出的区块有效。带 “!” 前缀的规则含义也与 BIP-9 一致。
- 强制信号的注意事项:实现不得因对等节点发来未信号的无效区块(或建在其上的区块)就封禁对方,否则一条短暂更长的不兼容链可能把点对点网络切开;设置 lockinontimeout=true 的节点可能在较长时间内跟随工作量较低的链,部署方应选用不致出现更高工作量替代链的参数,或指定这类节点互相优先连接的机制。
4.5 向后兼容
BIP-8 与 BIP-9 的部署不应并发共用同一 bit。只实现 BIP-9 的节点不会激活一个未在 timeoutheight 前达到算力阈值的 BIP-8 软分叉,但仍会接受已激活节点产出的区块。
五、谁必须动
普通持币人:无直接动作。某次具体软分叉用不用 BIP-8 部署,是那次升级自己的部署决定。
矿工:在 STARTED 期按所支持的部署置位;在 MUST_SIGNAL 期必须置位,缺口超过 (2016 − threshold) 后再不信号的区块无效。
全节点与实现开发者:按高度计算状态机(含缓存与重组时的重算),执行 ACTIVE 状态下的新规则,并实现未知升级警告与 getblocktemplate 扩展。
共识层:本 BIP 本身是信息类文档,改的是“部署机制”而非任何一次具体升级的规则;具体新规则仍由各自的软分叉 BIP 定义、在 ACTIVE 后才被执行。
六、现在算不算数,以及一个常见误读
状态为 Complete:按现行 BIP-3 的定义,即作者已完成全部计划工作、推荐采用。原文 Changelog 显示它走过一段弯路:2017 年发布初稿,2020 年曾因三年超时被移入 Rejected,同年又回到 Draft 并大改(加入 minimum_activation_height、以 MUST_SIGNAL 取代 FAILING 等),最终版本 1.0.0 升至 Complete。Complete 不等于“所有软分叉都必须用它部署”——用不用、用哪组参数,由每次具体部署决定。
常见误读:
“lockinontimeout=true 就是矿工不同意也能自动强行升级,谁也拦不住。”
不准确。它保证的是:在运行这套实现、且该参数设为 true 的节点看来,部署最迟在 timeoutheight 前进入 LOCKED_IN 并随后激活——强制信号是这套实现内部的共识规则。原文同时提醒,这类节点可能因此在一段时间内跟随工作量更低的链,并要求部署方处理好节点互联问题;它并不取消节点运营者选择运行什么软件的自由。
七、延伸
- 阅读版:https://bips.dev/8
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0008.mediawiki
- 相关:BIP-9(被替代对照的原版 version bits)
- 仓库总目录:https://github.com/bitcoin/bips
