孤儿交易:还没资格进池的孩子
内存池有条铁律:交易引用的输入必须已经存在——要么在链上,要么已在池内。一笔交易迟到了,节点先收着它的身份证(wtxid),把本体挂进”孤儿库”等父母。旧实现的管理方式很朴素:限制孤儿数量(默认 100,可用 maxorphantx 调),数量满了就整批丢。问题在于攻击者控制成本的方式变过:与其塞满数量,不如用输入极多的大交易喂你——每笔孤儿都占内存与解析成本,数量上限却感觉不到体积。

v30 重写的账本
v30 发布说明记录了这次重设计:孤儿库不再限制唯一交易数量,改记两本账。第一本按”条目数加每笔唯一交易输入数除以十”计量,总额不超过 3000;第二本按体积计量,唯一交易的总权重不超过 404000 权重单位乘以对端数。同时每个唯一交易对每个对端只存一份,重复推送不再造成重复存储。maxorphantx 就此作废——配置了它的节点应当删掉这一项,继续留着会在未来版本直接报错。数字变化之外还有个行为改进:节点会向所有宣告过该孤儿的对端同时追要父交易,不再只问第一个。
这对”交易卡住”排障意味着什么
普通用户最常撞上孤儿的地方是链条式付款:你的交易花了一笔还没被节点看到的新收入。过去常见剧本是孩子先到、父母缺席,孩子进孤儿库,父母却从别的路径进了池——旧版处理这种”迟到父母已入池”的场景偶有丢包,v30 的包逻辑明确了更宽拓扑的处理。排障动作依旧三段式:先在节点上 getmempoolentry 查交易是否在本节点池内;查不到就向你的节点要孤儿状态与 getblockfrompeer 类手动补块手段;若整条链是别人构造的复杂包,submitpackage 直送整包往往胜过零散广播。日志里 orphan 相关行的出现频率本身就是信号:持续大量孤儿意味着上游中继有问题,而不是你的钱包坏了。
矿池与服务的对照面
对批量收单系统,孤儿率是健康指标:突发孤儿飙升常见于两类原因——上游节点重启清空了依赖、或交易依赖被替换导致子交易悬空。处置顺序是重提交依赖链而不是重提交孤儿;v30 的 submitpackage 放宽(不再要求包内包含全部未确认父)让”补交缺失父”的操作窗口更宽。写自动化时记得兼容过渡:同一版本窗口内,新旧孤儿行为在发布说明里都有行为变化注记。
一句收尾
孤儿库是个小模块,却浓缩了比特币节点的生存哲学:任何”先欠着等补齐”的功能都必须让欠账成本可计量,否则善意会被滥用成攻击面。v30 的改写没有发明新机制,只是把那本账从”数人头”改成”量体积”——大多数协议防御走到最后都是这种朴素修正。
一个值得养成的观测习惯
v30 之后,孤儿库的两本账都可以通过日志与调试参数观测:体积账与条目账接近上限时,新孤儿会被静默丢弃——你的节点”收到了但没存”,表现为用户侧交易莫名失踪但对端日志毫无异常。运维视角的对照信号是连接质量:孤儿率高往往伴随高丢包或上游节点频繁轮换,先修中继路径再怀疑业务逻辑。另一个免费信号来自新行为:节点会向宣告过孤儿的每个对端索取缺失父交易,对端里谁一直没响应,谁就是你的可疑跳点。把它记进监控面板,比事后翻一小时日志高效得多。
风险提示:交易依赖与包提交涉及专业操作,请以官方 RPC 文档与拒绝原因字段为准;本文不构成任何付款延迟承诺或投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。