付款前先问路:LND queryroutes 的路由预演与三种排障用法 图 1
付款前先问路:LND queryroutes 的路由预演与三种排障用法 · 图 1

闪电付款失败最常见的解释是”找不到路径”,但 LND 在真正发起支付之前,允许你把这个问题先单独拿出来问一次:queryroutes。它在 v0.19.0-beta 源码 cmd/commands/cmd_payments.go 里的定位一句话——“查询一条到目的地的潜在路径,要求该路径对含费用的金额有足够的流量”。这是一次纯本地的路由预演:不动钱、不惊动对端、不建 HTLC,只在内存里的通道图上做一次最短路搜索。

参数面

核心参数两个:dest 填目的地节点的 33 字节十六进制公钥,amt 填要送的聪数。围绕它们的是预演视角的旋钮。fee_limitfee_limit_percent 给路由费用设上限——前者按聪,后者按付款金额百分比,搜索时超预算的路径直接剪掉;这决定了”贵到离谱的绕路”会不会出现在结果里。final_cltv_delta 指定最后一跳解锁时间锁的块数,源码注释特别提示:路径含遮蔽路径(blinded path)时不要设它,因为接收方已经把该项算进 blinded_cltv。use_mc 让搜索借用 mission control——LND 的失败概率记录器——把历史上反复失败的钱道在图搜索里降权。outgoing_chan_id 锁定首跳必须走某条通道,做定向诊断时用。

付款前先问路:LND queryroutes 的路由预演与三种排障用法 图 2
付款前先问路:LND queryroutes 的路由预演与三种排障用法 · 图 2

返回什么、意味着什么

成功时返回若干条候选路由:每条列出途经节点、各跳的费用与 CLTV 增量、总重量。它回答的是一个静态问题——“按当前通道图的账面余额,这多少钱理论上走得到吗,走得到有几条路”。它不回答动态问题:余额是图公告里的公开额度,不含对方通道此刻被别笔在途 HTLC 占掉的额度(私有通道的容量细节也不会进公开图),所以预演成功不等于支付必成,预演失败却相当可靠地说明公开图上此刻无路。

三个值得单独跑的故障场景

第一,“对方明明在线为什么收不到”。先用 describegraph 或资源管理器确认目标节点存在且通道已公告,再 queryroutes:若返回”no routes found”,问题大概率在图可见性——通道未公告、容量公告为零、或金额超过路径上任一跳的 in/out 上限。第二,“金额调多大还能通”。用二分式的 amt 重跑,能粗测出到该目的地的最大可送金额,定位是哪一跳的额度卡住——返回路径里各跳容量就是最好的证词。第三,费用审计。对同一目的地跑 amt 相同、fee_limit 递减的几轮,能看出路由费率的悬崖在哪,日常配置 max_fee_rate 之类的支付默认值时就有依据,而不是凭感觉喊”闪电费用太贵”。

与支付路径的分界线

真正付款走 sendpayment/sendtoroute,那是一条带状态机的流水线:建 HTLC、逐跳锁定、失败换路、mission control 记分。queryroutes 是流水线上线前的图纸检查——它甚至不会告诉你所选路径的接收方能不能真正落账(不验支付密钥、不占额度)。把它当排障工具而不是支付前置步骤,是它设计上最清楚的红线;对普通钱包用户,这一切都发生在”点一下发送”的背后,只有当发送反复报路由类错误时,懂这张图纸的人才知道下一步该查容量、公告还是费用上限。

一组可以照做的实验

先在 regtest 或测试网搭两个节点、开一条小额通道,然后跑 queryroutes 把目的地公钥与一个刚好等于通道余额的 amt 递进去——路径应声而出,各跳容量与费用一目了然;把 amt 再加一聪,同样的命令会翻脸报无路可走,这条边界就是通道容量的公开投影。接着把费用上限用 fee_limit 压到低于路径费用,看它如何用另一类拒绝把”有路但太贵”与”无路”区分开。三组实验做完,你对路由系统的理解就从”能不能付”升级成了”卡在哪一跳、多少钱封顶”,日后生产环境里看付款失败报告,读的也是同样三个维度:连通性、容量、费用。

风险提示:本文描述闪电路由诊断工具的机制,不构成任何投资建议;通道容量与费用随网络状态实时变化,命令结论仅代表执行时刻的图快照。