From 29aadf0547f948a63aa737c29c72b2335d3d25b7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 15 Jun 2023 10:41:07 +0930 Subject: [PATCH] plugins: don't let multifundchannel open a new anchor channel without reserves. If we're opening a channel with a peer which support anchors (and we do), we tell fundpsbt/utxopsbt to enforce the emergency reserve; this matters, as it doesn't know about the channel yet, and thus won't (if it's our first anchor channel). Signed-off-by: Rusty Russell Changelog-Changed: JSON-RPC: `fundchannel` and `multifundchannel` will refuse to spend funds below `min-emergency-msat` if we have any anchor channels (or are opening one). --- doc/lightning-fundchannel.7.md | 3 ++- doc/lightning-multifundchannel.7.md | 3 ++- plugins/spender/multifundchannel.c | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/doc/lightning-fundchannel.7.md b/doc/lightning-fundchannel.7.md index 5a5cbae5dd12..f5e9c16e3464 100644 --- a/doc/lightning-fundchannel.7.md +++ b/doc/lightning-fundchannel.7.md @@ -27,7 +27,7 @@ for the channel. *id* is the peer id obtained from **connect**. *amount* is the amount in satoshis taken from the internal wallet to -fund the channel. The string *all* can be used to specify all available +fund the channel (but if we have any anchor channels, this will always leave at least `min-emergency-msat` as change). The string *all* can be used to specify all available funds (or 16777215 satoshi if more is available and large channels were not negotiated with the peer). Otherwise, it is in satoshi precision; it can be a whole number, a whole number ending in *sat*, a whole number ending in *000msat*, or a number with 1 to 8 @@ -100,6 +100,7 @@ The following error codes may occur: - 301: There are not enough funds in the internal wallet (including fees) to create the transaction. - 302: The output amount is too small, and would be considered dust. - 303: Broadcasting of the funding transaction failed, the internal call to bitcoin-cli returned with an error. +- 313: The `min-emergency-msat` reserve not be preserved (and we have or are opening anchor channels). Failure may also occur if **lightningd** and the peer cannot agree on channel parameters (funding limits, channel reserves, fees, etc.). diff --git a/doc/lightning-multifundchannel.7.md b/doc/lightning-multifundchannel.7.md index 0203be78e939..ddde69877e94 100644 --- a/doc/lightning-multifundchannel.7.md +++ b/doc/lightning-multifundchannel.7.md @@ -28,7 +28,7 @@ Readiness is indicated by **listpeers** reporting a *state* of in a manner understood by **connect**; see lightning-connect(7). Each entry in the *destinations* array must have a unique node *id*. * *amount* is the amount in satoshis taken from the internal wallet - to fund the channel. + to fund the channel (but if we have any anchor channels, this will always leave at least `min-emergency-msat` as change). The string *all* can be used to specify all available funds (or 16,777,215 satoshi if more is available and large channels were not negotiated with the peer). @@ -122,6 +122,7 @@ The following error codes may occur: - 301: There are not enough funds in the internal wallet (including fees) to create the transaction. - 302: The output amount is too small, and would be considered dust. - 303: Broadcasting of the funding transaction failed, the internal call to bitcoin-cli returned with an error. +- 313: The `min-emergency-msat` reserve not be preserved (and we have or are opening anchor channels). Failure may also occur if **lightningd** and the peer cannot agree on channel parameters (funding limits, channel reserves, fees, etc.). diff --git a/plugins/spender/multifundchannel.c b/plugins/spender/multifundchannel.c index 861c47a97b08..d090ded8286b 100644 --- a/plugins/spender/multifundchannel.c +++ b/plugins/spender/multifundchannel.c @@ -1291,6 +1291,18 @@ after_fundpsbt(struct command *cmd, } +static bool any_dest_negotiated_anchors(const struct plugin *plugin, + const struct multifundchannel_destination *dests) +{ + for (size_t i = 0; i < tal_count(dests); i++) { + if (feature_negotiated(plugin_feature_set(plugin), + dests[i].their_features, + OPT_ANCHORS_ZERO_FEE_HTLC_TX)) + return true; + } + return false; +} + static struct command_result * perform_fundpsbt(struct multifundchannel_command *mfc, u32 feerate) { @@ -1329,6 +1341,12 @@ perform_fundpsbt(struct multifundchannel_command *mfc, u32 feerate) dest_count(mfc, OPEN_CHANNEL) > 0); } + /* If we're about to open an anchor channel, we need emergency funds! */ + if (any_dest_negotiated_anchors(mfc->cmd->plugin, + mfc->destinations)) { + json_add_bool(req->js, "opening_anchor_channel", true); + } + /* The entire point is to reserve the inputs. */ /* BOLT #2: * The sender: