From b63abef5424475cf2ad54b6d7446fa3909e3061f Mon Sep 17 00:00:00 2001 From: niftynei Date: Sat, 6 Jun 2020 14:47:40 -0500 Subject: [PATCH] psbt: add method to finalize + extract a psbt will either use a temporary psbt (and not munge the passed in psbt) or will finalize in place -- finalization erases most of the signature metadata from the psbt struct --- bitcoin/psbt.c | 32 ++++++++++++++++++++++++++++++++ bitcoin/psbt.h | 2 ++ bitcoin/tx.c | 26 +++----------------------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/bitcoin/psbt.c b/bitcoin/psbt.c index 383f51f4f..e17237ae5 100644 --- a/bitcoin/psbt.c +++ b/bitcoin/psbt.c @@ -340,6 +340,38 @@ struct amount_sat psbt_input_get_amount(struct wally_psbt *psbt, return val; } +struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place) +{ + struct wally_psbt *tmppsbt; + struct wally_tx *wtx; + + /* We want the 'finalized' tx since that includes any signature + * data, not the global tx. But 'finalizing' a tx destroys some fields + * so we 'clone' it first and then finalize it */ + if (!finalize_in_place) { + if (wally_psbt_clone(psbt, &tmppsbt) != WALLY_OK) + return NULL; + } else + tmppsbt = cast_const(struct wally_psbt *, psbt); + + if (wally_finalize_psbt(tmppsbt) != WALLY_OK) { + if (!finalize_in_place) + wally_psbt_free(tmppsbt); + return NULL; + } + + if (psbt_is_finalized(tmppsbt) + && wally_extract_psbt(tmppsbt, &wtx) == WALLY_OK) { + if (!finalize_in_place) + wally_psbt_free(tmppsbt); + return wtx; + } + + if (!finalize_in_place) + wally_psbt_free(tmppsbt); + return NULL; +} + bool psbt_from_b64(const char *b64str, struct wally_psbt **psbt) { int wally_err; diff --git a/bitcoin/psbt.h b/bitcoin/psbt.h index 8a483d682..68d718f96 100644 --- a/bitcoin/psbt.h +++ b/bitcoin/psbt.h @@ -32,6 +32,8 @@ struct wally_psbt *new_psbt(const tal_t *ctx, */ bool psbt_is_finalized(struct wally_psbt *psbt); +struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place); + struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt, struct wally_tx_input *input, size_t insert_at); diff --git a/bitcoin/tx.c b/bitcoin/tx.c index d7e839417..50f224a41 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -501,38 +501,18 @@ char *bitcoin_tx_to_psbt_base64(const tal_t *ctx, struct bitcoin_tx *tx) struct bitcoin_tx *bitcoin_tx_with_psbt(const tal_t *ctx, struct wally_psbt *psbt STEALS) { - struct wally_psbt *tmppsbt; struct bitcoin_tx *tx = bitcoin_tx(ctx, chainparams, psbt->tx->num_inputs, psbt->tx->num_outputs, psbt->tx->locktime); wally_tx_free(tx->wtx); - - /* We want the 'finalized' tx since that includes any signature - * data, not the global tx. But 'finalizing' a tx destroys some fields - * so we 'clone' it first and then finalize it */ - if (wally_psbt_clone(psbt, &tmppsbt) != WALLY_OK) + tx->wtx = psbt_finalize(psbt, false); + if (!tx->wtx && wally_tx_clone(psbt->tx, &tx->wtx) != WALLY_OK) return NULL; - if (wally_finalize_psbt(tmppsbt) != WALLY_OK) { - wally_psbt_free(tmppsbt); - return NULL; - } - - if (psbt_is_finalized(tmppsbt)) { - if (wally_extract_psbt(tmppsbt, &tx->wtx) != WALLY_OK) { - wally_psbt_free(tmppsbt); - return NULL; - } - } else if (wally_tx_clone(psbt->tx, &tx->wtx) != WALLY_OK) { - wally_psbt_free(tmppsbt); - return NULL; - } - - wally_psbt_free(tmppsbt); - tal_free(tx->psbt); tx->psbt = tal_steal(tx, psbt); + return tx; }