Browse Source

bitcoin/psbt: attach destructors to wally allocations to avoid leaks.

This covers the obvious ones, but the later patches fix this more
seriously.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: Some memory leaks in transaction and PSBT manipulate closed.
travis-experimental
Rusty Russell 4 years ago
parent
commit
11ebb84e7d
  1. 18
      bitcoin/psbt.c

18
bitcoin/psbt.c

@ -49,6 +49,7 @@ struct wally_psbt *create_psbt(const tal_t *ctx, size_t num_inputs, size_t num_o
wally_err = wally_psbt_set_global_tx(psbt, wtx); wally_err = wally_psbt_set_global_tx(psbt, wtx);
assert(wally_err == WALLY_OK); assert(wally_err == WALLY_OK);
wally_tx_free(wtx);
return psbt; return psbt;
} }
@ -252,7 +253,7 @@ bool psbt_input_set_signature(struct wally_psbt *psbt, size_t in,
void psbt_input_set_wit_utxo(struct wally_psbt *psbt, size_t in, void psbt_input_set_wit_utxo(struct wally_psbt *psbt, size_t in,
const u8 *scriptPubkey, struct amount_sat amt) const u8 *scriptPubkey, struct amount_sat amt)
{ {
struct wally_tx_output tx_out; struct wally_tx_output *tx_out;
int wally_err; int wally_err;
assert(in < psbt->num_inputs); assert(in < psbt->num_inputs);
@ -265,7 +266,7 @@ void psbt_input_set_wit_utxo(struct wally_psbt *psbt, size_t in,
sizeof(value)); sizeof(value));
assert(wally_err == WALLY_OK); assert(wally_err == WALLY_OK);
wally_err = wally_err =
wally_tx_elements_output_init(scriptPubkey, wally_tx_elements_output_init_alloc(scriptPubkey,
tal_bytelen(scriptPubkey), tal_bytelen(scriptPubkey),
chainparams->fee_asset_tag, chainparams->fee_asset_tag,
ELEMENTS_ASSET_LEN, ELEMENTS_ASSET_LEN,
@ -274,12 +275,13 @@ void psbt_input_set_wit_utxo(struct wally_psbt *psbt, size_t in,
NULL, 0, &tx_out); NULL, 0, &tx_out);
} else } else
wally_err = wally_tx_output_init(amt.satoshis, /* Raw: type conv */ wally_err = wally_tx_output_init_alloc(amt.satoshis, /* Raw: type conv */
scriptPubkey, scriptPubkey,
tal_bytelen(scriptPubkey), tal_bytelen(scriptPubkey),
&tx_out); &tx_out);
assert(wally_err == WALLY_OK); assert(wally_err == WALLY_OK);
wally_err = wally_psbt_input_set_witness_utxo(&psbt->inputs[in], &tx_out); wally_err = wally_psbt_input_set_witness_utxo(&psbt->inputs[in], tx_out);
wally_tx_output_free(tx_out);
assert(wally_err == WALLY_OK); assert(wally_err == WALLY_OK);
} }
@ -516,6 +518,12 @@ void psbt_output_add_unknown(struct wally_psbt_output *out,
abort(); abort();
} }
/* Use the destructor to free the wally_tx */
static void wally_tx_destroy(struct wally_tx *wtx)
{
wally_tx_free(wtx);
}
struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place) struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place)
{ {
struct wally_psbt *tmppsbt; struct wally_psbt *tmppsbt;
@ -527,6 +535,7 @@ struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place)
if (!finalize_in_place) { if (!finalize_in_place) {
if (wally_psbt_clone_alloc(psbt, 0, &tmppsbt) != WALLY_OK) if (wally_psbt_clone_alloc(psbt, 0, &tmppsbt) != WALLY_OK)
return NULL; return NULL;
tal_add_destructor(tmppsbt, psbt_destroy);
} else } else
tmppsbt = cast_const(struct wally_psbt *, psbt); tmppsbt = cast_const(struct wally_psbt *, psbt);
@ -576,6 +585,7 @@ struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place)
if (psbt_is_finalized(tmppsbt) if (psbt_is_finalized(tmppsbt)
&& wally_psbt_extract(tmppsbt, &wtx) == WALLY_OK) { && wally_psbt_extract(tmppsbt, &wtx) == WALLY_OK) {
tal_add_destructor(wtx, wally_tx_destroy);
if (!finalize_in_place) if (!finalize_in_place)
wally_psbt_free(tmppsbt); wally_psbt_free(tmppsbt);
return wtx; return wtx;

Loading…
Cancel
Save