内存池压力退潮要多久:ROLLING_FEE_HALFLIFE 与 mempoolminfee 的十二小时半衰
当内存池被高费交易塞满时,节点会悄悄抬高自己愿意接收新交易的下限费率,getmempoolinfo 里那个会浮动的 mempoolminfee 就是这个门槛。很多人关心它的另一头:压力过去了,这个门槛会不会立刻掉下来?答案藏在源码一个常量里——ROLLING_FEE_HALFLIFE,取值为 12 小时。它决定的是一个”衰减半衰期”,不是即时开关。本文全部以 Bitcoin Core v31.0 源码为准。
这个下限是怎么冒出来的
内存池有个容量预算(由 maxmempool 决定,默认三百兆字节量级)。当占用逼近上限、又需要为新交易腾地方时,节点会把当前正被考虑移除的交易里最高的那个费率记成一个”滚动下限”(rollingMinimumFeeRate),从此低于它的交易就先不收了——否则收进来也会被立刻挤掉,白白浪费验证。这个下限在有过打包活动之后才被激活:源码 CTxMemPool::GetMinFee 里有个条件,如果自上次下限抬升以来还没有出过块、或者下限本来就是零,就直接返回基础值,不做衰减。
十二小时半衰:越空掉得越快
真正有意思的是退潮的方式。GetMinFee 每次被查询、且距上次更新超过十秒时,会按经过的时间对这个下限做一次指数衰减:用 2 的幂次去除。公式里的关键就是半衰期 ROLLING_FEE_HALFLIFE,在 src/txmempool.h 里定义为 60 * 60 * 12,即 43200 秒(十二小时)。含义是:什么都不发生的情况下,门槛大约每过十二小时降低一半。更妙的是它还会加速——源码会看内存池实际占用了预算的多少:占用低于四分之一时,半衰期除以 4(变成三小时就降一半);低于二分之一时除以 2(六小时)。也就是说,池子越空,门槛回落得越快,这符合”压力已经解除就尽快恢复正常接单”的直觉。
归零的临界点
衰减不是无限拖着一条尾巴。源码里有个终点判定:一旦滚动下限掉到”增量中继费率”(incrementalrelayfee)的一半以下,就直接归零并返回零,等于宣布下限解除、恢复正常接单。所以 mempoolminfee 的回落是一条先慢(指数)后突零(阈值)的曲线,不会长时间挂着一点点残余门槛。
对观察者的实际含义
如果你用 getmempoolinfo 盯着 mempoolminfee 做运维判断,需要知道它读到的就是这个衰减函数的实时输出:同一台节点,隔一段时间查,数值会因为时间流逝而自发变小,即使内存池内容没怎么变。反过来说,看到 mempoolminfee 迟迟不降,往往意味着池子里仍有过半占用,或者刚有过块把下限重新抬高过。把它和 usage、maxmempool、total_out 一起看,比单看一个数字更能还原压力全貌。
常见误区
第一,把 mempoolminfee 和固定的 minrelaytxfee(默认中继下限)搞混:后者是你手动配的静态地板,前者是随压力上下浮动的动态门。第二,以为门槛下降意味着”我的低费交易马上会被收”:还得看衰减后的当前值和交易自身的费率、依赖是否达标。第三,把十二小时当”必须等满十二小时才能降”:那是半衰期,不是倒计时,压力越轻降得越快,且查询时刻不同读到的值就不同。把这些区分开,才不会被一个会呼吸的数字带偏。
和钱包默认值接上头
这条动态下限还解释了钱包侧一个常见困惑:为什么同一张低费交易在 A 节点能进池、在 B 节点被拒。每台节点的 mempoolminfee 是各自内存池压力的函数——A 机器池子空闲、下限早已衰减归零,B 机器刚经历拥堵、下限还挂在高位。钱包把造好的交易广播给哪台节点、节点又按谁的状态收货,结果自然不同。想复现”别人家节点能收”的判断,最可靠的做法是调用 testmempoolaccept 让目标节点亲口回答,而不是拿自己机器上看到的门槛外推全网。写自动化脚本时,把 mempoolminfee、incrementalrelayfee 与提交时刻一并存档,事后复盘才不会把两次不同压力的快照混成一条时间线。
风险提示:本文为内存池机制科普,具体参数与衰减规则以 Bitcoin Core 当前版本源码为准,可能随版本调整;本文不构成费率高低或确认快慢的承诺,亦不构成投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。