Skip to content

Commit 5be061c

Browse files
committed
closingd: allow higher closing fee if anchor_outputs.
This follows lightning/bolts#847. For anchor_outputs, we pass down a max_feerate to closingd, and set the fee ceiling to MAX. It uses that to estimate the desired closing fee. Signed-off-by: Rusty Russell <[email protected]> Changelog-EXPERIMENTAL: Anchor output mutual close allow a fee higher than the final commitment transaction (as per lightning-rfc #847)
1 parent a70d029 commit 5be061c

File tree

5 files changed

+97
-36
lines changed

5 files changed

+97
-36
lines changed

closingd/closingd.c

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -584,16 +584,58 @@ static size_t closing_tx_weight_estimate(u8 *scriptpubkey[NUM_SIDES],
584584
static void calc_fee_bounds(size_t expected_weight,
585585
u32 min_feerate,
586586
u32 desired_feerate,
587-
struct amount_sat maxfee,
587+
u32 *max_feerate,
588+
struct amount_sat commitment_fee,
589+
enum side opener,
588590
struct amount_sat *minfee,
589-
struct amount_sat *desiredfee)
591+
struct amount_sat *desiredfee,
592+
struct amount_sat *maxfee)
590593
{
591594
*minfee = amount_tx_fee(min_feerate, expected_weight);
592595
*desiredfee = amount_tx_fee(desired_feerate, expected_weight);
593596

597+
/* BOLT-closing-fee_range #2:
598+
* - if it is not the funder:
599+
* - SHOULD set `max_fee_satoshis` to at least the `max_fee_satoshis`
600+
* received
601+
*...
602+
* Note that the non-funder is not paying the fee, so there is
603+
* no reason for it to have a maximum feerate.
604+
*/
605+
if (opener == REMOTE) {
606+
*maxfee = AMOUNT_SAT(-1ULL);
607+
/* BOLT-closing-fee_range #2:
608+
* - If the channel does not use `option_anchor_outputs`:
609+
* - MUST set `fee_satoshis` less than or equal to the base fee of
610+
* the final commitment transaction, as calculated in
611+
* [BOLT #3](03-transactions.md#fee-calculation).
612+
*/
613+
} else if (max_feerate) {
614+
*maxfee = amount_tx_fee(*max_feerate, expected_weight);
615+
616+
status_debug("deriving max fee from rate %u -> %s (not %s)",
617+
*max_feerate,
618+
type_to_string(tmpctx, struct amount_sat, maxfee),
619+
type_to_string(tmpctx, struct amount_sat, &commitment_fee));
620+
621+
/* option_anchor_outputs sets commitment_fee to max, so this
622+
* doesn't do anything */
623+
if (amount_sat_greater(*maxfee, commitment_fee)) {
624+
status_unusual("Maximum feerate %u would give fee %s:"
625+
" we must limit it to the final commitment fee %s",
626+
*max_feerate,
627+
type_to_string(tmpctx, struct amount_sat,
628+
maxfee),
629+
type_to_string(tmpctx, struct amount_sat,
630+
&commitment_fee));
631+
*maxfee = commitment_fee;
632+
}
633+
} else
634+
*maxfee = commitment_fee;
635+
594636
/* Can't exceed maxfee. */
595-
if (amount_sat_greater(*minfee, maxfee))
596-
*minfee = maxfee;
637+
if (amount_sat_greater(*minfee, *maxfee))
638+
*minfee = *maxfee;
597639

598640
if (amount_sat_less(*desiredfee, *minfee)) {
599641
status_unusual("Our ideal fee is %s (%u sats/perkw),"
@@ -603,20 +645,20 @@ static void calc_fee_bounds(size_t expected_weight,
603645
type_to_string(tmpctx, struct amount_sat, minfee));
604646
*desiredfee = *minfee;
605647
}
606-
if (amount_sat_greater(*desiredfee, maxfee)) {
648+
if (amount_sat_greater(*desiredfee, *maxfee)) {
607649
status_unusual("Our ideal fee is %s (%u sats/perkw),"
608650
" but our maximum is %s: using that",
609651
type_to_string(tmpctx, struct amount_sat, desiredfee),
610652
desired_feerate,
611-
type_to_string(tmpctx, struct amount_sat, &maxfee));
612-
*desiredfee = maxfee;
653+
type_to_string(tmpctx, struct amount_sat, maxfee));
654+
*desiredfee = *maxfee;
613655
}
614656

615657
status_debug("Expected closing weight = %zu, fee %s (min %s, max %s)",
616658
expected_weight,
617659
type_to_string(tmpctx, struct amount_sat, desiredfee),
618660
type_to_string(tmpctx, struct amount_sat, minfee),
619-
type_to_string(tmpctx, struct amount_sat, &maxfee));
661+
type_to_string(tmpctx, struct amount_sat, maxfee));
620662
}
621663

622664
/* We've received one offer; if we're opener, that means we've already sent one
@@ -799,8 +841,9 @@ int main(int argc, char *argv[])
799841
u16 funding_txout;
800842
struct amount_sat funding, out[NUM_SIDES];
801843
struct amount_sat our_dust_limit;
802-
struct amount_sat min_fee_to_accept, commitment_fee, offer[NUM_SIDES];
803-
u32 min_feerate, initial_feerate;
844+
struct amount_sat min_fee_to_accept, commitment_fee, offer[NUM_SIDES],
845+
max_fee_to_accept;
846+
u32 min_feerate, initial_feerate, *max_feerate;
804847
struct feerange feerange;
805848
enum side opener;
806849
u8 *scriptpubkey[NUM_SIDES], *funding_wscript;
@@ -830,7 +873,7 @@ int main(int argc, char *argv[])
830873
&out[LOCAL],
831874
&out[REMOTE],
832875
&our_dust_limit,
833-
&min_feerate, &initial_feerate,
876+
&min_feerate, &initial_feerate, &max_feerate,
834877
&commitment_fee,
835878
&scriptpubkey[LOCAL],
836879
&scriptpubkey[REMOTE],
@@ -852,8 +895,9 @@ int main(int argc, char *argv[])
852895
calc_fee_bounds(closing_tx_weight_estimate(scriptpubkey,
853896
funding_wscript,
854897
out, funding, our_dust_limit),
855-
min_feerate, initial_feerate, commitment_fee,
856-
&min_fee_to_accept, &offer[LOCAL]);
898+
min_feerate, initial_feerate, max_feerate,
899+
commitment_fee, opener,
900+
&min_fee_to_accept, &offer[LOCAL], &max_fee_to_accept);
857901

858902
/* Write values into tlv for updated closing fee neg */
859903
their_feerange = tal(ctx, struct tlv_closing_signed_tlvs_fee_range *);
@@ -862,19 +906,7 @@ int main(int argc, char *argv[])
862906
if (use_quickclose) {
863907
our_feerange = tal(ctx, struct tlv_closing_signed_tlvs_fee_range);
864908
our_feerange->min_fee_satoshis = min_fee_to_accept;
865-
866-
/* BOLT-closing-fee_range #2:
867-
* - if it is not the funder:
868-
* - SHOULD set `max_fee_satoshis` to at least the
869-
* `max_fee_satoshis` received
870-
*...
871-
* Note that the non-funder is not paying the fee, so there is
872-
* no reason for it to have a maximum feerate.
873-
*/
874-
if (opener == REMOTE)
875-
our_feerange->max_fee_satoshis = AMOUNT_SAT(-1ULL);
876-
else
877-
our_feerange->max_fee_satoshis = commitment_fee;
909+
our_feerange->max_fee_satoshis = max_fee_to_accept;
878910
} else
879911
our_feerange = NULL;
880912

@@ -904,7 +936,7 @@ int main(int argc, char *argv[])
904936
"Negotiating closing fee between %s and %s satoshi (ideal %s) "
905937
"using step %s",
906938
type_to_string(tmpctx, struct amount_sat, &min_fee_to_accept),
907-
type_to_string(tmpctx, struct amount_sat, &commitment_fee),
939+
type_to_string(tmpctx, struct amount_sat, &max_fee_to_accept),
908940
type_to_string(tmpctx, struct amount_sat, &offer[LOCAL]),
909941
fee_negotiation_step_str);
910942

@@ -967,7 +999,7 @@ int main(int argc, char *argv[])
967999
}
9681000

9691001
/* Now we have first two points, we can init fee range. */
970-
init_feerange(&feerange, commitment_fee, offer);
1002+
init_feerange(&feerange, max_fee_to_accept, offer);
9711003

9721004
/* Apply (and check) opener offer now. */
9731005
adjust_feerange(&feerange, offer[opener], opener);
@@ -1026,6 +1058,7 @@ int main(int argc, char *argv[])
10261058
tal_free(wrong_funding);
10271059
tal_free(our_feerange);
10281060
tal_free(their_feerange);
1061+
tal_free(max_feerate);
10291062
closing_dev_memleak(ctx, scriptpubkey, funding_wscript);
10301063
#endif
10311064

closingd/closingd_wire.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ msgdata,closingd_init,remote_sat,amount_sat,
1919
msgdata,closingd_init,our_dust_limit,amount_sat,
2020
msgdata,closingd_init,min_feerate_perksipa,u32,
2121
msgdata,closingd_init,preferred_feerate_perksipa,u32,
22+
msgdata,closingd_init,max_feerate_perksipa,?u32,
2223
msgdata,closingd_init,fee_limit_satoshi,amount_sat,
2324
msgdata,closingd_init,local_scriptpubkey_len,u16,
2425
msgdata,closingd_init,local_scriptpubkey,u8,local_scriptpubkey_len

closingd/closingd_wiregen.c

Lines changed: 15 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

closingd/closingd_wiregen.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lightningd/closing_control.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ void peer_start_closingd(struct channel *channel,
197197
struct per_peer_state *pps)
198198
{
199199
u8 *initmsg;
200-
u32 feerate;
200+
u32 feerate, *max_feerate;
201201
struct amount_msat their_msat;
202202
struct amount_sat feelimit;
203203
int hsmfd;
@@ -256,6 +256,19 @@ void peer_start_closingd(struct channel *channel,
256256
feerate = feerate_floor();
257257
}
258258

259+
/* We use a feerate if anchor_outputs, otherwise max fee is set by
260+
* the final unilateral. */
261+
if (channel->option_anchor_outputs) {
262+
max_feerate = tal(tmpctx, u32);
263+
/* Aim for reasonable max, but use final if we don't know. */
264+
*max_feerate = unilateral_feerate(ld->topology);
265+
if (!*max_feerate)
266+
*max_feerate = final_commit_feerate;
267+
/* No other limit on fees */
268+
feelimit = AMOUNT_SAT(-1ULL);
269+
} else
270+
max_feerate = NULL;
271+
259272
/* BOLT #3:
260273
*
261274
* Each node offering a signature:
@@ -288,7 +301,9 @@ void peer_start_closingd(struct channel *channel,
288301
amount_msat_to_sat_round_down(channel->our_msat),
289302
amount_msat_to_sat_round_down(their_msat),
290303
channel->our_config.dust_limit,
291-
feerate_min(ld, NULL), feerate, feelimit,
304+
feerate_min(ld, NULL), feerate,
305+
max_feerate,
306+
feelimit,
292307
channel->shutdown_scriptpubkey[LOCAL],
293308
channel->shutdown_scriptpubkey[REMOTE],
294309
channel->closing_fee_negotiation_step,

0 commit comments

Comments
 (0)