Skip to content

Commit 3e3efac

Browse files
committed
rfc-proposal: relax closing fee requirements
Implementation of lightning/bolts#847 In particular see comment: OK, perhaps we should split this further, to make it explicit that there's no back-and-forth if both sides support this? If you both include the TLV, there's no back-and-forth, it's either two messages or three. If nodes receive the tlv, it picks from that range for its reply: if it doesn't care, uses the same rate. If reply has different rate (and it's acceptable), reply with using that rate. Otherwise it's complete. That will be a nice simplification in future... Needs tests, and interop check. Waiting for finalized wording before importing more spec notes.
1 parent b2ce878 commit 3e3efac

File tree

3 files changed

+140
-11
lines changed

3 files changed

+140
-11
lines changed

closingd/closingd.c

Lines changed: 118 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,12 @@ static void send_offer(struct per_peer_state *pps,
295295
enum side opener,
296296
struct amount_sat our_dust_limit,
297297
struct amount_sat fee_to_offer,
298-
const struct bitcoin_outpoint *wrong_funding)
298+
const struct bitcoin_outpoint *wrong_funding,
299+
struct tlv_closing_signed_tlvs_fee_range *tlv_fees)
299300
{
300301
struct bitcoin_tx *tx;
301302
struct bitcoin_signature our_sig;
303+
struct tlv_closing_signed_tlvs *close_tlvs;
302304
u8 *msg;
303305

304306
/* BOLT #2:
@@ -338,8 +340,14 @@ static void send_offer(struct per_peer_state *pps,
338340
status_debug("sending fee offer %s",
339341
type_to_string(tmpctx, struct amount_sat, &fee_to_offer));
340342

343+
/* Add the new close_tlvs with our fee range */
344+
close_tlvs = tlv_closing_signed_tlvs_new(msg);
345+
close_tlvs->fee_range = tlv_fees;
346+
341347
assert(our_sig.sighash_type == SIGHASH_ALL);
342-
msg = towire_closing_signed(NULL, channel_id, fee_to_offer, &our_sig.s);
348+
msg = towire_closing_signed(NULL, channel_id, fee_to_offer, &our_sig.s,
349+
close_tlvs);
350+
343351
sync_crypto_write(pps, take(msg));
344352
}
345353

@@ -376,13 +384,15 @@ receive_offer(struct per_peer_state *pps,
376384
struct amount_sat our_dust_limit,
377385
struct amount_sat min_fee_to_accept,
378386
const struct bitcoin_outpoint *wrong_funding,
379-
struct bitcoin_txid *closing_txid)
387+
struct bitcoin_txid *closing_txid,
388+
struct tlv_closing_signed_tlvs_fee_range **tlv_fees)
380389
{
381390
u8 *msg;
382391
struct channel_id their_channel_id;
383392
struct amount_sat received_fee;
384393
struct bitcoin_signature their_sig;
385394
struct bitcoin_tx *tx;
395+
struct tlv_closing_signed_tlvs *close_tlvs;
386396

387397
/* Wait for them to say something interesting */
388398
do {
@@ -406,8 +416,10 @@ receive_offer(struct per_peer_state *pps,
406416
} while (!msg);
407417

408418
their_sig.sighash_type = SIGHASH_ALL;
419+
close_tlvs = tlv_closing_signed_tlvs_new(msg);
409420
if (!fromwire_closing_signed(msg, &their_channel_id,
410-
&received_fee, &their_sig.s))
421+
&received_fee, &their_sig.s,
422+
close_tlvs))
411423
peer_failed_warn(pps, channel_id,
412424
"Expected closing_signed: %s",
413425
tal_hex(tmpctx, msg));
@@ -481,6 +493,11 @@ receive_offer(struct per_peer_state *pps,
481493
status_debug("Received fee offer %s",
482494
type_to_string(tmpctx, struct amount_sat, &received_fee));
483495

496+
if (close_tlvs)
497+
*tlv_fees = close_tlvs->fee_range;
498+
else
499+
*tlv_fees = NULL;
500+
484501
/* Master sorts out what is best offer, we just tell it any above min */
485502
if (amount_sat_greater_eq(received_fee, min_fee_to_accept)) {
486503
status_debug("...offer is reasonable");
@@ -546,6 +563,23 @@ static void adjust_feerange(struct feerange *feerange,
546563
"Overflow in updating fee range");
547564
}
548565

566+
static bool
567+
evaluate_their_offer(struct amount_sat their_offer,
568+
const struct tlv_closing_signed_tlvs_fee_range *our_range,
569+
const struct tlv_closing_signed_tlvs_fee_range *their_range)
570+
{
571+
/* They'd better be within their own range */
572+
if (amount_sat_greater(their_offer, their_range->max_fee_satoshis))
573+
return false;
574+
if (amount_sat_less(their_offer, their_range->min_fee_satoshis))
575+
return false;
576+
if (amount_sat_greater(their_offer, our_range->max_fee_satoshis))
577+
return false;
578+
if (amount_sat_less(their_offer, our_range->min_fee_satoshis))
579+
return false;
580+
return true;
581+
}
582+
549583
/* Figure out what we should offer now. */
550584
static struct amount_sat
551585
adjust_offer(struct per_peer_state *pps, const struct channel_id *channel_id,
@@ -669,6 +703,7 @@ int main(int argc, char *argv[])
669703
u8 *channel_reestablish;
670704
struct secret last_remote_per_commit_secret;
671705
struct bitcoin_outpoint *wrong_funding;
706+
struct tlv_closing_signed_tlvs_fee_range *our_feerange, **their_feerange;
672707

673708
subdaemon_setup(argc, argv);
674709

@@ -687,7 +722,8 @@ int main(int argc, char *argv[])
687722
&out[LOCAL],
688723
&out[REMOTE],
689724
&our_dust_limit,
690-
&min_fee_to_accept, &commitment_fee,
725+
&min_fee_to_accept,
726+
&commitment_fee,
691727
&offer[LOCAL],
692728
&scriptpubkey[LOCAL],
693729
&scriptpubkey[REMOTE],
@@ -706,6 +742,13 @@ int main(int argc, char *argv[])
706742
/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */
707743
per_peer_state_set_fds(notleak(pps), 3, 4, 5);
708744

745+
/* Write values into tlv for updated closing fee neg */
746+
their_feerange = tal(ctx, struct tlv_closing_signed_tlvs_fee_range *);
747+
*their_feerange = NULL;
748+
our_feerange = tal(ctx, struct tlv_closing_signed_tlvs_fee_range);
749+
our_feerange->min_fee_satoshis = min_fee_to_accept;
750+
our_feerange->max_fee_satoshis = commitment_fee;
751+
709752
snprintf(fee_negotiation_step_str, sizeof(fee_negotiation_step_str),
710753
"%" PRIu64 "%s", fee_negotiation_step,
711754
fee_negotiation_step_unit ==
@@ -763,7 +806,8 @@ int main(int argc, char *argv[])
763806
funding, out, opener,
764807
our_dust_limit,
765808
offer[LOCAL],
766-
wrong_funding);
809+
wrong_funding,
810+
our_feerange);
767811
} else {
768812
if (i == 0)
769813
peer_billboard(false, "Waiting for their initial"
@@ -785,7 +829,69 @@ int main(int argc, char *argv[])
785829
our_dust_limit,
786830
min_fee_to_accept,
787831
wrong_funding,
788-
&closing_txid);
832+
&closing_txid,
833+
their_feerange);
834+
835+
if (*their_feerange) {
836+
if (!evaluate_their_offer(offer[REMOTE],
837+
our_feerange,
838+
*their_feerange)) {
839+
peer_billboard(true,
840+
"Unable to agree on"
841+
" a feerate."
842+
" Our range %s-%s,"
843+
" their range %s-%s",
844+
type_to_string(tmpctx,
845+
struct amount_sat,
846+
&our_feerange->min_fee_satoshis),
847+
type_to_string(tmpctx,
848+
struct amount_sat,
849+
&our_feerange->max_fee_satoshis),
850+
type_to_string(tmpctx,
851+
struct amount_sat,
852+
&(*their_feerange)->min_fee_satoshis),
853+
type_to_string(tmpctx,
854+
struct amount_sat,
855+
&(*their_feerange)->max_fee_satoshis));
856+
goto exit_thru_the_giftshop;
857+
}
858+
859+
peer_billboard(true, "Using quick-close."
860+
" Updated our offer to match"
861+
" theirs (was %s, now %s",
862+
type_to_string(tmpctx,
863+
struct amount_sat,
864+
&offer[LOCAL]),
865+
type_to_string(tmpctx,
866+
struct amount_sat,
867+
&offer[REMOTE]));
868+
869+
/* We mirror it back */
870+
if (i == 1 && !amount_sat_eq(offer[LOCAL],
871+
offer[REMOTE])) {
872+
send_offer(pps, chainparams,
873+
&channel_id,
874+
funding_pubkey,
875+
funding_wscript,
876+
scriptpubkey,
877+
&funding_txid,
878+
funding_txout,
879+
funding, out, opener,
880+
our_dust_limit,
881+
offer[REMOTE],
882+
wrong_funding,
883+
our_feerange);
884+
}
885+
886+
/* BOLT-9a0b1f68d6c6feefe2c459e28adee3475d02a62e #2:
887+
* The receiving node:
888+
* - if `fee_satoshis` matches its previously sent
889+
* `fee_range`:
890+
* - SHOULD use `fee_satoshis` to sign and
891+
* broadcast the final closing transaction
892+
*/
893+
offer[LOCAL] = offer[REMOTE];
894+
}
789895
}
790896
}
791897

@@ -814,7 +920,8 @@ int main(int argc, char *argv[])
814920
funding, out, opener,
815921
our_dust_limit,
816922
offer[LOCAL],
817-
wrong_funding);
923+
wrong_funding,
924+
our_feerange);
818925
} else {
819926
peer_billboard(false, "Waiting for another"
820927
" closing fee offer:"
@@ -831,7 +938,8 @@ int main(int argc, char *argv[])
831938
our_dust_limit,
832939
min_fee_to_accept,
833940
wrong_funding,
834-
&closing_txid);
941+
&closing_txid,
942+
their_feerange);
835943
}
836944

837945
whose_turn = !whose_turn;
@@ -841,6 +949,7 @@ int main(int argc, char *argv[])
841949
offer[LOCAL],
842950
type_to_string(tmpctx, struct bitcoin_txid, &closing_txid));
843951

952+
exit_thru_the_giftshop:
844953
#if DEVELOPER
845954
/* We don't listen for master commands, so always check memleak here */
846955
tal_free(wrong_funding);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--- wire/peer_wire.csv 2021-05-18 11:15:05.539134131 -0500
2+
+++ - 2021-05-18 11:15:15.690789516 -0500
3+
@@ -90,6 +90,10 @@
4+
msgdata,closing_signed,channel_id,channel_id,
5+
msgdata,closing_signed,fee_satoshis,u64,
6+
msgdata,closing_signed,signature,signature,
7+
+msgdata,closing_signed,tlvs,closing_signed_tlvs,
8+
+tlvtype,closing_signed_tlvs,fee_range,1
9+
+tlvdata,closing_signed_tlvs,fee_range,min_fee_satoshis,u64,
10+
+tlvdata,closing_signed_tlvs,fee_range,max_fee_satoshis,u64,
11+
msgtype,update_add_htlc,128
12+
msgdata,update_add_htlc,channel_id,channel_id,
13+
msgdata,update_add_htlc,id,u64,

wire/test/run-peer-wire.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,20 +611,27 @@ static struct msg_funding_signed *fromwire_struct_funding_signed(const tal_t *ct
611611
static void *towire_struct_closing_signed(const tal_t *ctx,
612612
const struct msg_closing_signed *s)
613613
{
614+
struct tlv_closing_signed_tlvs *close_tlvs;
615+
616+
close_tlvs = tlv_closing_signed_tlvs_new(ctx);
614617
return towire_closing_signed(ctx,
615618
&s->channel_id,
616619
s->fee_satoshis,
617-
&s->signature);
620+
&s->signature,
621+
close_tlvs);
618622
}
619623

620624
static struct msg_closing_signed *fromwire_struct_closing_signed(const tal_t *ctx, const void *p)
621625
{
622626
struct msg_closing_signed *s = tal(ctx, struct msg_closing_signed);
627+
struct tlv_closing_signed_tlvs *close_tlvs;
623628

629+
close_tlvs = tlv_closing_signed_tlvs_new(ctx);
624630
if (fromwire_closing_signed(p,
625631
&s->channel_id,
626632
&s->fee_satoshis,
627-
&s->signature))
633+
&s->signature,
634+
close_tlvs))
628635
return s;
629636
return tal_free(s);
630637
}

0 commit comments

Comments
 (0)