From d36af2c34086723a3b2f84e2efed1fb5371d6fea Mon Sep 17 00:00:00 2001 From: lisa neigut Date: Mon, 30 Dec 2019 13:02:23 -0600 Subject: [PATCH] txprepare: make output finding map for withdraw_tx variable len The number of outputs got updated, but the map used to calculate the change output's location did not (still assumes only one output). This patch fixes this to make the output map a variable size. Changelog-Fixed: JSON API: `txprepare` no longer crashes when more than two outputs are specified --- common/withdraw_tx.c | 23 ++++++++++++++++++----- tests/test_wallet.py | 1 - 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/common/withdraw_tx.c b/common/withdraw_tx.c index 17e992cf3..e60e909e2 100644 --- a/common/withdraw_tx.c +++ b/common/withdraw_tx.c @@ -19,24 +19,37 @@ struct bitcoin_tx *withdraw_tx(const tal_t *ctx, int *change_outnum) { struct bitcoin_tx *tx; + int output_count; tx = tx_spending_utxos(ctx, chainparams, utxos, bip32_base, !amount_sat_eq(change, AMOUNT_SAT(0)), tal_count(outputs)); - bitcoin_tx_add_multi_outputs(tx, outputs); + output_count = bitcoin_tx_add_multi_outputs(tx, outputs); + assert(output_count == tal_count(outputs)); if (!amount_sat_eq(change, AMOUNT_SAT(0))) { - const void *map[2]; - map[0] = int2ptr(0); - map[1] = int2ptr(1); + /* Add one to the output_count, for the change */ + output_count++; + + const void *map[output_count]; + for (size_t i = 0; i < output_count; i++) + map[i] = int2ptr(i); + bitcoin_tx_add_output(tx, scriptpubkey_p2wpkh(tmpctx, changekey), change); + + assert(tx->wtx->num_outputs == output_count); permute_outputs(tx, NULL, map); + + /* The change is the last output added, so the last position + * in the map */ if (change_outnum) - *change_outnum = ptr2int(map[1]); + *change_outnum = ptr2int(map[output_count - 1]); + } else if (change_outnum) *change_outnum = -1; + permute_inputs(tx, (const void **)utxos); elements_tx_add_fee_output(tx); assert(bitcoin_tx_check(tx)); diff --git a/tests/test_wallet.py b/tests/test_wallet.py index 6d9c63fe2..0be04ed89 100644 --- a/tests/test_wallet.py +++ b/tests/test_wallet.py @@ -265,7 +265,6 @@ def test_deprecated_txprepare(node_factory, bitcoind): l1.rpc.call('txprepare', {'destination': addr, 'satoshi': Millisatoshi(amount * 100)}) -@pytest.mark.xfail def test_txprepare_multi(node_factory, bitcoind): amount = 10000000 l1 = node_factory.get_node(random_hsm=True)