闪电节点不肯转发:LND 时间锁预算 max-cltv-expiry 的账本 图 1
闪电节点不肯转发:LND 时间锁预算 max-cltv-expiry 的账本 · 图 1

闪电节点收到一笔转发请求,路由计算一切正常、通道余额也够用,最后却被自己拒之门外,日志里指向一个不太起眼的参数:转发时间锁上限。闪电支付靠“每跳多加一段区块倒计时”来保护转发者,而累计倒计时的总长,恰恰是路由能否成立的硬边界——这一篇把 LND 里管这件事的预算参数拆开看清楚。

时间锁为什么会累加

一笔跨多跳的付款,每一段通道都对下一跳承诺:“如果出问题,我有至少 N 个区块的时间在链上抢回资金。”这份安全余量就是转发方设置的 CLTV 增量,沿路径逐跳累加。对单个节点来说,增量越大越安全;对整条路径来说,累加值却变成了付款方必须接受的锁定深度——你的 HTLC 到期块高度等于当前高度加上一整串增量之和。风险也在这里:如果没人管上限,一个愿意押上自己资金的对手方,可以让经过你节点的 HTLC 把时间锁设到天文数字,你的通道资金就被无期限地占住——这正是转发上限存在的动机:宁可拒绝转发,也不接受被拉长的锁定。

LND 的默认账本:2016 个区块

LND 源码对这一预算的注释写得直白:默认的最大转发出站时间锁是 2016,按平均出块节奏约合两周;这个数字的推导是“最大跳数二十、默认增量 40,再留出余量以兼容其他实现与早期默认增量为 144 的历史版本”。换句话说,路径上所有增量之和(加上最后一跳收款方要求的增量)超过这个预算,你的节点就不会接受这笔转发。想改也有旋钮:守护进程的 max-cltv-expiry 配置项就是它,单位为区块数——但把它调大并不白得收益,等于宣布自己愿意把资金押得更久,路径可用性上升的另一面是占用周期的拉长。

增量自身的上下界

预算之外,单个增量的取值也有规矩。LND 对通道更新里可设置的转发增量、以及发票要求的最终增量统一设界:下界是 18 个区块——这个数字是为了绕开一个互操作陷阱:按 BOLT 11 的规定,发票里没写明增量时接收方应假定一个很小的默认值,一旦新旧节点对默认值预期不一致,收款方会永远觉得时间锁不够。LND 的对策是创建发票时永远显式写入增量,于是自己保有随时上调下界的空间,而不必担心把旧对手方甩在身后。上界则是 65535——CLTV 增量字段的表示上限,任何“把增量设成一百万”的操作都会被直接拒绝。

排障视角的三句话

给运维场景留下可直接使用的判断:第一,节点以“时间锁超限”为由拒绝转发时,先怀疑路径质量而不是故障——长路径或个别设置了激进增量的通道本就难走,缩短路径或调整自己对外公告的增量比改预算参数更对症。第二,大额付款“明明有余额却支付失败”时,检查发票声明的增量与各跳增量之和是否已逼近收款方的容忍范围,这类失败在参数层面就有确定答案。第三,改任何一侧的数都要想清楚另一侧的账:转发上限、公告增量、发票增量三者在协议上互相咬合,调对一个是优化,调错一次是全站付款集体改道。

风险提示:本文为闪电网络节点参数机制解读,具体数值与命令以你所部署软件版本的官方文档与源码为准;运行路由节点涉及资金占用与费率风险,不构成投资建议。