mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 06:41:44 +01:00
mfc: final inversion!
Move only.
This commit is contained in:
parent
6ccdd1dbab
commit
a9794889bf
1 changed files with 149 additions and 153 deletions
|
@ -51,6 +51,17 @@ size_t dest_count(const struct multifundchannel_command *mfc,
|
|||
return count;
|
||||
}
|
||||
|
||||
void fail_destination(struct multifundchannel_destination *dest,
|
||||
char *error TAKES)
|
||||
{
|
||||
dest->fail_state = dest->state;
|
||||
dest->state = MULTIFUNDCHANNEL_FAILED;
|
||||
if (taken(error))
|
||||
dest->error = tal_steal(dest->mfc, error);
|
||||
else
|
||||
dest->error = tal_strdup(dest->mfc, error);
|
||||
}
|
||||
|
||||
/* Return true if this destination failed, false otherwise. */
|
||||
static bool dest_failed(struct multifundchannel_destination *dest)
|
||||
{
|
||||
|
@ -426,151 +437,6 @@ param_destinations_array(struct command *cmd, const char *name,
|
|||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
fundchannel_complete_dest(struct multifundchannel_destination *dest);
|
||||
struct command_result *
|
||||
perform_fundchannel_complete(struct multifundchannel_command *mfc)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
plugin_log(mfc->cmd->plugin, LOG_DBG,
|
||||
"mfc %"PRIu64": parallel fundchannel_complete.",
|
||||
mfc->id);
|
||||
|
||||
mfc->pending = dest_count(mfc, FUND_CHANNEL);
|
||||
|
||||
for (i = 0; i < tal_count(mfc->destinations); ++i) {
|
||||
if (mfc->destinations[i].protocol == FUND_CHANNEL)
|
||||
fundchannel_complete_dest(&mfc->destinations[i]);
|
||||
}
|
||||
|
||||
assert(mfc->pending != 0);
|
||||
return command_still_pending(mfc->cmd);
|
||||
}
|
||||
|
||||
|
||||
/*~ The PSBT we are holding currently has no outputs.
|
||||
We now proceed to filling in those outputs now that
|
||||
we know what the funding scriptpubkeys are.
|
||||
|
||||
First thing we do is to shuffle the outputs.
|
||||
This is needed in order to decorrelate the transaction
|
||||
outputs from the parameters passed into the command.
|
||||
We should assume that the caller of the command might
|
||||
inadvertently leak important privacy data in the order
|
||||
of its arguments, so we shuffle the outputs.
|
||||
*/
|
||||
static struct command_result *
|
||||
perform_funding_tx_finalize(struct multifundchannel_command *mfc)
|
||||
{
|
||||
struct multifundchannel_destination **deck;
|
||||
char *content = tal_strdup(tmpctx, "");
|
||||
size_t v1_dest_count = dest_count(mfc, FUND_CHANNEL);
|
||||
size_t v2_dest_count = dest_count(mfc, OPEN_CHANNEL);
|
||||
size_t i, deck_i;
|
||||
|
||||
plugin_log(mfc->cmd->plugin, LOG_DBG,
|
||||
"mfc %"PRIu64": Creating funding tx.",
|
||||
mfc->id);
|
||||
|
||||
/* Construct a deck of destinations. */
|
||||
deck = tal_arr(tmpctx, struct multifundchannel_destination *,
|
||||
v1_dest_count + mfc->change_needed);
|
||||
|
||||
deck_i = 0;
|
||||
for (i = 0; i < tal_count(mfc->destinations); i++) {
|
||||
if (mfc->destinations[i].protocol == OPEN_CHANNEL)
|
||||
continue;
|
||||
|
||||
assert(deck_i < tal_count(deck));
|
||||
deck[deck_i++] = &mfc->destinations[i];
|
||||
}
|
||||
|
||||
/* Add a NULL into the deck as a proxy for change output, if
|
||||
* needed. */
|
||||
if (mfc->change_needed)
|
||||
deck[v1_dest_count] = NULL;
|
||||
/* Fisher-Yates shuffle. */
|
||||
for (i = tal_count(deck); i > 1; --i) {
|
||||
size_t j = pseudorand(i);
|
||||
if (j == i - 1)
|
||||
continue;
|
||||
struct multifundchannel_destination *tmp;
|
||||
tmp = deck[j];
|
||||
deck[j] = deck[i - 1];
|
||||
deck[i - 1] = tmp;
|
||||
}
|
||||
|
||||
/* Now that we have our outputs shuffled, add outputs to the PSBT. */
|
||||
for (unsigned int outnum = 0; outnum < tal_count(deck); ++outnum) {
|
||||
if (outnum != 0)
|
||||
tal_append_fmt(&content, ", ");
|
||||
if (deck[outnum]) {
|
||||
/* Funding outpoint. */
|
||||
struct multifundchannel_destination *dest;
|
||||
dest = deck[outnum];
|
||||
(void) psbt_insert_output(mfc->psbt,
|
||||
dest->funding_script,
|
||||
dest->amount,
|
||||
outnum);
|
||||
/* The actual output index will be based on the
|
||||
* serial_id if this contains any v2 outputs */
|
||||
if (v2_dest_count == 0)
|
||||
dest->outnum = outnum;
|
||||
tal_append_fmt(&content, "%s: %s",
|
||||
type_to_string(tmpctx, struct node_id,
|
||||
&dest->id),
|
||||
type_to_string(tmpctx,
|
||||
struct amount_sat,
|
||||
&dest->amount));
|
||||
} else {
|
||||
/* Change output. */
|
||||
assert(mfc->change_needed);
|
||||
(void) psbt_insert_output(mfc->psbt,
|
||||
mfc->change_scriptpubkey,
|
||||
mfc->change_amount,
|
||||
outnum);
|
||||
tal_append_fmt(&content, "change: %s",
|
||||
type_to_string(tmpctx,
|
||||
struct amount_sat,
|
||||
&mfc->change_amount));
|
||||
}
|
||||
}
|
||||
|
||||
if (v2_dest_count > 0) {
|
||||
/* Add serial_ids to all the new outputs */
|
||||
psbt_add_serials(mfc->psbt, TX_INITIATOR);
|
||||
|
||||
/* Now we stash the 'mfc' command, so when/if
|
||||
* signature notifications start coming
|
||||
* in, we'll catch them. */
|
||||
register_mfc(mfc);
|
||||
|
||||
/* Take a side-quest to finish filling out
|
||||
* the funding tx */
|
||||
return perform_openchannel_update(mfc);
|
||||
}
|
||||
|
||||
/* We've only got v1 destinations, move onward */
|
||||
/* Elements requires a fee output. */
|
||||
psbt_elements_normalize_fees(mfc->psbt);
|
||||
|
||||
/* Generate the TXID. */
|
||||
mfc->txid = tal(mfc, struct bitcoin_txid);
|
||||
psbt_txid(NULL, mfc->psbt, mfc->txid, NULL);
|
||||
|
||||
plugin_log(mfc->cmd->plugin, LOG_DBG,
|
||||
"mfc %"PRIu64": funding tx %s: %s",
|
||||
mfc->id,
|
||||
type_to_string(tmpctx, struct bitcoin_txid,
|
||||
mfc->txid),
|
||||
content);
|
||||
|
||||
/* Now we can feed the TXID and outnums to the peer. */
|
||||
return perform_fundchannel_complete(mfc);
|
||||
}
|
||||
|
||||
/*~
|
||||
We now have an unsigned funding transaction in
|
||||
mfc->psbt and mfc->txid that puts the money into
|
||||
|
@ -936,15 +802,145 @@ fundchannel_complete_dest(struct multifundchannel_destination *dest)
|
|||
send_outreq(cmd->plugin, req);
|
||||
}
|
||||
|
||||
void fail_destination(struct multifundchannel_destination *dest,
|
||||
char *error TAKES)
|
||||
struct command_result *
|
||||
perform_fundchannel_complete(struct multifundchannel_command *mfc)
|
||||
{
|
||||
dest->fail_state = dest->state;
|
||||
dest->state = MULTIFUNDCHANNEL_FAILED;
|
||||
if (taken(error))
|
||||
dest->error = tal_steal(dest->mfc, error);
|
||||
else
|
||||
dest->error = tal_strdup(dest->mfc, error);
|
||||
unsigned int i;
|
||||
|
||||
plugin_log(mfc->cmd->plugin, LOG_DBG,
|
||||
"mfc %"PRIu64": parallel fundchannel_complete.",
|
||||
mfc->id);
|
||||
|
||||
mfc->pending = dest_count(mfc, FUND_CHANNEL);
|
||||
|
||||
for (i = 0; i < tal_count(mfc->destinations); ++i) {
|
||||
if (mfc->destinations[i].protocol == FUND_CHANNEL)
|
||||
fundchannel_complete_dest(&mfc->destinations[i]);
|
||||
}
|
||||
|
||||
assert(mfc->pending != 0);
|
||||
return command_still_pending(mfc->cmd);
|
||||
}
|
||||
|
||||
/*~ The PSBT we are holding currently has no outputs.
|
||||
We now proceed to filling in those outputs now that
|
||||
we know what the funding scriptpubkeys are.
|
||||
|
||||
First thing we do is to shuffle the outputs.
|
||||
This is needed in order to decorrelate the transaction
|
||||
outputs from the parameters passed into the command.
|
||||
We should assume that the caller of the command might
|
||||
inadvertently leak important privacy data in the order
|
||||
of its arguments, so we shuffle the outputs.
|
||||
*/
|
||||
static struct command_result *
|
||||
perform_funding_tx_finalize(struct multifundchannel_command *mfc)
|
||||
{
|
||||
struct multifundchannel_destination **deck;
|
||||
char *content = tal_strdup(tmpctx, "");
|
||||
size_t v1_dest_count = dest_count(mfc, FUND_CHANNEL);
|
||||
size_t v2_dest_count = dest_count(mfc, OPEN_CHANNEL);
|
||||
size_t i, deck_i;
|
||||
|
||||
plugin_log(mfc->cmd->plugin, LOG_DBG,
|
||||
"mfc %"PRIu64": Creating funding tx.",
|
||||
mfc->id);
|
||||
|
||||
/* Construct a deck of destinations. */
|
||||
deck = tal_arr(tmpctx, struct multifundchannel_destination *,
|
||||
v1_dest_count + mfc->change_needed);
|
||||
|
||||
deck_i = 0;
|
||||
for (i = 0; i < tal_count(mfc->destinations); i++) {
|
||||
if (mfc->destinations[i].protocol == OPEN_CHANNEL)
|
||||
continue;
|
||||
|
||||
assert(deck_i < tal_count(deck));
|
||||
deck[deck_i++] = &mfc->destinations[i];
|
||||
}
|
||||
|
||||
/* Add a NULL into the deck as a proxy for change output, if
|
||||
* needed. */
|
||||
if (mfc->change_needed)
|
||||
deck[v1_dest_count] = NULL;
|
||||
/* Fisher-Yates shuffle. */
|
||||
for (i = tal_count(deck); i > 1; --i) {
|
||||
size_t j = pseudorand(i);
|
||||
if (j == i - 1)
|
||||
continue;
|
||||
struct multifundchannel_destination *tmp;
|
||||
tmp = deck[j];
|
||||
deck[j] = deck[i - 1];
|
||||
deck[i - 1] = tmp;
|
||||
}
|
||||
|
||||
/* Now that we have our outputs shuffled, add outputs to the PSBT. */
|
||||
for (unsigned int outnum = 0; outnum < tal_count(deck); ++outnum) {
|
||||
if (outnum != 0)
|
||||
tal_append_fmt(&content, ", ");
|
||||
if (deck[outnum]) {
|
||||
/* Funding outpoint. */
|
||||
struct multifundchannel_destination *dest;
|
||||
dest = deck[outnum];
|
||||
(void) psbt_insert_output(mfc->psbt,
|
||||
dest->funding_script,
|
||||
dest->amount,
|
||||
outnum);
|
||||
/* The actual output index will be based on the
|
||||
* serial_id if this contains any v2 outputs */
|
||||
if (v2_dest_count == 0)
|
||||
dest->outnum = outnum;
|
||||
tal_append_fmt(&content, "%s: %s",
|
||||
type_to_string(tmpctx, struct node_id,
|
||||
&dest->id),
|
||||
type_to_string(tmpctx,
|
||||
struct amount_sat,
|
||||
&dest->amount));
|
||||
} else {
|
||||
/* Change output. */
|
||||
assert(mfc->change_needed);
|
||||
(void) psbt_insert_output(mfc->psbt,
|
||||
mfc->change_scriptpubkey,
|
||||
mfc->change_amount,
|
||||
outnum);
|
||||
tal_append_fmt(&content, "change: %s",
|
||||
type_to_string(tmpctx,
|
||||
struct amount_sat,
|
||||
&mfc->change_amount));
|
||||
}
|
||||
}
|
||||
|
||||
if (v2_dest_count > 0) {
|
||||
/* Add serial_ids to all the new outputs */
|
||||
psbt_add_serials(mfc->psbt, TX_INITIATOR);
|
||||
|
||||
/* Now we stash the 'mfc' command, so when/if
|
||||
* signature notifications start coming
|
||||
* in, we'll catch them. */
|
||||
register_mfc(mfc);
|
||||
|
||||
/* Take a side-quest to finish filling out
|
||||
* the funding tx */
|
||||
return perform_openchannel_update(mfc);
|
||||
}
|
||||
|
||||
/* We've only got v1 destinations, move onward */
|
||||
/* Elements requires a fee output. */
|
||||
psbt_elements_normalize_fees(mfc->psbt);
|
||||
|
||||
/* Generate the TXID. */
|
||||
mfc->txid = tal(mfc, struct bitcoin_txid);
|
||||
psbt_txid(NULL, mfc->psbt, mfc->txid, NULL);
|
||||
|
||||
plugin_log(mfc->cmd->plugin, LOG_DBG,
|
||||
"mfc %"PRIu64": funding tx %s: %s",
|
||||
mfc->id,
|
||||
type_to_string(tmpctx, struct bitcoin_txid,
|
||||
mfc->txid),
|
||||
content);
|
||||
|
||||
/* Now we can feed the TXID and outnums to the peer. */
|
||||
return perform_fundchannel_complete(mfc);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
Loading…
Add table
Reference in a new issue