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