From joost.jager at gmail.com Thu Feb 11 14:28:14 2021 From: joost.jager at gmail.com (Joost Jager) Date: Thu, 11 Feb 2021 15:28:14 +0100 Subject: [Lightning-dev] Hold fee rates as DoS protection (channel spamming and jamming) Message-ID: Hi all, Things have been quiet around channel jamming lately, but the vulnerability it still there as much as it was before. I've participated in an (isolated) mainnet channel jamming experiment ( https://bitcoinmagazine.com/articles/good-griefing-a-lingering-vulnerability-on-lightning-network-that-still-needs-fixing) which only confirmed the seriousness of the issue. BIDIRECTIONAL UPFRONT PAYMENT Of all the proposals that have been presented, t-bast's remix of forward and backward upfront payments ( https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-October/002862.html , https://github.com/t-bast/lightning-docs/blob/master/spam-prevention.md#bidirectional-upfront-payment) indicates in my opinion the most promising direction. One characteristic of the proposal is that the `hold_fees` are time-independent. If an htlc doesn't resolve within the `grace_period`, the receiver of the htlc will be forced to pay the full hold fee. The hold fee should cover the expenses for locking up an htlc for the maximum duration (could be 2000 blocks), so this can be a significant penalty. Applications such as atomic onchain/offchain swaps (Lightning Loop and others) rely on locking funds for some time and could get expensive with a fixed hold fee. HOLD FEE RATE In this post I'd like to present a variation of bidirectional upfront payments that uses a time-proportional hold fee rate to address the limitation above. I also tried to come up with a system that aims to relate the fees paid more directly to the actual costs incurred and thereby reduce the number of parameters. In a Lightning channel, the sender of an htlc always incurs the cost. The htlc value is deduced from their balance and the money can't be used for other purposes when the htlc is in flight. Therefore ideally a routing node is compensated for the time that their outgoing htlc is in flight. To communicate this cost to the outside world, routing nodes advertise a `hold_fee_rate` as part of their channel forwarding policy. An example would be "0.3 msat per sat per minute". So if someone wants to forward 10k sat through that channel and the htlc remains in flight for 5 minutes, the routing node would like to see a compensation of 0.3msat * 10k sat * 5 mins = 15 sat. (it is possible to extend the model with a base fee rate to also cover the cost of an occupied slot on the commitment tx) The question here again is who is going to pay the hold fee. The answer is that it is primarily the receiver of the htlc who is going to pay. They are the ones that can fail or settle the htlc and are therefore in control of the hold time ("Reverse upfront payment") But this would also mean that anyone can send out an htlc and collect hold fees unconditionally. Therefore routing nodes advertise on the network their `hold_grace_period`. When routing nodes accept an htlc to forward, they're willing to pay hold fees for it. But only if they added a delay greater than `hold_grace_period` for relaying the payment and its response. If they relayed in a timely fashion, they expect the sender of the htlc to cover those costs themselves. If the sender is also a routing node, the sender should expect the node before them to cover it. Of course, routing nodes can't be trusted. So in practice we can just as well assume that they'll always try to claim from the prior node the maximum amount in compensation. This is the basic idea. Routing nodes have real costs for the lock up of their money and will be compensated for it. To coordinate the payment of the fees, the `update_add_htlc` message is extended with: * `hold_fee_rate`: the fee rate that the sender charges for having the htlc in-flight (msat per sat per min) * `hold_fee_discount`: the absolute fee discount (sat) that the receiver gets as a compensation for hold fees that couldn't be claimed downstream because of the grace periods (the worst case amount). (the previous `hold_grace_period` in `update_add_htlc` is no longer needed) When an htlc is resolved, the receiver of the htlc will pay the sender the `hold_fee_rate` minus `hold_fee_discount` (exact details of how to integrate this into the channel state machine and deal with clock shift tbd). It is up to the sender of a payment to construct the onion payloads such that all nodes along the route will have their costs covered. EXAMPLE A ----> B ----> C ----> D Every node charges 0.6 msat/sat/minute with a hold grace period of 1 minute. In this example, the routing fees are zero. A wants to send 1000 sat to D. A will charge B a hold fee rate of 0.6 sat/min (1000 sat at 0.6 msat/sat/min). B will charge C a hold fee rate of 1.2 sat/min to cover both its own cost and what must be paid back to A. C will charge D a hold fee rate of 1.8 sat/min to cover the costs of A, B and C. D has a grace period of 1 minute. At the 1.8 sat/min fee rate that C charges, D would need to pay a maximum of 1.8 sat if it meets its grace deadline just in time. C pays the 1.8 sats to D as a discount on its hold fee (assuming D will settle right before the deadline anyway). C also has a grace period of 1 minute. But because D has a grace period too, it could be that C needs to hold on to the htlc for a total of 2 minutes. At the 1.2 sat/min fee rate B charges, C would need to pay a maximum of 2.4 sats, plus the hold fee that it needs to pay to D (1.8 sats). Therefore B gives C a hold fee discount of 2.4+1.8 = 4.2 sats. The same logic applies to A and B. A offers a hold fee discount of 0.6 * 3 min + 4.2 = 6 sats to cover the worst case cost of B, C and D. If A is just spamming/probing, it will cost hem 6 sats per htlc. If D is trying to channel-jam by hodling htlcs, it will cost them 1.8 sat/min. If an intermediate hop is delaying the payment, they will pay at least 0.6 sat/min (depending on the position in the route). In the happy flow, A is still paying 6 sat per payment attempt which is used to compensate B, C and D for the short unavailability of their funds. To me, this seems only fair. CONCLUSION Even though the proposal above is not fundamentally different from what was known already, I do think that it adds the flexibility that we need to not take a step back in terms of functionality (fair pricing for hodl invoices and its applications). Plus that it simplifies the parameter set. Thoughts? Joost -------------- next part -------------- An HTML attachment was scrubbed... URL: