Little bit of HTLCs
Atomic Multihop Payments
The Lightning Network is made up of payment channels between nodes. A channel holds the balance between two nodes. This is done without the nodes having to trust each other by exchanging valid, but not broadcasted, bitcoin transactions. To avoid paying onchain transaction fees, the nodes just keep swapping updated transactions. I ain’t gonna sink into it here, but let’s just accept that swapping transactions also happens in a trustless manner. More on that in the Lightning manual.
But how do routed (across multiple nodes) payments remain trustless and atomic? How are multiple channel tied together for a payment to shoot across the network?
(A) -> (B) -> (C)
Routed payment from from A to C through B
Enter Hash Time-Lock Contracts (HTLCs).
These contracts operate on top of existing payment channels. To perform a payment from
C channels need to be updated. The unbroadcasted commitment transactions which make up the channels always have at least two outputs, one to each node with their current channel balance. In order to create the HTLC, a third output is added which pays the node who is in the direction of the routed the payment. The new HTLC output requires a special key unique to the payment in order to be spent. This is called the preimage and it is generated by the receiver, in this case, node
The new output is kinda a form of escrow. The funds are now tied down and separated from the rest of the funds in the channel. How does this help all the nodes to play nice and complete the payment in an atomic fashion?
The general flow:
Ccreates an invoice for
A, the invoice contains a hash of the preimage, which is just a random secret that only
Athe invoice out-of-band of the Lightning Network.
Afigures out the path to
Cacross the Lightning Network (this pathfinding algorithm is another can of worms we will just accept for now).
B“I’ll give you a few sats if you forward this payment to
Badd the HTLC output to their channel.
At this point,
B has an incentive to get that preimage in order to earn a few sats.
C“I’ll pay that invoice you have if you give me the preimage”
Cadd the HTLC output to their channel
C could just publish the commitment transaction with
B which includes the HTLC output. If
C does broadcast the transaction, they would have to use the preimage to pay from the HTLC UTXO. This would mean the preimage is now on the blockchain for
B (and everyone else) to read!
B can use it though to claim the
B HTLC output transaction. But like all broadcasts, it would cost onchain fees so this is best to be avoided and only used if there is a dispute of some sort. Every node in the chain has an incentive to just update their channel balance and fold the escrow’d HTLC funds back in. But this is part of what ensures that the HTLC atomic: either all the nodes get paid (preimage on blockchain) or none.
Bwill only update the channel balance with
Cif it gets the preimage, so
Csends over the preimage and they update the balance.
C sends over a bogus preimage and
B still updates the channel balance,
B would be giving away funds with no way to get reimbursed from
B always checks the preimage hash to make sure it unlocks the commitment transaction from
A before doing anything hasty. Once
B checks, they know
C could broadcast their commitment transaction and use the preimage to claim the HTLC output, so might as well fold in the value to the channel.
Bfollow the same pattern, the payment from
Cis now complete
Nodes charge a fee to forward payments since they are doing some work and escrowing their funds. What if a payment stalls? It could get expensive (missed fees for other HTLCs) for a middle node to have their funds needlessly tied down. Or what if a node in the chain disappears forever? For these reasons, HTLCs contain a time-lock for which they are valid, expiring after some time to be routed back to the node stacking the funds.
Every hop in the chain must have a time-lock significantly less than the hop before it. This is to prevent scenarios where node
C waits a long time to release the preimage to
B settles up with
C, but time runs out and the HTLC between
B is no longer valid, which results in
B losing their funds to
C with no reimbursement from
A. I think this is one of the risks of staking BTC in a lightning channel, its small so won’t pay huge dividends, but enough to justify why charging fees is necessary.
[ A | 2 of 2 of A and B] -- [ SigA <SigB> | A's balance of 50% / A ] | B's balance of 49% / (B && after 3 days) || (A && revocation secret) ] | HTLC amount / (B && after 40 blocks) || (C && preimage) ]
HTLC output added to a commitment transaction
Nodes broadcast their CLTV delta setting, the block delta that they are comfortable forwarding payments with. When a lighting wallet builds a payment route, it calculates the necessary CLTV block heights for each hop and these are baked in to the onion messages.
If One Hop?
Step 7 might seem a little overkill since at this point there is only one hop left in the payment chain, could we skip right to just updating the channel balance? However, B doesn’t know that C is the final destination of the payment. This is a nice privacy benefit. C could tell B that it is the final destination, but there is no incentive to do so. So the protocol just errors on the side of simplicity and privacy and always uses HTLCs.
The Wormhole attack effects routing nodes. It involves an attacker realizing that they have multiple nodes along a payment route, which they can do since the preimage hash is the same for each hop.
(A) -> (E1) -> (B) -> (E2) -> (C)
E1 and E2 are evil nodes coordinating to perform a wormhole attack
As the preimage is being passed back across the route, E2 skips B and passes it straight to E1. To nodes A and C, the payment looks successful. To node B, the payment looks like a failure and it unlocks its funds in the HTLC to E2. However, the fees that were originally meant for B have now been pocketed by E1.#lightning