Browse Source

wallet: check that funding_tx is affordabe if we trim change

In some cases, the funding transaction is affordable only
if we leave out the change amount.
travis-debug
lisa neigut 5 years ago
committed by Rusty Russell
parent
commit
fdcacbc7f0
  1. 31
      common/wallet_tx.c

31
common/wallet_tx.c

@ -156,6 +156,16 @@ struct command_result *wtx_select_utxos(struct wallet_tx *tx,
fee_rate_per_kw, out_len,
maxheight,
&fee_estimate, &tx->change);
if (!tx->utxos) {
/* Try again, without change this time */
tx->utxos = wallet_select_coins(tx, tx->cmd->ld->wallet,
false, tx->amount,
fee_rate_per_kw, out_len,
maxheight,
&fee_estimate, &tx->change);
}
res = check_amount(tx, tx->amount);
if (res)
return res;
@ -206,8 +216,8 @@ struct command_result *wtx_from_utxos(struct wallet_tx *tx,
if (!tx->all_funds && amount_sat_less(tx->amount, total_amount)
&& !amount_sat_sub(&tx->change, total_amount, tx->amount))
fatal("Overflow when computing change");
if (amount_sat_greater_eq(tx->change, get_chainparams(tx->cmd->ld)->dust_limit)) {
tx->change_key_index = wallet_get_newindex(tx->cmd->ld);
/* Add the change output's weight */
weight += (8 + 1 + out_len) * 4;
}
@ -222,11 +232,20 @@ struct command_result *wtx_from_utxos(struct wallet_tx *tx,
type_to_string(tmpctx, struct amount_sat,
&fee_estimate));
} else {
if (!amount_sat_sub(&tx->change, tx->change, fee_estimate))
return command_fail(tx->cmd, FUND_CANNOT_AFFORD,
"Cannot afford transaction with %s sats of fees",
type_to_string(tmpctx, struct amount_sat,
&fee_estimate));
if (!amount_sat_sub(&tx->change, tx->change, fee_estimate)) {
/* Try again without a change output */
weight -= (8 + 1 + out_len) * 4;
fee_estimate = amount_tx_fee(fee_rate_per_kw, weight);
if (!amount_sat_sub(&tx->change, tx->change, fee_estimate))
return command_fail(tx->cmd, FUND_CANNOT_AFFORD,
"Cannot afford transaction with %s sats of fees",
type_to_string(tmpctx, struct amount_sat,
&fee_estimate));
tx->change = AMOUNT_SAT(0);
} else {
tx->change_key_index = wallet_get_newindex(tx->cmd->ld);
}
}
return check_amount(tx, tx->amount);
}

Loading…
Cancel
Save