协议演进 / BIP/比特币改进提案 / BIP-31
BIP-31
给 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消息必须包含一个uint64字段,名为nonce;- 发送方应把 nonce 设为随机值;
- 接收方用一个新的
pong消息回应该 nonce,pong 同样只包含一个uint64字段,原样回显。
客户端发出 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 回得再快,也不能替代对区块和交易的独立验证。
七、延伸
- 阅读版:https://bips.dev/31
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki
- 相关:BIP-14 协议版本与用户代理、BIP-35 mempool 消息、BIP-37 连接布隆过滤
- 仓库总目录:https://github.com/bitcoin/bips
