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
This commit is contained in:
lisa neigut 2019-12-30 13:02:23 -06:00 committed by Christian Decker
parent f15d34465d
commit d36af2c340
2 changed files with 18 additions and 6 deletions

View File

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

View File

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