Unjamming Lightning15 Nov 2022
This post summarizes a paper by Clara Shikhelman and Sergei Tikhomirov on countermeasures against jamming in the Lightning Network.
Jamming is a denial-of-service attack in Lightning. An adversary can cheaply block payment channels by initiating payments and delaying their finalization. Multiple countermeasures have been proposed but none have been yet implemented.
After carefully reviewing the available design options, we propose a two-part solution. We combine unconditional fees (applied to failed as well as successful payments) and local peer reputation. Unconditional fees impose costs on the adversary, which is more effective for jams that are resolved quickly. Local reputation, in turn, protect channels from long-held jams by allocating less resources to less trusted peers.
We believe that our proposal strikes a good balance between effectiveness and practicality. Simulations show that unconditional fees don’t have to be high to fully compensate the victims. The UX burden of unconditional fees shouldn’t be a showstopper, given that payments generally succeed after a few attempts. We also analyze our solution in terms of security, privacy, and incentive compatibility. We conclude that the proposal is practical and comparatively straightforward to implement.
The Lightning Network (LN) is a payment channel network on top of Bitcoin. A channel is an instance of a cryptographic protocol between two nodes. Channel partners lock-up bitcoins into a jointly owned address and make low-latency payments off-chain. A penalty mechanism ensures cryptoeconomic security of balance updates. Lightning supports multi-hop payments, which involve an atomic chain of balance updates along a path from the sender to the receiver. Routing nodes earn fees from payments they forward.
Lightning’s protocol design strongly emphasizes privacy. Payments are onion-routed: an intermediary node only knows its immediate neighbors on the path, but not the ultimate sender or receiver. Enhanced privacy makes it difficult to punish remote adversarial nodes as it’s unclear who the attacker is.
Jamming is a denial-of-service attack on Lightning channels. An attacker sets up two nodes and initiates a payment between them, but doesn’t finalize it promptly. Coins (aka liquidity) remain stuck (in-flight) in all channels along the route and cannot be used to forward other payments. Victims cannot send or receive payments and lose potential routing revenue.
An in-flight payment occupies one payment slot and a portion of liquidity of a channel. The attack, therefore, can either target slots (slot-based jamming) or liquidity (liquidity-based jamming). Jammed channels remain unusable until the attacker fails the jams or the victim closes the channel.
We differentiate between quick and slow jamming. Quick jams are resolved and sent again every few seconds, which them hardly distinguishable from failing honest payments. Slow jams, in contrast, remain in-flight for hours or even days. Slow jamming is easily detectable, but the victim can’t do much to stop an ongoing attack (besides closing the channel).
Multiple countermeasures against jamming have been discussed. The two major directions are fees and reputation. First, we could impose fees on the attacker, making jamming at least a minimally costly. Currently, jamming is essentially free: fees are only charged when the payment succeeds, while jams always fail. Second, we could limit the amount of resources available for the attacker. Such a countermeasure would involve some notion of “good” and “bad” payments, where “good” payments are routed on the best effort basis, whereas “bad” (or “risky”) payments are only allowed to occupy some portion of channel resources. Under such a scheme, a low-reputation jammer can never jam channels fully. The key question is how to assign reputation scores while avoiding centralization.
We take a systematic approach to constructing an anti-jamming countermeasure. We start by outlining the desired properties of a potential solution. Besides being effective, it should meet the following requirements:
- be incentive compatible;
- avoid deteriorating the user experience;
- introduce no new attack vectors (including privacy leaks);
- be easily implementable.
We then list the design decisions to be made when constructing a protocol upgrade. Ultimately, we converge on a combination of unconditional fees and local reputation.
Unconditional fees, which are paid regardless of payment success, aim at discouraging quick jamming and may be implemented differently. One way would be to pay unconditional fees upfront (when the payment is offered). An alternative approach implies that the downstream node keeps a small part of the payment amount in case it fails.
Unconditional fees inherit the structure of success-case fees, which remain in place. Fees of both types consist of a base fee and a proportional part that depends on the payment amount. The coefficients, however, can be much lower for unconditional fees than for their success-case counterparts, as our simulations indicate.
When deciding how much to charge unconditionally, we may pursue different goals. Ideally, we would like to make the attack prohibitively expensive. However, that may impose too much of a burden on honest users. A more realistic goal is to compensate the routing node under attack for the lost revenue.
We have implemented a simulator that models LN payments with unconditional fees. Under certain assumptions about the honest payment flow, increasing the total fee by just 2% (paid unconditionally) fully compensates a routing node. In other words, if the success-case fee is 100 coins, additionally charging 2 coins upfront for all payments is sufficient. A routing node would receive the same revenue from frequent jams compared to what honest payments normally pay.
We also consider the UX implications of unconditional fees. The concern is that users won’t be willing to pay for failed payment attempts. We argue, however, that UX should not be a deal-breaker. The reasoning is that the total unconditional fee stays low even if the failure rate is (reasonably) high. For instance, if every attempt has a 20% chance of failure, a payment has a 99% chance of success after just three attempts.
Fees are ineffective against slow jamming attacks, which only involve a few jams. Instead, we address slow jamming using local reputation.
We suggest that nodes keep track of their peers’ past behavior. A routing node considers its peer high-reputation if it only forwards honest payments that resolve quickly and bring in sufficient fee revenue. A peer that forwards jams, in contrast, is labeled low-reputation. Nodes may (but don’t have to) endorse payments that they forward. A payment endorsed by a high-reputation peer are considered low-risk. They are forwarded on the best efforts basis, as per the current protocol. High-risk payments, in contrast, can only use a predefined quota of liquidity and slots. A high-risk payment is dropped if the next channel lacks slots or liquidity in its high-risk quota, even if it could technically forward the payment. Unless the attacker builds up a reputation in advance, it cannot fully jam a channel with at least some resources outside of the high-risk quota. Nodes parameterize their reputation algorithms according to their risk tolerance.
Our reputation scheme is local. Nodes only assign reputation scores to their peers. Additionally, the risk level of a payment is determined by a routing node based on its local opinion of the upstream peer. The sender’s identity is not attached to payments (otherwise privacy could be endangered).
From the incentives standpoint, the scheme can be parameterized to make it in the routing nodes’ best interest to endorse payments based on their true perception of their risk levels. Implementation-wise, local reputation is beneficial as it requires no coordination. Each node reflects its own risk preferences by tuning the parameters of its reputation adjustment algorithm.
Lightning community has proposed multiple ideas on jamming countermeasures in the last few years. We think that those ideas may be well worth exploring further, including those we have set aside for now. We have decided to emphasize practicality and have (hopefully) come up with a simple yet efficient solution that can be implemented in the near future.
One idea that we’d greatly appreciate further research on is time-dependent fee amounts. Lightning fees (both in the existing protocol and in our proposal) do not depend on the actual payment resolution time. Routing nodes provide access to resources for the same fee regardless of whether these resources are occupied for a second or for a day. From the economical standpoint, fees should reflect the time-value of the consumed resources. However, it’s unclear how to implement such fees without a (semi-)trusted time signal.
Privacy-preserving reputation is another promising research direction. Jamming illustrates the dilemma that anonymity-preserving P2P network face. Given that identities are ephemeral and obfuscated in such networks, how do we prevent malicious actors from abusing the system? An ideal reputation system would allow routing nodes to filter out bad actors without revealing their (or anyone else’s) identities. Further research in this direction would be highly appreciated.
In this work, we propose a mitigation strategy against jamming in the Lightning Network. Our solution combines unconditional fees and local reputation. Small unconditional fees discourage quick jamming and compensate routing nodes for the damage. Local reputation allows for prioritizing reliable peers and limits the amount of slots and liquidity the attacker can easily block. We argue that our proposal can discourage jamming while scoring well with respect to security and privacy, user experience, incentive compatibility, and ease of implementation (see a proof-of-concept by Sergi Delgado Segura). Finally, a solution to jamming may also help address other LN issues, such as balance probing and watchtower incentivization. For more details, please refer to the full paper.