Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mfc: bug fixes for v2 opens #4294

Merged
merged 4 commits into from
Jan 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions plugins/spender/multifundchannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,35 @@ mfc_cleanup_done(struct command *cmd,
else
return command_still_pending(cmd);
}

/* Cleans up a txid by doing `txdiscard` on it. */
static void
mfc_cleanup_psbt(struct command *cmd,
struct multifundchannel_cleanup *cleanup,
struct wally_psbt *psbt)
{
struct wally_psbt *pruned_psbt;
struct out_req *req = jsonrpc_request_start(cmd->plugin,
cmd,
"unreserveinputs",
&mfc_cleanup_done,
&mfc_cleanup_done,
cleanup);
json_add_psbt(req->js, "psbt", psbt);

/* We might have peer's inputs on this, get rid of them */
tal_wally_start();
if (wally_psbt_clone_alloc(psbt, 0, &pruned_psbt) != WALLY_OK)
abort();
tal_wally_end(tal_steal(NULL, pruned_psbt));

for (size_t i = pruned_psbt->num_inputs - 1;
i < pruned_psbt->num_inputs;
i--) {
if (!psbt_input_is_ours(&pruned_psbt->inputs[i]))
psbt_rm_input(pruned_psbt, i);
}

json_add_psbt(req->js, "psbt", take(pruned_psbt));
send_outreq(cmd->plugin, req);
}
/* Cleans up a `fundchannel_start` by doing `fundchannel_cancel` on
Expand Down Expand Up @@ -852,7 +868,7 @@ static struct command_result *
handle_mfc_change(struct multifundchannel_command *mfc)
{
size_t change_weight;
struct amount_sat change_fee;
struct amount_sat change_fee, fee_paid, total_fee;
struct amount_sat change_min_limit;

/* Determine if adding a change output is worth it.
Expand All @@ -861,7 +877,18 @@ handle_mfc_change(struct multifundchannel_command *mfc)
*/
change_weight = bitcoin_tx_output_weight(
BITCOIN_SCRIPTPUBKEY_P2WPKH_LEN);
change_fee = amount_tx_fee(mfc->feerate_per_kw, change_weight);

/* To avoid 'off-by-one' errors due to rounding down
* (which we do in `amount_tx_fee`), we find the total calculated
* fees (estimated_weight + change weight @ feerate) and subtract
* the originally calculated fees (estimated_weight @ feerate) */
fee_paid = amount_tx_fee(mfc->feerate_per_kw,
mfc->estimated_final_weight);
total_fee = amount_tx_fee(mfc->feerate_per_kw,
mfc->estimated_final_weight + change_weight);
if (!amount_sat_sub(&change_fee, total_fee, fee_paid))
abort();

/* The limit is equal to the change_fee plus the dust limit. */
if (!amount_sat_add(&change_min_limit,
change_fee, chainparams->dust_limit))
Expand Down
48 changes: 23 additions & 25 deletions plugins/spender/openchannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,30 @@ static bool update_node_psbt(const tal_t *ctx,
static struct command_result *
openchannel_finished(struct multifundchannel_command *mfc)
{
for (size_t i = 0; i < tal_count(mfc->destinations); i++) {
struct multifundchannel_destination *dest;
dest = &mfc->destinations[i];

/* If there's a single failure, we have to
* return the failure to the user. */
if (dest->state == MULTIFUNDCHANNEL_FAILED) {
struct json_stream *out;

plugin_log(mfc->cmd->plugin, LOG_DBG,
"mfc %"PRIu64": %u failed, failing.",
mfc->id, dest->index);

out = jsonrpc_stream_fail_data(mfc->cmd,
dest->code,
dest->error);
json_add_node_id(out, "id", &dest->id);
json_add_string(out, "method", "openchannel_signed");
json_add_jsonstr(out, "error", dest->error);
json_object_end(out);

return mfc_finished(mfc, out);
}
}
mfc->psbt = tal_free(mfc->psbt);
return multifundchannel_finished(mfc);
}
Expand Down Expand Up @@ -393,14 +416,6 @@ openchannel_signed_err(struct command *cmd,
struct multifundchannel_command *mfc = dest->mfc;
const jsmntok_t *code_tok;

plugin_log(mfc->cmd->plugin, LOG_DBG,
"mfc %"PRIu64", dest %u: "
"failed! openchannel_signed %s: %.*s.",
mfc->id, dest->index,
node_id_to_hexstr(tmpctx, &dest->id),
json_tok_full_len(error),
json_tok_full(buf, error));

code_tok = json_get_member(buf, error, "code");
if (!code_tok)
plugin_err(cmd->plugin,
Expand Down Expand Up @@ -757,16 +772,8 @@ openchannel_update_err(struct command *cmd,
const jsmntok_t *error,
struct multifundchannel_destination *dest)
{
struct multifundchannel_command *mfc = dest->mfc;
const jsmntok_t *code_tok;

plugin_err(mfc->cmd->plugin,
"mfc %"PRIu64", dest %u: "
"failed! `openchannel_update` %s: %.*s",
mfc->id, dest->index,
node_id_to_hexstr(tmpctx, &dest->id),
json_tok_full_len(error), json_tok_full(buf, error));

code_tok = json_get_member(buf, error, "code");
if (!code_tok)
plugin_err(cmd->plugin,
Expand Down Expand Up @@ -983,17 +990,8 @@ openchannel_init_err(struct command *cmd,
const jsmntok_t *error,
struct multifundchannel_destination *dest)
{
struct multifundchannel_command *mfc = dest->mfc;
const jsmntok_t *code_tok;

plugin_err(mfc->cmd->plugin,
"mfc %"PRIu64", dest %u: "
"failed! openchannel_init %s: %.*s.",
mfc->id, dest->index,
node_id_to_hexstr(tmpctx, &dest->id),
json_tok_full_len(error),
json_tok_full(buf, error));

code_tok = json_get_member(buf, error, "code");
if (!code_tok)
plugin_err(cmd->plugin,
Expand Down