一次替换最多动一百簇:RBF 规则五里的 MAX_REPLACEMENT_CANDIDATES
费换费(RBF)让一笔未确认交易能被更高费的新版本顶替,看起来只是”换一笔”,但节点背后要做一串核对:新交易和哪些在池交易冲突、要把多少条依赖链一起请出去、账算完是不是真的更优。为防有人用一笔”巨型冲突”交易把节点的计算量瞬间撑爆,源码给替换能触及的规模钉了一个数:一百。这个一百来自 MAX_REPLACEMENT_CANDIDATES 常量。本文全部以 Bitcoin Core v31.0 源码为准。
冲突不是零散交易,而是一簇一簇
从 v31.0 起,内存池改成了”簇”(cluster)设计:互相有父子依赖的交易被归成一簇,替换、驱逐、出块选排都以簇为最小单位。所以当一笔新交易想顶替旧交易时,它冲突的不是一笔孤立交易,而是被冲突交易所在的整簇——把这条依赖链上的所有交易一起纳入处理。RBF 的第五条规则(Rule #5)正是给这件事封顶:一笔替换所能直接冲突的”不同簇”的数量不能超过一百。源码里这一步在收集完冲突项之后调用 GetUniqueClusterCount 数一下到底涉及多少个不同的簇,一旦超过常量值,替换直接被拒。
一百写在哪个文件
在 src/policy/rbf.h 里,MAX_REPLACEMENT_CANDIDATES 定义为 100,注释原话是”一次 RBF 所能影响的唯一簇的最大数量”。对应的拒绝理由在 src/policy/rbf.cpp 里拼装成一条字符串:“rejecting replacement …; too many conflicting clusters”(拒绝替换,冲突簇过多)。如果你排查一笔高费交易为什么进不了内存池、testmempoolaccept 或 submitpackage 返回的 reject-reason 出现类似措辞,那多半就是你这一笔一次性撞上了太多互相独立的依赖簇。
为什么要限”簇”而不是限”交易数”
关键在于成本形态。真正吃算力的不是”顶掉一笔旧交易”,而是把每个被卷入的簇重新整理、把它们的后代交易重新算费、重新排布——每多一个簇,这套重算就多一层。旧版本内存池曾以”直接冲突的交易数”作限制口径,但簇设计下,一笔交易可能牵出一整条链,用”簇”计量才贴近真实处理量。注释里还特别说明:这个数字是对”直接被冲突的簇数”设的界,实际被重新线性化处理的簇数可能因簇分裂而略多,但量级仍受这条规则约束。
现场怎么用
普通用户几乎撞不到这条线:日常 RBF 一般只顶掉自己那一条依赖链,涉及的簇远不到一百。真正会撞上的,多是精心构造的压力测试、或某些把大量独立小额依赖聚到一笔上的合约场景。测试套件里也专门有 mempool_package_rbf.py、mempool_truc.py 用常量 100 去构造”正好一百个簇”和”超过一百个簇”的边界用例,验证规则按预期放行与拒绝。读这些测试文件是理解这条规则触发点的最快方式。
常见误区
第一,把这一百当成”一笔交易最多替换一百笔交易”:它数的是”簇”这一独立依赖分组的数量,一个簇里可能有很多笔,一百簇能牵连远超一百笔。第二,把它和包(package)的大小上限混为一谈:包是给”你一次提交的一组交易”封顶,而这条规则是给”你的替换会波及多少既有簇”封顶,一个管入口、一个管连锁。第三,以为提高这个常量就能随便做大扫除:它是防消耗攻击的护栏,真要把成千上万簇一次清空,该考虑的是拆成多笔、分批替换。理解它,就理解了 RBF 不只是一句”加钱重发”,而是一套被明确限了连锁规模的记账操作。
风险提示:本文为内存池与替换机制科普,常量与规则以 Bitcoin Core 当前版本源码为准,可能随版本调整;不构成交易能否被替换或确认快慢的承诺,亦不构成投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。