diff --git a/Makefile b/Makefile index f0b72dd3d276..d7a853e71814 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ CCANDIR := ccan # Where we keep the BOLT RFCs BOLTDIR := ../lightning-rfc/ -DEFAULT_BOLTVERSION := 3508e4e85d26240ae7492c3d2e02770cdc360fe9 +DEFAULT_BOLTVERSION := 498f104fd399488c77f449d05cb21c0b604636a2 # Can be overridden on cmdline. BOLTVERSION := $(DEFAULT_BOLTVERSION) diff --git a/channeld/channeld.c b/channeld/channeld.c index 51e43117cdc9..3bb10e168ac4 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -1173,7 +1173,7 @@ static struct bitcoin_signature *unraw_sigs(const tal_t *ctx, /* BOLT #3: * ## HTLC-Timeout and HTLC-Success Transactions *... - * * if `option_anchor_outputs` applies to this commitment + * * if `option_anchors` applies to this commitment * transaction, `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is * used. */ @@ -2489,7 +2489,8 @@ static void resend_commitment(struct peer *peer, struct changed_htlc *last) /* BOLT #2: * * A receiving node: - * - if `option_static_remotekey` applies to the commitment transaction: + * - if `option_static_remotekey` or `option_anchors` applies to the + * commitment transaction: * - if `next_revocation_number` is greater than expected above, AND * `your_last_per_commitment_secret` is correct for that * `next_revocation_number` minus 1: @@ -2552,7 +2553,8 @@ static void check_future_dataloss_fields(struct peer *peer, /* BOLT #2: * * A receiving node: - * - if `option_static_remotekey` applies to the commitment transaction: + * - if `option_static_remotekey` or `option_anchors` applies to the + * commitment transaction: * ... * - if `your_last_per_commitment_secret` does not match the expected values: * - SHOULD fail the channel. @@ -2764,7 +2766,7 @@ static void peer_reconnect(struct peer *peer, * of the next `commitment_signed` it expects to receive. * - MUST set `next_revocation_number` to the commitment number * of the next `revoke_and_ack` message it expects to receive. - * - if `option_static_remotekey` applies to the commitment transaction: + * - if `option_static_remotekey` or `option_anchors` applies to the commitment transaction: * - MUST set `my_current_per_commitment_point` to a valid point. * - otherwise: * - MUST set `my_current_per_commitment_point` to its commitment @@ -3789,6 +3791,8 @@ static void init_channel(struct peer *peer) &funding_pubkey[REMOTE], option_static_remotekey, option_anchor_outputs, + feature_offered(peer->their_features, + OPT_LARGE_CHANNELS), opener); if (!channel_force_htlcs(peer->channel, diff --git a/channeld/commit_tx.c b/channeld/commit_tx.c index 8718d7577e18..26c8cf1f8eb7 100644 --- a/channeld/commit_tx.c +++ b/channeld/commit_tx.c @@ -147,7 +147,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, base_fee.satoshis /* Raw: spec uses raw numbers */); /* BOLT #3: - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, also subtract two times the fixed anchor size * of 330 sats from the funder (either `to_local` or * `to_remote`). @@ -281,7 +281,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, * * #### `to_remote` Output * - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, the `to_remote` output is encumbered by a one * block csv lock. * OP_CHECKSIGVERIFY 1 OP_CHECKSEQUENCEVERIFY @@ -329,7 +329,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, /* BOLT #3: * - * 8. If `option_anchor_outputs` applies to the commitment transaction: + * 8. If `option_anchors` applies to the commitment transaction: * * if `to_local` exists or there are untrimmed HTLCs, add a * [`to_local_anchor` output]... * * if `to_remote` exists or there are untrimmed HTLCs, add a diff --git a/channeld/full_channel.c b/channeld/full_channel.c index f9291a8d7e09..39fb3dacb8a7 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -109,6 +109,7 @@ struct channel *new_full_channel(const tal_t *ctx, const struct pubkey *remote_funding_pubkey, bool option_static_remotekey, bool option_anchor_outputs, + bool option_wumbo, enum side opener) { struct channel *channel = new_initial_channel(ctx, @@ -128,6 +129,7 @@ struct channel *new_full_channel(const tal_t *ctx, remote_funding_pubkey, option_static_remotekey, option_anchor_outputs, + option_wumbo, opener); if (channel) { @@ -576,7 +578,8 @@ static enum channel_add_err add_htlc(struct channel *channel, return CHANNEL_ERR_HTLC_BELOW_MINIMUM; } - /* BOLT #2: + /* FIXME: There used to be a requirement that we not send more than + * 2^32 msat, *but* only electrum enforced it. Remove in next version: * * A sending node: *... @@ -584,7 +587,8 @@ static enum channel_add_err add_htlc(struct channel *channel, * - MUST set the four most significant bytes of `amount_msat` to 0. */ if (sender == LOCAL - && amount_msat_greater(htlc->amount, chainparams->max_payment)) { + && amount_msat_greater(htlc->amount, chainparams->max_payment) + && !channel->option_wumbo) { return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED; } @@ -676,7 +680,7 @@ static enum channel_add_err add_htlc(struct channel *channel, return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED; /* BOLT #3: - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, also subtract two times the fixed anchor size * of 330 sats from the funder (either `to_local` or * `to_remote`). @@ -1098,7 +1102,7 @@ u32 approx_max_feerate(const struct channel *channel) avail = amount_msat_to_sat_round_down(channel->view[!channel->opener].owed[channel->opener]); /* BOLT #3: - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, also subtract two times the fixed anchor size * of 330 sats from the funder (either `to_local` or * `to_remote`). @@ -1139,7 +1143,7 @@ bool can_opener_afford_feerate(const struct channel *channel, u32 feerate_per_kw channel->option_anchor_outputs); /* BOLT #3: - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, also subtract two times the fixed anchor size * of 330 sats from the funder (either `to_local` or * `to_remote`). diff --git a/channeld/full_channel.h b/channeld/full_channel.h index 56b7c1514aa1..689a873c339b 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -30,6 +30,7 @@ struct existing_htlc; * @remote_fundingkey: remote funding key * @option_static_remotekey: use `option_static_remotekey`. * @option_anchor_outputs: use `option_anchor_outputs`. + * @option_wumbo: large channel negotiated. * @opener: which side initiated it. * * Returns state, or NULL if malformed. @@ -52,6 +53,7 @@ struct channel *new_full_channel(const tal_t *ctx, const struct pubkey *remote_funding_pubkey, bool option_static_remotekey, bool option_anchor_outputs, + bool option_wumbo, enum side opener); /** diff --git a/channeld/test/run-commit_tx.c b/channeld/test/run-commit_tx.c index 2006d7194320..eb167f7d27ac 100644 --- a/channeld/test/run-commit_tx.c +++ b/channeld/test/run-commit_tx.c @@ -1067,7 +1067,7 @@ int main(int argc, const char *argv[]) option_anchor_outputs); /* BOLT #3: - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, also subtract two times the fixed anchor size * of 330 sats from the funder (either `to_local` or * `to_remote`). diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 3ab15b23957d..a9cb50362fbc 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -493,7 +493,7 @@ int main(int argc, const char *argv[]) &localbase, &remotebase, &local_funding_pubkey, &remote_funding_pubkey, - false, false, LOCAL); + false, false, false, LOCAL); rchannel = new_full_channel(tmpctx, &cid, &funding_txid, funding_output_index, 0, take(new_height_states(NULL, REMOTE, &blockheight)), @@ -506,7 +506,7 @@ int main(int argc, const char *argv[]) &remotebase, &localbase, &remote_funding_pubkey, &local_funding_pubkey, - false, false, REMOTE); + false, false, false, REMOTE); /* BOLT #3: * @@ -607,7 +607,7 @@ int main(int argc, const char *argv[]) /* FIXME: Compare signatures! */ /* BOLT #3: * - * output htlc_success_tx 0: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000 + * htlc_success_tx (htlc #0): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000 */ raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000"); raw_tx->chainparams = chainparams; @@ -616,7 +616,7 @@ int main(int argc, const char *argv[]) /* BOLT #3: * - * output htlc_timeout_tx 2: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000 + * htlc_timeout_tx (htlc #2): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000 */ raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"); raw_tx->chainparams = chainparams; @@ -625,7 +625,7 @@ int main(int argc, const char *argv[]) /* BOLT #3: * - * output htlc_success_tx 1: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f20201483045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000 + * htlc_success_tx (htlc #1): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f20201483045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000 */ raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f20201483045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000"); raw_tx->chainparams = chainparams; @@ -634,7 +634,7 @@ int main(int argc, const char *argv[]) /* BOLT #3: * - * output htlc_timeout_tx 3: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219703000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554014730440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac0872701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000 + * htlc_timeout_tx (htlc #3): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219703000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554014730440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac0872701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000 */ raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219703000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554014730440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac0872701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"); raw_tx->chainparams = chainparams; @@ -643,7 +643,7 @@ int main(int argc, const char *argv[]) /* BOLT #3: * - * output htlc_success_tx 4: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219704000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d014730440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000 + * htlc_success_tx (htlc #4): 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219704000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d014730440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000 */ raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219704000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d014730440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"); raw_tx->chainparams = chainparams; diff --git a/closingd/closingd.c b/closingd/closingd.c index 792749f21b26..0a32770a2876 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -141,10 +141,12 @@ static void send_offer(struct per_peer_state *pps, enum side opener, struct amount_sat our_dust_limit, struct amount_sat fee_to_offer, - const struct bitcoin_outpoint *wrong_funding) + const struct bitcoin_outpoint *wrong_funding, + const struct tlv_closing_signed_tlvs_fee_range *tlv_fees) { struct bitcoin_tx *tx; struct bitcoin_signature our_sig; + struct tlv_closing_signed_tlvs *close_tlvs; u8 *msg; /* BOLT #2: @@ -184,8 +186,19 @@ static void send_offer(struct per_peer_state *pps, status_debug("sending fee offer %s", type_to_string(tmpctx, struct amount_sat, &fee_to_offer)); + /* Add the new close_tlvs with our fee range */ + if (tlv_fees) { + close_tlvs = tlv_closing_signed_tlvs_new(msg); + close_tlvs->fee_range + = cast_const(struct tlv_closing_signed_tlvs_fee_range *, + tlv_fees); + } else + close_tlvs = NULL; + assert(our_sig.sighash_type == SIGHASH_ALL); - msg = towire_closing_signed(NULL, channel_id, fee_to_offer, &our_sig.s); + msg = towire_closing_signed(NULL, channel_id, fee_to_offer, &our_sig.s, + close_tlvs); + sync_crypto_write(pps, take(msg)); } @@ -222,13 +235,15 @@ receive_offer(struct per_peer_state *pps, struct amount_sat our_dust_limit, struct amount_sat min_fee_to_accept, const struct bitcoin_outpoint *wrong_funding, - struct bitcoin_txid *closing_txid) + struct bitcoin_txid *closing_txid, + struct tlv_closing_signed_tlvs_fee_range **tlv_fees) { u8 *msg; struct channel_id their_channel_id; struct amount_sat received_fee; struct bitcoin_signature their_sig; struct bitcoin_tx *tx; + struct tlv_closing_signed_tlvs *close_tlvs; /* Wait for them to say something interesting */ do { @@ -252,8 +267,10 @@ receive_offer(struct per_peer_state *pps, } while (!msg); their_sig.sighash_type = SIGHASH_ALL; + close_tlvs = tlv_closing_signed_tlvs_new(msg); if (!fromwire_closing_signed(msg, &their_channel_id, - &received_fee, &their_sig.s)) + &received_fee, &their_sig.s, + close_tlvs)) peer_failed_warn(pps, channel_id, "Expected closing_signed: %s", tal_hex(tmpctx, msg)); @@ -327,6 +344,13 @@ receive_offer(struct per_peer_state *pps, status_debug("Received fee offer %s", type_to_string(tmpctx, struct amount_sat, &received_fee)); + if (tlv_fees) { + if (close_tlvs) + *tlv_fees = tal_steal(tlv_fees, close_tlvs->fee_range); + else + *tlv_fees = NULL; + } + /* Master sorts out what is best offer, we just tell it any above min */ if (amount_sat_greater_eq(received_fee, min_fee_to_accept)) { status_debug("...offer is reasonable"); @@ -347,7 +371,8 @@ static void init_feerange(struct feerange *feerange, { feerange->min = AMOUNT_SAT(0); - /* BOLT #2: + /* FIXME: BOLT 2 previously said that we have to set it to less than + * the final commit fee: we do this for now, still: * * - MUST set `fee_satoshis` less than or equal to the base * fee of the final commitment transaction, as calculated @@ -371,7 +396,8 @@ static void adjust_feerange(struct feerange *feerange, { bool ok; - /* BOLT #2: + /* FIXME: BOLT 2 previously said that we have to set it to less than + * the final commit fee: we do this for now, still: * * - MUST propose a value "strictly between" the received * `fee_satoshis` and its previously-sent `fee_satoshis`. @@ -392,6 +418,32 @@ static void adjust_feerange(struct feerange *feerange, "Overflow in updating fee range"); } +/* Do these two ranges overlap? If so, return that range. */ +static bool get_overlap(const struct tlv_closing_signed_tlvs_fee_range *r1, + const struct tlv_closing_signed_tlvs_fee_range *r2, + struct tlv_closing_signed_tlvs_fee_range *overlap) +{ + if (amount_sat_greater(r1->min_fee_satoshis, r2->min_fee_satoshis)) + overlap->min_fee_satoshis = r1->min_fee_satoshis; + else + overlap->min_fee_satoshis = r2->min_fee_satoshis; + if (amount_sat_less(r1->max_fee_satoshis, r2->max_fee_satoshis)) + overlap->max_fee_satoshis = r1->max_fee_satoshis; + else + overlap->max_fee_satoshis = r2->max_fee_satoshis; + + return amount_sat_less_eq(overlap->min_fee_satoshis, + overlap->max_fee_satoshis); +} + +/* Is this amount in this range? */ +static bool amount_in_range(struct amount_sat amount, + const struct tlv_closing_signed_tlvs_fee_range *r) +{ + return amount_sat_greater_eq(amount, r->min_fee_satoshis) + && amount_sat_less_eq(amount, r->max_fee_satoshis); +} + /* Figure out what we should offer now. */ static struct amount_sat adjust_offer(struct per_peer_state *pps, const struct channel_id *channel_id, @@ -532,16 +584,60 @@ static size_t closing_tx_weight_estimate(u8 *scriptpubkey[NUM_SIDES], static void calc_fee_bounds(size_t expected_weight, u32 min_feerate, u32 desired_feerate, - struct amount_sat maxfee, + u32 *max_feerate, + struct amount_sat commitment_fee, + struct amount_sat funding, + enum side opener, struct amount_sat *minfee, - struct amount_sat *desiredfee) + struct amount_sat *desiredfee, + struct amount_sat *maxfee) { *minfee = amount_tx_fee(min_feerate, expected_weight); *desiredfee = amount_tx_fee(desired_feerate, expected_weight); + /* BOLT-closing-fee_range #2: + * - if it is not the funder: + * - SHOULD set `max_fee_satoshis` to at least the `max_fee_satoshis` + * received + *... + * Note that the non-funder is not paying the fee, so there is + * no reason for it to have a maximum feerate. + */ + if (opener == REMOTE) { + *maxfee = funding; + /* BOLT-closing-fee_range #2: + * - If the channel does not use `option_anchor_outputs`: + * - MUST set `fee_satoshis` less than or equal to the base fee of + * the final commitment transaction, as calculated in + * [BOLT #3](03-transactions.md#fee-calculation). + */ + } else if (max_feerate) { + *maxfee = amount_tx_fee(*max_feerate, expected_weight); + + status_debug("deriving max fee from rate %u -> %s (not %s)", + *max_feerate, + type_to_string(tmpctx, struct amount_sat, maxfee), + type_to_string(tmpctx, struct amount_sat, &commitment_fee)); + + /* option_anchor_outputs sets commitment_fee to max, so this + * doesn't do anything */ + if (amount_sat_greater(*maxfee, commitment_fee)) { + /* FIXME: would be nice to notify close cmd here! */ + status_unusual("Maximum feerate %u would give fee %s:" + " we must limit it to the final commitment fee %s", + *max_feerate, + type_to_string(tmpctx, struct amount_sat, + maxfee), + type_to_string(tmpctx, struct amount_sat, + &commitment_fee)); + *maxfee = commitment_fee; + } + } else + *maxfee = commitment_fee; + /* Can't exceed maxfee. */ - if (amount_sat_greater(*minfee, maxfee)) - *minfee = maxfee; + if (amount_sat_greater(*minfee, *maxfee)) + *minfee = *maxfee; if (amount_sat_less(*desiredfee, *minfee)) { status_unusual("Our ideal fee is %s (%u sats/perkw)," @@ -551,20 +647,191 @@ static void calc_fee_bounds(size_t expected_weight, type_to_string(tmpctx, struct amount_sat, minfee)); *desiredfee = *minfee; } - if (amount_sat_greater(*desiredfee, maxfee)) { + if (amount_sat_greater(*desiredfee, *maxfee)) { status_unusual("Our ideal fee is %s (%u sats/perkw)," " but our maximum is %s: using that", type_to_string(tmpctx, struct amount_sat, desiredfee), desired_feerate, - type_to_string(tmpctx, struct amount_sat, &maxfee)); - *desiredfee = maxfee; + type_to_string(tmpctx, struct amount_sat, maxfee)); + *desiredfee = *maxfee; } status_debug("Expected closing weight = %zu, fee %s (min %s, max %s)", expected_weight, type_to_string(tmpctx, struct amount_sat, desiredfee), type_to_string(tmpctx, struct amount_sat, minfee), - type_to_string(tmpctx, struct amount_sat, &maxfee)); + type_to_string(tmpctx, struct amount_sat, maxfee)); +} + +/* We've received one offer; if we're opener, that means we've already sent one + * too. */ +static void do_quickclose(struct amount_sat offer[NUM_SIDES], + struct per_peer_state *pps, + const struct channel_id *channel_id, + const struct pubkey funding_pubkey[NUM_SIDES], + const u8 *funding_wscript, + u8 *scriptpubkey[NUM_SIDES], + const struct bitcoin_txid *funding_txid, + unsigned int funding_txout, + struct amount_sat funding, + const struct amount_sat out[NUM_SIDES], + enum side opener, + struct amount_sat our_dust_limit, + const struct bitcoin_outpoint *wrong_funding, + struct bitcoin_txid *closing_txid, + const struct tlv_closing_signed_tlvs_fee_range *our_feerange, + const struct tlv_closing_signed_tlvs_fee_range *their_feerange) +{ + struct tlv_closing_signed_tlvs_fee_range overlap; + + + /* BOLT-closing-fee_range #2: + * - if the message contains a `fee_range`: + * - if there is no overlap between that and its own `fee_range`: + * - SHOULD fail the connection + */ + if (!get_overlap(our_feerange, their_feerange, &overlap)) { + peer_failed_warn(pps, channel_id, + "Unable to agree on a feerate." + " Our range %s-%s, other range %s-%s", + type_to_string(tmpctx, + struct amount_sat, + &our_feerange->min_fee_satoshis), + type_to_string(tmpctx, + struct amount_sat, + &our_feerange->max_fee_satoshis), + type_to_string(tmpctx, + struct amount_sat, + &their_feerange->min_fee_satoshis), + type_to_string(tmpctx, + struct amount_sat, + &their_feerange->max_fee_satoshis)); + return; + } + + status_info("performing quickclose in range %s-%s", + type_to_string(tmpctx, struct amount_sat, + &overlap.min_fee_satoshis), + type_to_string(tmpctx, struct amount_sat, + &overlap.max_fee_satoshis)); + + /* BOLT-closing-fee_range #2: + * - otherwise: + * - if it is the funder: + * - if `fee_satoshis` is not in the overlap between the sent + * and received `fee_range`: + * - SHOULD fail the connection + * - otherwise: + * - MUST reply with the same `fee_satoshis`. + */ + if (opener == LOCAL) { + if (!amount_in_range(offer[REMOTE], &overlap)) { + peer_failed_warn(pps, channel_id, + "Your fee %s was not in range:" + " Our range %s-%s, other range %s-%s", + type_to_string(tmpctx, + struct amount_sat, &offer[REMOTE]), + type_to_string(tmpctx, + struct amount_sat, + &our_feerange->min_fee_satoshis), + type_to_string(tmpctx, + struct amount_sat, + &our_feerange->max_fee_satoshis), + type_to_string(tmpctx, + struct amount_sat, + &their_feerange->min_fee_satoshis), + type_to_string(tmpctx, + struct amount_sat, + &their_feerange->max_fee_satoshis)); + return; + } + /* Only reply if we didn't already completely agree. */ + if (!amount_sat_eq(offer[LOCAL], offer[REMOTE])) { + offer[LOCAL] = offer[REMOTE]; + send_offer(pps, chainparams, + channel_id, funding_pubkey, funding_wscript, + scriptpubkey, funding_txid, funding_txout, + funding, out, opener, + our_dust_limit, + offer[LOCAL], + wrong_funding, + our_feerange); + } + } else { + /* BOLT-closing-fee_range #2: + * - otherwise (it is not the funder): + * - if it has already sent a `closing_signed`: + * - if `fee_satoshis` is not the same as the value it sent: + * - SHOULD fail the connection. + * - otherwise: + * - MUST propose a `fee_satoshis` in the overlap between + * received and (about-to-be) sent `fee_range`. + */ + if (!amount_in_range(offer[LOCAL], &overlap)) { + /* Hmm, go to edges. */ + if (amount_sat_greater(offer[LOCAL], + overlap.max_fee_satoshis)) { + offer[LOCAL] = overlap.max_fee_satoshis; + status_unusual("Lowered offer to max allowable" + " %s", + type_to_string(tmpctx, + struct amount_sat, + &offer[LOCAL])); + } else if (amount_sat_less(offer[LOCAL], + overlap.min_fee_satoshis)) { + offer[LOCAL] = overlap.min_fee_satoshis; + status_unusual("Increased offer to min allowable" + " %s", + type_to_string(tmpctx, + struct amount_sat, + &offer[LOCAL])); + } + } + send_offer(pps, chainparams, + channel_id, funding_pubkey, funding_wscript, + scriptpubkey, funding_txid, funding_txout, + funding, out, opener, + our_dust_limit, + offer[LOCAL], + wrong_funding, + our_feerange); + + /* They will reply unless we completely agreed. */ + if (!amount_sat_eq(offer[LOCAL], offer[REMOTE])) { + offer[REMOTE] + = receive_offer(pps, chainparams, + channel_id, funding_pubkey, + funding_wscript, + scriptpubkey, funding_txid, + funding_txout, funding, + out, opener, + our_dust_limit, + our_feerange->min_fee_satoshis, + wrong_funding, + closing_txid, + NULL); + /* BOLT-closing-fee_range #2: + * - otherwise (it is not the funder): + * - if it has already sent a `closing_signed`: + * - if `fee_satoshis` is not the same as the value + * it sent: + * - SHOULD fail the connection. + */ + if (!amount_sat_eq(offer[LOCAL], offer[REMOTE])) { + peer_failed_warn(pps, channel_id, + "Your fee %s was not equal to %s", + type_to_string(tmpctx, + struct amount_sat, &offer[REMOTE]), + type_to_string(tmpctx, + struct amount_sat, &offer[LOCAL])); + return; + } + } + } + + peer_billboard(true, "We agreed on a closing fee of %"PRIu64" satoshi for tx:%s", + offer[LOCAL], + type_to_string(tmpctx, struct bitcoin_txid, closing_txid)); } int main(int argc, char *argv[]) @@ -579,8 +846,9 @@ int main(int argc, char *argv[]) u16 funding_txout; struct amount_sat funding, out[NUM_SIDES]; struct amount_sat our_dust_limit; - struct amount_sat min_fee_to_accept, commitment_fee, offer[NUM_SIDES]; - u32 min_feerate, initial_feerate; + struct amount_sat min_fee_to_accept, commitment_fee, offer[NUM_SIDES], + max_fee_to_accept; + u32 min_feerate, initial_feerate, *max_feerate; struct feerange feerange; enum side opener; u8 *scriptpubkey[NUM_SIDES], *funding_wscript; @@ -589,6 +857,8 @@ int main(int argc, char *argv[]) char fee_negotiation_step_str[32]; /* fee_negotiation_step + "sat" */ struct channel_id channel_id; enum side whose_turn; + bool use_quickclose; + struct tlv_closing_signed_tlvs_fee_range *our_feerange, **their_feerange; struct bitcoin_outpoint *wrong_funding; subdaemon_setup(argc, argv); @@ -608,12 +878,13 @@ int main(int argc, char *argv[]) &out[LOCAL], &out[REMOTE], &our_dust_limit, - &min_feerate, &initial_feerate, + &min_feerate, &initial_feerate, &max_feerate, &commitment_fee, &scriptpubkey[LOCAL], &scriptpubkey[REMOTE], &fee_negotiation_step, &fee_negotiation_step_unit, + &use_quickclose, &dev_fast_gossip, &wrong_funding)) master_badmsg(WIRE_CLOSINGD_INIT, msg); @@ -629,8 +900,20 @@ int main(int argc, char *argv[]) calc_fee_bounds(closing_tx_weight_estimate(scriptpubkey, funding_wscript, out, funding, our_dust_limit), - min_feerate, initial_feerate, commitment_fee, - &min_fee_to_accept, &offer[LOCAL]); + min_feerate, initial_feerate, max_feerate, + commitment_fee, funding, opener, + &min_fee_to_accept, &offer[LOCAL], &max_fee_to_accept); + + /* Write values into tlv for updated closing fee neg */ + their_feerange = tal(ctx, struct tlv_closing_signed_tlvs_fee_range *); + *their_feerange = NULL; + + if (use_quickclose) { + our_feerange = tal(ctx, struct tlv_closing_signed_tlvs_fee_range); + our_feerange->min_fee_satoshis = min_fee_to_accept; + our_feerange->max_fee_satoshis = max_fee_to_accept; + } else + our_feerange = NULL; snprintf(fee_negotiation_step_str, sizeof(fee_negotiation_step_str), "%" PRIu64 "%s", fee_negotiation_step, @@ -658,7 +941,7 @@ int main(int argc, char *argv[]) "Negotiating closing fee between %s and %s satoshi (ideal %s) " "using step %s", type_to_string(tmpctx, struct amount_sat, &min_fee_to_accept), - type_to_string(tmpctx, struct amount_sat, &commitment_fee), + type_to_string(tmpctx, struct amount_sat, &max_fee_to_accept), type_to_string(tmpctx, struct amount_sat, &offer[LOCAL]), fee_negotiation_step_str); @@ -678,7 +961,8 @@ int main(int argc, char *argv[]) funding, out, opener, our_dust_limit, offer[LOCAL], - wrong_funding); + wrong_funding, + our_feerange); } else { if (i == 0) peer_billboard(false, "Waiting for their initial" @@ -700,12 +984,27 @@ int main(int argc, char *argv[]) our_dust_limit, min_fee_to_accept, wrong_funding, - &closing_txid); + &closing_txid, + their_feerange); + + if (our_feerange && *their_feerange) { + do_quickclose(offer, + pps, &channel_id, funding_pubkey, + funding_wscript, + scriptpubkey, + &funding_txid, funding_txout, + funding, out, opener, + our_dust_limit, + wrong_funding, + &closing_txid, + our_feerange, *their_feerange); + goto exit_thru_the_giftshop; + } } } /* Now we have first two points, we can init fee range. */ - init_feerange(&feerange, commitment_fee, offer); + init_feerange(&feerange, max_fee_to_accept, offer); /* Apply (and check) opener offer now. */ adjust_feerange(&feerange, offer[opener], opener); @@ -729,7 +1028,8 @@ int main(int argc, char *argv[]) funding, out, opener, our_dust_limit, offer[LOCAL], - wrong_funding); + wrong_funding, + our_feerange); } else { peer_billboard(false, "Waiting for another" " closing fee offer:" @@ -746,7 +1046,8 @@ int main(int argc, char *argv[]) our_dust_limit, min_fee_to_accept, wrong_funding, - &closing_txid); + &closing_txid, + their_feerange); } whose_turn = !whose_turn; @@ -756,9 +1057,13 @@ int main(int argc, char *argv[]) offer[LOCAL], type_to_string(tmpctx, struct bitcoin_txid, &closing_txid)); +exit_thru_the_giftshop: #if DEVELOPER /* We don't listen for master commands, so always check memleak here */ tal_free(wrong_funding); + tal_free(our_feerange); + tal_free(their_feerange); + tal_free(max_feerate); closing_dev_memleak(ctx, scriptpubkey, funding_wscript); #endif diff --git a/closingd/closingd_wire.csv b/closingd/closingd_wire.csv index aa58ea18fa08..b1e5ea8d47b2 100644 --- a/closingd/closingd_wire.csv +++ b/closingd/closingd_wire.csv @@ -19,6 +19,7 @@ msgdata,closingd_init,remote_sat,amount_sat, msgdata,closingd_init,our_dust_limit,amount_sat, msgdata,closingd_init,min_feerate_perksipa,u32, msgdata,closingd_init,preferred_feerate_perksipa,u32, +msgdata,closingd_init,max_feerate_perksipa,?u32, msgdata,closingd_init,fee_limit_satoshi,amount_sat, msgdata,closingd_init,local_scriptpubkey_len,u16, msgdata,closingd_init,local_scriptpubkey,u8,local_scriptpubkey_len @@ -26,6 +27,7 @@ msgdata,closingd_init,remote_scriptpubkey_len,u16, msgdata,closingd_init,remote_scriptpubkey,u8,remote_scriptpubkey_len msgdata,closingd_init,fee_negotiation_step,u64, msgdata,closingd_init,fee_negotiation_step_unit,u8, +msgdata,closingd_init,use_quickclose,bool, msgdata,closingd_init,dev_fast_gossip,bool, msgdata,closingd_init,shutdown_wrong_funding,?bitcoin_outpoint, diff --git a/closingd/closingd_wiregen.c b/closingd/closingd_wiregen.c index e53826507e43..c8c8b6c3ec9e 100644 --- a/closingd/closingd_wiregen.c +++ b/closingd/closingd_wiregen.c @@ -48,7 +48,7 @@ bool closingd_wire_is_defined(u16 type) /* WIRE: CLOSINGD_INIT */ /* Begin! (passes peer fd */ -u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, u32 min_feerate_perksipa, u32 preferred_feerate_perksipa, struct amount_sat fee_limit_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding) +u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, u32 min_feerate_perksipa, u32 preferred_feerate_perksipa, u32 *max_feerate_perksipa, struct amount_sat fee_limit_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool use_quickclose, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding) { u16 local_scriptpubkey_len = tal_count(local_scriptpubkey); u16 remote_scriptpubkey_len = tal_count(remote_scriptpubkey); @@ -69,6 +69,12 @@ u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams towire_amount_sat(&p, our_dust_limit); towire_u32(&p, min_feerate_perksipa); towire_u32(&p, preferred_feerate_perksipa); + if (!max_feerate_perksipa) + towire_bool(&p, false); + else { + towire_bool(&p, true); + towire_u32(&p, *max_feerate_perksipa); + } towire_amount_sat(&p, fee_limit_satoshi); towire_u16(&p, local_scriptpubkey_len); towire_u8_array(&p, local_scriptpubkey, local_scriptpubkey_len); @@ -76,6 +82,7 @@ u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams towire_u8_array(&p, remote_scriptpubkey, remote_scriptpubkey_len); towire_u64(&p, fee_negotiation_step); towire_u8(&p, fee_negotiation_step_unit); + towire_bool(&p, use_quickclose); towire_bool(&p, dev_fast_gossip); if (!shutdown_wrong_funding) towire_bool(&p, false); @@ -86,7 +93,7 @@ u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams return memcheck(p, tal_count(p)); } -bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, u32 *min_feerate_perksipa, u32 *preferred_feerate_perksipa, struct amount_sat *fee_limit_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding) +bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, u32 *min_feerate_perksipa, u32 *preferred_feerate_perksipa, u32 **max_feerate_perksipa, struct amount_sat *fee_limit_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *use_quickclose, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding) { u16 local_scriptpubkey_len; u16 remote_scriptpubkey_len; @@ -110,6 +117,12 @@ bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainp *our_dust_limit = fromwire_amount_sat(&cursor, &plen); *min_feerate_perksipa = fromwire_u32(&cursor, &plen); *preferred_feerate_perksipa = fromwire_u32(&cursor, &plen); + if (!fromwire_bool(&cursor, &plen)) + *max_feerate_perksipa = NULL; + else { + *max_feerate_perksipa = tal(ctx, u32); + **max_feerate_perksipa = fromwire_u32(&cursor, &plen); + } *fee_limit_satoshi = fromwire_amount_sat(&cursor, &plen); local_scriptpubkey_len = fromwire_u16(&cursor, &plen); // 2nd case local_scriptpubkey @@ -121,6 +134,7 @@ bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainp fromwire_u8_array(&cursor, &plen, *remote_scriptpubkey, remote_scriptpubkey_len); *fee_negotiation_step = fromwire_u64(&cursor, &plen); *fee_negotiation_step_unit = fromwire_u8(&cursor, &plen); + *use_quickclose = fromwire_bool(&cursor, &plen); *dev_fast_gossip = fromwire_bool(&cursor, &plen); if (!fromwire_bool(&cursor, &plen)) *shutdown_wrong_funding = NULL; @@ -195,4 +209,4 @@ bool fromwire_closingd_complete(const void *p) return false; return cursor != NULL; } -// SHA256STAMP:961ca5ceef03f911684ba0e7863d69993e692b9b418108e6038a567cb7cc7b3e +// SHA256STAMP:be6dbb532dfd3c159212838acedd4bad3c8b4b16b5193b8c2a752697a15c8ab1 diff --git a/closingd/closingd_wiregen.h b/closingd/closingd_wiregen.h index cc1ad7c9dfaa..5a02f8036a5e 100644 --- a/closingd/closingd_wiregen.h +++ b/closingd/closingd_wiregen.h @@ -37,8 +37,8 @@ bool closingd_wire_is_defined(u16 type); /* WIRE: CLOSINGD_INIT */ /* Begin! (passes peer fd */ -u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, u32 min_feerate_perksipa, u32 preferred_feerate_perksipa, struct amount_sat fee_limit_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding); -bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, u32 *min_feerate_perksipa, u32 *preferred_feerate_perksipa, struct amount_sat *fee_limit_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding); +u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, u32 min_feerate_perksipa, u32 preferred_feerate_perksipa, u32 *max_feerate_perksipa, struct amount_sat fee_limit_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool use_quickclose, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding); +bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, u32 *min_feerate_perksipa, u32 *preferred_feerate_perksipa, u32 **max_feerate_perksipa, struct amount_sat *fee_limit_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *use_quickclose, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding); /* WIRE: CLOSINGD_RECEIVED_SIGNATURE */ /* We received an offer */ @@ -56,4 +56,4 @@ bool fromwire_closingd_complete(const void *p); #endif /* LIGHTNING_CLOSINGD_CLOSINGD_WIREGEN_H */ -// SHA256STAMP:961ca5ceef03f911684ba0e7863d69993e692b9b418108e6038a567cb7cc7b3e +// SHA256STAMP:be6dbb532dfd3c159212838acedd4bad3c8b4b16b5193b8c2a752697a15c8ab1 diff --git a/common/htlc_tx.c b/common/htlc_tx.c index 030ae70fcf6e..2a18dbd6340d 100644 --- a/common/htlc_tx.c +++ b/common/htlc_tx.c @@ -44,7 +44,7 @@ static struct bitcoin_tx *htlc_tx(const tal_t *ctx, * * `txin[0]` outpoint: `txid` of the commitment transaction and * `output_index` of the matching HTLC output for the HTLC * transaction - * * `txin[0]` sequence: `0` (set to `1` for `option_anchor_outputs`) + * * `txin[0]` sequence: `0` (set to `1` for `option_anchors`) */ amount = amount_msat_to_sat_round_down(msat); bitcoin_tx_add_input(tx, commit_txid, commit_output_number, diff --git a/common/htlc_tx.h b/common/htlc_tx.h index 018013c8aff1..2ab1f1c42dd3 100644 --- a/common/htlc_tx.h +++ b/common/htlc_tx.h @@ -47,7 +47,8 @@ static inline struct amount_sat htlc_timeout_fee(u32 feerate_per_kw, /* BOLT #3: * * The fee for an HTLC-timeout transaction: - * - MUST BE calculated to match: + *... + * - Otherwise, MUST BE calculated to match: * 1. Multiply `feerate_per_kw` by 663 (666 if `option_anchor_outputs` * applies) and divide by 1000 (rounding down). */ @@ -65,6 +66,7 @@ static inline struct amount_sat htlc_success_fee(u32 feerate_per_kw, /* BOLT #3: * * The fee for an HTLC-success transaction: + *... * - MUST BE calculated to match: * 1. Multiply `feerate_per_kw` by 703 (706 if `option_anchor_outputs` * applies) and divide by 1000 (rounding down). diff --git a/common/initial_channel.c b/common/initial_channel.c index 2b1cafc98f49..19e6291cbd5e 100644 --- a/common/initial_channel.c +++ b/common/initial_channel.c @@ -35,6 +35,7 @@ struct channel *new_initial_channel(const tal_t *ctx, const struct pubkey *remote_funding_pubkey, bool option_static_remotekey, bool option_anchor_outputs, + bool option_wumbo, enum side opener) { struct channel *channel = tal(ctx, struct channel); @@ -83,6 +84,7 @@ struct channel *new_initial_channel(const tal_t *ctx, channel->option_static_remotekey = option_static_remotekey; channel->option_anchor_outputs = option_anchor_outputs; + channel->option_wumbo = option_wumbo; if (option_anchor_outputs) assert(option_static_remotekey); return channel; diff --git a/common/initial_channel.h b/common/initial_channel.h index 13dcb5e49f2c..dde829e68c23 100644 --- a/common/initial_channel.h +++ b/common/initial_channel.h @@ -75,6 +75,9 @@ struct channel { /* Is this using option_anchor_outputs? */ bool option_anchor_outputs; + /* Are we using big channels? */ + bool option_wumbo; + /* When the lease expires for the funds in this channel */ u32 lease_expiry; }; @@ -99,6 +102,7 @@ struct channel { * @remote_fundingkey: remote funding key * @option_static_remotekey: was this created with option_static_remotekey? * @option_anchor_outputs: was this created with option_anchor_outputs? + * @option_wumbo: has peer currently negotiated wumbo? * @opener: which side initiated it. * * Returns channel, or NULL if malformed. @@ -121,6 +125,7 @@ struct channel *new_initial_channel(const tal_t *ctx, const struct pubkey *remote_funding_pubkey, bool option_static_remotekey, bool option_anchor_outputs, + bool option_wumbo, enum side opener); /** diff --git a/common/initial_commit_tx.c b/common/initial_commit_tx.c index ec515f06d57b..4cb47032ab35 100644 --- a/common/initial_commit_tx.c +++ b/common/initial_commit_tx.c @@ -143,7 +143,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, * * 3. Subtract this base fee from the funder (either `to_local` or * `to_remote`). - * If `option_anchor_outputs` applies to the commitment transaction, + * If `option_anchors` applies to the commitment transaction, * also subtract two times the fixed anchor size of 330 sats from the * funder (either `to_local` or `to_remote`). */ @@ -236,7 +236,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, if (amount_msat_greater_eq_sat(other_pay, dust_limit)) { /* BOLT #3: * - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, the `to_remote` output is encumbered by a one * block csv lock. * OP_CHECKSIGVERIFY 1 OP_CHECKSEQUENCEVERIFY @@ -267,7 +267,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, to_remote = false; /* BOLT #3: - * 8. If `option_anchor_outputs` applies to the commitment transaction: + * 8. If `option_anchors` applies to the commitment transaction: * * if `to_local` exists or there are untrimmed HTLCs, add a * [`to_local_anchor` output]... * * if `to_remote` exists or there are untrimmed HTLCs, add a diff --git a/common/initial_commit_tx.h b/common/initial_commit_tx.h index 90f7dbda426a..4e89f2d4d774 100644 --- a/common/initial_commit_tx.h +++ b/common/initial_commit_tx.h @@ -33,7 +33,7 @@ static inline size_t commit_tx_base_weight(size_t num_untrimmed_htlcs, * * The base fee for a commitment transaction: * - MUST be calculated to match: - * 1. Start with `weight` = 724 (1124 if `option_anchor_outputs` applies). + * 1. Start with `weight` = 724 (1124 if `option_anchors` applies). */ if (option_anchor_outputs) weight = 1124; diff --git a/common/key_derive.c b/common/key_derive.c index 17c14072b1ac..2ed74198e53c 100644 --- a/common/key_derive.c +++ b/common/key_derive.c @@ -20,7 +20,7 @@ * the `local_delayedpubkey` uses the local node's `delayed_payment_basepoint`; * and the `remote_delayedpubkey` uses the remote node's `delayed_payment_basepoint`. *... - * If `option_static_remotekey` or `option_anchor_outputs` is negotiated, the + * If `option_static_remotekey` or `option_anchors` is negotiated, the * `remotepubkey` is simply the remote node's `payment_basepoint`, otherwise * it is calculated as above using the remote node's `payment_basepoint`. */ diff --git a/common/keyset.c b/common/keyset.c index 41c770ebf5d7..680d891c49c4 100644 --- a/common/keyset.c +++ b/common/keyset.c @@ -32,7 +32,7 @@ bool derive_keyset(const struct pubkey *per_commitment_point, * * ### `remotepubkey` Derivation * - * If `option_static_remotekey` or `option_anchor_outputs` is + * If `option_static_remotekey` or `option_anchors` is * negotiated, the `remotepubkey` is simply the remote node's * `payment_basepoint`, otherwise it is calculated as above using the * remote node's `payment_basepoint`. diff --git a/common/test/run-bolt11.c b/common/test/run-bolt11.c index 39747180fd7d..8fb329e536bb 100644 --- a/common/test/run-bolt11.c +++ b/common/test/run-bolt11.c @@ -157,7 +157,7 @@ int main(int argc, char *argv[]) /* BOLT #11: * * > ### Please make a donation of any amount using payment_hash 0001020304050607080900010203040506070809000102030405060708090102 to me @03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad - * > lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w + * > lnbc1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq0py3tfrnxkt5xadpzangn5rry6r0kqt4f3g36lwln8wwpxtxqccn5agpyte3nx0v78uwn78zu6k30k5mgdgn50yvnd20namlmzp2ersq8065fg */ if (!node_id_from_hexstr("03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad", strlen("03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad"), &node)) abort(); @@ -169,14 +169,17 @@ int main(int argc, char *argv[]) * * `lnbc`: prefix, Lightning on Bitcoin mainnet * * `1`: Bech32 separator * * `pvjluez`: timestamp (1496314658) + * * `s`: payment secret + * * `p5`: `data_length` (`p` = 1, `5` = 20; 1 * 32 + 20 == 52) + * * `zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs`: payment secret 1111111111111111111111111111111111111111111111111111111111111111 * * `p`: payment hash * * `p5`: `data_length` (`p` = 1, `5` = 20; 1 * 32 + 20 == 52) * * `qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq`: payment hash 0001020304050607080900010203040506070809000102030405060708090102 * * `d`: short description * * `pl`: `data_length` (`p` = 1, `l` = 31; 1 * 32 + 31 == 63) * * `2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq`: 'Please consider supporting this project' - * * `8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcq`: signature - * * `ca784w`: Bech32 checksum + * * `0py3tfrnxkt5xadpzangn5rry6r0kqt4f3g36lwln8wwpxtxqccn5agpyte3nx0v78uwn78zu6k30k5mgdgn50yvnd20namlmzp2ersq`: signature + * * `8065fg`: Bech32 checksum */ b11 = new_bolt11(tmpctx, NULL); b11->chain = chainparams_for_network("bitcoin"); @@ -186,14 +189,16 @@ int main(int argc, char *argv[]) &b11->payment_hash, sizeof(b11->payment_hash))) abort(); b11->receiver_id = node; + b11->payment_secret = tal(b11, struct secret); + memset(b11->payment_secret, 0x11, sizeof(*b11->payment_secret)); b11->description = "Please consider supporting this project"; - test_b11("lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w", b11, NULL); + test_b11("lnbc1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq0py3tfrnxkt5xadpzangn5rry6r0kqt4f3g36lwln8wwpxtxqccn5agpyte3nx0v78uwn78zu6k30k5mgdgn50yvnd20namlmzp2ersq8065fg", b11, NULL); /* BOLT #11: * * > ### Please send $3 for a cup of coffee to the same peer, within one minute - * > lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuaztrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rspfj9srp + * > lnbc2500u1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuu4tgyw2zt3v3c7eljkv2cn8a3etgn8kh8ukctqdmuxdfa7xup0w5ruwpt6eugv73pgzqczz3nc8tcqt2pcljp8ldkrnu5klff35vyscq6lp6ja * * Breakdown: * @@ -201,6 +206,7 @@ int main(int argc, char *argv[]) * * `2500u`: amount (2500 micro-bitcoin) * * `1`: Bech32 separator * * `pvjluez`: timestamp (1496314658) + * * `s`: payment secret... * * `p`: payment hash... * * `d`: short description * * `q5`: `data_length` (`q` = 0, `5` = 20; 0 * 32 + 20 == 20) @@ -208,13 +214,15 @@ int main(int argc, char *argv[]) * * `x`: expiry time * * `qz`: `data_length` (`q` = 0, `z` = 2; 0 * 32 + 2 == 2) * * `pu`: 60 seconds (`p` = 1, `u` = 28; 1 * 32 + 28 == 60) - * * `aztrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rsp`: signature - * * `fj9srp`: Bech32 checksum + * * `u4tgyw2zt3v3c7eljkv2cn8a3etgn8kh8ukctqdmuxdfa7xup0w5ruwpt6eugv73pgzqczz3nc8tcqt2pcljp8ldkrnu5klff35vyscq`: signature + * * `6lp6ja`: Bech32 checksum */ msatoshi = AMOUNT_MSAT(2500 * (1000ULL * 100000000) / 1000000); b11 = new_bolt11(tmpctx, &msatoshi); b11->chain = chainparams_for_network("bitcoin"); b11->timestamp = 1496314658; + b11->payment_secret = tal(b11, struct secret); + memset(b11->payment_secret, 0x11, sizeof(*b11->payment_secret)); if (!hex_decode("0001020304050607080900010203040506070809000102030405060708090102", strlen("0001020304050607080900010203040506070809000102030405060708090102"), &b11->payment_hash, sizeof(b11->payment_hash))) @@ -223,12 +231,12 @@ int main(int argc, char *argv[]) b11->description = "1 cup coffee"; b11->expiry = 60; - test_b11("lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuaztrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rspfj9srp", b11, NULL); + test_b11("lnbc2500u1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuu4tgyw2zt3v3c7eljkv2cn8a3etgn8kh8ukctqdmuxdfa7xup0w5ruwpt6eugv73pgzqczz3nc8tcqt2pcljp8ldkrnu5klff35vyscq6lp6ja", b11, NULL); /* BOLT #11: * * > ### Now send $24 for an entire list of things (hashed) - * > lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqscc6gd6ql3jrc5yzme8v4ntcewwz5cnw92tz0pc8qcuufvq7khhr8wpald05e92xw006sq94mg8v2ndf4sefvf9sygkshp5zfem29trqq2yxxz7 + * > lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs6e4fy93me7wjwdf9sxgrzr8xldm570z02ur92rv6pa7wkhzpfehnecuyhp4mdhsv5t7em4jz4tjtchs8zmx3tr555yl59lk848due0gqvkanpl * * Breakdown: * @@ -236,24 +244,27 @@ int main(int argc, char *argv[]) * * `20m`: amount (20 milli-bitcoin) * * `1`: Bech32 separator * * `pvjluez`: timestamp (1496314658) + * * `s`: payment secret... * * `p`: payment hash... * * `h`: tagged field: hash of description * * `p5`: `data_length` (`p` = 1, `5` = 20; 1 * 32 + 20 == 52) * * `8yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs`: SHA256 of 'One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon' - * * `cc6gd6ql3jrc5yzme8v4ntcewwz5cnw92tz0pc8qcuufvq7khhr8wpald05e92xw006sq94mg8v2ndf4sefvf9sygkshp5zfem29trqq`: signature - * * `2yxxz7`: Bech32 checksum + * * `6e4fy93me7wjwdf9sxgrzr8xldm570z02ur92rv6pa7wkhzpfehnecuyhp4mdhsv5t7em4jz4tjtchs8zmx3tr555yl59lk848due0gq`: signature + * * `vkanpl`: Bech32 checksum */ msatoshi = AMOUNT_MSAT(20 * (1000ULL * 100000000) / 1000); b11 = new_bolt11(tmpctx, &msatoshi); b11->chain = chainparams_for_network("bitcoin"); b11->timestamp = 1496314658; + b11->payment_secret = tal(b11, struct secret); + memset(b11->payment_secret, 0x11, sizeof(*b11->payment_secret)); if (!hex_decode("0001020304050607080900010203040506070809000102030405060708090102", strlen("0001020304050607080900010203040506070809000102030405060708090102"), &b11->payment_hash, sizeof(b11->payment_hash))) abort(); b11->receiver_id = node; b11->description_hash = tal(b11, struct sha256); - test_b11("lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqscc6gd6ql3jrc5yzme8v4ntcewwz5cnw92tz0pc8qcuufvq7khhr8wpald05e92xw006sq94mg8v2ndf4sefvf9sygkshp5zfem29trqq2yxxz7", b11, "One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"); + test_b11("lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs6e4fy93me7wjwdf9sxgrzr8xldm570z02ur92rv6pa7wkhzpfehnecuyhp4mdhsv5t7em4jz4tjtchs8zmx3tr555yl59lk848due0gqvkanpl", b11, "One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"); /* Malformed bolt11 strings (no '1'). */ badstr = "lnbc20mpvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqscc6gd6ql3jrc5yzme8v4ntcewwz5cnw92tz0pc8qcuufvq7khhr8wpald05e92xw006sq94mg8v2ndf4sefvf9sygkshp5zfem29trqq2yxxz7"; @@ -326,7 +337,7 @@ int main(int argc, char *argv[]) * * `9`: features * * `q5`: `data_length` (`q` = 0, `5` = 20; 0 * 32 + 20 == 20) * * `sqqqqqqqqqqqqqqqpqsq`: b1000....00001000001000000000 - ** `67gye39hfg3zd8rgc8032tvy9xk2xunwm5lzexnvpx6fd77en8qaq424dxgt56cag2dpt359k3ssyhetktkpqh24jqnjyw6uqd08sgp`: signature + ** `67gye39hfg3zd8rgc80k32tvy9xk2xunwm5lzexnvpx6fd77en8qaq424dxgt56cag2dpt359k3ssyhetktkpqh24jqnjyw6uqd08sgp`: signature ** `tq44qu`: Bech32 checksum */ msatoshi = AMOUNT_MSAT(25 * (1000ULL * 100000000) / 1000); @@ -474,7 +485,7 @@ int main(int argc, char *argv[]) /* BOLT #11: * * > ### Please send 0.00967878534 BTC for a list of items within one week, amount in pico-BTC - * > lnbc9678785340p1pwmna7lpp5gc3xfm08u9qy06djf8dfflhugl6p7lgza6dsjxq454gxhj9t7a0sd8dgfkx7cmtwd68yetpd5s9xar0wfjn5gpc8qhrsdfq24f5ggrxdaezqsnvda3kkum5wfjkzmfqf3jkgem9wgsyuctwdus9xgrcyqcjcgpzgfskx6eqf9hzqnteypzxz7fzypfhg6trddjhygrcyqezcgpzfysywmm5ypxxjemgw3hxjmn8yptk7untd9hxwg3q2d6xjcmtv4ezq7pqxgsxzmnyyqcjqmt0wfjjq6t5v4khxxqyjw5qcqp2rzjq0gxwkzc8w6323m55m4jyxcjwmy7stt9hwkwe2qxmy8zpsgg7jcuwz87fcqqeuqqqyqqqqlgqqqqn3qq9qn07ytgrxxzad9hc4xt3mawjjt8znfv8xzscs7007v9gh9j569lencxa8xeujzkxs0uamak9aln6ez02uunw6rd2ht2sqe4hz8thcdagpleym0j + * > lnbc9678785340p1pwmna7lpp5gc3xfm08u9qy06djf8dfflhugl6p7lgza6dsjxq454gxhj9t7a0sd8dgfkx7cmtwd68yetpd5s9xar0wfjn5gpc8qhrsdfq24f5ggrxdaezqsnvda3kkum5wfjkzmfqf3jkgem9wgsyuctwdus9xgrcyqcjcgpzgfskx6eqf9hzqnteypzxz7fzypfhg6trddjhygrcyqezcgpzfysywmm5ypxxjemgw3hxjmn8yptk7untd9hxwg3q2d6xjcmtv4ezq7pqxgsxzmnyyqcjqmt0wfjjq6t5v4khxsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsxqyjw5qcqp2rzjq0gxwkzc8w6323m55m4jyxcjwmy7stt9hwkwe2qxmy8zpsgg7jcuwz87fcqqeuqqqyqqqqlgqqqqn3qq9q0777th7sgnqqpykcmu4c2u65vtnefrnjzws78maaxy87euvpj0hr8t5ma58cyw5f3f9ej4aw9swcyvk4vp6vjlxtgpcfdy8u9m4c6wgpdqfxt2 * * Breakdown: * @@ -482,7 +493,8 @@ int main(int argc, char *argv[]) * * `9678785340p`: amount (9678785340 pico-bitcoin = 967878534 milli satoshi) * * `1`: Bech32 separator * * `pwmna7l`: timestamp (1572468703) - * * `p`: payment hash. + * * `s`: payment secret... + * * `p`: payment hash * * `p5`: `data_length` (`p` = 1, `5` = 20; 1 * 32 + 20 == 52) * * `gc3xfm08u9qy06djf8dfflhugl6p7lgza6dsjxq454gxhj9t7a0s`: payment hash 462264ede7e14047e9b249da94fefc47f41f7d02ee9b091815a5506bc8abf75f * * `d`: short description @@ -502,8 +514,8 @@ int main(int argc, char *argv[]) * * fee_base_msat = 1000 * * fee_proportional_millionths = 2500 * * cltv_expiry_delta = 40 - * * `n07ytgrxxzad9hc4xt3mawjjt8znfv8xzscs7007v9gh9j569lencxa8xeujzkxs0uamak9aln6ez02uunw6rd2ht2sqe4hz8thcdagp`: signature - * * `leym0j`: Bech32 checksum + * * `0777th7sgnqqpykcmu4c2u65vtnefrnjzws78maaxy87euvpj0hr8t5ma58cyw5f3f9ej4aw9swcyvk4vp6vjlxtgpcfdy8u9m4c6wgp`: signature + * * `dqfxt2`: Bech32 checksum */ msatoshi = AMOUNT_MSAT(967878534); b11 = new_bolt11(tmpctx, &msatoshi); diff --git a/contrib/pyln-client/pyln/client/lightning.py b/contrib/pyln-client/pyln/client/lightning.py index 951cca349844..e3f780e1f547 100644 --- a/contrib/pyln-client/pyln/client/lightning.py +++ b/contrib/pyln-client/pyln/client/lightning.py @@ -516,7 +516,7 @@ def check(self, command_to_check, **kwargs): return self.call("check", payload) def close(self, peer_id, unilateraltimeout=None, destination=None, - fee_negotiation_step=None, force_lease_closed=None): + fee_negotiation_step=None, force_lease_closed=None, feerange=None): """ Close the channel with peer {id}, forcing a unilateral close after {unilateraltimeout} seconds if non-zero, and @@ -533,6 +533,7 @@ def close(self, peer_id, unilateraltimeout=None, destination=None, "destination": destination, "fee_negotiation_step": fee_negotiation_step, "force_lease_closed": force_lease_closed, + "feerange": feerange, } return self.call("close", payload) diff --git a/devtools/mkclose.c b/devtools/mkclose.c index 3f0ebb5c17c3..a93e94458bae 100644 --- a/devtools/mkclose.c +++ b/devtools/mkclose.c @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) fee = commit_tx_base_fee(feerate_per_kw, 0, option_anchor_outputs); /* BOLT #3: - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, also subtract two times the fixed anchor size * of 330 sats from the funder (either `to_local` or * `to_remote`). diff --git a/devtools/mkcommit.c b/devtools/mkcommit.c index 3abf94cf6f5b..b0f26b5707cd 100644 --- a/devtools/mkcommit.c +++ b/devtools/mkcommit.c @@ -408,6 +408,7 @@ int main(int argc, char *argv[]) &funding_localkey, &funding_remotekey, option_static_remotekey, option_anchor_outputs, + false, fee_payer); if (!channel_force_htlcs(channel, diff --git a/doc/lightning-close.7 b/doc/lightning-close.7 index 61b03701c5a2..eba084438dce 100644 --- a/doc/lightning-close.7 +++ b/doc/lightning-close.7 @@ -3,7 +3,7 @@ lightning-close - Command for closing channels with direct peers .SH SYNOPSIS -\fBclose\fR \fIid\fR [\fIunilateraltimeout\fR] [\fIdestination\fR] [\fIfee_negotiation_step\fR] [\fIwrong_funding\fR] [\fIforce_lease_closed\fR] +\fBclose\fR \fIid\fR [\fIunilateraltimeout\fR] [\fIdestination\fR] [\fIfee_negotiation_step\fR] [\fIwrong_funding\fR] [\fIforce_lease_closed\fR] [*feerange*] .SH DESCRIPTION @@ -35,7 +35,10 @@ friends to upgrade! The \fIfee_negotiation_step\fR parameter controls how closing fee negotiation is performed assuming the peer proposes a fee that is -different than our estimate\. On every negotiation step we must give up +different than our estimate\. (Note that modern peers use the quick-close protocol which does not allow negotiation: see \fIfeerange\fR instead)\. + + +On every negotiation step we must give up some amount from our proposal towards the peer's proposal\. This parameter can be an integer in which case it is interpreted as number of satoshis to step at a time\. Or it can be an integer followed by "%" to designate @@ -74,6 +77,27 @@ can rescue openings which have been manually miscreated\. unless this flag is passed in\. Defaults to false\. +\fIfeerange\fR is an optional array [ \fImin\fR, \fImax\fR ], indicating the +minimum and maximum feerates to offer: the peer will obey these if it +supports the quick-close protocol\. \fIslow\fR and \fIunilateral_close\fR are +the defaults\. + + +Rates are one of the strings \fIurgent\fR (aim for next block), \fInormal\fR +(next 4 blocks or so) or \fIslow\fR (next 100 blocks or so) to use +lightningd’s internal estimates, or one of the names from +\fBlightning-feerates\fR(7)\. Otherwise, they can be numbers with +an optional suffix: \fIperkw\fR means the number is interpreted as +satoshi-per-kilosipa (weight), and \fIperkb\fR means it is interpreted +bitcoind-style as satoshi-per-kilobyte\. Omitting the suffix is +equivalent to \fIperkb\fR\. + + +Note that the maximum fee will be capped at the final commitment +transaction fee (unless the experimental anchor-outputs option is +negotiated)\. + + The peer needs to be live and connected in order to negotiate a mutual close\. The default of unilaterally closing after 48 hours is usually a reasonable indication that you can no longer contact the peer\. @@ -130,4 +154,4 @@ ZmnSCPxj \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:0af2affd80bd44dcd733b24c17429058c20b0c3ca41d23e06d70487ea759320c +\" SHA256STAMP:1182e596ddf208f37d269e37b06e30199b8d6b6bc1373d92096557c20ad437ac diff --git a/doc/lightning-close.7.md b/doc/lightning-close.7.md index 978dfa7d4b17..89a368151110 100644 --- a/doc/lightning-close.7.md +++ b/doc/lightning-close.7.md @@ -4,7 +4,7 @@ lightning-close -- Command for closing channels with direct peers SYNOPSIS -------- -**close** *id* \[*unilateraltimeout*\] \[*destination*\] \[*fee_negotiation_step*\] \[*wrong_funding*\] \[*force_lease_closed*\] +**close** *id* \[*unilateraltimeout*\] \[*destination*\] \[*fee_negotiation_step*\] \[*wrong_funding*\] \[*force_lease_closed*\] [\*feerange\*] DESCRIPTION ----------- @@ -33,7 +33,9 @@ friends to upgrade! The *fee_negotiation_step* parameter controls how closing fee negotiation is performed assuming the peer proposes a fee that is -different than our estimate. On every negotiation step we must give up +different than our estimate. (Note that modern peers use the quick-close protocol which does not allow negotiation: see *feerange* instead). + +On every negotiation step we must give up some amount from our proposal towards the peer's proposal. This parameter can be an integer in which case it is interpreted as number of satoshis to step at a time. Or it can be an integer followed by "%" to designate @@ -61,6 +63,23 @@ can rescue openings which have been manually miscreated. (option_will_fund), we prevent initiation of a mutual close unless this flag is passed in. Defaults to false. +*feerange* is an optional array [ *min*, *max* ], indicating the +minimum and maximum feerates to offer: the peer will obey these if it +supports the quick-close protocol. *slow* and *unilateral_close* are +the defaults. + +Rates are one of the strings *urgent* (aim for next block), *normal* +(next 4 blocks or so) or *slow* (next 100 blocks or so) to use +lightningd’s internal estimates, or one of the names from +lightning-feerates(7). Otherwise, they can be numbers with +an optional suffix: *perkw* means the number is interpreted as +satoshi-per-kilosipa (weight), and *perkb* means it is interpreted +bitcoind-style as satoshi-per-kilobyte. Omitting the suffix is +equivalent to *perkb*. + +Note that the maximum fee will be capped at the final commitment +transaction fee (unless the experimental anchor-outputs option is +negotiated). The peer needs to be live and connected in order to negotiate a mutual close. The default of unilaterally closing after 48 hours is usually a diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index b1db7aac5474..d43edee78279 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -292,7 +292,7 @@ static void hsm_unilateral_close_privkey(struct privkey *dst, /* BOLT #3: * - * If `option_static_remotekey` or `option_anchor_outputs` is + * If `option_static_remotekey` or `option_anchors` is * negotiated, the `remotepubkey` is simply the remote node's * `payment_basepoint`, otherwise it is calculated as above using the * remote node's `payment_basepoint`. @@ -1041,7 +1041,7 @@ static u8 *handle_sign_local_htlc_tx(struct hsmd_client *c, const u8 *msg_in) /* BOLT #3: * ## HTLC-Timeout and HTLC-Success Transactions *... - * * if `option_anchor_outputs` applies to this commitment transaction, + * * if `option_anchors` applies to this commitment transaction, * `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is used. */ sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey, @@ -1094,7 +1094,7 @@ static u8 *handle_sign_remote_htlc_tx(struct hsmd_client *c, const u8 *msg_in) /* BOLT #3: * ## HTLC-Timeout and HTLC-Success Transactions *... - * * if `option_anchor_outputs` applies to this commitment transaction, + * * if `option_anchors` applies to this commitment transaction, * `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is used. */ sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey, @@ -1289,7 +1289,7 @@ static u8 *handle_sign_remote_htlc_to_us(struct hsmd_client *c, /* BOLT #3: * ## HTLC-Timeout and HTLC-Success Transactions *... - * * if `option_anchor_outputs` applies to this commitment transaction, + * * if `option_anchors` applies to this commitment transaction, * `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is used. */ return handle_sign_to_us_tx( diff --git a/lightningd/channel.c b/lightningd/channel.c index a4ead163d169..ead10e2f2bf5 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -263,6 +263,7 @@ struct channel *new_unsaved_channel(struct peer *peer, channel->closing_fee_negotiation_step_unit = CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE; channel->shutdown_wrong_funding = NULL; + channel->closing_feerate_range = NULL; /* Channel is connected! */ channel->connected = true; @@ -429,6 +430,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, = CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE; channel->shutdown_wrong_funding = tal_steal(channel, shutdown_wrong_funding); + channel->closing_feerate_range = NULL; if (local_shutdown_scriptpubkey) channel->shutdown_scriptpubkey[LOCAL] = tal_steal(channel, local_shutdown_scriptpubkey); diff --git a/lightningd/channel.h b/lightningd/channel.h index 19611944597b..8c54a7db5b1a 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -174,6 +174,9 @@ struct channel { /* optional wrong_funding for mutual close */ const struct bitcoin_outpoint *shutdown_wrong_funding; + /* optional feerate min/max for mutual close */ + u32 *closing_feerate_range; + /* Reestablishment stuff: last sent commit and revocation details. */ bool last_was_revoke; struct changed_htlc *last_sent_commit; diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index 4574c5580768..ccf189a995d5 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -192,7 +193,7 @@ void peer_start_closingd(struct channel *channel, struct per_peer_state *pps) { u8 *initmsg; - u32 feerate; + u32 min_feerate, feerate, *max_feerate; struct amount_msat their_msat; struct amount_sat feelimit; int hsmfd; @@ -231,7 +232,8 @@ void peer_start_closingd(struct channel *channel, return; } - /* BOLT #2: + /* FIXME: This is the old BOLT 2 text, which restricted the closing + * fee to cap at the final commitment fee. We still do this for now. * * The sending node: * - MUST set `fee_satoshis` less than or equal to the base @@ -251,6 +253,27 @@ void peer_start_closingd(struct channel *channel, feerate = feerate_floor(); } + /* We use a feerate if anchor_outputs, otherwise max fee is set by + * the final unilateral. */ + if (channel->option_anchor_outputs) { + max_feerate = tal(tmpctx, u32); + /* Aim for reasonable max, but use final if we don't know. */ + *max_feerate = unilateral_feerate(ld->topology); + if (!*max_feerate) + *max_feerate = final_commit_feerate; + /* No other limit on fees */ + feelimit = channel->funding; + } else + max_feerate = NULL; + + min_feerate = feerate_min(ld, NULL); + + /* If they specified feerates in `close`, they apply now! */ + if (channel->closing_feerate_range) { + min_feerate = channel->closing_feerate_range[0]; + max_feerate = &channel->closing_feerate_range[1]; + } + /* BOLT #3: * * Each node offering a signature: @@ -283,11 +306,17 @@ void peer_start_closingd(struct channel *channel, amount_msat_to_sat_round_down(channel->our_msat), amount_msat_to_sat_round_down(their_msat), channel->our_config.dust_limit, - feerate_min(ld, NULL), feerate, feelimit, + min_feerate, feerate, max_feerate, + feelimit, channel->shutdown_scriptpubkey[LOCAL], channel->shutdown_scriptpubkey[REMOTE], channel->closing_fee_negotiation_step, channel->closing_fee_negotiation_step_unit, + /* Don't quickclose if they specified how to negotiate! */ + (channel->closing_fee_negotiation_step == 50 + && channel->closing_fee_negotiation_step_unit == CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE) + /* Always use quickclose with anchors */ + || channel->option_anchor_outputs, IFDEV(ld->dev_fast_gossip, false), channel->shutdown_wrong_funding); diff --git a/lightningd/invoice.c b/lightningd/invoice.c index b4434fe8973b..542b6ac5bc2c 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -885,19 +885,6 @@ invoice_complete(struct invoice_info *info, info->label->s); } - /* If this requires a giant HTLC, most implementations cannot - * send that much; will need to split. */ - /* BOLT #2: - * ### Adding an HTLC: `update_add_htlc` - *... - * - for channels with `chain_hash` identifying the Bitcoin blockchain: - * - MUST set the four most significant bytes of `amount_msat` to 0. - */ - if (info->b11->msat - && amount_msat_greater(*info->b11->msat, chainparams->max_payment)) { - warning_mpp = true; - } - /* Get details */ details = wallet_invoice_details(info, wallet, invoice); @@ -916,7 +903,7 @@ invoice_complete(struct invoice_info *info, "No listincoming command available, cannot add routehints to invoice"); if (warning_mpp) json_add_string(response, "warning_mpp", - "The invoice might only be payable by MPP-capable payers."); + "The invoice is only payable by MPP-capable payers."); if (warning_capacity) json_add_string(response, "warning_capacity", "Insufficient incoming channel capacity to pay invoice"); diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 995acc76252a..905800f2fca5 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -147,12 +147,18 @@ wallet_commit_channel(struct lightningd *ld, * #### Requirements * * Both peers: - * - if `option_static_remotekey` or `option_anchor_outputs` was negotiated: - * - `option_static_remotekey` or `option_anchor_outputs` applies to all commitment - * transactions + * ... + * - if `option_anchors_zero_fee_htlc_tx` was negotiated: + * - the `channel_type` is `option_anchors_zero_fee_htlc_tx` and + * `option_static_remotekey` (bits 22 and 12) + * - otherwise, if `option_anchor_outputs` was negotiated: + * - the `channel_type` is `option_anchor_outputs` and + * `option_static_remotekey` (bits 20 and 12) + * - otherwise, if `option_static_remotekey` was negotiated: + * - the `channel_type` is `option_static_remotekey` (bit 12) * - otherwise: - * - `option_static_remotekey` or `option_anchor_outputs` does not apply to any commitment - * transactions + * - the `channel_type` is empty + * - MUST use that `channel_type` for all commitment transactions. */ /* i.e. We set it now for the channel permanently. */ if (feature_negotiated(ld->our_features, diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index b8566946f589..98b79493f8c8 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -612,7 +612,7 @@ static struct amount_sat commit_txfee(const struct channel *channel, if (channel->option_anchor_outputs) { /* BOLT #3: - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, also subtract two times the fixed anchor size * of 330 sats from the funder (either `to_local` or * `to_remote`). @@ -1661,6 +1661,31 @@ static struct command_result *param_outpoint(struct command *cmd, "should be a txid:outnum"); } +static struct command_result *param_feerate_range(struct command *cmd, + const char *name, + const char *buffer, + const jsmntok_t *tok, + u32 **feerate_range) +{ + struct command_result *ret; + u32 *rate; + + *feerate_range = tal_arr(cmd, u32, 2); + if (tok->type != JSMN_ARRAY || tok->size != 2) + return command_fail_badparam(cmd, name, buffer, tok, + "should be an array of 2 entries"); + + ret = param_feerate(cmd, name, buffer, tok+1, &rate); + if (ret) + return ret; + (*feerate_range)[0] = *rate; + ret = param_feerate(cmd, name, buffer, tok+2, &rate); + if (ret) + return ret; + (*feerate_range)[1] = *rate; + return NULL; +} + static struct command_result *json_close(struct command *cmd, const char *buffer, const jsmntok_t *obj UNNEEDED, @@ -1674,6 +1699,7 @@ static struct command_result *json_close(struct command *cmd, bool close_script_set, wrong_funding_changed, *force_lease_close; const char *fee_negotiation_step_str; struct bitcoin_outpoint *wrong_funding; + u32 *feerate_range; char* end; bool anysegwit; @@ -1687,6 +1713,7 @@ static struct command_result *json_close(struct command *cmd, p_opt("wrong_funding", param_outpoint, &wrong_funding), p_opt_def("force_lease_closed", param_bool, &force_lease_close, false), + p_opt("feerange", param_feerate_range, &feerate_range), NULL)) return command_param_failed(); @@ -1845,6 +1872,9 @@ static struct command_result *json_close(struct command *cmd, wrong_funding_changed = false; } + /* Works fine if feerate_range is NULL */ + channel->closing_feerate_range = tal_steal(channel, feerate_range); + /* Normal case. * We allow states shutting down and sigexchange; a previous * close command may have timed out, and this current command diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index d16263f540ab..5a44a0db457d 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -534,6 +534,11 @@ struct command_result *param_escaped_string(struct command *cmd UNNEEDED, const jsmntok_t *tok UNNEEDED, const char **str UNNEEDED) { fprintf(stderr, "param_escaped_string called!\n"); abort(); } +/* Generated stub for param_feerate */ +struct command_result *param_feerate(struct command *cmd UNNEEDED, const char *name UNNEEDED, + const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, + u32 **feerate UNNEEDED) +{ fprintf(stderr, "param_feerate called!\n"); abort(); } /* Generated stub for param_label */ struct command_result *param_label(struct command *cmd UNNEEDED, const char *name UNNEEDED, const char * buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index 6baacd2b1e89..6772a96efeab 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -470,13 +470,17 @@ static bool grind_htlc_tx_fee(struct amount_sat *fee, /* BOLT #3: * * The fee for an HTLC-timeout transaction: - * - MUST BE calculated to match: + * - If `option_anchors_zero_fee_htlc_tx` applies: + * 1. MUST BE 0. + * - Otherwise, MUST BE calculated to match: * 1. Multiply `feerate_per_kw` by 663 * (666 if `option_anchor_outputs` applies) * and divide by 1000 (rounding down). * * The fee for an HTLC-success transaction: - * - MUST BE calculated to match: + * - If `option_anchors_zero_fee_htlc_tx` applies: + * 1. MUST BE 0. + * - MUST BE calculated to match: * 1. Multiply `feerate_per_kw` by 703 * (706 if `option_anchor_outputs` applies) * and divide by 1000 (rounding down). @@ -517,7 +521,9 @@ static bool set_htlc_timeout_fee(struct bitcoin_tx *tx, /* BOLT #3: * * The fee for an HTLC-timeout transaction: - * - MUST BE calculated to match: + * - If `option_anchors_zero_fee_htlc_tx` applies: + * 1. MUST BE 0. + * - Otherwise, MUST BE calculated to match: * 1. Multiply `feerate_per_kw` by 663 (666 if `option_anchor_outputs` * applies) and divide by 1000 (rounding down). */ @@ -564,6 +570,8 @@ static void set_htlc_success_fee(struct bitcoin_tx *tx, /* BOLT #3: * * The fee for an HTLC-success transaction: + * - If `option_anchors_zero_fee_htlc_tx` applies: + * 1. MUST BE 0. * - MUST BE calculated to match: * 1. Multiply `feerate_per_kw` by 703 (706 if `option_anchor_outputs` * applies) and divide by 1000 (rounding down). @@ -2566,7 +2574,7 @@ static u8 *scriptpubkey_to_remote(const tal_t *ctx, * * #### `to_remote` Output * - * If `option_anchor_outputs` applies to the commitment + * If `option_anchors` applies to the commitment * transaction, the `to_remote` output is encumbered by a one * block csv lock. * OP_CHECKSIGVERIFY 1 OP_CHECKSEQUENCEVERIFY diff --git a/openingd/common.c b/openingd/common.c index 6bc3dd5340f1..7326bc48b82c 100644 --- a/openingd/common.c +++ b/openingd/common.c @@ -63,7 +63,7 @@ bool check_config_bounds(const tal_t *ctx, } /* BOLT #2: - * - if `option_anchor_outputs` applies to this commitment + * - if `option_anchors` applies to this commitment * transaction and the sending node is the funder: * - MUST be able to additionally pay for `to_local_anchor` and * `to_remote_anchor` above its reserve. diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 32c96ae8bbb8..ddc8a2066d36 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -1726,6 +1726,8 @@ static void revert_channel_state(struct state *state) &state->our_funding_pubkey, &state->their_funding_pubkey, true, true, + feature_offered(state->their_features, + OPT_LARGE_CHANNELS), opener); } @@ -1828,6 +1830,8 @@ static u8 *accepter_commits(struct state *state, &state->our_funding_pubkey, &state->their_funding_pubkey, true, true, + feature_offered(state->their_features, + OPT_LARGE_CHANNELS), REMOTE); local_commit = initial_channel_tx(state, &wscript, state->channel, @@ -2436,6 +2440,8 @@ static u8 *opener_commits(struct state *state, &state->our_funding_pubkey, &state->their_funding_pubkey, true, true, + feature_offered(state->their_features, + OPT_LARGE_CHANNELS), /* Opener is local */ LOCAL); @@ -3411,7 +3417,7 @@ static bool dualopend_handle_custommsg(const u8 *msg) /* BOLT #2: * * A receiving node: - * - if `option_static_remotekey` applies to the commitment transaction: + * - if `option_static_remotekey` or `option_anchors` applies to the commitment transaction: * - if `next_revocation_number` is greater than expected above, AND * `your_last_per_commitment_secret` is correct for that * `next_revocation_number` minus 1: @@ -3858,7 +3864,10 @@ int main(int argc, char *argv[]) &state->their_points, &state->our_funding_pubkey, &state->their_funding_pubkey, - true, true, opener); + true, true, + feature_offered(state->their_features, + OPT_LARGE_CHANNELS), + opener); if (opener == LOCAL) state->our_role = TX_INITIATOR; diff --git a/openingd/openingd.c b/openingd/openingd.c index d12850fd2772..6afadb3aaf7c 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -533,6 +533,8 @@ static bool funder_finalize_channel_setup(struct state *state, &state->their_funding_pubkey, state->option_static_remotekey, state->option_anchor_outputs, + feature_offered(state->their_features, + OPT_LARGE_CHANNELS), /* Opener is local */ LOCAL); /* We were supposed to do enough checks above, but just in case, @@ -1023,6 +1025,8 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &their_funding_pubkey, state->option_static_remotekey, state->option_anchor_outputs, + feature_offered(state->their_features, + OPT_LARGE_CHANNELS), REMOTE); /* We don't expect this to fail, but it does do some additional * internal sanity checks. */ diff --git a/tests/test_closing.py b/tests/test_closing.py index 18b5a5e06f77..9dc68f61dd8d 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -6,7 +6,7 @@ from utils import ( only_one, sync_blockheight, wait_for, TIMEOUT, account_balance, first_channel_id, closing_fee, TEST_NETWORK, - scriptpubkey_addr, calc_lease_fee + scriptpubkey_addr, calc_lease_fee, EXPERIMENTAL_FEATURES ) import os @@ -446,6 +446,7 @@ def get_mempool_when_size_1(): assert opts['expected_close_fee'] == fee_mempool +@unittest.skipIf(EXPERIMENTAL_FEATURES, "anchors uses quick-close, not negotiation") def test_closing_negotiation_step_30pct(node_factory, bitcoind, chainparams): """Test that the closing fee negotiation step works, 30%""" opts = {} @@ -460,20 +461,7 @@ def test_closing_negotiation_step_30pct(node_factory, bitcoind, chainparams): closing_negotiation_step(node_factory, bitcoind, chainparams, opts) -def test_closing_negotiation_step_50pct(node_factory, bitcoind, chainparams): - """Test that the closing fee negotiation step works, 50%, the default""" - opts = {} - opts['fee_negotiation_step'] = '50%' - - opts['close_initiated_by'] = 'opener' - opts['expected_close_fee'] = 20334 if not chainparams['elements'] else 25789 - closing_negotiation_step(node_factory, bitcoind, chainparams, opts) - - opts['close_initiated_by'] = 'peer' - opts['expected_close_fee'] = 20334 if not chainparams['elements'] else 25789 - closing_negotiation_step(node_factory, bitcoind, chainparams, opts) - - +@unittest.skipIf(EXPERIMENTAL_FEATURES, "anchors uses quick-close, not negotiation") def test_closing_negotiation_step_100pct(node_factory, bitcoind, chainparams): """Test that the closing fee negotiation step works, 100%""" opts = {} @@ -493,6 +481,7 @@ def test_closing_negotiation_step_100pct(node_factory, bitcoind, chainparams): closing_negotiation_step(node_factory, bitcoind, chainparams, opts) +@unittest.skipIf(EXPERIMENTAL_FEATURES, "anchors uses quick-close, not negotiation") def test_closing_negotiation_step_1sat(node_factory, bitcoind, chainparams): """Test that the closing fee negotiation step works, 1sat""" opts = {} @@ -507,6 +496,7 @@ def test_closing_negotiation_step_1sat(node_factory, bitcoind, chainparams): closing_negotiation_step(node_factory, bitcoind, chainparams, opts) +@unittest.skipIf(EXPERIMENTAL_FEATURES, "anchors uses quick-close, not negotiation") def test_closing_negotiation_step_700sat(node_factory, bitcoind, chainparams): """Test that the closing fee negotiation step works, 700sat""" opts = {} @@ -3127,6 +3117,43 @@ def test_shutdown_alternate_txid(node_factory, bitcoind): wait_for(lambda: l1.rpc.listpeers()['peers'] == []) +@unittest.skipIf(not EXPERIMENTAL_FEATURES, "Needs anchor_outputs") +@pytest.mark.developer("needs to set dev-disconnect") +def test_closing_higherfee(node_factory, bitcoind, executor): + """With anchor outputs we can ask for a *higher* fee than the last commit tx""" + + # We change the feerate before it starts negotiating close, so it aims + # for *higher* than last commit tx. + l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True, + 'dev-no-reconnect': None, + 'feerates': (7500, 7500, 7500, 7500), + 'disconnect': ['-WIRE_CLOSING_SIGNED']}, + {'may_reconnect': True, + 'dev-no-reconnect': None, + 'feerates': (7500, 7500, 7500, 7500)}]) + # This will trigger disconnect. + fut = executor.submit(l1.rpc.close, l2.info['id']) + l1.daemon.wait_for_log('dev_disconnect') + + # Now adjust fees so l1 asks for more on reconnect. + l1.set_feerates((30000,) * 4, False) + l2.set_feerates((30000,) * 4, False) + l1.restart() + l2.restart() + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + + # This causes us to *exceed* previous requirements! + l1.daemon.wait_for_log(r'deriving max fee from rate 30000 -> 16440sat \(not 1000000sat\)') + + # This will fail because l1 restarted! + with pytest.raises(RpcError, match=r'Connection to RPC server lost.'): + fut.result(TIMEOUT) + + # But we still complete negotiation! + wait_for(lambda: only_one(l1.rpc.listpeers()['peers'])['channels'][0]['state'] == 'CLOSINGD_COMPLETE') + wait_for(lambda: only_one(l2.rpc.listpeers()['peers'])['channels'][0]['state'] == 'CLOSINGD_COMPLETE') + + @pytest.mark.developer("needs dev_disconnect") def test_htlc_rexmit_while_closing(node_factory, executor): """Retranmitting an HTLC revocation while shutting down should work""" @@ -3285,3 +3312,25 @@ def test_anysegwit_close_needs_feature(node_factory, bitcoind): l1.rpc.close(l2.info['id'], destination='bcrt1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k0ylj56') wait_for(lambda: only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['state'] == 'CLOSINGD_COMPLETE') bitcoind.generate_block(1, wait_for_mempool=1) + + +def test_close_feerate_range(node_factory, bitcoind, chainparams): + """Test the quick-close fee range negotiation""" + l1, l2 = node_factory.line_graph(2) + + # Lowball the range here. + l1.rpc.close(l2.info['id'], feerange=['253perkw', 'normal']) + + if not chainparams['elements']: + l1_range = [138, 4110] + l2_range = [1027, 1000000] + else: + # That fee output is a little chunky. + l1_range = [175, 5212] + l2_range = [1303, 1000000] + + l1.daemon.wait_for_log('Negotiating closing fee between {}sat and {}sat satoshi'.format(l1_range[0], l1_range[1])) + l2.daemon.wait_for_log('Negotiating closing fee between {}sat and {}sat satoshi'.format(l2_range[0], l2_range[1])) + + overlap = [max(l1_range[0], l2_range[0]), min(l1_range[1], l2_range[1])] + l1.daemon.wait_for_log('performing quickclose in range {}sat-{}sat'.format(overlap[0], overlap[1])) diff --git a/tests/test_invoices.py b/tests/test_invoices.py index 59b8dc794dc8..386f5a99e533 100644 --- a/tests/test_invoices.py +++ b/tests/test_invoices.py @@ -54,11 +54,6 @@ def test_invoice(node_factory, chainparams): assert 'routes' not in b11 assert 'warning_capacity' in inv - # Make sure wumbo invoices warn about mpp being needed. - inv = l2.rpc.invoice(4294967295 + 1, 'inv4', '?') - assert 'warning_mpp' in inv - l2.rpc.invoice(4294967295, 'inv3', '?') - # Test cltv option. inv = l1.rpc.invoice(123000, 'label3', 'description', '3700', cltv=99) b11 = l1.rpc.decodepay(inv['bolt11']) diff --git a/wallet/db_postgres_sqlgen.c b/wallet/db_postgres_sqlgen.c index ddeedf6bfc03..6ca03f26a771 100644 --- a/wallet/db_postgres_sqlgen.c +++ b/wallet/db_postgres_sqlgen.c @@ -2074,4 +2074,4 @@ struct db_query db_postgres_queries[] = { #endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */ -// SHA256STAMP:219fccaaf2391eeabadd4cc15b4a3431c7ecab9d17755582e6962a34c74982c5 +// SHA256STAMP:f929ee6db13bdf55b5e0cdf54840091948b664a61c63a4aaaef403dc7e6f23ad diff --git a/wallet/db_sqlite3_sqlgen.c b/wallet/db_sqlite3_sqlgen.c index f53f4d9df08c..fa71450da8e6 100644 --- a/wallet/db_sqlite3_sqlgen.c +++ b/wallet/db_sqlite3_sqlgen.c @@ -2074,4 +2074,4 @@ struct db_query db_sqlite3_queries[] = { #endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */ -// SHA256STAMP:219fccaaf2391eeabadd4cc15b4a3431c7ecab9d17755582e6962a34c74982c5 +// SHA256STAMP:f929ee6db13bdf55b5e0cdf54840091948b664a61c63a4aaaef403dc7e6f23ad diff --git a/wallet/statements_gettextgen.po b/wallet/statements_gettextgen.po index 252944764be0..a0bff95df0f5 100644 --- a/wallet/statements_gettextgen.po +++ b/wallet/statements_gettextgen.po @@ -1362,11 +1362,11 @@ msgstr "" msgid "not a valid SQL statement" msgstr "" -#: wallet/test/run-wallet.c:1540 +#: wallet/test/run-wallet.c:1545 msgid "SELECT COUNT(1) FROM channel_funding_inflights WHERE channel_id = ?;" msgstr "" -#: wallet/test/run-wallet.c:1753 +#: wallet/test/run-wallet.c:1758 msgid "INSERT INTO channels (id) VALUES (1);" msgstr "" -# SHA256STAMP:d098fea63dcba84aefff5cf924cbc455caf9d2ec13cb28ad9ab929bb001a12e6 +# SHA256STAMP:35e10cb3ec34af54b6d78d9eea1aefa0861ef9acbfe0e78745d24b8e49e50b05 diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 1709c42e0c65..666068099d33 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -575,6 +575,11 @@ struct command_result *param_channel_id(struct command *cmd UNNEEDED, const jsmntok_t *tok UNNEEDED, struct channel_id **cid UNNEEDED) { fprintf(stderr, "param_channel_id called!\n"); abort(); } +/* Generated stub for param_feerate */ +struct command_result *param_feerate(struct command *cmd UNNEEDED, const char *name UNNEEDED, + const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, + u32 **feerate UNNEEDED) +{ fprintf(stderr, "param_feerate called!\n"); abort(); } /* Generated stub for param_loglevel */ struct command_result *param_loglevel(struct command *cmd UNNEEDED, const char *name UNNEEDED, diff --git a/wallet/wallet.c b/wallet/wallet.c index ab3df12ec469..fc85bd982572 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -896,7 +896,7 @@ wallet_htlc_sigs_load(const tal_t *ctx, struct wallet *w, u64 channelid, /* BOLT #3: * ## HTLC-Timeout and HTLC-Success Transactions *... - * * if `option_anchor_outputs` applies to this commitment + * * if `option_anchors` applies to this commitment * transaction, `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is * used. */ diff --git a/wire/peer_printgen.c b/wire/peer_printgen.c index f36f70eccb72..4e689ea40240 100644 --- a/wire/peer_printgen.c +++ b/wire/peer_printgen.c @@ -470,10 +470,24 @@ static void printwire_tlv_open_channel_tlvs_upfront_shutdown_script(const char * return; } +} +static void printwire_tlv_open_channel_tlvs_channel_type(const char *fieldname, const u8 **cursor, size_t *plen) +{ + printf("(msg_name=%s)\n", "channel_type"); + + printf("type="); + printwire_u8_array(tal_fmt(NULL, "%s.type", fieldname), cursor, plen, *plen); + + if (!*cursor) { + printf("**TRUNCATED**\n"); + return; + } + } static const struct tlv_print_record_type print_tlvs_open_channel_tlvs[] = { { 0, printwire_tlv_open_channel_tlvs_upfront_shutdown_script }, + { 1, printwire_tlv_open_channel_tlvs_channel_type }, }; static void printwire_tlv_accept_channel_tlvs_upfront_shutdown_script(const char *fieldname, const u8 **cursor, size_t *plen) @@ -488,10 +502,24 @@ static void printwire_tlv_accept_channel_tlvs_upfront_shutdown_script(const char return; } +} +static void printwire_tlv_accept_channel_tlvs_channel_type(const char *fieldname, const u8 **cursor, size_t *plen) +{ + printf("(msg_name=%s)\n", "channel_type"); + + printf("type="); + printwire_u8_array(tal_fmt(NULL, "%s.type", fieldname), cursor, plen, *plen); + + if (!*cursor) { + printf("**TRUNCATED**\n"); + return; + } + } static const struct tlv_print_record_type print_tlvs_accept_channel_tlvs[] = { { 0, printwire_tlv_accept_channel_tlvs_upfront_shutdown_script }, + { 1, printwire_tlv_accept_channel_tlvs_channel_type }, }; static void printwire_tlv_opening_tlvs_option_upfront_shutdown_script(const char *fieldname, const u8 **cursor, size_t *plen) @@ -611,6 +639,33 @@ static const struct tlv_print_record_type print_tlvs_shutdown_tlvs[] = { { 100, printwire_tlv_shutdown_tlvs_wrong_funding }, }; +static void printwire_tlv_closing_signed_tlvs_fee_range(const char *fieldname, const u8 **cursor, size_t *plen) +{ + printf("(msg_name=%s)\n", "fee_range"); + + printf("min_fee_satoshis="); + struct amount_sat min_fee_satoshis = fromwire_amount_sat(cursor, plen); + + printwire_amount_sat(tal_fmt(NULL, "%s.min_fee_satoshis", fieldname), &min_fee_satoshis); + if (!*cursor) { + printf("**TRUNCATED**\n"); + return; + } + printf("max_fee_satoshis="); + struct amount_sat max_fee_satoshis = fromwire_amount_sat(cursor, plen); + + printwire_amount_sat(tal_fmt(NULL, "%s.max_fee_satoshis", fieldname), &max_fee_satoshis); + if (!*cursor) { + printf("**TRUNCATED**\n"); + return; + } + +} + +static const struct tlv_print_record_type print_tlvs_closing_signed_tlvs[] = { + { 1, printwire_tlv_closing_signed_tlvs_fee_range }, +}; + static void printwire_tlv_node_ann_tlvs_option_will_fund(const char *fieldname, const u8 **cursor, size_t *plen) { printf("(msg_name=%s)\n", "option_will_fund"); @@ -2032,6 +2087,8 @@ void printwire_closing_signed(const char *fieldname, const u8 *cursor) printf("**TRUNCATED**\n"); return; } + printf("tlvs="); + printwire_tlvs(tal_fmt(NULL, "%s.tlvs", fieldname), &cursor, &plen, print_tlvs_closing_signed_tlvs, ARRAY_SIZE(print_tlvs_closing_signed_tlvs)); if (plen != 0) @@ -3063,6 +3120,9 @@ void printpeer_wire_tlv_message(const char *tlv_name, const u8 *msg) { if (strcmp(tlv_name, "shutdown_tlvs") == 0) { printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_shutdown_tlvs, ARRAY_SIZE(print_tlvs_shutdown_tlvs)); } + if (strcmp(tlv_name, "closing_signed_tlvs") == 0) { + printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_closing_signed_tlvs, ARRAY_SIZE(print_tlvs_closing_signed_tlvs)); + } if (strcmp(tlv_name, "node_ann_tlvs") == 0) { printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_node_ann_tlvs, ARRAY_SIZE(print_tlvs_node_ann_tlvs)); } @@ -3079,4 +3139,4 @@ void printpeer_wire_tlv_message(const char *tlv_name, const u8 *msg) { printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_onion_message_tlvs, ARRAY_SIZE(print_tlvs_onion_message_tlvs)); } } -// SHA256STAMP:7acdb2f85dec7c26fb60ae3302f387fbccae349e182d05c6e4bb043ce2546797 +// SHA256STAMP:c55c98a2d8cac53c9f0db9ca4eb5ef1caac507e2f7cf4d1988cfc548efe40bbf diff --git a/wire/peer_printgen.h b/wire/peer_printgen.h index 99c8995603dd..b6bc64290ca2 100644 --- a/wire/peer_printgen.h +++ b/wire/peer_printgen.h @@ -99,4 +99,4 @@ void printwire_channel_update_checksums(const char *fieldname, const u8 **cursor void printwire_channel_update_timestamps(const char *fieldname, const u8 **cursor, size_t *plen); void printwire_witness_stack(const char *fieldname, const u8 **cursor, size_t *plen); #endif /* LIGHTNING_WIRE_PEER_PRINTGEN_H */ -// SHA256STAMP:7acdb2f85dec7c26fb60ae3302f387fbccae349e182d05c6e4bb043ce2546797 +// SHA256STAMP:c55c98a2d8cac53c9f0db9ca4eb5ef1caac507e2f7cf4d1988cfc548efe40bbf diff --git a/wire/peer_wire.csv b/wire/peer_wire.csv index 6cfe78176272..8bd6392ffd35 100644 --- a/wire/peer_wire.csv +++ b/wire/peer_wire.csv @@ -91,6 +91,8 @@ msgdata,open_channel,channel_flags,byte, msgdata,open_channel,tlvs,open_channel_tlvs, tlvtype,open_channel_tlvs,upfront_shutdown_script,0 tlvdata,open_channel_tlvs,upfront_shutdown_script,shutdown_scriptpubkey,byte,... +tlvtype,open_channel_tlvs,channel_type,1 +tlvdata,open_channel_tlvs,channel_type,type,byte,... msgtype,accept_channel,33 msgdata,accept_channel,temporary_channel_id,byte,32 msgdata,accept_channel,dust_limit_satoshis,u64, @@ -109,6 +111,8 @@ msgdata,accept_channel,first_per_commitment_point,point, msgdata,accept_channel,tlvs,accept_channel_tlvs, tlvtype,accept_channel_tlvs,upfront_shutdown_script,0 tlvdata,accept_channel_tlvs,upfront_shutdown_script,shutdown_scriptpubkey,byte,... +tlvtype,accept_channel_tlvs,channel_type,1 +tlvdata,accept_channel_tlvs,channel_type,type,byte,... msgtype,funding_created,34 msgdata,funding_created,temporary_channel_id,byte,32 msgdata,funding_created,funding_txid,sha256, @@ -194,6 +198,10 @@ msgtype,closing_signed,39 msgdata,closing_signed,channel_id,channel_id, msgdata,closing_signed,fee_satoshis,u64, msgdata,closing_signed,signature,signature, +msgdata,closing_signed,tlvs,closing_signed_tlvs, +tlvtype,closing_signed_tlvs,fee_range,1 +tlvdata,closing_signed_tlvs,fee_range,min_fee_satoshis,u64, +tlvdata,closing_signed_tlvs,fee_range,max_fee_satoshis,u64, msgtype,update_add_htlc,128 msgdata,update_add_htlc,channel_id,channel_id, msgdata,update_add_htlc,id,u64, diff --git a/wire/peer_wiregen.c b/wire/peer_wiregen.c index 3365a3e8d4bb..7e7f95cef6b5 100644 --- a/wire/peer_wiregen.c +++ b/wire/peer_wiregen.c @@ -517,20 +517,43 @@ static void fromwire_tlv_open_channel_tlvs_upfront_shutdown_script(const u8 **cu r->upfront_shutdown_script = tal_arr(r, u8, *plen); fromwire_u8_array(cursor, plen, r->upfront_shutdown_script, *plen); } +/* OPEN_CHANNEL_TLVS MSG: channel_type */ +static u8 *towire_tlv_open_channel_tlvs_channel_type(const tal_t *ctx, const void *vrecord) +{ + const struct tlv_open_channel_tlvs *r = vrecord; + u8 *ptr; + + if (!r->channel_type) + return NULL; + + + ptr = tal_arr(ctx, u8, 0); + + towire_u8_array(&ptr, r->channel_type, tal_count(r->channel_type)); + return ptr; +} +static void fromwire_tlv_open_channel_tlvs_channel_type(const u8 **cursor, size_t *plen, void *vrecord) +{ + struct tlv_open_channel_tlvs *r = vrecord; + + r->channel_type = tal_arr(r, u8, *plen); +fromwire_u8_array(cursor, plen, r->channel_type, *plen); +} static const struct tlv_record_type tlvs_open_channel_tlvs[] = { { 0, towire_tlv_open_channel_tlvs_upfront_shutdown_script, fromwire_tlv_open_channel_tlvs_upfront_shutdown_script }, + { 1, towire_tlv_open_channel_tlvs_channel_type, fromwire_tlv_open_channel_tlvs_channel_type }, }; void towire_open_channel_tlvs(u8 **pptr, const struct tlv_open_channel_tlvs *record) { - towire_tlv(pptr, tlvs_open_channel_tlvs, 1, record); + towire_tlv(pptr, tlvs_open_channel_tlvs, 2, record); } bool fromwire_open_channel_tlvs(const u8 **cursor, size_t *max, struct tlv_open_channel_tlvs *record) { - return fromwire_tlv(cursor, max, tlvs_open_channel_tlvs, 1, record, &record->fields); + return fromwire_tlv(cursor, max, tlvs_open_channel_tlvs, 2, record, &record->fields); } bool open_channel_tlvs_is_valid(const struct tlv_open_channel_tlvs *record, size_t *err_index) @@ -571,20 +594,43 @@ static void fromwire_tlv_accept_channel_tlvs_upfront_shutdown_script(const u8 ** r->upfront_shutdown_script = tal_arr(r, u8, *plen); fromwire_u8_array(cursor, plen, r->upfront_shutdown_script, *plen); } +/* ACCEPT_CHANNEL_TLVS MSG: channel_type */ +static u8 *towire_tlv_accept_channel_tlvs_channel_type(const tal_t *ctx, const void *vrecord) +{ + const struct tlv_accept_channel_tlvs *r = vrecord; + u8 *ptr; + + if (!r->channel_type) + return NULL; + + + ptr = tal_arr(ctx, u8, 0); + + towire_u8_array(&ptr, r->channel_type, tal_count(r->channel_type)); + return ptr; +} +static void fromwire_tlv_accept_channel_tlvs_channel_type(const u8 **cursor, size_t *plen, void *vrecord) +{ + struct tlv_accept_channel_tlvs *r = vrecord; + + r->channel_type = tal_arr(r, u8, *plen); +fromwire_u8_array(cursor, plen, r->channel_type, *plen); +} static const struct tlv_record_type tlvs_accept_channel_tlvs[] = { { 0, towire_tlv_accept_channel_tlvs_upfront_shutdown_script, fromwire_tlv_accept_channel_tlvs_upfront_shutdown_script }, + { 1, towire_tlv_accept_channel_tlvs_channel_type, fromwire_tlv_accept_channel_tlvs_channel_type }, }; void towire_accept_channel_tlvs(u8 **pptr, const struct tlv_accept_channel_tlvs *record) { - towire_tlv(pptr, tlvs_accept_channel_tlvs, 1, record); + towire_tlv(pptr, tlvs_accept_channel_tlvs, 2, record); } bool fromwire_accept_channel_tlvs(const u8 **cursor, size_t *max, struct tlv_accept_channel_tlvs *record) { - return fromwire_tlv(cursor, max, tlvs_accept_channel_tlvs, 1, record, &record->fields); + return fromwire_tlv(cursor, max, tlvs_accept_channel_tlvs, 2, record, &record->fields); } bool accept_channel_tlvs_is_valid(const struct tlv_accept_channel_tlvs *record, size_t *err_index) @@ -822,6 +868,63 @@ bool shutdown_tlvs_is_valid(const struct tlv_shutdown_tlvs *record, size_t *err_ } +struct tlv_closing_signed_tlvs *tlv_closing_signed_tlvs_new(const tal_t *ctx) +{ + /* Initialize everything to NULL. (Quiet, C pedants!) */ + struct tlv_closing_signed_tlvs *inst = talz(ctx, struct tlv_closing_signed_tlvs); + + /* Initialized the fields to an empty array. */ + inst->fields = tal_arr(inst, struct tlv_field, 0); + return inst; +} + +/* CLOSING_SIGNED_TLVS MSG: fee_range */ +static u8 *towire_tlv_closing_signed_tlvs_fee_range(const tal_t *ctx, const void *vrecord) +{ + const struct tlv_closing_signed_tlvs *r = vrecord; + u8 *ptr; + + if (!r->fee_range) + return NULL; + + + ptr = tal_arr(ctx, u8, 0); + + towire_amount_sat(&ptr, r->fee_range->min_fee_satoshis); + + towire_amount_sat(&ptr, r->fee_range->max_fee_satoshis); + return ptr; +} +static void fromwire_tlv_closing_signed_tlvs_fee_range(const u8 **cursor, size_t *plen, void *vrecord) +{ + struct tlv_closing_signed_tlvs *r = vrecord; + + r->fee_range = tal(r, struct tlv_closing_signed_tlvs_fee_range); + r->fee_range->min_fee_satoshis = fromwire_amount_sat(cursor, plen); + r->fee_range->max_fee_satoshis = fromwire_amount_sat(cursor, plen); +} + +static const struct tlv_record_type tlvs_closing_signed_tlvs[] = { + { 1, towire_tlv_closing_signed_tlvs_fee_range, fromwire_tlv_closing_signed_tlvs_fee_range }, +}; + +void towire_closing_signed_tlvs(u8 **pptr, const struct tlv_closing_signed_tlvs *record) +{ + towire_tlv(pptr, tlvs_closing_signed_tlvs, 1, record); +} + + +bool fromwire_closing_signed_tlvs(const u8 **cursor, size_t *max, struct tlv_closing_signed_tlvs *record) +{ + return fromwire_tlv(cursor, max, tlvs_closing_signed_tlvs, 1, record, &record->fields); +} + +bool closing_signed_tlvs_is_valid(const struct tlv_closing_signed_tlvs *record, size_t *err_index) +{ + return tlv_fields_valid(record->fields, NULL, err_index); +} + + struct tlv_node_ann_tlvs *tlv_node_ann_tlvs_new(const tal_t *ctx) { /* Initialize everything to NULL. (Quiet, C pedants!) */ @@ -1834,7 +1937,7 @@ bool fromwire_shutdown(const tal_t *ctx, const void *p, struct channel_id *chann } /* WIRE: CLOSING_SIGNED */ -u8 *towire_closing_signed(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat fee_satoshis, const secp256k1_ecdsa_signature *signature) +u8 *towire_closing_signed(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat fee_satoshis, const secp256k1_ecdsa_signature *signature, const struct tlv_closing_signed_tlvs *tlvs) { u8 *p = tal_arr(ctx, u8, 0); @@ -1842,10 +1945,11 @@ u8 *towire_closing_signed(const tal_t *ctx, const struct channel_id *channel_id, towire_channel_id(&p, channel_id); towire_amount_sat(&p, fee_satoshis); towire_secp256k1_ecdsa_signature(&p, signature); + towire_closing_signed_tlvs(&p, tlvs); return memcheck(p, tal_count(p)); } -bool fromwire_closing_signed(const void *p, struct channel_id *channel_id, struct amount_sat *fee_satoshis, secp256k1_ecdsa_signature *signature) +bool fromwire_closing_signed(const void *p, struct channel_id *channel_id, struct amount_sat *fee_satoshis, secp256k1_ecdsa_signature *signature, struct tlv_closing_signed_tlvs *tlvs) { const u8 *cursor = p; size_t plen = tal_count(p); @@ -1855,6 +1959,7 @@ bool fromwire_closing_signed(const void *p, struct channel_id *channel_id, struc fromwire_channel_id(&cursor, &plen, channel_id); *fee_satoshis = fromwire_amount_sat(&cursor, &plen); fromwire_secp256k1_ecdsa_signature(&cursor, &plen, signature); + fromwire_closing_signed_tlvs(&cursor, &plen, tlvs); return cursor != NULL; } @@ -2484,4 +2589,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec *htlc_maximum_msat = fromwire_amount_msat(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:7acdb2f85dec7c26fb60ae3302f387fbccae349e182d05c6e4bb043ce2546797 +// SHA256STAMP:c55c98a2d8cac53c9f0db9ca4eb5ef1caac507e2f7cf4d1988cfc548efe40bbf diff --git a/wire/peer_wiregen.h b/wire/peer_wiregen.h index b6a2e1f60c06..2deb9d052677 100644 --- a/wire/peer_wiregen.h +++ b/wire/peer_wiregen.h @@ -115,6 +115,10 @@ struct tlv_shutdown_tlvs_wrong_funding { struct bitcoin_txid txid; u32 outnum; }; +struct tlv_closing_signed_tlvs_fee_range { + struct amount_sat min_fee_satoshis; + struct amount_sat max_fee_satoshis; +}; struct tlv_query_short_channel_ids_tlvs_query_flags { u8 encoding_type; u8 *encoded_query_flags; @@ -158,6 +162,7 @@ struct tlv_open_channel_tlvs { /* TODO The following explicit fields could just point into the * tlv_field entries above to save on memory. */ u8 *upfront_shutdown_script; + u8 *channel_type; }; struct tlv_accept_channel_tlvs { /* Raw fields including unknown ones. */ @@ -166,6 +171,7 @@ struct tlv_accept_channel_tlvs { /* TODO The following explicit fields could just point into the * tlv_field entries above to save on memory. */ u8 *upfront_shutdown_script; + u8 *channel_type; }; struct tlv_opening_tlvs { /* Raw fields including unknown ones. */ @@ -193,6 +199,14 @@ struct tlv_shutdown_tlvs { * tlv_field entries above to save on memory. */ struct tlv_shutdown_tlvs_wrong_funding *wrong_funding; }; +struct tlv_closing_signed_tlvs { + /* Raw fields including unknown ones. */ + struct tlv_field *fields; + + /* TODO The following explicit fields could just point into the + * tlv_field entries above to save on memory. */ + struct tlv_closing_signed_tlvs_fee_range *fee_range; +}; struct tlv_node_ann_tlvs { /* Raw fields including unknown ones. */ struct tlv_field *fields; @@ -555,6 +569,43 @@ void towire_shutdown_tlvs(u8 **pptr, const struct tlv_shutdown_tlvs *record); bool shutdown_tlvs_is_valid(const struct tlv_shutdown_tlvs *record, size_t *err_index); +struct tlv_closing_signed_tlvs *tlv_closing_signed_tlvs_new(const tal_t *ctx); + +/** + * Deserialize a TLV stream for the closing_signed_tlvs namespace. + * + * This function will parse any TLV stream, as long as the type, length and + * value fields are formatted correctly. Fields that are not known in the + * current namespace are stored in the `fields` member. Validity can be + * checked using closing_signed_tlvs_is_valid. + */ +bool fromwire_closing_signed_tlvs(const u8 **cursor, size_t *max, + struct tlv_closing_signed_tlvs * record); + +/** + * Serialize a TLV stream for the closing_signed_tlvs namespace. + * + * This function only considers known fields from the closing_signed_tlvs namespace, + * and will ignore any fields that may be stored in the `fields` member. This + * ensures that the resulting stream is valid according to + * `closing_signed_tlvs_is_valid`. + */ +void towire_closing_signed_tlvs(u8 **pptr, const struct tlv_closing_signed_tlvs *record); + +/** + * Check that the TLV stream is valid. + * + * Enforces the followin validity rules: + * - Types must be in monotonic non-repeating order + * - We must understand all even types + * + * Returns false if an error was detected, otherwise returns true. If err_index + * is non-null and we detect an error it is set to the index of the first error + * detected. + */ +bool closing_signed_tlvs_is_valid(const struct tlv_closing_signed_tlvs *record, + size_t *err_index); + struct tlv_node_ann_tlvs *tlv_node_ann_tlvs_new(const tal_t *ctx); /** @@ -845,8 +896,8 @@ u8 *towire_shutdown(const tal_t *ctx, const struct channel_id *channel_id, const bool fromwire_shutdown(const tal_t *ctx, const void *p, struct channel_id *channel_id, u8 **scriptpubkey, struct tlv_shutdown_tlvs *tlvs); /* WIRE: CLOSING_SIGNED */ -u8 *towire_closing_signed(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat fee_satoshis, const secp256k1_ecdsa_signature *signature); -bool fromwire_closing_signed(const void *p, struct channel_id *channel_id, struct amount_sat *fee_satoshis, secp256k1_ecdsa_signature *signature); +u8 *towire_closing_signed(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat fee_satoshis, const secp256k1_ecdsa_signature *signature, const struct tlv_closing_signed_tlvs *tlvs); +bool fromwire_closing_signed(const void *p, struct channel_id *channel_id, struct amount_sat *fee_satoshis, secp256k1_ecdsa_signature *signature, struct tlv_closing_signed_tlvs *tlvs); /* WIRE: UPDATE_ADD_HTLC */ u8 *towire_update_add_htlc(const tal_t *ctx, const struct channel_id *channel_id, u64 id, struct amount_msat amount_msat, const struct sha256 *payment_hash, u32 cltv_expiry, const u8 onion_routing_packet[1366]); @@ -930,4 +981,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec #endif /* LIGHTNING_WIRE_PEER_WIREGEN_H */ -// SHA256STAMP:7acdb2f85dec7c26fb60ae3302f387fbccae349e182d05c6e4bb043ce2546797 +// SHA256STAMP:c55c98a2d8cac53c9f0db9ca4eb5ef1caac507e2f7cf4d1988cfc548efe40bbf diff --git a/wire/test/run-peer-wire.c b/wire/test/run-peer-wire.c index 1f2e4b7a8524..4c74c3314491 100644 --- a/wire/test/run-peer-wire.c +++ b/wire/test/run-peer-wire.c @@ -615,20 +615,27 @@ static struct msg_funding_signed *fromwire_struct_funding_signed(const tal_t *ct static void *towire_struct_closing_signed(const tal_t *ctx, const struct msg_closing_signed *s) { + struct tlv_closing_signed_tlvs *close_tlvs; + + close_tlvs = tlv_closing_signed_tlvs_new(ctx); return towire_closing_signed(ctx, &s->channel_id, s->fee_satoshis, - &s->signature); + &s->signature, + close_tlvs); } static struct msg_closing_signed *fromwire_struct_closing_signed(const tal_t *ctx, const void *p) { struct msg_closing_signed *s = tal(ctx, struct msg_closing_signed); + struct tlv_closing_signed_tlvs *close_tlvs; + close_tlvs = tlv_closing_signed_tlvs_new(ctx); if (fromwire_closing_signed(p, &s->channel_id, &s->fee_satoshis, - &s->signature)) + &s->signature, + close_tlvs)) return s; return tal_free(s); }