协议演进 / 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 消息的第一个布尔值切换:

4.2 线上传的是什么

新增四个数据结构:

也就是说,大部分交易在线上只以 6 字节的短 ID 出现;全文只出现两次例外:预填的少数交易,以及接收方事后点名补要的交易。

4.3 短交易 ID 怎么算

短 ID 用来以 48 位代表一笔交易,替代完整的 256 位交易哈希,算法分三步:

  1. 把区块头与 nonce(小端)拼接后作一次 SHA256,得到密钥材料;
  2. 取其中前两个小端 64 位整数作 SipHash-2-4 的密钥 k0/k1,以交易 ID 为输入运行 SipHash;
  3. 丢弃 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 计算。

实现说明中的硬性纪律包括:

向后兼容:旧客户端完全兼容、可互操作。原文 Implementation 一节给出了第 1、2 版的 Bitcoin Core 参考实现合并请求链接。

五、谁必须动

普通持币人:无直接动作。不改变交易格式、地址或确认规则;受益方式只是节点同步更省带宽。

钱包开发者:一般不必实现本协议;只有自带完整 P2P 同步的轻客户端/SPV 实现需要留意原文提醒——高带宽模式下收到的区块可能尚未被发送方完整验证,采用“受信全节点”模式的产品尤其要谨慎。

全节点与矿工:这是本 BIP 的实现主体:协商版本、按模式公告或应答紧凑区块、用内存池交易重建整块、缺失时点名补取,并遵守最多 3 个高带宽对等、碰撞不罚、验证前公告不罚等纪律。

共识层:本 BIP 不修改任何共识规则。区块的合法性判定与以往完全相同,变的只是区块在节点之间传递时的编码方式。

六、现在算不算数,以及一个常见误读

状态为 Deployed(已部署)。按 BIP 体系的用法,这表示该规范已被实际部署进运行中的实现,而非仍停留在草案讨论阶段。它至今仍是节点间中继新区块的标准方式之一:节点先尝试用紧凑形式重建,凑不齐就补取交易,再不行就回退到完整的区块传输,任何一步都不影响区块最终是否被接受。

常见误读:

“紧凑区块就是把区块压缩打包后再传输,区块格式被改小了。”

不对。区块本身——区块头、交易顺序、默克尔承诺——一个字节都没改。紧凑的只是某一次 P2P 传输的表示法:发送方赌接收方已经见过块里的大多数交易,只发短 ID 让对方对号入座。接收方重建出的仍是原来那个完整区块,并按原有共识规则完整验证;短 ID 碰撞或交易缺失时,协议自带补取与整块回退,绝不会因为“传得省”就少验一步。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。