协议演进 / BIP/比特币改进提案 / BIP-133
BIP-133
新增 feefilter 消息,让节点提前告诉对等节点:低于某个费率的交易不要再发 inv,以减少低费交易的无效公告与请求。本 BIP 目前处于已部署状态。
一、档案卡
| 编号 | BIP-133 |
|---|---|
| 标题 | feefilter message |
| 作者 | Alex Morcos <[email protected]> |
| 指定日期 | 2016-02-13 |
| 层级 | Peer Services(对等服务) |
| 类型 | Specification(规范类) |
| 状态 | Deployed(已部署) |
| 阅读版 | https://bips.dev/133 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki |
二、放在哪一族
对等网络消息与交易转发策略族。BIP-133 不改交易格式,也不改共识,只在节点之间多加一种“事先打招呼”的消息,让转发更省带宽、省内存池资源。
它与几条既有机制是配合关系,而不是替代关系:
有限内存池:Bitcoin Core 0.12 引入的思路,原文以此为背景——节点只保留自己愿意处理的交易,低费、不会被挖出的交易不无限堆积。
拒绝过滤器(reject filter):帮助节点避免反复请求同一笔刚因费不足被拒的交易;但它每个区块后重置,管不了第一次请求。
Bloom 过滤器:SPV 客户端用来只接收与自己相关的交易;原文明确 feefilter 与它叠加生效,两个过滤器都要通过才转发。
理解这一族的关键是分清“公告”和“本体”:inv 只是“我有这笔交易”的公告,getdata 才是去索取本体。BIP-133 过滤的是公告环节。
三、它要解决什么
3.1 有限内存池挡不住无效公告
内存池有限之后,节点有了自我保护:低费垃圾交易不会无限占用资源,拒绝过滤器也能减少重复索取。
但原文指出两个漏洞:
- 拒绝过滤器每出一个区块就重置,时间跨度较长的 inv 会让同一笔交易被重新请求,且第一次请求根本拦不住;
- 每一笔被内存池接受的交易,其 inv 至少要在每个对等连接上发送或接收一次,发送方无从知道:这条 inv 发过去,对方会不会因为费太低而根本不会用 getdata 来取。
结果是带宽和处理都花在了注定被对方丢弃的交易上。
3.2 先声明门槛,再决定发不发
思路很直接:如果接收方先把自己的最低费率告诉发送方,发送方在发 inv 之前就能算出这笔交易的费率够不够门槛,不够就不发。
feefilter 要补的就是这个“事前声明”,而不是事后拒绝。
四、规则本身
4.1 消息格式
feefilter 是一条对等网络消息,pchCommand 为 “feefilter”,内容是一个 int64_t,数值按聪每千字节(satoshis per kilobyte)解释,表示费率门槛。
功能发现靠协议版本:protocol version >= 70013 才视为支持该特性。
4.2 收到之后怎么做
收到 feefilter 的节点,可以(permitted)但并非必须(not required)按它过滤交易 inv:费率低于消息所给费率的交易,不向该对等节点发送 inv。
注意三点原文细节:
- 这是按连接生效的门槛:同一个节点对不同对等节点,面对的门槛可以不同;
- 由 mempool 消息生成的 inv 同样受已存在的费过滤约束;
- 若 SPV 客户端同时装了 bloom 过滤器又发了 feefilter,交易必须同时通过两个过滤器才会被转发。
4.3 注意事项
原文单列了几条考虑:
传播效率:一般而言,不被某节点内存池接受的交易本来也不会被它转发,本机制过滤的正是这类交易,预期不损害整体传播;只有少数边缘情形——某节点内存池最低费实际低于对等节点所知的过滤值——落在两者之间的费率会被新拦住。
白名单对等节点:若设置了 “-whitelistforcerelay”,不对白名单对等节点发送 feefilter,因为这类连接本就打算转发哪怕未进内存池的交易。
隐私:广播自己的内存池最低费,本身会泄露可识别信息,有去匿名化担忧。实现的做法是把广播的过滤值量化并加入少量随机性,且向不同对等节点在各自随机错开的时间发送。
优先交易:若节点用 prioritisetransaction 接受实际费率可能低于内存池最低费的交易,应考虑关闭费过滤,以免错过任何 txid。
4.4 实现指向
原文正文很短,实现一节只给一个链接:Bitcoin Core 的合并请求 #7542。
这也符合它作为对等服务规范的定位:判断一条实现是否合规,看的是它是否按本节的消息格式与过滤语义行事,而不是另有一套可执行规格。
还要注意措辞的强度:规范对接收方用的是“被允许过滤”,对发送方也没有规定必须何时、向谁发送。
发不发、何时发,在原文框架下留给实现自己决定,隐私一节的随机化与错时做法正是实现层面的安排。
五、谁必须动
普通持币人:无须做任何事。这不是钱包格式或地址规则,用不用 feefilter 对收款、付款没有直接影响。
钱包开发者:一般钱包不直接实现对等协议,可不处理。做 SPV 客户端的需知道:feefilter 与 bloom 过滤器叠加,两者都通过才转发。
全节点与对等服务实现者:这是主要实现方。发送方要能发出 feefilter 并按随机化、错时等隐私做法处理数值;接收方要能在发 inv 前按对方门槛过滤,且实现上是“可以过滤”,不是强制丢弃的共识义务。
共识层:不动。本 BIP 不改变区块或交易有效性,费率门槛从来都是节点本地策略,不是共识规则。
六、现在算不算数,以及一个常见误读
状态为 Deployed(已部署),指这条消息已作为对等服务规范落地到实现中。原文给出的实现指向 Bitcoin Core 的相关合并请求。不升级的旧客户端按原文仍完全兼容、可以互通;实现本 BIP 的客户端也可以选择一条 feefilter 都不发。
它算数的方式是“省事”,不是“定罪”:低于门槛的交易不是无效,只是不会被公告给这个对等节点,它仍可能从别的路径传播、进别的节点的内存池。
常见误读:
“feefilter 给全网定了一个最低手续费。”
不对。它没有全网统一值,每个节点发给对等节点的是自己的门槛,数值还经过量化与随机化处理;收到的一方也只是被允许过滤,并非被强制执行某个网络级标准。
七、延伸
- 阅读版:https://bips.dev/133
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki
- 相关:BIP-133 本身属对等服务层消息规范,与内存池与转发策略配合使用
- 仓库总目录:https://github.com/bitcoin/bips
