闪电付款失败时,洋葱错误码为什么故意不说破位置 图 1
闪电付款失败时,洋葱错误码为什么故意不说破位置 · 图 1

一张洋葱,一条“已读不回”的路

闪电付款把路径信息裹成多层加密的洋葱:每个节点只撕开自己那层,看到“下一跳是谁”,不知道整条路径的全貌。当某个节点无法继续转发时,它必须把失败消息送回付款人——问题是:回信的路途要穿过所有它不想暴露的节点,而每一个中间节点都不该从回信里推断“原来付款走的是我”。协议对失败消息的处理方式和错误码设计,是一场围绕“知道到哪,不许知道是谁”的精密权衡。

闪电付款失败时,洋葱错误码为什么故意不说破位置 图 2
闪电付款失败时,洋葱错误码为什么故意不说破位置 · 图 2

标志位:四个比特讲完失败性质

失败消息的 failure_code 高字节被设计成一组标志位:0x8000 标记洋葱本身解析失败;0x4000 区分永久失败与临时失败;0x2000 标记问题出在节点而非某条通道;0x1000 标记“违反了通道转发参数”,并会附上一条更新后的通道参数供重算。组合出的常见码各有语义:临时性节点故障提示稍后重试,永久性节点故障、节点特性缺失、通道永久性故障意味着换路而非重试,未知下一跳则暴露出路由图的某个入口已失效。对端收到 onion 相关解析错误时,回信还会带上 onion 哈希,帮助定位是哪一层的封装出了错。

为什么付款人看到的总是“一团雾”

协议为失败消息做了专门加扰:失败类型在回传途中被统一压缩表述,目的是限制中间节点从错误细节推断自己在路径中的位置。于是实际体验是:钱包界面显示一句泛化的失败描述,有时连“路由失败”和“通道容量不足”都不易区分。这不是软件偷懒,而是隐私设计的一部分——失败信息越少被用来做相关性指纹,通道的图论关系就越难被外部测绘者拼出来。

排查清单:付款失败时先看什么

  • 金额与费率:检查发票要求的路由费、超时参数与通道限额是否匹配。
  • 容量方向:付款方向可用余额不足会表现为路径类错误,和通道状态直接相关。
  • 临时失败:换一条路径或稍后重试;带更新标志的失败则说明该通道参数已变,重试前钱包会刷新图数据。
  • 永久失败:重试同一路线没有意义,应请求收款方提供新的路由信息。

无论哪种失败,只要收款人没有出示支付证据,已锁定的 HTLC 都会在超时后沿原路退回——超时退款本身就是洋葱网络对付款人的最终安全网。本文仅提供诊断参考,不构成投资建议。

把错误码翻译成行动

对运行钱包与路由节点的读者,实用的一张对照表是:收到 UPDATE 标志的错误,说明路径里某个通道更新了容量、手续费或超时参数,你的图数据库应当先吸收这份更新再重试,这是唯一“错误消息自带修复数据”的类别;临时节点与临时通道失败适合原路或换路各试一次,仍失败就冷却几分钟;带 PERM 标志的失败里,节点特性缺失与未知下一跳通常指向图数据过期,可请求收款方刷新路由信息;而 BADONION 一族基本只说明 onion 构造本身有缺陷,应当检查软件版本而非网络。至于隐私侧的提醒:反复向同一收款方尝试不同路径、又仔细记录每次失败类别的行为,会被收款端当成探测信号。付款方最健康的姿势是:默认信任钱包的自动重试与图刷新策略,把人工干预留给“同一笔发票多次失败”这种真正需要换路径策略或联系对方的场景,让失败码回归它设计的本意——给协议看的信号,而不是给对手看的指纹。