wallet: be a little more flexible with change for emergency reserve.

We used to look for either other outputs which are sufficient for
reserve, *or* be able to create sufficient change to meet the
emergency reserve.  Allow the sum of both to meet the requirements:
otherwise test_funder_contribution_limits can flake.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-02-05 02:48:01 +10:30
parent 162a0abef4
commit e4d3cc8b04
3 changed files with 15 additions and 24 deletions

View file

@ -461,40 +461,40 @@ static bool change_for_emergency(struct lightningd *ld,
struct amount_sat *excess,
struct amount_sat *change)
{
struct amount_sat fee;
struct amount_sat needed = ld->emergency_sat, fee;
/* Only needed for anchor channels */
if (!have_anchor_channel)
return true;
/* Fine if rest of wallet has funds. */
/* Fine if rest of wallet has funds. Otherwise it may reduce
* needed amount. */
if (wallet_has_funds(ld->wallet,
cast_const2(const struct utxo **, utxos),
get_block_height(ld->topology),
ld->emergency_sat))
&needed))
return true;
/* If we can afford with existing change output, great (or
/* If we can afford the rest with existing change output, great (or
* ld->emergency_sat is 0) */
if (amount_sat_greater_eq(change_amount(*change,
feerate_per_kw, weight),
ld->emergency_sat))
needed))
return true;
/* Try splitting excess to add to change. */
fee = change_fee(feerate_per_kw, weight);
if (!amount_sat_sub(excess, *excess, fee)
|| !amount_sat_sub(excess, *excess, ld->emergency_sat))
|| !amount_sat_sub(excess, *excess, needed))
return false;
if (!amount_sat_add(change, *change, fee)
|| !amount_sat_add(change, *change, ld->emergency_sat))
|| !amount_sat_add(change, *change, needed))
abort();
/* We *will* get a change output now! */
assert(amount_sat_eq(change_amount(*change, feerate_per_kw,
weight),
ld->emergency_sat));
assert(amount_sat_eq(change_amount(*change, feerate_per_kw, weight),
needed));
return true;
}

View file

@ -674,10 +674,9 @@ struct utxo *wallet_find_utxo(const tal_t *ctx, struct wallet *w,
bool wallet_has_funds(struct wallet *w,
const struct utxo **excludes,
u32 current_blockheight,
struct amount_sat sats)
struct amount_sat *needed)
{
struct db_stmt *stmt;
struct amount_sat total = AMOUNT_SAT(0);
stmt = db_prepare_v2(w->db, SQL("SELECT"
" prev_out_tx"
@ -712,17 +711,9 @@ bool wallet_has_funds(struct wallet *w,
continue;
}
/* Overflow Should Not Happen */
if (!amount_sat_add(&total, total, utxo->amount)) {
db_fatal(w->db, "Invalid value for %s: %s",
type_to_string(tmpctx,
struct bitcoin_outpoint,
&utxo->outpoint),
fmt_amount_sat(tmpctx, utxo->amount));
}
/* If we've found enough, answer is yes. */
if (amount_sat_greater_eq(total, sats)) {
if (!amount_sat_sub(needed, *needed, utxo->amount)) {
*needed = AMOUNT_SAT(0);
tal_free(stmt);
return true;
}

View file

@ -482,7 +482,7 @@ struct utxo *wallet_find_utxo(const tal_t *ctx, struct wallet *w,
* @w: the wallet
* @excludes: the utxos not to count (tal_arr or NULL)
* @current_blockheight: current chain length.
* @sats: the target
* @needed: the target, reduced if we find some funds
*
* This is a gross estimate, since it doesn't take into account the fees we
* would need to actually spend these utxos!
@ -490,7 +490,7 @@ struct utxo *wallet_find_utxo(const tal_t *ctx, struct wallet *w,
bool wallet_has_funds(struct wallet *wallet,
const struct utxo **excludes,
u32 current_blockheight,
struct amount_sat sats);
struct amount_sat *needed);
/**
* wallet_add_onchaind_utxo - Add a UTXO with spending info from onchaind.