协议演进 / BIP/比特币改进提案 / BIP-152
BIP-152
只传区块头、短交易 ID 与少数预填交易,让接收方用本地已有的交易重建整块,大幅节省区块中继带宽。本 BIP 目前处于已部署状态。
一、档案卡
| 编号 | BIP-152 |
|---|---|
| 标题 | Compact Block Relay |
| 作者 | Matt Corallo <[email protected]> |
| 指定日期 | 2016-04-27 |
| 层级 | Peer Services(对等服务) |
| 类型 | Specification(规范类) |
| 状态 | Deployed(已部署) |
| 阅读版 | https://bips.dev/152 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki |
二、放在哪一族
区块中继与网络效率族的核心文档。比特币节点之间转发新区块时,传统做法是把整块连同每一笔交易全文发出去;BIP-152 改的只是“线上怎么传”,不改区块本身长什么样。
它与相邻文档的关系:
BIP-130:sendheaders 消息。低带宽模式下,新区块仍先按 BIP-130 的 inv/headers 方式公告,再由接收方主动索取紧凑区块
BIP-141 与 BIP-144:隔离见证的共识层与对等服务层定义。紧凑区块的第 2 版专门为见证交易而设,短 ID 改用 wtxid 计算
理解 BIP-152,是理解现代节点为何能在带宽尖峰小得多的情况下仍然快速同步新区块的起点。
三、它要解决什么
原文 Motivation 指出,历史上的 P2P 协议在中继区块时非常浪费带宽:区块里的每一笔交易都被完整包含,哪怕其中绝大多数在区块被中继之前就已经到达过接收节点(它们早已在各地节点的内存池里传播过一轮)。
后果有两层:
- 接收区块时,节点会出现中等程度的入站带宽尖峰;
- 若某节点比它的对等节点先收到区块,它要把整块再转发出去,出站尖峰会非常显著。
尖峰一旦引发缓冲膨胀(buffer bloat),家用网络会暂时近乎不可用,还会拖慢向远端对等节点的转发——对方可能宁可等,也不愿重复请求同一区块。因此,降低区块中继的带宽占用,对大量个人节点运行者直接有用。
原文特意说明:本工作的目标明确不是降低区块传输延迟,但作为副作用,它在若干重要情形下确实降低了延迟,并为后续专门面向低延迟中继的工作打下基础。
四、规则本身
4.1 两种模式:高带宽与低带宽
协议按对等关系与带宽条件分两种用法,由 sendcmpct 消息的第一个布尔值切换:
- 高带宽模式(置 1):发送方直接用
cmpctblock消息公告新区块,附带短交易 ID,甚至可以在完整验证区块之前就发出(只要求区块头已核验等条件,见 4.5)。接收方若本地已有全部交易,一次往返都不需要即可重建整块;缺交易时走一轮getblocktxn/blocktxn补齐,最好情形延迟与旧流程的 1.5×RTT 下限相同,但带宽省得多。此模式只能对少数对等节点开启(见 4.5)。 - 低带宽模式(置 0):仍按 BIP-130 用 inv/headers 公告(且在完整验证之后),接收方再用
getdata请求MSG_CMPCT_BLOCK(类型值 4)索取紧凑形式;缺交易时再多一轮补齐,最坏到 2.5×RTT,但带宽仍远低于传整块。原文指出,由于 TCP 传大数据时延迟往往更差,即便走到 2.5×RTT,总延迟预期仍会下降。
4.2 线上传的是什么
新增四个数据结构:
- HeaderAndShortIDs:区块头(80 字节)、一个 64 位 nonce、短交易 ID 列表,以及预填交易列表;
- PrefilledTransaction:显式全文给出的少数交易(附其在区块中的下标,下标作差分编码)。典型是 coinbase 交易,以及发送方预期对方可能缺失的个别交易;
- BlockTransactionsRequest:接收方按下标索取缺失交易的请求,含目标区块哈希;
- BlockTransactions:对上述请求的应答,只含被点名索取的那些交易。
也就是说,大部分交易在线上只以 6 字节的短 ID 出现;全文只出现两次例外:预填的少数交易,以及接收方事后点名补要的交易。
4.3 短交易 ID 怎么算
短 ID 用来以 48 位代表一笔交易,替代完整的 256 位交易哈希,算法分三步:
- 把区块头与 nonce(小端)拼接后作一次 SHA256,得到密钥材料;
- 取其中前两个小端 64 位整数作 SipHash-2-4 的密钥 k0/k1,以交易 ID 为输入运行 SipHash;
- 丢弃 SipHash 输出的最高 2 字节,得到 6 字节短 ID。
原文的 Justification 说明了取舍:SipHash 快且抗碰撞操纵;密钥混入区块哈希,攻击者在交易真正进块之前无法预知密钥;nonce 又按连接独立,使碰撞只影响少数连接。48 位在原文给定的量级假设下(块内至多约 10,000 笔交易、内存池至多约 100,000 笔)足以让重建失败率低到每约 281,474 次传输不超过一次,而失败也只是回退到普通中继,不是错误。短 ID 偶发碰撞是预期之内的,节点不得因此惩罚对等节点。
4.4 新增消息与版本协商
新增消息共四个:sendcmpct(协商与模式开关)、cmpctblock(紧凑区块本体)、getblocktxn(按下标索取缺失交易)、blocktxn(补发所索取的交易);getdata 新增 MSG_CMPCT_BLOCK 索取类型,且该类型不得出现在 getdata 之外。
sendcmpct 的第二个整数是版本号,现行取 1;收到未知版本的节点必须当作没收到该消息处理,以便未来版本借重复发送不同版本的 sendcmpct 完成握手。节点应在连接建立时把自己愿意支持的全部版本按优先级顺序发一遍,实际编码版本取“双方都发过、且对方先发到的”那一个。
接收与重建流程:收到 cmpctblock 后,节点为本地内存池中每笔未确认交易计算短 ID 并逐一比对;凑齐全部交易即按下标拼回整块并照常处理;缺交易则发 getblocktxn 点名索取。发送方不得发送自己无力应答“索取全部交易”的 cmpctblock;若对 MSG_CMPCT_BLOCK 请求不回 cmpctblock,必须回完整的 block 消息兜底。
4.5 第 2 版与实现纪律
第 2 版与第 1 版几乎相同,只为支持隔离见证:sendcmpct 版本号改为 2;cmpctblock 与 blocktxn 中的交易带见证数据(格式同 BIP-144 的 MSG_WITNESS_TX 应答);短 ID 改以 wtxid(见 BIP-141)而非 txid 计算。
实现说明中的硬性纪律包括:
- 高带宽模式(第一个整数为 1)的
sendcmpct最多只能发给 3 个对等节点——原文建议按“过去谁最快送来区块”挑选——以免全网出站带宽被浪费;所有节点则应向所有合适的对等节点发送sendcmpct,好让对方能改用紧凑形式索取; - 预填交易建议限制在 10KB 以内,拿不准时只放 coinbase;
- 同一 nonce 不得跨不同区块复用;发送紧凑区块前至少须验证区块头确实承诺了块内各交易、接在已充分验证的链上且工作量证明有效,但可以先于“逐笔核验 UTXO 花费是否合法”发出;
- 高带宽模式允许在完整验证前中继,因此节点不应仅因收到“区块头有效但整块后来无效”的
cmpctblock就封禁对方;协议版本 70015 以上即表示不会为此惩罚对方,低于该版本的对等节点则不应在完整验证前收到此类公告。
向后兼容:旧客户端完全兼容、可互操作。原文 Implementation 一节给出了第 1、2 版的 Bitcoin Core 参考实现合并请求链接。
五、谁必须动
普通持币人:无直接动作。不改变交易格式、地址或确认规则;受益方式只是节点同步更省带宽。
钱包开发者:一般不必实现本协议;只有自带完整 P2P 同步的轻客户端/SPV 实现需要留意原文提醒——高带宽模式下收到的区块可能尚未被发送方完整验证,采用“受信全节点”模式的产品尤其要谨慎。
全节点与矿工:这是本 BIP 的实现主体:协商版本、按模式公告或应答紧凑区块、用内存池交易重建整块、缺失时点名补取,并遵守最多 3 个高带宽对等、碰撞不罚、验证前公告不罚等纪律。
共识层:本 BIP 不修改任何共识规则。区块的合法性判定与以往完全相同,变的只是区块在节点之间传递时的编码方式。
六、现在算不算数,以及一个常见误读
状态为 Deployed(已部署)。按 BIP 体系的用法,这表示该规范已被实际部署进运行中的实现,而非仍停留在草案讨论阶段。它至今仍是节点间中继新区块的标准方式之一:节点先尝试用紧凑形式重建,凑不齐就补取交易,再不行就回退到完整的区块传输,任何一步都不影响区块最终是否被接受。
常见误读:
“紧凑区块就是把区块压缩打包后再传输,区块格式被改小了。”
不对。区块本身——区块头、交易顺序、默克尔承诺——一个字节都没改。紧凑的只是某一次 P2P 传输的表示法:发送方赌接收方已经见过块里的大多数交易,只发短 ID 让对方对号入座。接收方重建出的仍是原来那个完整区块,并按原有共识规则完整验证;短 ID 碰撞或交易缺失时,协议自带补取与整块回退,绝不会因为“传得省”就少验一步。
七、延伸
- 阅读版:https://bips.dev/152
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
- 相关:BIP-130 sendheaders、BIP-141 隔离见证(共识层)、BIP-144 隔离见证(对等服务)
- 仓库总目录:https://github.com/bitcoin/bips
