协议演进 / 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 的节点:

此外应当忽略 version 之后、verack 之前收到的未知消息;可以忽略 verack 之后收到的 feature 消息;也可以断开在 verack 之后发送 feature 消息的对等节点。

基于本 BIP 的功能规范,必须禁止:对未曾用 feature 消息表明支持该功能的对等节点,在 verack 之后发送该功能引入的消息。

4.2 feature 消息格式

其载荷恰好包含两项:

类型 名称 说明
string featureid 功能的唯一标识
byte-vector featuredata 该功能专属的配置数据

两者都用 CompactSize 前缀长度后接字节的方式编码,且只许最小化编码。具体约束:

实现方必须忽略自己不支持的 featureid(前提是载荷符合上述格式);若载荷根本无法正确解析(含缺失或多余数据),即使不认识该 featureid,也可以断开对方。

与 BIP-324 的衔接:同时实现两者的节点,必须把 verack 之前收到的、一字节 message_type 等于 37 的消息当作 feature 消息处理。

4.3 协商时序与三种模式

原文推荐:收到对方的 version 消息后,立即把所有 feature 消息连同 verack 一并发出去;收到对方的 verack 后,立即做协商计算。这样实现简单,也不会引入交互式协商的额外延迟。

功能规范可按需选用三种模式:

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 必须忽略,而不是默认对方全都会。

七、延伸

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