Browse Source

mfc-df: after sigs are collected, go sign the psbt

fix-mocks
niftynei 4 years ago
committed by neil saitug
parent
commit
a34425abd1
  1. 10
      plugins/spender/multifundchannel.c
  2. 6
      plugins/spender/multifundchannel.h
  3. 93
      plugins/spender/openchannel.c
  4. 3
      plugins/spender/openchannel.h

10
plugins/spender/multifundchannel.c

@ -1467,9 +1467,6 @@ fundchannel_complete_done(struct multifundchannel_destination *dest)
return command_still_pending(mfc->cmd); return command_still_pending(mfc->cmd);
} }
static struct command_result *
perform_signpsbt(struct multifundchannel_command *mfc);
static struct command_result * static struct command_result *
after_fundchannel_complete(struct multifundchannel_command *mfc) after_fundchannel_complete(struct multifundchannel_command *mfc)
{ {
@ -1515,14 +1512,17 @@ after_signpsbt(struct command *cmd,
const jsmntok_t *result, const jsmntok_t *result,
struct multifundchannel_command *mfc); struct multifundchannel_command *mfc);
static struct command_result * struct command_result *
perform_signpsbt(struct multifundchannel_command *mfc) perform_signpsbt(struct multifundchannel_command *mfc)
{ {
struct out_req *req; struct out_req *req;
/* Now we sign our inputs. You do remember which inputs
* are yours, right? */
plugin_log(mfc->cmd->plugin, LOG_DBG, plugin_log(mfc->cmd->plugin, LOG_DBG,
"mfc %"PRIu64": signpsbt.", mfc->id); "mfc %"PRIu64": signpsbt.", mfc->id);
/* FIXME: indicate our inputs with signonly */
req = jsonrpc_request_start(mfc->cmd->plugin, mfc->cmd, req = jsonrpc_request_start(mfc->cmd->plugin, mfc->cmd,
"signpsbt", "signpsbt",
&after_signpsbt, &after_signpsbt,
@ -1911,6 +1911,8 @@ json_multifundchannel(struct command *cmd,
mfc->final_tx = NULL; mfc->final_tx = NULL;
mfc->final_txid = NULL; mfc->final_txid = NULL;
mfc->sigs_collected = false;
return perform_multifundchannel(mfc); return perform_multifundchannel(mfc);
} }

6
plugins/spender/multifundchannel.h

@ -229,6 +229,9 @@ struct multifundchannel_command {
/* V2 things */ /* V2 things */
struct list_node list; struct list_node list;
/* V2 channel opens use this flag to gate PSBT signing */
bool sigs_collected;
}; };
/* Use this instead of forward_error. */ /* Use this instead of forward_error. */
@ -256,6 +259,9 @@ after_channel_start(struct multifundchannel_command *mfc);
struct command_result * struct command_result *
perform_fundchannel_complete(struct multifundchannel_command *mfc); perform_fundchannel_complete(struct multifundchannel_command *mfc);
struct command_result *
perform_signpsbt(struct multifundchannel_command *mfc);
struct command_result * struct command_result *
redo_multifundchannel(struct multifundchannel_command *mfc, redo_multifundchannel(struct multifundchannel_command *mfc,
const char *failing_method); const char *failing_method);

93
plugins/spender/openchannel.c

@ -477,7 +477,7 @@ openchannel_signed_dest(struct multifundchannel_destination *dest)
send_outreq(cmd->plugin, req); send_outreq(cmd->plugin, req);
} }
static struct command_result * struct command_result *
perform_openchannel_signed(struct multifundchannel_command *mfc) perform_openchannel_signed(struct multifundchannel_command *mfc)
{ {
plugin_log(mfc->cmd->plugin, LOG_DBG, plugin_log(mfc->cmd->plugin, LOG_DBG,
@ -514,47 +514,17 @@ perform_openchannel_signed(struct multifundchannel_command *mfc)
return command_still_pending(mfc->cmd); return command_still_pending(mfc->cmd);
} }
static struct command_result *
after_psbt_signed(struct command *cmd,
const char *buf,
const jsmntok_t *result,
struct multifundchannel_command *mfc)
{
const jsmntok_t *field;
struct wally_psbt *signed_psbt;
plugin_log(mfc->cmd->plugin, LOG_DBG,
"mfc %"PRIu64": `signpsbt` completed",
mfc->id);
field = json_get_member(buf, result, "signed_psbt");
if (!field)
plugin_err(mfc->cmd->plugin,
"`signpsbt` did not return 'signed_psbt'? %.*s",
json_tok_full_len(result),
json_tok_full(buf, result));
if (!json_to_psbt(tmpctx, buf, field, &signed_psbt))
plugin_err(mfc->cmd->plugin,
"`signpsbt` returned invalid 'signed_psbt' %.*s",
json_tok_full_len(field),
json_tok_full(buf, field));
tal_free(mfc->psbt);
mfc->psbt = tal_steal(mfc, signed_psbt);
return perform_openchannel_signed(mfc);
}
static struct command_result * static struct command_result *
collect_sigs(struct multifundchannel_command *mfc) collect_sigs(struct multifundchannel_command *mfc)
{ {
/* We need to sign the PSBT, we also need to /* There's a very small chance that we'll get a
* wait for all of the sigs to come in */ * race condition between when a signature arrives
struct out_req *req; * and all of the fundchannel_completes return.
struct bitcoin_txid mfc_txid; * This flag helps us avoid invoking this twice.*/
psbt_txid(NULL, mfc->psbt, &mfc_txid, NULL); if (mfc->sigs_collected)
return NULL;
mfc->sigs_collected = true;
/* But first! we sanity check that everyone's /* But first! we sanity check that everyone's
* expecting the same funding txid */ * expecting the same funding txid */
for (size_t i = 0; i < tal_count(mfc->destinations); i++) { for (size_t i = 0; i < tal_count(mfc->destinations); i++) {
@ -562,37 +532,42 @@ collect_sigs(struct multifundchannel_command *mfc)
struct bitcoin_txid dest_txid; struct bitcoin_txid dest_txid;
dest = &mfc->destinations[i]; dest = &mfc->destinations[i];
assert(dest->state == MULTIFUNDCHANNEL_SECURED || if (dest->protocol == FUND_CHANNEL) {
dest->state == MULTIFUNDCHANNEL_SIGNED); /* Since we're here, double check that
* every v1 has their commitment txs */
assert(dest->state == MULTIFUNDCHANNEL_COMPLETED);
continue;
}
assert(dest->state == MULTIFUNDCHANNEL_SIGNED);
psbt_txid(NULL, dest->psbt, &dest_txid, NULL); psbt_txid(NULL, dest->psbt, &dest_txid, NULL);
assert(bitcoin_txid_eq(&mfc_txid, &dest_txid)); assert(bitcoin_txid_eq(mfc->txid, &dest_txid));
} }
/* Now we sign our inputs. You do remember which inputs return perform_signpsbt(mfc);
* are yours, right? */
plugin_log(mfc->cmd->plugin, LOG_DBG,
"mfc %"PRIu64": signpsbt.", mfc->id);
req = jsonrpc_request_start(mfc->cmd->plugin, mfc->cmd,
"signpsbt",
&after_psbt_signed,
&mfc_forward_error,
mfc);
json_add_psbt(req->js, "psbt", mfc->psbt);
return send_outreq(mfc->cmd->plugin, req);
} }
struct command_result * struct command_result *
check_sigs_ready(struct multifundchannel_command *mfc) check_sigs_ready(struct multifundchannel_command *mfc)
{ {
static struct command_result *result;
bool ready = true; bool ready = true;
for (size_t i = 0; i < tal_count(mfc->destinations); i++)
ready &= mfc->destinations[i].state ==
MULTIFUNDCHANNEL_SIGNED;
if (ready) for (size_t i = 0; i < tal_count(mfc->destinations); i++) {
collect_sigs(mfc); enum multifundchannel_state state =
mfc->destinations[i].protocol == OPEN_CHANNEL ?
MULTIFUNDCHANNEL_SIGNED :
MULTIFUNDCHANNEL_COMPLETED;
ready &= mfc->destinations[i].state == state;
}
if (ready) {
result = collect_sigs(mfc);
if (result)
return result;
}
return command_still_pending(mfc->cmd); return command_still_pending(mfc->cmd);
} }

3
plugins/spender/openchannel.h

@ -24,4 +24,7 @@ perform_openchannel_update(struct multifundchannel_command *mfc);
struct command_result * struct command_result *
check_sigs_ready(struct multifundchannel_command *mfc); check_sigs_ready(struct multifundchannel_command *mfc);
struct command_result *
perform_openchannel_signed(struct multifundchannel_command *mfc);
#endif /* LIGHTNING_PLUGINS_SPENDER_OPENCHANNEL_H */ #endif /* LIGHTNING_PLUGINS_SPENDER_OPENCHANNEL_H */

Loading…
Cancel
Save