Although the technology is promising, this article hopes to address the flaws that are present.
So I guess I should start this off with a disclaimer: I actually love the Lightning Network. It’s one of my favorite parts of the Bitcoin protocol stack and I’ve followed it pretty closely for years. If Lightning didn’t exist, I would still own Bitcoin, but I would be much less optimistic about its potential future. I don’t see many real alternatives to scaling that don’t involve custodians, trust and the erosion of the properties of self-sovereignty for most people on the poorer end of the wealth spectrum.
At a high level a Lightning channel is just this simple:
- Two people lock up money in a 2-of-2 multisig address.
- Both parties arrange a pre-signed transaction that would give each of them their money back before funding.
- To update the balance, both parties sign a new transaction with the updated balance and exchange “penalty keys” to let the other party take all the money in the multisig address if someone tries to use an old pre-signed transaction.
But the Lightning Network is way more than just a few direct connections between two parties. These single channels can be chained together with other single channels to form a vast interconnected payment network. It’s a very flexible system that enables payments between otherwise unconnected parties. That being said, there are many downsides and limitations I see that are not really widely acknowledged or talked about outside of developer groups and more technical users.
State Management Issues
A Lightning channel really is just a set of pre-signed transactions — what I didn’t get into is the incentive model that allows this to work. Once a transaction is signed, you can never take it back. It’s out there and will always be a valid Bitcoin transaction unless you spend that bitcoin with a different transaction (you can’t spend bitcoin twice; once a transaction spends some bitcoin, any other transactions that try to act on those coins will be invalid). Now, because a Lightning channel is a 2-of-2 multisig, neither party can sign a new transaction without the cooperation of the other. This means that you cannot invalidate all the other pre-signed transactions you have made on chain without the cooperation of the other party. The two of you opened this channel together so you must update it together. If either party could act unilaterally, one of you could just steal all the funds.
Each time the parties exchange funds in their Lightning channel — Bob sends Alice 1000 sats — they generate a new pre-signed transaction that reflects their updated balances. If each party is playing nice, they would only keep the latest pre-signed transaction around as the previous ones would no longer reflect the correct balances. And if both parties wanted to cash out, they can use the most recent pre-signed transaction to pay each party their current balance as on-chain bitcoin.
But what if the other party isn’t playing nice? What if Bob spent his share of the funds by sending them to Alice but now wants to cash out using an earlier pre-signed transaction that still showed all the funds on his side of their channel? We get around this with penalty keys. These allow you to effectively invalidate all prior pre-signed transactions without actually having to really invalidate them on-chain each time.
The idea is that once both parties have replaced the older pre-signed transaction with a new one that updates the balances, they also exchange penalty keys. The system is designed so that if one of them tries to execute an old transaction, the other party’s penalty key is enabled and can be used to claim 100% of the funds in the channel. Crucially, the pre-signed transactions have a built-in timelock so there’s always a window of opportunity for the other party to use the penalty key before the transaction can be confirmed in a Bitcoin block. You aren’t actually invalidating the existing pre-signed transactions, you’re just incentivizing the other party not to use them. If they try it and you catch them, you get to keep all of their money.
This introduces a scaling dynamic that I think is not well understood by less technical users. Every time either of you spend a single satoshi, you replace a pre-signed transaction with a new one. But you still have to keep some information about every old transaction — as well as the penalty key associated with that specific transaction — in case you ever have to use it to punish a dishonest channel counterparty. There is no way to escape this, because if a channel counterparty is going to try to close the channel with an old transaction, you need that exact transaction’s penalty key in order to stop and punish them. This means you have to keep all the relevant data for every transaction you ever made with them.
I’m sure that many readers are rolling their eyes thinking, “that’s not a big deal, hard drives are cheap.” Let’s look at all the different ways this dynamic can cause issues. Before that though, I do want to remind everyone of a core assumption of Lightning: the idea of opening a channel is to keep it open as long as possible to maximize the value gained from it before incurring on-chain fees. So, ideally, you want to open a channel and keep it open for a very long time.
Let’s consider a mobile user: bitcoin wallets aren’t the only things stored on people’s phones. They take pictures, download music, videos, apps and games, etc. I’m sure most of you are familiar with having to wipe a bunch of stuff from storage because you’re running out of space. The data your Lightning wallet has to store will keep growing forever (until you close your channels) as long as you’re transacting. Eventually, this will come into conflict with other things you want to store on your phone and, after that, eventually start bumping into the upper storage limits for your phone. And remember, you absolutely have to keep 100% of this data or your Lightning channel might not be safe to keep open.
Now let’s consider routing nodes. The name says it all; these are nodes that are set up to be the highways of the Lightning Network, actively routing tons of payments across their carefully managed channels. Same basic logic, although in this case it’s a lot more likely that someone has acquired a device just for running their Lightning node. But of course a routing node is going to be updating channel balances much much more frequently, so the growth rate will far exceed that of a mobile wallet if it’s a successful routing node. Also note that the more mission-critical data you have to store, the more costly it is to store it redundantly so device failure doesn’t lead to losing money.
Lastly, the area where I think this dynamic really causes some problems: watchtowers. Most people are not going to be able to be online 24/7 to make sure their channel counterparty isn’t trying to cheat them. This is where a watchtower comes in; they watch things for you. But in order to do that, they need to store all the same data you do to be able to penalize your counterparty if they cheat. Watchtowers are still barely developed or deployed, but long term they are an absolutely critical piece of infrastructure for people to use the Lightning Network safely.
There are three ways watchtowers could work. First, an altruistic watchtower that gets nothing in return for watching the chain for you. Second, a watchtower that only gets paid if your counterparty cheats and they have to penalize it. Lastly, a watchtower that gets paid just for storing data and watching the chain. Now given that the data per user will continue growing forever until a channel is closed, do you see the issue? In the second and third models the fees for a user will start adding upto cover the data storage costs of the watchtower the longer a channel is open. This would be a kind of hidden fee users would have to pay that could grow to absurd levels.
For the skeptics still thinking this isn’t really a substantial scaling issue at all, in a world where Lightning is used solely for modest everyday transactions like coffee and dinner I’d agree with you, but in a world where major use cases for Lightning are things like microtransactions and streaming payments done in real time through an entire interaction (e.g. streaming sats to a podcaster each minute or even each second), I disagree.
Thankfully this issue would be solved with a proposed Bitcoin protocol upgrade called ANYPREVOUT and Lightning channels based on eltoo which would allow a single constant-sized piece of data to accomplish the same disincentive mechanism that penalty keys currently do. But until that feature makes it into Bitcoin, current Lightning channels have this scaling issue.
The next two major issues revolve around HTLCs (Hashed Timelock Contracts). These are new outputs added to the pre-signed transactions that say “if you know a secret, you can claim the money, otherwise the sender can reclaim it after a waiting period.” They use hashlocks and timelocks. This is how payments get forwarded trustlessly across multiple hops through the Lightning Network; the final receiver either releases the secret and everyone who helped forward the payment through their channels can claim what they’re owed, or the receiver doesn’t release the secret and after a waiting period everyone is refunded.
This structure has implications for scaling in two ways, 1) how many HTLCs a channel can be forwarding at any time, and 2) the minimum value for an HTLC because they ultimately have to be economical to settle on-chain if disrupted.
A Lightning channel can only forward so many HTLCs at once because each one has to be represented by an actual output in the most recent pre-signed transaction. This isn’t a credit system and we don’t do rehypothecation in Bitcoin or in Lightning; you can only forward payments that are ultimately backed by specific on-chain outputs that your channel has provable claims to. And because Bitcoin transactions themselves have maximum size limits, so does the number of HTLCs a transaction can have (483). If a transaction had more HTLCs than that, it would not be a valid Bitcoin transaction and therefore would leave the channel in a weird state where every pre-signed transaction that was valid (those constructed before the 483 limit had been reached) would allow the other person to steal your money and none of the current pre-signed transactions (those constructed after the 483 limit) could be used to close the channel honestly. Unless a solution to this issue is found, it presents an upper ceiling of how many HTLCs may be passing through one Lightning node at a time, which will eventually create an uneven upper ceiling on how many HTLCs the whole Lightning Network can forward at any given moment.
The on-chain dynamics also factor into the value of an HTLC. If an HTLC is only forwarding 10 satoshis, but adding the HTLC output would cost 100 satoshis in on-chain fees, can you really enforce that on-chain if you have to? No. Because enforcing it on-chain would actually lose you money, there is no economic incentive to enforce it, and there really isn’t a rational point for making the HTLC in the first place in that high-fee environment. Fees are likely to keep increasing in the long term, so this will affect the value that can rationally be routed over the Lightning Network with HTLCs.
A solution does exist for this problem, but it comes with it’s own trade offs and downsides: Packetized Payments. The idea is that instead of routing a payment with a chain of HTLCs all at once, you break it up into multiple individual payments that don’t use HTLCs. This allows you to push a tiny fraction of the payment to the intended receiver over and over again until it is complete. But because there is no HTLC, any of your small payment packets can be completely ripped off. If any one piece of the payment fails to go through, you can stop using the current route and find another to try. The problem is that if a part of the payment fails, you don’t know who along the routing chain to blame. So you have to reconstruct a new route from scratch, trusting no one in the prior route. This doesn’t function well in an adversarial environment.
Every time a Lightning payment is routed through the network all the nodes involved have to sign the updates to their channels from the start of the route to the end — twice. Once when the payment is set up using HTLCs and once again when the HTLC is cleared and settled. This introduces a kind of “weakest link” dynamic in terms of how fast a payment can actually clear. You may notice this if you are a frequent user of Lightning; sometimes wallets take a few seconds (or in bad cases many seconds) before a payment actually goes through and updates the balance. The only light wallet I’m familiar with is Breez which can take anywhere from 5-20 seconds in my experience to actually go through after clicking send.
Currently this amounts to nothing more than a slight UX friction, no different than having to stand there awkwardly at a cash register waiting for a credit card purchase to be authorized. But recall the proposal for packetized payments mentioned above to deal with the issue of amounts too small to use HTLCs. As a very small, growing network pushing non-micropayment amounts with HTLCs, this latency presents a noticeable issue. Now imagine if instead of two signing rounds for a single HTLC, you had hundreds of signing rounds to push the same payment broken up into individual micropayment-sized amounts.
This becomes a much bigger issue in terms of the UX at that point, but also a scaling bottleneck for routing nodes. Cryptographic signing operations are very quick and cheap in the absolute sense, but in a world where Lightning is simultaneously being built out to facilitate all kinds of micropayment and streaming payment use cases and more conventional larger payments also have to be broken up into micropayment sized streams of sats, this becomes a big bottleneck for routing nodes as well. This dynamic in the long term could very well kill the idea of running a profitable (or even reliable enough to be used widely) routing node on cheap hardware such as a Raspberry Pi or other single board computers.
Channel Amount Viability
HTLCs are not the only thing about the Lightning Network that are affected heavily by the fluctuation or steady rise of on-chain fees. Lightning channels themselves fall victim to this dynamic as well. Let’s say that you want to open a Lightning channel with a capacity of $10 of BTC, but the on-chain fee for that transaction will cost $1. That channel has a 10% fee to establish it in the first place. However if you fund a channel with $100, your effective fee rate is only 1%. This creates a very real market floor for people trying to directly interact with the Lightning Network. If the effective fee rate for opening a channel is too high, they won’t open that channel.
The only real tradeoff or solution to this dynamic is time. If you only have $10 instead of $100 and don’t want to pay a 10% fee, then you submit your channel-opening transaction with a lower fee. And you wait. How long that wait will be is going to depend on the real-time Bitcoin fee market and how backlogged the mempool is (Bitcoin miners pick the highest-fee transactions off the mempool until their candidate block is full). In a good situation the wait could wind up just being an extra couple of hours. In a bad situation you could potentially have to wait days or weeks. In times of extreme transaction demand, the mempool can even purge the lowest-fee transactions, guaranteeing that your channel open never occurs. With the current way that Lightning channels work, this waiting game is really the only solution to this problem.
High effective fee rates have another implication: the timelocks used to guarantee that someone can penalize an old pre-signed transaction would have to be much longer for low-value channels that don’t want to pay a high effective fee rate. The whole point of the timelock is that you can effectively jump the queue and beat your channel partner to claim the funds. But if you’re not willing or able to pay the potentially high fee for your claim to execute quickly, you need to code extra wait time for your slow low-fee transaction into your pre-signed transactions. Over time this will likely lead to much longer waits for low-value channels to open and close on-chain and require much longer timelock periods to guarantee that these low-value channel owners don’t lose money to theft in the case of a malicious channel counter party.
Depending On Tor
One of the major downsides of Lightning should be known to even the most non-technical users: you have to be online to use it because sending and receiving is an interactive process. This means peers need IP addresses to be able to talk to each other. Having to expose your IP address to your channel peers is a big privacy issue and also potentially a censorship issue if ISPs want to go snooping around at which IP addresses are talking to each other.
Tor is pretty much the go-to solution for dealing with this problem currently. The issue with that is… that Tor has many problems of its own. It relies on an entirely trust-based reputational authority run by volunteers. These “directory servers” are run by project members and are where your Tor node finds all the other peers on the network to construct Tor circuits with. These entities’ trustworthiness is the foundation that allows you to route through Tor nodes that do not have knowledge of the entire path your information is taking through the network.
There are also numerous attack vulnerabilities that Tor is subject to. Distributed Denial of Service (DDoS) attacks are much harder to deal with in Tor than on the wider internet. There are professional services that handle massive traffic spikes on the regular internet. Traffic can also be refused from malicious endpoints on the unshielded internet.But in the Tor network, by design you don’t know where traffic is coming from, so DDoS attacks are much more difficult to deal with. This is actually such a systemic issue that the Tor developers are currently considering integration of anonymized tokens or proof-of-work like hashcash in order to deal with these attack vectors. The network being so vulnerable to these types of attacks brings into question the reliability of Lightning nodes running over Tor.
The most fundamental weakness of Tor interacting with Lightning is even bigger than the risk of network disruptions or having to trust the Tor directory authorities. Tor connections are trivial to identify, so your ISP or government could just block the ability to connect to Tor entirely. Obviously in most of the world that doesn’t happen, but it easily could. And the sad part about this is that the places where it would be most likely to happen are authoritarian countries where it would be most needed to protect your privacy. China blocks Tor and Iran has made attempts to that were successfully negated by Tor developers. Russia and France in the past decade or so have both broached the topic of blocking Tor for different reasons: child pornography in the case of Russia and France in response to terrorist attacks.
More technical readers may be aware of bridge nodes on Tor. These are sort of like special Tor nodes that don’t advertise themselves as publicly as regular nodes to allow users who cannot access Tor directly to connect through these bridge nodes. But bridge nodes are not immune to being attacked, identified and blocked either. Ultimately, if nation states or ISPs want to apply pressure to the Tor network they can, and it becomes a game of cat and mouse that further degrades the reliability of Tor as a way to make quick seamless Bitcoin payments privately.
The Lightning Network is a truly amazing leap forward for the Bitcoin protocol stack. It is a scalability extension to the settlement mechanism of the blockchain that creates exponential throughput gains versus just relying solely on the blockchain itself to process transactions. But just like the blockchain itself, it has its limitations. It’s not a magic bullet, it’s not a solution to every problem, it’s not without its own shortcomings. And that’s okay.
Bitcoin existed for 9 years before the Lightning Network went live on mainnet with all kinds of existential problems and scaling issues that were open ended or unsolved. It’s still here. It’s still working. Bitcoin did not just explode and cease to exist because problems were open ended or unsolved. Open ended problems mean that we are not lying to ourselves. It means that Bitcoiners are acknowledging the realistic shortcomings of things and searching for solutions to them. That isn’t FUD, or an attack, that’s a good thing. That’s how something grows stronger and evolves, by acknowledging its current limitations and looking for ways to grow beyond them.
This is a guest post by Shinobi. Opinions expressed are entirely their own and do not necessarily reflect those of BTC, Inc. or BitcoinLinux.