钱包造交易时报了一句和依赖有关的错误,节点日志却一切正常——这类悬案的主角往往是 -walletrejectlongchains。v31.0 源码 src/wallet/init.cpp 给它的帮助文本只有一句:Wallet will not create transactions that violate mempool chain limits,默认开启(src/wallet/wallet.h 的常量 DEFAULT_WALLET_REJECT_LONG_CHAINS 取真),并且被标注为仅调试用途的钱包参数。要理解它在防什么,得先把排队纪律和选币策略分开。
一、两套限制和一套仍然保守的选币
节点内存池对”带依赖的交易”管得一直很严。v31.0 的 src/policy/policy.h 里仍然留着两个旧常量:DEFAULT_ANCESTOR_LIMIT 与 DEFAULT_DESCENDANT_LIMIT,都等于二十五,簇限制一族参数(-limitclustercount 等)默认阈值取 64;src/init.cpp 参数表里 -limitancestorcount 与 -limitdescendantcount 的说明文字已经明确写着:这条规则已被簇限制接替,现在只被钱包用于选币。也就是说,钱包在拼一笔新交易挑未确认零钱时,仍会按祖先不超过二十五条的保守口径筛选——不是因为新节点还按这个数记账,而是为了让造出来的单子能顺利通过沿途旧节点的闸门。这道闸门做的取舍很直白:宁可当场报选币失败,也不造依赖链太深、传播性存疑的交易。
二、报错出现时按三步定位
第一步,分清两类失败:错误文本指向依赖链限制,才轮到本参数;只报费率不足,那是另一回事。第二步,核对余额构成——给 listunspent 加上确认数下限,如果只数成熟输出就够付款,说明可用资金没有真耗尽,钱包只是在保守筛选里先试了深链那一层。深链零钱的典型来历,是某笔在内存池滞留很久、被反复替换的低费交易的找零:每被替换一次,它与祖先们的依赖结构就更复杂一分。第三步,才决定要不要动参数。
临时放开的正确姿势是:在确认打包方可以一次性处理整条依赖链的前提下(例如你自己控制出块,或对接方明确支持包形式提交),重启时加 walletrejectlongchains=0,让选币器跳出祖先计数限制,把整条链上的零钱带进同一笔新交易。发送成功、交易被受理后,把参数收回默认值。长期开着它,等于让你的钱包经常制造传播性存疑的单子。
三、三个容易混淆的近邻
第一,它和 -limitancestorcount 互不继承:后者管的是你这台节点怎么给交易记账排名,前者管钱包怎么挑钱;放开选币闸门不会解除任何入池检查。第二,它和加急操作不冲突:利用”后代会随祖先一起被考虑”的规则做家族加急时,只要整族没撞上限制就照常可用,本参数只在选币阶段说话;它开口的时机也仅限选币触及未确认输入的场合——纯靠已确认余额就能付清的交易,和这个参数毫无关系。第三,一个常被读反的推论:默认开启意味着拥塞期你的钱包更容易干脆地拒绝造单,这通常被误读为节点故障。判断依据永远是先取交易级证据(比如看某笔零钱在内存池里的真实祖先计数),再决定动哪一侧。
再做两件廉价的核验。对任何疑似深链的零钱,把它的交易编号交给 getmempoolancestors,整条依赖链直接列出来;给 getrawmempool 加 verbose 参数更省事——每笔交易的 ancestorcount 字段就是选币闸门同一把尺子量出的读数。如果这个数字已经贴近二十五,说明即便这次没报错,下一次凑钱也会被闸门拦下;与其反复琢磨参数,不如挑一个拥塞较轻的窗口,把整条链用一笔足率交易一次合并掉——合并是一次性的,参数闸门则是长期纪律。
压缩成一句话:它不是资金开关、不是费率开关,而是”钱包敢不敢用深链零钱”的开关,默认不敢。理解这一点,两种最常见的误判——把保守选币当故障、把放开闸门当加速魔法——就都能提前排除。涉及真金白银的操作,任何参数改动都应与备份和小额试发配套进行;本文只讲机制,不构成任何投资或操作建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。