diff --git a/bitcoin/psbt.c b/bitcoin/psbt.c index e2b45a71b..67c15435e 100644 --- a/bitcoin/psbt.c +++ b/bitcoin/psbt.c @@ -1,6 +1,7 @@ #include #include -#include +#include +#include #include #include #include @@ -13,6 +14,54 @@ memmove((arr) + (pos), (arr) + (pos) + 1, \ sizeof(*(arr)) * ((num) - ((pos) + 1))) +void psbt_destroy(struct wally_psbt *psbt) +{ + wally_psbt_free(psbt); +} + +struct wally_psbt *new_psbt(const tal_t *ctx, const struct wally_tx *wtx) +{ + struct wally_psbt *psbt; + int wally_err; + u8 **scripts; + size_t *script_lens; + struct wally_tx_witness_stack **witnesses; + + wally_err = wally_psbt_init_alloc(wtx->num_inputs, wtx->num_outputs, 0, &psbt); + assert(wally_err == WALLY_OK); + tal_add_destructor(psbt, psbt_destroy); + + /* we can't have scripts on the psbt's global tx, + * so we erase them/stash them until after it's been populated */ + scripts = tal_arr(NULL, u8 *, wtx->num_inputs); + script_lens = tal_arr(NULL, size_t, wtx->num_inputs); + witnesses = tal_arr(NULL, struct wally_tx_witness_stack *, wtx->num_inputs); + for (size_t i = 0; i < wtx->num_inputs; i++) { + scripts[i] = (u8 *)wtx->inputs[i].script; + wtx->inputs[i].script = NULL; + script_lens[i] = wtx->inputs[i].script_len; + wtx->inputs[i].script_len = 0; + witnesses[i] = wtx->inputs[i].witness; + wtx->inputs[i].witness = NULL; + } + + wally_err = wally_psbt_set_global_tx(psbt, cast_const(struct wally_tx *, wtx)); + assert(wally_err == WALLY_OK); + + /* set the scripts + witnesses back */ + for (size_t i = 0; i < wtx->num_inputs; i++) { + wtx->inputs[i].script = (unsigned char *)scripts[i]; + wtx->inputs[i].script_len = script_lens[i]; + wtx->inputs[i].witness = witnesses[i]; + } + + tal_free(witnesses); + tal_free(scripts); + tal_free(script_lens); + + return tal_steal(ctx, psbt); +} + struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt, struct wally_tx_input *input, size_t insert_at) diff --git a/bitcoin/psbt.h b/bitcoin/psbt.h index 96327c7a3..6f7e5a8e2 100644 --- a/bitcoin/psbt.h +++ b/bitcoin/psbt.h @@ -1,12 +1,19 @@ #ifndef LIGHTNING_BITCOIN_PSBT_H #define LIGHTNING_BITCOIN_PSBT_H #include "config.h" +#include #include struct wally_tx_input; struct wally_tx_output; struct wally_psbt; struct wally_psbt_input; +struct wally_tx; + +void psbt_destroy(struct wally_psbt *psbt); + +struct wally_psbt *new_psbt(const tal_t *ctx, + const struct wally_tx *wtx); struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt, struct wally_tx_input *input, diff --git a/bitcoin/test/run-bitcoin_block_from_hex.c b/bitcoin/test/run-bitcoin_block_from_hex.c index 8359db321..b94a9f702 100644 --- a/bitcoin/test/run-bitcoin_block_from_hex.c +++ b/bitcoin/test/run-bitcoin_block_from_hex.c @@ -1,4 +1,5 @@ #include "../block.c" +#include "../psbt.c" #include "../pullpush.c" #include "../shadouble.c" #include "../tx.c" @@ -42,16 +43,6 @@ u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED, /* Generated stub for fromwire_u16 */ u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u16 called!\n"); abort(); } -/* Generated stub for psbt_add_input */ -struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt UNNEEDED, - struct wally_tx_input *input UNNEEDED, - size_t insert_at UNNEEDED) -{ fprintf(stderr, "psbt_add_input called!\n"); abort(); } -/* Generated stub for psbt_add_output */ -struct wally_psbt_output *psbt_add_output(struct wally_psbt *psbt UNNEEDED, - struct wally_tx_output *output UNNEEDED, - size_t insert_at UNNEEDED) -{ fprintf(stderr, "psbt_add_output called!\n"); abort(); } /* Generated stub for towire_amount_sat */ void towire_amount_sat(u8 **pptr UNNEEDED, const struct amount_sat sat UNNEEDED) { fprintf(stderr, "towire_amount_sat called!\n"); abort(); } diff --git a/bitcoin/test/run-tx-encode.c b/bitcoin/test/run-tx-encode.c index 397bb01e3..e88a094a9 100644 --- a/bitcoin/test/run-tx-encode.c +++ b/bitcoin/test/run-tx-encode.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -43,16 +44,6 @@ u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED, /* Generated stub for fromwire_u16 */ u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u16 called!\n"); abort(); } -/* Generated stub for psbt_add_input */ -struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt UNNEEDED, - struct wally_tx_input *input UNNEEDED, - size_t insert_at UNNEEDED) -{ fprintf(stderr, "psbt_add_input called!\n"); abort(); } -/* Generated stub for psbt_add_output */ -struct wally_psbt_output *psbt_add_output(struct wally_psbt *psbt UNNEEDED, - struct wally_tx_output *output UNNEEDED, - size_t insert_at UNNEEDED) -{ fprintf(stderr, "psbt_add_output called!\n"); abort(); } /* Generated stub for towire_amount_sat */ void towire_amount_sat(u8 **pptr UNNEEDED, const struct amount_sat sat UNNEEDED) { fprintf(stderr, "towire_amount_sat called!\n"); abort(); } diff --git a/bitcoin/tx.c b/bitcoin/tx.c index 1ce17d585..4d1c76512 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -478,7 +478,6 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, varint_t input_count, varint_t output_count, u32 nlocktime) { - int ret; struct bitcoin_tx *tx = tal(ctx, struct bitcoin_tx); assert(chainparams); @@ -496,11 +495,7 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, tx->wtx->locktime = nlocktime; tx->wtx->version = 2; tx->chainparams = chainparams; - - ret = wally_psbt_init_alloc(input_count, output_count, - 0, &tx->psbt); - assert(ret == WALLY_OK); - ret = wally_psbt_set_global_tx(tx->psbt, tx->wtx); + tx->psbt = new_psbt(tx, tx->wtx); return tx; } @@ -519,7 +514,7 @@ struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx, const u8 **cursor, size_t *max) { size_t wsize; - int flags = WALLY_TX_FLAG_USE_WITNESS, ret; + int flags = WALLY_TX_FLAG_USE_WITNESS; struct bitcoin_tx *tx = tal(ctx, struct bitcoin_tx); if (chainparams->is_elements) @@ -546,11 +541,7 @@ struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx, const u8 **cursor, tal_arrz(tx, struct amount_sat *, tx->wtx->inputs_allocation_len); tx->chainparams = chainparams; - ret = wally_psbt_init_alloc(tx->wtx->num_inputs, tx->wtx->num_outputs, - 0, &tx->psbt); - assert(ret == WALLY_OK); - ret = wally_psbt_set_global_tx(tx->psbt, tx->wtx); - + tx->psbt = new_psbt(tx, tx->wtx); *cursor += wsize; *max -= wsize;