Skip to content

Commit f9d02b6

Browse files
rustyrussellcdecker
authored andcommitted
channeld: fix update_fee cap.
We would sometimes propose fees which we couldn't afford, and thus the peer would get upset: if we didn't recover it could cause force closes. This was because we didn't take into account that pending htlcs will remove our total available funds. Changelog-Fixes: Protocol: Don't upset peers by sending `update_fee` with fees we cannot afford in the case where HTLCs are large.
1 parent 1350194 commit f9d02b6

File tree

1 file changed

+44
-12
lines changed

1 file changed

+44
-12
lines changed

channeld/full_channel.c

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,8 @@ u32 approx_max_feerate(const struct channel *channel)
12271227
{
12281228
size_t num;
12291229
u64 weight;
1230-
struct amount_sat avail;
1230+
struct amount_msat avail;
1231+
struct balance balance;
12311232
const struct htlc **committed, **adding, **removing;
12321233
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
12331234
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
@@ -1241,7 +1242,18 @@ u32 approx_max_feerate(const struct channel *channel)
12411242
weight = commit_tx_base_weight(num, option_anchor_outputs, option_anchors_zero_fee_htlc_tx);
12421243

12431244
/* Available is their view */
1244-
avail = amount_msat_to_sat_round_down(channel->view[!channel->opener].owed[channel->opener]);
1245+
to_balance(&balance, channel->view[!channel->opener].owed[channel->opener]);
1246+
1247+
/* But take into account any pending added htlcs (conservatively, we ignore removed ones) */
1248+
for (size_t i = 0; i < tal_count(adding); i++)
1249+
balance_add_htlc(&balance, adding[i], channel->opener);
1250+
1251+
if (!balance_ok(&balance, &avail)) {
1252+
status_broken("Negative balance %"PRId64" after removing %zu htlcs!",
1253+
balance.msat,
1254+
tal_count(removing));
1255+
return 0;
1256+
}
12451257

12461258
/* BOLT #3:
12471259
* If `option_anchors` applies to the commitment
@@ -1250,16 +1262,16 @@ u32 approx_max_feerate(const struct channel *channel)
12501262
* `to_remote`).
12511263
*/
12521264
if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
1253-
&& !amount_sat_sub(&avail, avail, AMOUNT_SAT(660))) {
1254-
avail = AMOUNT_SAT(0);
1265+
&& !amount_msat_sub_sat(&avail, avail, AMOUNT_SAT(660))) {
1266+
avail = AMOUNT_MSAT(0);
12551267
} else {
12561268
/* We should never go below reserve. */
1257-
if (!amount_sat_sub(&avail, avail,
1258-
channel->config[!channel->opener].channel_reserve))
1259-
avail = AMOUNT_SAT(0);
1269+
if (!amount_msat_sub_sat(&avail, avail,
1270+
channel->config[!channel->opener].channel_reserve))
1271+
avail = AMOUNT_MSAT(0);
12601272
}
12611273

1262-
return avail.satoshis / weight * 1000; /* Raw: once-off reverse feerate*/
1274+
return avail.millisatoshis / weight; /* Raw: once-off reverse feerate*/
12631275
}
12641276

12651277
/* Is the sum of trimmed htlcs, as this new feerate, above our
@@ -1301,10 +1313,15 @@ bool can_opener_afford_feerate(const struct channel *channel, u32 feerate_per_kw
13011313
const struct htlc **committed, **adding, **removing;
13021314
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
13031315
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
1316+
struct balance balance;
1317+
struct amount_msat available;
13041318

13051319
gather_htlcs(tmpctx, channel, !channel->opener,
13061320
&committed, &removing, &adding);
13071321

1322+
status_debug("Committed %zu, removing %zu, adding %zu",
1323+
tal_count(committed), tal_count(removing), tal_count(adding));
1324+
13081325
untrimmed = commit_tx_num_untrimmed(committed, feerate_per_kw, dust_limit,
13091326
option_anchor_outputs,
13101327
option_anchors_zero_fee_htlc_tx,
@@ -1354,15 +1371,30 @@ bool can_opener_afford_feerate(const struct channel *channel, u32 feerate_per_kw
13541371
type_to_string(tmpctx, struct amount_sat,
13551372
&channel->config[!channel->opener].channel_reserve));
13561373

1357-
status_debug("We need %s at feerate %u for %zu untrimmed htlcs: we have %s/%s",
1374+
/* The amount we have needs to take into account that we're
1375+
* adding and removing htlcs */
1376+
to_balance(&balance, channel->view[!channel->opener].owed[channel->opener]);
1377+
for (size_t i = 0; i < tal_count(removing); i++)
1378+
balance_remove_htlc(&balance, removing[i], channel->opener);
1379+
for (size_t i = 0; i < tal_count(adding); i++)
1380+
balance_add_htlc(&balance, adding[i], channel->opener);
1381+
1382+
if (!balance_ok(&balance, &available)) {
1383+
status_broken("Negative balance %"PRId64" after removing %zu htlcs!",
1384+
balance.msat,
1385+
tal_count(removing));
1386+
return false;
1387+
}
1388+
1389+
status_debug("We need %s at feerate %u for %zu untrimmed htlcs: we have %s/%s (will have %s)",
13581390
type_to_string(tmpctx, struct amount_sat, &needed),
13591391
feerate_per_kw, untrimmed,
13601392
type_to_string(tmpctx, struct amount_msat,
13611393
&channel->view[LOCAL].owed[channel->opener]),
13621394
type_to_string(tmpctx, struct amount_msat,
1363-
&channel->view[REMOTE].owed[channel->opener]));
1364-
return amount_msat_greater_eq_sat(channel->view[!channel->opener].owed[channel->opener],
1365-
needed);
1395+
&channel->view[REMOTE].owed[channel->opener]),
1396+
type_to_string(tmpctx, struct amount_msat, &available));
1397+
return amount_msat_greater_eq_sat(available, needed);
13661398
}
13671399

13681400
bool channel_update_feerate(struct channel *channel, u32 feerate_per_kw)

0 commit comments

Comments
 (0)