|
7 | 7 | #include <common/blockheight_states.h> |
8 | 8 | #include <common/features.h> |
9 | 9 | #include <common/fee_states.h> |
| 10 | +#include <common/htlc_trim.h> |
10 | 11 | #include <common/htlc_tx.h> |
11 | 12 | #include <common/htlc_wire.h> |
12 | 13 | #include <common/keyset.h> |
@@ -423,6 +424,37 @@ static struct amount_sat fee_for_htlcs(const struct channel *channel, |
423 | 424 | return commit_tx_base_fee(feerate, untrimmed, option_anchor_outputs); |
424 | 425 | } |
425 | 426 |
|
| 427 | +static bool htlc_dust(const struct channel *channel, |
| 428 | + const struct htlc **committed, |
| 429 | + const struct htlc **adding, |
| 430 | + const struct htlc **removing, |
| 431 | + enum side side, |
| 432 | + u32 feerate, |
| 433 | + struct amount_msat *trim_total) |
| 434 | +{ |
| 435 | + struct amount_sat dust_limit = channel->config[side].dust_limit; |
| 436 | + bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); |
| 437 | + struct amount_msat trim_rmvd = AMOUNT_MSAT(0); |
| 438 | + |
| 439 | + if (!commit_tx_amount_trimmed(committed, feerate, |
| 440 | + dust_limit, |
| 441 | + option_anchor_outputs, |
| 442 | + side, trim_total)) |
| 443 | + return false; |
| 444 | + if (!commit_tx_amount_trimmed(adding, feerate, |
| 445 | + dust_limit, |
| 446 | + option_anchor_outputs, |
| 447 | + side, trim_total)) |
| 448 | + return false; |
| 449 | + if (!commit_tx_amount_trimmed(removing, feerate, |
| 450 | + dust_limit, |
| 451 | + option_anchor_outputs, |
| 452 | + side, &trim_rmvd)) |
| 453 | + return false; |
| 454 | + |
| 455 | + return amount_msat_sub(trim_total, *trim_total, trim_rmvd); |
| 456 | +} |
| 457 | + |
426 | 458 | /* |
427 | 459 | * There is a corner case where the opener can spend so much that the |
428 | 460 | * non-opener can't add any non-dust HTLCs (since the opener would |
@@ -497,12 +529,14 @@ static enum channel_add_err add_htlc(struct channel *channel, |
497 | 529 | bool err_immediate_failures) |
498 | 530 | { |
499 | 531 | struct htlc *htlc, *old; |
500 | | - struct amount_msat msat_in_htlcs, committed_msat, adding_msat, removing_msat; |
| 532 | + struct amount_msat msat_in_htlcs, committed_msat, |
| 533 | + adding_msat, removing_msat, htlc_dust_amt; |
501 | 534 | enum side sender = htlc_state_owner(state), recipient = !sender; |
502 | 535 | const struct htlc **committed, **adding, **removing; |
503 | 536 | const struct channel_view *view; |
504 | 537 | size_t htlc_count; |
505 | 538 | bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); |
| 539 | + u32 feerate, feerate_ceil; |
506 | 540 |
|
507 | 541 | htlc = tal(tmpctx, struct htlc); |
508 | 542 |
|
@@ -753,6 +787,42 @@ static enum channel_add_err add_htlc(struct channel *channel, |
753 | 787 | } |
754 | 788 | } |
755 | 789 |
|
| 790 | + htlc_dust_amt = AMOUNT_MSAT(0); |
| 791 | + feerate = channel_feerate(channel, recipient); |
| 792 | + /* Note that we check for trimmed htlcs at an |
| 793 | + * *accelerated* rate, so that future feerate changes |
| 794 | + * don't suddenly surprise us */ |
| 795 | + feerate_ceil = htlc_trim_feerate_ceiling(feerate); |
| 796 | + |
| 797 | + if (!htlc_dust(channel, committed, |
| 798 | + adding, removing, recipient, |
| 799 | + feerate_ceil, &htlc_dust_amt)) |
| 800 | + return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED; |
| 801 | + |
| 802 | + if (amount_msat_greater(htlc_dust_amt, |
| 803 | + channel->config[LOCAL].max_dust_htlc_exposure_msat)) { |
| 804 | + htlc->fail_immediate = true; |
| 805 | + if (err_immediate_failures) |
| 806 | + return CHANNEL_ERR_DUST_FAILURE; |
| 807 | + } |
| 808 | + |
| 809 | + |
| 810 | + /* Also check the sender, as they'll eventually have the same |
| 811 | + * constraint */ |
| 812 | + htlc_dust_amt = AMOUNT_MSAT(0); |
| 813 | + feerate = channel_feerate(channel, sender); |
| 814 | + feerate_ceil = htlc_trim_feerate_ceiling(feerate); |
| 815 | + if (!htlc_dust(channel, committed, adding, |
| 816 | + removing, sender, feerate_ceil, |
| 817 | + &htlc_dust_amt)) |
| 818 | + return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED; |
| 819 | + |
| 820 | + if (amount_msat_greater(htlc_dust_amt, |
| 821 | + channel->config[LOCAL].max_dust_htlc_exposure_msat)) { |
| 822 | + htlc->fail_immediate = true; |
| 823 | + if (err_immediate_failures) |
| 824 | + return CHANNEL_ERR_DUST_FAILURE; |
| 825 | + } |
756 | 826 | dump_htlc(htlc, "NEW:"); |
757 | 827 | htlc_map_add(channel->htlcs, tal_steal(channel, htlc)); |
758 | 828 | if (htlcp) |
@@ -1109,6 +1179,37 @@ u32 approx_max_feerate(const struct channel *channel) |
1109 | 1179 | return avail.satoshis / weight * 1000; /* Raw: once-off reverse feerate*/ |
1110 | 1180 | } |
1111 | 1181 |
|
| 1182 | +/* Is the sum of trimmed htlcs, as this new feerate, above our |
| 1183 | + * max allowed htlc dust limit? */ |
| 1184 | +static struct amount_msat htlc_calculate_dust(const struct channel *channel, |
| 1185 | + u32 feerate_per_kw, |
| 1186 | + enum side side) |
| 1187 | +{ |
| 1188 | + const struct htlc **committed, **adding, **removing; |
| 1189 | + struct amount_msat acc_dust = AMOUNT_MSAT(0); |
| 1190 | + |
| 1191 | + gather_htlcs(tmpctx, channel, side, |
| 1192 | + &committed, &removing, &adding); |
| 1193 | + |
| 1194 | + htlc_dust(channel, committed, adding, removing, |
| 1195 | + side, feerate_per_kw, &acc_dust); |
| 1196 | + |
| 1197 | + return acc_dust; |
| 1198 | +} |
| 1199 | + |
| 1200 | +bool htlc_dust_ok(const struct channel *channel, |
| 1201 | + u32 feerate_per_kw, |
| 1202 | + enum side side) |
| 1203 | +{ |
| 1204 | + struct amount_msat total_dusted; |
| 1205 | + |
| 1206 | + total_dusted = htlc_calculate_dust(channel, feerate_per_kw, side); |
| 1207 | + |
| 1208 | + return amount_msat_greater_eq( |
| 1209 | + channel->config[LOCAL].max_dust_htlc_exposure_msat, |
| 1210 | + total_dusted); |
| 1211 | +} |
| 1212 | + |
1112 | 1213 | bool can_opener_afford_feerate(const struct channel *channel, u32 feerate_per_kw) |
1113 | 1214 | { |
1114 | 1215 | struct amount_sat needed, fee; |
@@ -1180,6 +1281,9 @@ bool channel_update_feerate(struct channel *channel, u32 feerate_per_kw) |
1180 | 1281 | if (!can_opener_afford_feerate(channel, feerate_per_kw)) |
1181 | 1282 | return false; |
1182 | 1283 |
|
| 1284 | + if (!htlc_dust_ok(channel, feerate_per_kw, REMOTE)) |
| 1285 | + return false; |
| 1286 | + |
1183 | 1287 | status_debug("Setting %s feerate to %u", |
1184 | 1288 | side_to_str(!channel->opener), feerate_per_kw); |
1185 | 1289 |
|
|
0 commit comments