From 3b7e8bcac719c405807f103059d9b1fbce0735ea Mon Sep 17 00:00:00 2001 From: t-bast Date: Thu, 5 Nov 2020 18:32:29 +0100 Subject: [PATCH] Bidirectional upfront payments: decrement forward fee As pointed out on the ML, the forward fee needs to be strictly decrementing to protect against short-lived controlled spam. --- spam-prevention.md | 84 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/spam-prevention.md b/spam-prevention.md index 9400f34..81aaec1 100644 --- a/spam-prevention.md +++ b/spam-prevention.md @@ -198,62 +198,100 @@ A -----> B -----> C -----> D ``` We add a `hold_grace_period_delta` field to `channel_update` (in seconds). -We add two new fields in the tlv extension of `update_add_htlc`: +We add three new fields in the tlv extension of `update_add_htlc`: +* `spam_fees` (msat) * `hold_grace_period` (seconds) * `hold_fees` (msat) -We add an `outgoing_hold_grace_period` field in the onion per-hop payload. +We add two new fields in the onion per-hop payload: + +* `outgoing_hold_grace_period` +* `outgoing_spam_fees` When nodes receive an `update_add_htlc`, they verify that: * `hold_fees` is not unreasonable large * `hold_grace_period` is not unreasonably small or large * `hold_grace_period` - `outgoing_hold_grace_period` >= `hold_grace_period_delta` +* `spam_fees` - `outgoing_spam_fees` > `0` and not unreasonably small Otherwise they immediately fail the HTLC instead of relaying it. For the example we assume all nodes use `hold_grace_period_delta = 10`. -We add a forward upfront payment of 1 msat (fixed) that is paid unconditionally when offering an HTLC. +We add a forward upfront payment (`spam_fees`) that is paid unconditionally when offering an HTLC. We add a backwards upfront payment of `hold_fees` that is paid when receiving an HTLC, but refunded if the HTLC is settled before the `hold_grace_period` ends (see footnotes about this). +Forward upfront payments strictly decrement at each hop, while backwards upfront payments increment +at each hop (non-strictly). + +```text ++---+ +---+ +---+ +---+ +| A | | B | | C | | D | ++---+ +---+ +---+ +---+ + | | | | + | Non-refundable fee: 15 msat | | | + |----------------------------->| | | + | Refundable fee: 50 msat | | | + | Refund deadline: 100 seconds | | | + |<-----------------------------| | | + | | Non-refundable fee: 14 msat | | + | |----------------------------->| | + | | Refundable fee: 60 msat | | + | | Refund deadline: 90 seconds | | + | |<-----------------------------| | + | | | Non-refundable fee: 13 msat | + | | |----------------------------->| + | | | Refundable fee: 70 msat | + | | | Refund deadline: 80 seconds | + | | |<-----------------------------| + | | | | +``` + * A sends an HTLC to B: * `hold_grace_period = 100 sec` - * `hold_fees = 5 msat` - * `next_hold_grace_period = 90 sec` - * forward upfront payment: 1 msat is deduced from A's main output and added to B's main output - * backwards upfront payment: 5 msat are deduced from B's main output and added to A's main output + * `hold_fees = 50 msat` + * `outgoing_hold_grace_period = 90 sec` + * `spam_fees = 15 msat` + * `outgoing_spam_fees = 14 msat` + * forward upfront payment: 15 msat are deduced from A's main output and added to B's main output + * backwards upfront payment: 50 msat are deduced from B's main output and added to A's main output * B forwards the HTLC to C: * `hold_grace_period = 90 sec` - * `hold_fees = 6 msat` - * `next_hold_grace_period = 80 sec` - * forward upfront payment: 1 msat is deduced from B's main output and added to C's main output - * backwards upfront payment: 6 msat are deduced from C's main output and added to B's main output + * `hold_fees = 60 msat` + * `outgoing_hold_grace_period = 80 sec` + * `spam_fees = 14 msat` + * `outgoing_spam_fees = 13 msat` + * forward upfront payment: 14 msat are deduced from B's main output and added to C's main output + * backwards upfront payment: 60 msat are deduced from C's main output and added to B's main output * C forwards the HTLC to D: * `hold_grace_period = 80 sec` - * `hold_fees = 7 msat` - * `next_hold_grace_period = 70 sec` - * forward upfront payment: 1 msat is deduced from C's main output and added to D's main output - * backwards upfront payment: 7 msat are deduced from D's main output and added to C's main output + * `hold_fees = 70 msat` + * `spam_fees = 13 msat` + * forward upfront payment: 13 msat are deduced from C's main output and added to D's main output + * backwards upfront payment: 70 msat are deduced from D's main output and added to C's main output * Scenario 1: D settles the HTLC quickly: * all backwards upfront payments are refunded (returned to the respective main outputs) - * only the forward upfront payments have been paid (to protect against `uncontrolled spam`) + * only the forward upfront payments have been paid (to protect against `uncontrolled spam` and + `short-lived controlled spam`) * Scenario 2: D settles the HTLC after the grace period: * D's backwards upfront payment is not refunded * If C and B relay the settlement upstream quickly (before `hold_grace_period_delta`) their backwards upfront payments are refunded - * all the forward upfront payments have been paid (to protect against `uncontrolled spam`) + * all the forward upfront payments have been paid (to protect against `uncontrolled spam` and + `short-lived controlled spam`) * Scenario 3: C delays the HTLC: * D settles before its `grace_period`, so its backwards upfront payment is refunded by C * C delays before settling upstream: it can ensure B will not get refunded, but C will not get refunded either so B gains the difference in backwards upfront payments (which protects against `controlled spam`) - * all the forward upfront payments have been paid (to protect against `uncontrolled spam`) + * all the forward upfront payments have been paid (to protect against `uncontrolled spam` and + `short-lived controlled spam`) * Scenario 4: the channel B <-> C closes: * D settles before its `grace_period`, so its backwards upfront payment is refunded by C @@ -262,7 +300,8 @@ if the HTLC is settled before the `hold_grace_period` ends (see footnotes about * if C publishes an HTLC-fulfill quickly, B may have his backwards upfront payment refunded by A * if B is forced to wait for his HTLC-timeout, his backwards upfront payment will not be refunded but it's ok because B got C's backwards upfront payment - * all the forward upfront payments have been paid (to protect against `uncontrolled spam`) + * all the forward upfront payments have been paid (to protect against `uncontrolled spam` and + `short-lived controlled spam`) The backwards upfront payment is fixed instead of scaled based on the time an HTLC is left pending; it's slightly less penalizing for spammers, but is less complex and introduces less potential @@ -272,7 +311,7 @@ unilaterally closed is too heavily penalized (because it has to pay for the maxi Drawbacks: * If done naively, this mechanism may allow intermediate nodes to deanonymize sender/recipient. - Randomizing the base `grace_period` and `hold_fees` may remove that probing vector. + Randomizing the base `grace_period`, `hold_fees` and `spam_fees` may remove that probing vector. * Handling the `grace_period` will be a pain: * when do you start counting: when you send/receive `commit_sig` or `revoke_and_ack`? * what happens if there is a disconnection (how do you account for the delay of reconnecting)? @@ -281,11 +320,6 @@ Drawbacks: `grace_period`)? In that case the behavior should probably be to give your peers some leeway and let them get away with it, but record it. If they're doing it too often, close channels and ban them; stealing upfront fees should never be worth losing channels. -* If the forward upfront payment is a network constant (1 msat?), do we need to add a mechanism to - upgrade it? -* Short-lived `controlled spam` is still free for the attacker: we should probably make the forward - upfront payment a decrementing value at each hop (committed inside the onion) to penalize this - type of attacks ### Web of trust HTLC hold fees