作者:Bastien Teinturier

来源:<https://github.com/t-bast/lightn ing-docs/blob/master/pinning-attacks.md>

本文总结了关于交易钉死攻击(pinning attacks)的讨论(见讨论 1讨论 2)以及缓解此类攻击的提议。

威胁模型

在比特币网络中,“没有 ’全局交易池‘ 这样的东西”(ZmnSCPxj 语)。因此,比特币不会试图执行交易池聚合或解决交易池 “脑裂问题”(译者注:指因为各种原因而在两个应当一致的数据集中出现不一致)。通过在区块中确认交易池内的部分交易,脑裂问题逐步得到缓解:无论是现在还是将来,这都是唯一可用的基于共识执行的数据结构。

头脑聪明、资金充裕的攻击者能够操纵交易池,随心所欲地制造脑裂,想持续多久都可以。我们必须保证系统可以在攻击者确实能够分裂网络交易池的设想下正常运作,比方说,当 N% 的矿工的交易池内包含交易 txA 时,则其余矿工的交易池内均包含与 txA 相矛盾的 txB。

闪电网络以及其它链下合约必须确保用户不会因为交易池分裂而承受经济损失。

针对闪电网络的攻击

这个威胁模型中存在两类可能发生的攻击:针对 HTLC 交易的攻击和针对承诺交易的攻击。这两类攻击的目的都是窃取待处理的 HTLC(被广播的承诺交易中的 HTLC 输出),做法是利用路由节点让上游的 HTLC 超时,并在下游将这些 HTLC 收集上链。

(译者注:以下图为例,上游的攻击者在闪电通道中给了受害者一个 HTLC,但是在时间锁过期后,其中的资金就会被上游攻击者收回;而受害者给下游攻击者的、包含 HTLC 的承诺交易,则会被下游攻击者发到链上,并使用原像解锁、拿走;攻击的关键是阻止受害者在上游的 HTLC 超时之前获得原像,同时阻止他在下游的 HTLC 超时后发起链上交易收回自己在 HTLC 中的资金。这种阻止操作利用了网络中的节点的一些交易转发规则和限制。)

  Attacker -----------------------> Victim ----------------------------> Attacker
 (upstream)         ^                                    ^             (downstream)
                    |                                    |
                    |                                    |
     +---------------------------+          +------------------------+
     | HTLCs timed out off-chain |          | HTLCs claimed on-chain |
     +---------------------------+          +------------------------+
     

请注意这两类攻击无法窃取参与方的主要输出,只能窃取 HTLC。因此,我们常用的解决方案是限制承诺交易中待处理 HTLC 的数量,并限制这些 HTLC 的待处理比特币数量。现有的闪电网络实现已经支持用户配置这些限制。

这两类攻击同样无法窃取钱包里的资金,因为它们不转发付款。

针对 HTLC 的攻击

这类攻击在 HTLC 交易层面发挥作用。攻击者会制造以下交易池脑裂:

  • 所有矿工的交易池里都有一个 success 交易揭示获取 HTLC 资金的原像(即下游攻击者发起的交易)
  • 其余网络参与者的交易池里有一个超时交易(即受害者发起的、回收自己放在 HTLC 中的资金的交易)

攻击者会确保原像交易的费用足够低,致使原像交易滞留在交易池内得不到确认,直到上游通道能够在链下判定原像交易超时为止。(译者注:如果原像在上游的 HTLC 超时之前揭晓,受害者就可以获得上游攻击者的资金,即攻击失败。)

攻击者还可以为一个交易附上一条足够长的子交易链,以确保这笔交易在矿工的交易池里无法被替换(利用 BIP 125 的规则 5)。(译者注:因为下游攻击者转移 HTLC 资金的交易和受害者回收 HTLC 资金的交易,都以同一个 HTLC 为输入,所以在交易池内,它们互为替换交易;而根据 BIP 125 的规则,当一笔交易的 替换交易/子交易 数量触发某些限制后,就不能继续添加 替换交易/子交易,即无法继续替换。这即是钉死攻击的实质:阻止另一笔交易上链。)

(阻止交易被替换的)具体的做法是:

  • 在当前承诺交易格式(无锚点输出)下,强迫受害者广播其承诺交易,因为 HTLC 原像分支并未限制花费方式。
  • 在有锚点输出的情况下,要么使用与上述相同的解决方案,要么将输出添加至 HTLC-success 交易中。

受害者可以采用两种方法来抵御这类攻击:

  • 在上游 HTLC 超时之前获悉原像
  • 或让自己的超时交易得到确认

针对承诺交易的攻击

这类攻击在承诺交易层面发挥作用,因此会影响承诺交易中的所有 HTLC 输出。攻击者会制造交易池脑裂:

  • 所有矿工持有同一版本的承诺交易
  • 其余网络参与者持有另一版本的承诺交易

请注意这类攻击有多个变体:网络可以被任意分裂成 N 个集群,每个集群都持有一个不同版本的承诺交易。总的来说,这类攻击会造成相同的后果,我们应该找到通用解决方案。

攻击者会确保矿工交易池内承诺交易的费用足够低,致使承诺交易滞留在交易池内得不到确认,直到上游通道能够在链下判定承诺交易超时为止。

攻击者还可以确保矿工交易池内的承诺交易无法被替换:

  • 在当前承诺格式(无锚点输出)下,使用费用不低于受害者的最新承诺的承诺交易即可,因为受害者无法提高其承诺交易的费用。
  • 在有锚点输出的情况下,通过攻击者的锚点附加一条足够长的子交易链即可(BIP 125 的规则 5)。

受害者抵御这类攻击的唯一方法是通过某种方式让承诺交易得到确认。至于是哪个承诺交易得到确认并不重要:如果是已撤销承诺交易得到确认,受害者可以取走所有通道资金;如果是最新承诺交易得到确认,受害者必须取走资金(让 HTLC 超时)。

锚点输出

锚点输出提议虽然无法解决这类攻击,但它不会让情况变得更糟。关于详细信息,请参见前文。

由于该提议可以解决另一类攻击,我认为在当下实现它是有意义的(不论未来比特币会不会提供某种交易包转发策略,致使承诺交易发生任何变化)。

缓解措施

首先,我们要阐明的一点是:CPFP/carve-out 在这种情况下无法帮助我们。如果没有交易包转发策略,CPFP 无法将我们的有效交易一路传播至矿工的交易池。即使你通过某种方式获知矿工的交易池内有什么交易,想要使用 CPFP/carve-out 让这个交易得到确认(打破阻塞),你也无法将你通过 carve out 附加的子交易传播给矿工,因为你所在的网络区域的交易池内没有原交易,自然不会为你中继。

一种长期缓解措施是在比特币网络上部署某种交易包转发策略,确保我们能够发送一个包(“我们的有效交易 + 一个提高费用的子交易”)来替换攻击者的钉死交易(只要我们的包支付的费用足够高)。实现这一长期缓解措施并非易事,而且需要投入很多时间,因此我们将探索一些短期缓解措施。

免责声明:这些(巧妙的)想法大多不是我本人提出的。我只是尝试将它们进行汇总以推动讨论。

费用更新机制必须保留

当前的费用更新机制显然并不完善,因为预测未来是不可能的。但是,该机制确实提高了承诺交易钉死攻击的门槛。如果你能确保你签署的承诺交易支付的费用较高,攻击者只能在交易池严重拥堵的情况下将你的承诺交易钉死在矿工的交易池中。如果你的 cltv_expiry_delta (HTLC 超时时间)足够高,攻击者的承诺交易有可能得到确认,从而阻止攻击(尤其是当已撤销承诺交易得到确认时)。

但是,费用更新机制并不能减轻对 HTLC 原像交易的攻击,因为这类交易的费用由攻击者单方面设置。

在比特币网络中广泛建立连接

由于问题的根源在于我们缺少一些交易池拥有的信息,最显而易见的解决方案是连接到每个可触达的人(即,每个接受传入连接的比特币节点)。如此一来,节点就能发现冲突的交易,要么获悉原像,要么弄清楚需要发送什么 CPFP 交易来让被钉死的承诺交易尽快得到确认。

这个解决方案显然不具备可扩展性,而且未必有效。你无法保证你能够连接到足够多的节点,足够快速地(在上游 HTLC 超时之前)打探到交易池的情况。

注意:此解决方案还需要对 bitcoind 进行细微改动。闪电网络节点需要它们的 bitcoind 发送符合给定格式的冲突交易给它们。当闪电网络节点接收到这类交易时,就可以对它们进行操作(提取原像/承诺交易)。

Pay-for-preimage 交易

当我们探测到我们的 HTLC-timeout 交易没有及时确认时,我们可以通过提供奖励来激励随机节点发现并共享原像。

可以采用以下三种形式:

  • 在链上广播 pay-for-preimage 交易,希望它们被认领,这样你就可以在某个区块(OP_SHA256 OP_EQUAL)中获悉原像。
  • 在链下发送探测 HTLC 至随机节点。如果这些节点知道了原像,即使它们没有创建匹配的发票,也会认领 HTLC。
  • 依靠被发现原像的链下 gossip(我们可以根据对等节点为我们开启的通道容量对 gossip 进行限速,避免使之成为 DoS 攻击的向量)

这些解决方案都假设节点会监控交易池内的冲突情况并分析冲突交易来发现原像(参见上一节)。它们只能减少针对 HTLC 的攻击,对于针对承诺交易的攻击无能为力。

协议外的交易包转发

我们还可以采用另一种缓解措施来抵御上述两类攻击:在比特币点对点中继机制之外实现一种有限的交易宝转发。如果(一些)矿工选中这些包,手动(待定义)将冲突交易替换为他们收到的费用较高的包,诚实的参与者就能让自己的交易及时得到确认。只要费用较高,就能激励矿工选择这类交易。

有很多协议外渠道可以用来传播这些包,例如:

  • 使用闪电网络 gossip(我们可以基于对等节点的通道容量进行限速)。这里假设(有些)矿工会运行闪电网络节点并接收该 gossip。
  • 使用通过 Tor 连接的中心化 API。如果是持有大量资金的闪电网络节点有风险,这些节点在广播高费用包时会暴露背后的网络服务器。矿工可以定期轮询这些服务器并选择他们喜欢的交易。
  • 使用矿工能够连接到的公共比特币节点。缺点是会招来 DoS 攻击(中心化 API 也是一样)。

这需要对 Bitcoin Core 进行一些更改。目前还没有 RPC 可以让用户从交易池中驱逐交易(并使用不同的包来替换它们)。引入这类 RPC 可能会有用。Bitcoin Core 还可以提供一个仅支持白名单的标志,让矿工可以从所选节点那里盲目接受冲突交易。

参考资料

感谢 David Harding、Matt Corallo、Antoine Riard 和 ZmnSCPxj 的耐心讲解、长时间的探讨和头脑风暴!

如果你想深入了解更多信息,查看以下链接:

(完)