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

BIP-31 Pong 消息

给 ping 消息加一个随机数 nonce,并新增 pong 回应,让客户端能及时发现连接已死、对方过载,并测出到对等节点的延迟。本 BIP 目前处于已部署状态。

一、档案卡

档案卡
编号BIP-31
标题Pong message
作者Mike Hearn <[email protected]>
指定日期2012-04-11
层级Peer Services(对等服务)
类型Specification(规范类)
状态Deployed(已部署)
阅读版https://bips.dev/31
官方原文https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki

二、放在哪一族

BIP-31 属于对等网络(P2P)基础消息族,处理的是节点之间最底层的连接健康检查:连接还在不在、对方还响不响应、延迟有多大。

它与 BIP-14(协议版本与用户代理)、BIP-35(mempool 消息)、BIP-37(连接布隆过滤)同属对等服务层,都是在不改共识规则的前提下,给节点间通信补上小而实用的机制。

这类改动的特点是:不触碰区块与交易的合法性,只改“节点怎么说话、怎么确认对方还活着”。

三、它要解决什么

原文列了三个当时常见的网络问题:

3.1 设备休眠后连接“假活”

一些客户端跑在会随时休眠的设备上,手机和笔记本(合上盖子)尤其常见。系统醒来后,原来的 TCP 连接表面上还在,实际上可能因为 IP 地址已变、对方已离开或连接已被中间系统超时而失效。现在往往要过很久才能发现。

3.2 对方过载,无从判断

参考客户端当时大体是单线程的,在重负载下(例如正在下载区块链时)响应网络消息会变得很慢。被动等待广播的一方很难判断对方是没消息,还是已经忙到回不过来。能探测到过载节点,就能避开它们、均衡负载。

3.3 不知道谁离自己“更近”

下载区块链这类大数据时,选网络上更近的节点效率更高,也能减轻拥挤的跨国链路负担。但当时没有简单的办法测量到某个对等节点的延迟,客户端只能随机选。

这三个问题,都可以用一个向后兼容的小改动一并解决:让 ping 带上可回显的标记,并规定对方必须回一个 pong。

四、规则本身

4.1 ping 加 nonce,新增 pong

当双方在 ver 消息中协商出的协议版本大于 60000 时:

客户端发出 ping 后计时,收到对应 pong 时就得到往返延迟。若在第一个 pong 回来之前又发了第二个 ping,可以靠 nonce 区分两次回应;若客户端从不让 ping 重叠发送,则把 nonce 设为零即可。

4.2 向后兼容

客户端必须先通过宣告协议版本大于 60000 来选择启用(opt-in)这一功能。旧版本客户端不被期望在 ping 中提供 nonce,也不会被发送 pong。

4.3 实现

原文给出的实现是比特币参考客户端的一个合并请求(bitcoin/bitcoin pull request #932)。改动范围刻意保持极小:一个字段加一个新消息,没有别的连带变化。

五、谁必须动

普通持币人:无直接变化。不改变地址、交易格式或余额。

钱包与轻客户端:实现 ping/pong 后,可以更快发现死连接、换掉无响应的节点,并按延迟挑选同步对象,移动端体验受益最直接。

全节点:升级到协议版本大于 60000 的实现后,需要在 ping 中带 nonce,并对收到的 ping 回 pong。仍是旧版本的节点按原方式运行,不受影响。

共识层:完全不动。区块和交易是否合法,与 ping/pong 无关。

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

状态为 Deployed。ping 带 nonce、pong 回显,已经是对等协议里沿用至今的基础机制:节点靠它定期探活、测延迟,并据此维护连接质量。

常见误读:

“收到 pong 就证明对方是诚实、可信的节点。”

不对。BIP-31 只解决“对方还活着、响应有多快”,不验证对方给的区块、交易或信息是否真实。pong 回得再快,也不能替代对区块和交易的独立验证。

七、延伸

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