协议演进 / BIP/比特币改进提案 / BIP-111
BIP-111
为 BIP-37 的连接 BLOOM 过滤定义一个服务位 NODE_BLOOM(1 « 2),让节点能明示自己是否提供过滤服务;不支持过滤的节点收到 filter 消息时应立即断开对方。本 BIP 目前处于已部署状态。
一、档案卡
| 编号 | BIP-111 |
|---|---|
| 标题 | NODE_BLOOM service bit |
| 作者 | Matt Corallo <[email protected]>;Peter Todd <[email protected]> |
| 指定日期 | 2015-08-20 |
| 层级 | Peer Services(对等服务) |
| 类型 | Specification(规范类) |
| 状态 | Deployed(已部署) |
| 阅读版 | https://bips.dev/111 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki |
二、放在哪一族
P2P 网络服务宣告族,是 BIP-37 的补丁式扩展。BIP-37(Connection Bloom filtering,连接布隆过滤)让轻客户端把一个 BLOOM 过滤器交给全节点,节点只回传匹配的交易,从而省下轻客户端的带宽——但它当年没有定义任何服务位(service bit)。
BIP-111 补的正是这一位:节点先宣告“我提供过滤服务”,对等方再决定要不要向它发过滤器。它与同期的时间锁族(BIP-112、BIP-113)同在 2015 年 8 月前后定稿、编号相邻,但层面完全不同——那两份改共识,这一份只改节点之间如何自我介绍。
后来轻客户端过滤又演进出 BIP-157(客户端区块过滤)与 BIP-158(紧凑区块过滤器):思路反过来,由节点提供紧凑过滤器、客户端在本地匹配。读 BIP-111,能看清 BLOOM 路线为什么需要先解决“谁愿意提供服务”这一步。
三、它要解决什么
3.1 BIP-37 默认“人人提供”,现实并非如此
BIP-37 没有规定服务位,等于隐含假设:所有向对等方提供数据的节点都支持连接过滤。
3.2 过滤的隐私与 DoS 问题
原文给出两个理由,说明这个假设站不住:
- 隐私:已发表的研究表明,BIP-37 的连接过滤算法提供的隐私很少、甚至没有;
- 拒绝服务风险:在某些节点上,连接过滤是一个很大的 DoS 风险点。原文脚注举了 2013 年 7 月 bitcoin-dev 邮件列表上的讨论为例,并链接了示例性的 DoS 利用代码。
结论是:允许节点运营者关掉连接 BLOOM 过滤,是一个非常需要的功能——而要让关闭成为可能,先得有一个办法把“提供/不提供”说清楚。这就是服务位的用途。
四、规则本身
4.1 新增服务位
NODE_BLOOM = (1 << 2)
- 支持 BLOOM 过滤的节点应当置起该位;不支持的,应当保持不置起。
- NODE_BLOOM 与 NODE_NETWORK 相互独立、互不相同:宣告 NODE_BLOOM 而不宣告 NODE_NETWORK 是合法的(原文说目前这样做没什么道理,但未来的某些提案可能使之更有用)。
- 选用服务位,理由是“应用一个 BLOOM 过滤器”本身就是一项服务。
4.2 协议版本一并抬高
参考实现中,协议版本从 70002 提高到 70011。这样做是为了向后兼容:
- 协议版本小于 70011、但大于 70000 的节点,往往在没有 NODE_BLOOM 位的情况下也支持过滤连接;
- 但需要过滤连接的客户端,不应依赖这一假设去猜老节点的能力。
4.3 不支持者收到过滤消息:立即断开
若一个节点不支持 BLOOM 过滤,却收到对等方发来的 “filterload”、“filteradd” 或 “filterclear” 消息,该节点应当立即断开那个对等方。
向后兼容的过渡安排:在最初的实现里,节点可以选择只断开那些已置起新协议版本的对等方,对老节点发来的过滤命令先尝试处理。原文在设计理由中说,这一过渡特征可以在有足够多 NODE_BLOOM 节点、且 SPV 客户端都升级之后移除,让节点运营者彻底关闭 BLOOM 相关的 DoS 向量。
4.4 附带建议(不在本 BIP 范围内)
原文建议,DNS 种子及其他对等方发现机制应支持按所需服务来筛选——当时的实现只检查 NODE_NETWORK 是否置起。这一条被明确放在本 BIP 范围之外,只是建议。
五、谁必须动
普通持币人:无直接操作。变化发生在节点之间,钱包地址与交易不受影响。
钱包开发者(尤其 SPV / 轻客户端):连接前应先看对等方是否宣告 NODE_BLOOM,不要再假设任何节点都接受过滤器;也不要把“老版本号的节点大概支持过滤”当作可靠前提。
全节点与矿工:节点运营者获得了一个正式开关:支持过滤就置起第 2 位,不支持就不置,并按规则断开硬发过滤消息的对等方——从而可以合法地关掉这项有 DoS 风险的服务,而不必担心被当作“不合规”。
共识层:完全不动。区块与交易的有效性规则没有任何变化,这只是一次对等服务层的协议补丁。
六、现在算不算数,以及一个常见误读
状态为 Deployed(已部署)。这里的“已部署”指的是这套服务位约定已被实现并投入使用,而不是某种共识规则被激活。它的效果至今仍是节点服务宣告的一部分:提供过滤是一种自愿、可宣告、可关闭的服务,不再是默认义务。
常见误读:
“BIP-111 废除了 BLOOM 过滤,或证明了 BIP-37 是错的。”
不对。它既没有改动 BIP-37 的过滤算法,也没有禁止任何节点继续提供过滤。它做的只是在协议里加了一个宣告位,并规定不支持者的应对方式(断开发来过滤消息的对等方)。它批评的是 BIP-37 “没给服务位、等于默认人人提供”这一隐含假设,以及由此带来的隐私误期与 DoS 暴露面。
七、延伸
- 阅读版:https://bips.dev/111
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki
- 相关:BIP-37 连接布隆过滤、BIP-157 客户端区块过滤、BIP-158 轻客户端紧凑区块过滤器
- 仓库总目录:https://github.com/bitcoin/bips
