跳转到正文
buybitcoinsmart

术语表 /开发者参考

MSG_CMPCT_BLOCK

MSG_CMPCT_BLOCK 是什么?
MSG_CMPCT_BLOCK 是编号为4的清单类型,是仅用于请求的代码:它从不出现在通告中,只能用于发送给事先已同意使用它的对等节点的 getdata 消息。

规定于 BIP-152。

紧凑区块是协商使用的,而非通告使用的。对等节点发送一次 sendcmpct 消息,表示将接受紧凑区块,此后对方才可以用类型4而不是类型2来响应新区块。BIP152 随 Bitcoin Core 0.13.0于2016年8月推出,其节省的开销正是全部意义所在:用六个字节指明接收方已经持有的交易,而不是将其重复传送一遍所需的两百个字节或更多。

运作方式

MSG_CMPCT_BLOCK 请求的是区块的描述而不是区块本身,只有当两个节点的内存池相近时,这份描述才有价值。

首先是协商。sendcmpct 消息包含一个标志和一个版本号:版本1按 txid 标识交易,版本2按见证 txid 标识交易,自隔离见证启用以来只有这一版本在使用。节点绝不能在发给未发送过 sendcmpct 的对等节点的 getdata 中放入类型4,因为该对等节点没有义务理解它。

回复是一条 cmpctblock 消息,其中包含80字节的区块头、一个八字节的随机数、每笔交易对应的一个六字节短标识符,以及少量完整提供的交易,其中始终包括 coinbase 交易,因为接收方不可能已经见过它。短标识符由 SipHash 生成,密钥取自区块头和该随机数,因此每个区块、每次请求的短标识符都不相同。这种随机化是一种防御措施:若采用固定方案,攻击者就可以预先计算出两笔相互冲突的交易,从而同时阻碍全网的区块重建。

接收方将这些标识符与其内存池进行匹配,用 getblocktxn 请求缺失的交易,并在本地重建区块。之后的验证与通常的验证无异,也不涉及任何共识规则。

深度是有限制的。Bitcoin Core 只为最近的五个区块提供紧凑区块,对更早区块的请求则以完整区块作答,因为落后这么多的接收方没有可用的内存池,最终会请求区块中的每一笔交易。

在哪里会遇到它

查看 MSG_CMPCT_BLOCK 最清楚的方式是 Bitcoin Core 自身的日志,它会报告每次重建的完成情况。

使用 -debug=cmpctblock 启动节点后,每个新区块都会生成一行记录,说明预填充了多少笔交易、在内存池中找到了多少笔、必须另行获取多少笔。在已运行数小时的机器上,需要获取的数量通常为零,区块到达时只有数十千字节,而不是一点五兆字节。一个包含3,000笔交易的区块,需要18,000字节的短标识符,外加区块头和 coinbase 交易。

这一计算在刚启动的节点上就不成立了。内存池为空意味着每个标识符都无法匹配,后续请求要求获取整个区块,多出的一次往返使紧凑区块的路径比直接请求区块更慢。这就是为什么该代码属于处于链端的节点,而从不出现在初始同步期间。

对于在家中运行节点的人来说,这项功能决定了普通网络连接能否跟上网络的节奏,还是每次出块时都会落后。

请勿混淆

常见问题

为什么这种清单类型只能出现在 getdata 消息中?

因为紧凑区块只有请求过它并事先就版本达成一致的对等节点才能解码。通告一个紧凑区块没有意义,所以 BIP152 将该代码限定为仅用于请求,并要求事先发送 sendcmpct 消息。

紧凑区块会改变有效区块的认定标准吗?

不会。它们只改变区块的传输方式。接收方根据其内存池重建出完全相同的字节,然后照常依据共识规则对其进行验证。

相关术语

开发者参考中的更多术语

阅读本页英文版