Discover more from Bram’s Thoughts
Y'all can calm down
People have been curious whether the recent Lightning attack applies to the state channel work I’m doing right now. The answer is no, the attack only applies at all when you’re routing payments and I’m not doing that yet, but there is a question of what should happen for the future.
The attack is a form of transaction bumping. There’s some transaction in the mempool which spends coin A which you wish to evict, so you make a higher fee transaction which spends A and B to get it out, then make a yet even higher fee transaction spending just B, and now the transaction to spend A has magically disappeared from the mempool. In principle full nodes could simply cache the transaction to spend A and try to reapply it when the second bump happens, and they absolutely should do that, but Bitcoin full nodes don’t do that today.
The way routed payments work is you have two HTLC coins in a route from A→B→C, one for A→B and one for B→C. The way HTLCs work is they can be pulled right immediately using a secure hash preimage reveal or to the left after a timeout. B’s strategy is to reuse the same preimage from B→C to claim the coin from A→B if it C makes that claim. Otherwise B uses the timeout to claim the B→C coin, and the timeout on that coin is set shorter than the A→B coin to ensure that B is always protected. To exploit of this with a fee bumping attack, C can wait until the B→C timeout comes up, then repeatedly foil B’s attempt to claim B→C coin by timeout with a transaction bumping attack. Then A can take the A→B payment when that timeout happens, and then C can claim the B→C payment using the secure hash preimage without B being able to reuse that to claim the A→B payment because it’s already gone. The result is that A and C successfully conspire to steal money from B.
There are numerous practical difficulties with pulling this off in practice. One can argue that many of those are dependent on mempool convention and hence outside of the threat model of blockchains, but that isn’t true for collaboratively controlled coins. If A and C could control the complete mempool for all full nodes B would be hosed no matter what the smart coin logic did, so some amount of security dependence on mempool behavior is necessary here. As it happens in Chia the conventional mempool behavior already defends against transaction bumping attacks very well, because it simply refuses to add in a new transaction which doesn’t replace the spends of every single coin which was spent before. This was introduced as a practical solution to the problem of transaction bumping being very easy in Chia because any transaction can be trivially aggregated with any other transaction.
The downside of this strategy is that it allows for a strange form of transaction pinning to happen, where you can make a transaction which spends coins A and B with a low fee which then can’t get bumped by a transaction spending just A regardless of how high the fee is set. This allows for a funny attack where you bump a transaction by pinning it to a near zero fee when the mempool isn’t full, then fill up the mempool just enough to increase the fees to epsilon, and for a very small fee you’ve locked the other transaction out of the mempool. We should probably modify this logic to allow not completely replaced transactions to get bumped if they don’t have a high enough fee to get into the next block. That allows transaction bumping, but only after a transaction has been bumped by overall fees getting set high enough, which is an expensive attack and an inherent issue anyway. Ideally transactions which get bumped from the outer parts of the mempool should get cached and reapplied, but as long as somebody somewhere tries to reintroduce all cached transactions after each new block is made you’re protected, and that’s a good thing for smart wallets to attempt to do for their own transactions anyway.