协议演进 / BIP/比特币改进提案 / BIP-180

BIP-180 区块大小/重量欺诈证明

为轻客户端设计一种欺诈证明,使其能凭全节点给出的尺寸下界证明,识别超出大小或重量上限的无效区块。本 BIP 目前处于已关闭状态。

一、档案卡

档案卡
编号BIP-180
标题Block size/weight fraud proof
作者Luke Dashjr <[email protected]>
指定日期2017-03-17
层级Peer Services(对等服务)
类型Specification(规范类)
状态Closed(已关闭)
阅读版https://bips.dev/180
官方原文https://github.com/bitcoin/bips/blob/master/bip-0180.mediawiki

二、放在哪一族

轻客户端安全与对等网络协议族。轻客户端(SPV 客户端)只下载区块头、不验证全部交易,天然无法自己发现“这个区块其实无效”;欺诈证明(fraud proof)的思路是让全节点拿出可验证的证据,使轻客户端不必下载全块也能确信某块违规。

本篇只挑一种违规来证明:区块超出大小/重量上限。重量口径来自 BIP-141(SegWit 对区块重量的定义:剥离见证后的大小 × 3 + 完整大小)。原文在答疑中说明为什么只做这一种:当时活跃的威胁正是矿工以超大区块强行推动硬分叉,而这一种违规恰好可被可靠证明、且证明无法在不破坏该次硬分叉尝试的前提下被攻破;对所有无效情形给出证明,当时被认为不可能。

三、它要解决什么

原文动机写得很直白:当时不断有人提出硬分叉扩大区块上限,在达不成共识的情况下,支持者常威胁并试图让矿工强行推行。

在当时的现状下,轻客户端根本无法检测无效区块:只要一条链工作量最大,它就可能被骗着接受这条由超大区块组成的无效链。有了区块大小欺诈证明,轻客户端就能保护自己的用户免受这种未经共识的“硬分叉”尝试——别人声称某块合法时,它可以要求对方拿出证明,或者接受诚实节点给出的超限证明并拒绝该链。

四、规则本身

4.1 核心思路:只证下界

证明不必给出区块的精确大小,只需给出一个可验证的下界:只要下界已经超过上限,区块必然无效。由此定义了几个概念:

其中 SHA2 能证明大小的原因,原文在答疑中解释:SHA2 最后一块必须在末尾写入输入数据的总长度,因此提交最后一块之前的 midstate、只重放最后一块,就能核对声称的交易大小与实际被哈希的数据是否一致,最终哈希即该交易的 txid 或见证哈希。

4.2 证明格式要点

证明依次包含:交易数量的 log2 量级、剥离尺寸证明的分量个数与各分量、各分量代表的交易数(同样以 log2 表达),完整交易大小证明还包括 256 位 midstate、交易总大小、最后一块大小(0–55)及其内容。剥离证明中普通交易按默认 60 字节计,完整证明则沿用剥离证明已确立的尺寸。

以 log2 表达交易数量,是为了防攻击:避免客户端被无法验证的虚报数量欺骗。证明中至少须含一个完整交易大小证明,以钉死交易总数不被虚增。

4.3 验证步骤(概要)

  1. 分别验证剥离尺寸证明与完整尺寸证明,得到各自的大小下界(lowStrippedSize、lowFullSize);验证中要重建默克尔根并与区块头(剥离证明)或见证承诺(完整证明)比对,且不得有重复的默克尔链接;
  2. 在算得的交易数据下界上加上 80 字节区块头与交易计数变长整数的大小;
  3. 按重量公式算下界重量:完整大小下界 + 剥离大小下界 × 3;
  4. 把下界重量与适用的区块重量上限比较,超过即证明该块超限。

原文说明:证明生成方应尽量用最少的数据凑出超限下界(通常是挑最大的几笔交易做完整大小证明,直到越过上限),但具体优化方式不作强制。

4.4 网络协议:getfraud / fraud

当轻客户端发现某个对等节点不把自己认为工作量最大的区块当作最佳区块时,它应向这些节点发出新消息 getfraud,参数为一个区块定位器(介于最后一个共同区块与 presumed 最佳链尖之间)。

兼容节点以新消息 fraud 回应,包含:定位器中它已检查过的最近区块哈希(若有无效块,应精确给出该无效块哈希),以及欺诈证明类型码:

若对方报称更早的区块有效,客户端应缩小定位器区间反复询问,直到定位到对方拒绝哪个块、为什么。一旦某块被证明无效,轻客户端永不应再把包含它的链当作最佳链候选,也不应重复验证已知无效的块;用户可被允许手动推翻拒绝,但须被警告其后果。若收到的欺诈证明本身无效,客户端应考虑断开并可能封禁提供它的节点。

五、谁必须动

普通持币人(轻客户端用户):不需操作;保护发生在客户端内部,前提是所用客户端与相连节点都实现本协议。

钱包开发者(轻客户端):需实现 getfraud/fraud 消息、证明验证逻辑与“已证明无效即拒绝该链”的处理。

全节点与矿工:兼容节点需能按请求生成并回送欺诈证明;区块的共识有效性规则本身没有任何改变——超限区块本来就无效,本篇只是让轻客户端能“看见”这一点。

共识层:无改动。它证明的是既有大小/重量上限被违反,不新增上限、不放宽上限。

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

状态为 Closed(已关闭),且原文的参考实现一栏至今只写着 TODO。也就是说,这套欺诈证明协议并未作为现行标准落地;读它应着眼于设计本身——为何只证下界、为何用 SHA2 midstate 钉住交易大小、轻客户端与全节点之间如何一问一答。在没有实现的前提下,不能声称今天的轻客户端已经具备这种自证能力。

常见误读:

“有了欺诈证明,轻客户端就等于全节点一样安全了。”

不对,本篇自己就限定了范围:它只证明“大小/重量超限”这一种无效。原文在答疑中明说,当时被认为不可能对所有无效情形都给出证明。脚本错误、双花构造等其他违规不在本证明的覆盖之内;而且整套机制只保护实际使用它的客户端,不使用的客户端行为与从前无异。

七、延伸

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