协议演进 / BIP/比特币改进提案 / BIP-434
BIP-434
定义一条通用的 feature 消息,让节点在握手完成前协商新 P2P 功能,不必再为每个新功能协调 bump 协议版本号。本 BIP 目前处于已完成状态。
一、档案卡
| 编号 | BIP-434 |
|---|---|
| 标题 | Peer Feature Negotiation |
| 作者 | Anthony Towns <[email protected]> |
| 指定日期 | 2026-01-14 |
| 讨论日期 | 2025-12-19 |
| 层级 | Peer Services(对等服务) |
| 类型 | Specification(规范类) |
| 状态 | Complete(已完成) |
| 阅读版 | https://bips.dev/434 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0434.md |
二、放在哪一族
点对点网络协议与功能协商族。过去每个 P2P 新功能都要单独发明协商方式,BIP-434 是把这套做法收拢、定型的一份总规范。它在原文中点名的前辈:
BIP-35:mempool 消息,原文用作“功能广告”模式的例子
BIP-130:sendheaders,要求协议版本 70012 以上
BIP-133:feefilter,要求协议版本 70013 以上
BIP-152:紧凑区块,建议协议版本 70014/70015 以上
BIP-155:addrv2,在 version 与 verack 之间发 sendaddrv2 协商,实现中事实上要求 70016 以上
BIP-324:v2 加密传输,与本 BIP 的一字节消息类型衔接
BIP-339:wtxid-relay,要求协议版本 70016 以上;本 BIP 正是把它的协商机制加以成文化与一般化
三、它要解决什么
历史上,新 P2P 功能往往与协议版本号的提升绑在一起,好让节点只对支持该功能的对等节点尝试协商。但不同客户端对功能的优先级不同,协调一个全网共用的版本号是升级过程中不必要的负担;原文从理念上也提出:去中心化系统里的 P2P 协议最好是无需许可即可扩展的,不必在实现之间、开发者之间协调。
既有做法分两类:一类是连接建立后(双方都收到 verack 之后)再发新消息,如 BIP-130、BIP-133、BIP-152;另一类是需要在握手完成前协商,如 BIP-155 与 BIP-339,做法是在 version 与 verack 之间插入一条新消息表明支持。
隐患在于:对等节点收到不认识的消息会作何反应?网络上常见行为是忽略未知消息,第一版比特币也明确以“支持协议可扩展性”为由忽略未知消息;但历史上也有客户端在 version 与 verack 之间、乃至 verack 之后劝阻或禁止未知消息,节点若因不认识的消息而断开连接,网络就有被分割的风险。为稳妥起见,上述多数 BIP 仍不得不要求提升协议版本号(70012 至 70016 不等)。
BIP-434 的解法:只加一条可复用的 feature 协商消息,供今后任意新功能在 verack 之前通告与协商;同时规定实现方必须忽略自己不支持的功能通告。这样以后的升级不必再担心被不理解的对等节点无谓断开,也不用再协调协议版本号。
四、规则本身
4.1 基本义务
实现本 BIP 的节点:
- 必须通告不低于 70017 的协议版本号;
- 不得向通告版本号低于 70017 的对等节点发送
feature消息; - 必须接受在 version 消息之后、verack 消息之前收到的
feature消息; - 在自己发出 verack 之后,不得再发送
feature消息。
此外应当忽略 version 之后、verack 之前收到的未知消息;可以忽略 verack 之后收到的 feature 消息;也可以断开在 verack 之后发送 feature 消息的对等节点。
基于本 BIP 的功能规范,必须禁止:对未曾用 feature 消息表明支持该功能的对等节点,在 verack 之后发送该功能引入的消息。
4.2 feature 消息格式
其载荷恰好包含两项:
| 类型 | 名称 | 说明 |
|---|---|---|
| string | featureid |
功能的唯一标识 |
| byte-vector | featuredata |
该功能专属的配置数据 |
两者都用 CompactSize 前缀长度后接字节的方式编码,且只许最小化编码。具体约束:
featureid长度必须在 4 到 80 字节之间(含);应只含可打印 ASCII 字符(每字节 32–126);必须全局唯一。作为 BIP 发布的功能,其featureid应为获派的 BIP 编号(如 “BIP434”),或基于编号加后缀(如 “BIP434v2” 表示版本、 “BIP434.3” 表示该 BIP 的第 3 部分);尚无编号的实验功能必须另选唯一标识,如开发仓库的 URL 或某段更长引用的 sha256 摘要。featuredata长度不得超过 512 字节;该字段不可省略,不需要数据时也要给出空向量(即 CompactSize 的 0)。其字节如何解释,由各功能自己的规范定义。
实现方必须忽略自己不支持的 featureid(前提是载荷符合上述格式);若载荷根本无法正确解析(含缺失或多余数据),即使不认识该 featureid,也可以断开对方。
与 BIP-324 的衔接:同时实现两者的节点,必须把 verack 之前收到的、一字节 message_type 等于 37 的消息当作 feature 消息处理。
4.3 协商时序与三种模式
原文推荐:收到对方的 version 消息后,立即把所有 feature 消息连同 verack 一并发出去;收到对方的 verack 后,立即做协商计算。这样实现简单,也不会引入交互式协商的额外延迟。
功能规范可按需选用三种模式:
- 功能广告:无条件发送
feature通告,无条件接受该功能的相关消息,但只有对方也发了该功能的feature消息时才向其发送。适合多为新增消息、且实现可能只发不收或只收不发的简单功能,原文以 BIP-35 为例。 - 功能协调:无条件发送通告;对方发了相同(或兼容)的通告才对该对等节点启用功能;只有启用后才按功能规范收发消息或编码数据。适合 P2P 消息的数据编码升级,原文以 BIP-339、BIP-155 为例。
- 功能版本化:按偏好从高到低发送多个不兼容版本的通告(如 BIP434v3、BIP434v2、BIP434v1),双方再按原文为监听方与发起方分别给出的选择规则,从共同支持的版本中作出选择。适合对已部署协议做重大修改、短期内又希望保持向后兼容的情形。
4.4 为什么不用 verack 载荷
原文比较过另一条路:给 verack 加一个(featureid, featuredata)列表的载荷。放弃它的理由包括:要兼容预期 verack 无载荷的实现;逐条处理功能请求比一次性把全部配置读入内存再校验更顺手;限制可接受的消息载荷大小也不会顺带限制可接受的功能数量;以及生态已有逐条消息协商的经验、没有 verack 载荷协商的经验。
五、谁必须动
普通持币人:无任何直接变化,不涉及钱包与交易。
全节点软件开发者:实现本 BIP 需处理 70017 版本门槛、feature 消息的发送与接收时机、未知功能的忽略与非法载荷的处理;用 BIP-324 传输的还要识别消息类型 37。今后设计新 P2P 功能时,应改走 featureid 协商而非申请新版本号。原文给出的参考实现是 Bitcoin Core PR #35221。
全节点运行者(未升级):向后兼容方面原文写明:通告版本号低于 70017 的客户端与本变更完全兼容;通告 70017 以上但未实现本 BIP 的客户端,只要不在 version 与 verack 之间收到意外消息时断开对方,也完全兼容。
共识层:完全不涉及。这是节点间通信的协商机制,不改变区块与交易规则。
六、现在算不算数,以及一个常见误读
状态为 Complete(已完成):规范本身已经定稿,且原文给出了 Bitcoin Core 的参考实现(PR #35221)。需要注意 Complete 说的是这份文档的完成度;某个具体新功能是否能用,仍取决于各节点软件是否用 feature 消息通告并实现了那个 featureid。它带来的直接改变是:今后的 P2P 功能多了一条无需协调版本号的协商通道,老的版本号门槛做法(如 70016)并不因此失效。
常见误读:
“节点通告了 70017 以上版本,就等于支持此后所有新 P2P 功能。”
不对。原文特意指出新机制的好处之一,正是“支持某个新功能不再意味着同时支持此前所有功能”:版本号只表明会说 feature 这套协商语言,具体支持哪些功能要看逐个 featureid 的通告;不认识的 featureid 必须忽略,而不是默认对方全都会。
七、延伸
- 阅读版:https://bips.dev/434
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0434.md
- 相关:BIP-130 sendheaders、BIP-155 addrv2、BIP-324 v2 加密传输、BIP-339 wtxid-relay
- 仓库总目录:https://github.com/bitcoin/bips
