psbt: create new_psbt method

Move all psbt creation into single method, new_psbt

note that if a psbt is init'd for a transaction that's
deserialized with scripts etc already attached, then set_global_tx
will fail. instead, we empty all of this out first.

if the tx is being re-init'd from a tx source that had a psbt attached
(e.g. fromwire_) then the script/witness data will get populated
appropriatel from there.
This commit is contained in:
niftynei 2020-05-21 11:27:01 +09:30 committed by Rusty Russell
parent a848df67f1
commit 5d0fc176e8
5 changed files with 62 additions and 33 deletions

View File

@ -1,6 +1,7 @@
#include <assert.h>
#include <bitcoin/psbt.h>
#include <ccan/tal/tal.h>
#include <ccan/cast/cast.h>
#include <ccan/short_types/short_types.h>
#include <string.h>
#include <wally_psbt.h>
#include <wally_transaction.h>
@ -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)

View File

@ -1,12 +1,19 @@
#ifndef LIGHTNING_BITCOIN_PSBT_H
#define LIGHTNING_BITCOIN_PSBT_H
#include "config.h"
#include <ccan/tal/tal.h>
#include <stddef.h>
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,

View File

@ -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(); }

View File

@ -1,4 +1,5 @@
#include <assert.h>
#include <bitcoin/psbt.c>
#include <bitcoin/pullpush.c>
#include <bitcoin/shadouble.c>
#include <bitcoin/tx.c>
@ -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(); }

View File

@ -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;