From d05a2a5aa9d928ec72e4dcaf77629dfb58da4dd6 Mon Sep 17 00:00:00 2001 From: niftynei Date: Fri, 2 Jul 2021 16:38:04 -0500 Subject: [PATCH] channel leases: add expected lease fee to opening PSBT We need to parse the feerate string, so we can figure out what our weight fee will be for a leased channel, so we go get the feerate and use that to calculate what our expected lease fee will be for the requested amount. --- plugins/spender/multifundchannel.c | 76 ++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/plugins/spender/multifundchannel.c b/plugins/spender/multifundchannel.c index e2de18446..5cce683f0 100644 --- a/plugins/spender/multifundchannel.c +++ b/plugins/spender/multifundchannel.c @@ -1376,9 +1376,8 @@ fail: } - static struct command_result * -perform_fundpsbt(struct multifundchannel_command *mfc) +perform_fundpsbt(struct multifundchannel_command *mfc, u32 feerate) { struct out_req *req; @@ -1425,11 +1424,34 @@ perform_fundpsbt(struct multifundchannel_command *mfc) else { struct amount_sat sum = AMOUNT_SAT(0); for (size_t i = 0; i < tal_count(mfc->destinations); ++i) { + struct amount_sat requested + = mfc->destinations[i].request_amt; + if (!amount_sat_add(&sum, sum, mfc->destinations[i].amount)) return mfc_fail(mfc, JSONRPC2_INVALID_PARAMS, "Overflow while summing " "destination values."); + /* Also add in any fees for requested amt! */ + if (!amount_sat_zero(requested)) { + struct amount_sat fee; + + /* Assume they send >= what we've + * requested (otherwise we error) */ + if (!lease_rates_calc_fee(mfc->destinations[i].rates, + requested, requested, + feerate, + &fee)) + return mfc_fail(mfc, JSONRPC2_INVALID_PARAMS, + "Overflow calculating" + " lease fee."); + + + if (!amount_sat_add(&sum, sum, fee)) + return mfc_fail(mfc, JSONRPC2_INVALID_PARAMS, + "Overflow while summing" + " lease fee"); + } } json_add_string(req->js, "satoshi", type_to_string(tmpctx, struct amount_sat, @@ -1467,6 +1489,54 @@ perform_fundpsbt(struct multifundchannel_command *mfc) return send_outreq(mfc->cmd->plugin, req); } +static struct command_result * +after_getfeerate(struct command *cmd, + const char *buf, + const jsmntok_t *result, + struct multifundchannel_command *mfc) +{ + const char *err; + u32 feerate; + + plugin_log(mfc->cmd->plugin, LOG_DBG, + "mfc %"PRIu64": 'parsefeerate' done", mfc->id); + + err = json_scan(tmpctx, buf, result, + "{perkw:%}", + JSON_SCAN(json_to_number, &feerate)); + if (err) + mfc_fail(mfc, JSONRPC2_INVALID_PARAMS, + "Unable to parse feerate %s: %*.s", + err, json_tok_full_len(result), + json_tok_full(buf, result)); + + return perform_fundpsbt(mfc, feerate); +} + +static struct command_result * +getfeerate(struct multifundchannel_command *mfc) +{ + struct out_req *req; + /* With the introduction of channel leases (option_will_fund), + * we need to include enough in the PSBT to cover our expected + * fees for the channel open. This requires that we know + * the feerate ahead of time, so that we can figure the + * expected lease fees, and add that to the funding amount. */ + req = jsonrpc_request_start(mfc->cmd->plugin, + mfc->cmd, + "parsefeerate", + &after_getfeerate, + &mfc_forward_error, + mfc); + + /* Internally, it defaults to 'opening', so we use that here */ + if (!mfc->feerate_str) + mfc->feerate_str = "opening"; + json_add_string(req->js, "feerate", mfc->feerate_str); + + return send_outreq(mfc->cmd->plugin, req); +} + /*---------------------------------------------------------------------------*/ /*~ First, connect to all the peers. @@ -1511,7 +1581,7 @@ after_multiconnect(struct multifundchannel_command *mfc) dest->error_message); } - return perform_fundpsbt(mfc); + return getfeerate(mfc); } static struct command_result *