Skip to content

Commit 2db1153

Browse files
committed
wallet: generalize wallet_utxo_boost.
We use this for anchors, in which case we have a minimum value for change. If we don't take this into account, we end up with a lower feerate once we actually create the tx. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent a89a2d4 commit 2db1153

File tree

4 files changed

+52
-19
lines changed

4 files changed

+52
-19
lines changed

lightningd/anchorspend.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,14 +294,16 @@ static struct wally_psbt *try_anchor_psbt(const tal_t *ctx,
294294
struct wally_psbt *psbt;
295295
struct amount_sat fee;
296296

297-
/* Ask for some UTXOs which could meet this feerate */
297+
/* Ask for some UTXOs which could meet this feerate, and since
298+
* we need one output, meet the minumum output requirement */
298299
*total_weight = base_weight;
299300
*utxos = wallet_utxo_boost(ctx,
300301
ld->wallet,
301302
get_block_height(ld->topology),
302303
anch->info.commitment_fee,
304+
chainparams->dust_limit,
303305
feerate_target,
304-
total_weight);
306+
total_weight, NULL);
305307

306308
/* Create a new candidate PSBT */
307309
psbt = anchor_psbt(ctx, channel, anch, *utxos, feerate_target,

lightningd/onchain_control.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1091,8 +1091,9 @@ static bool consider_onchain_htlc_tx_rebroadcast(struct channel *channel,
10911091
ld->wallet,
10921092
get_block_height(ld->topology),
10931093
bitcoin_tx_compute_fee(newtx),
1094+
AMOUNT_SAT(0),
10941095
feerate,
1095-
&weight);
1096+
&weight, NULL);
10961097

10971098
/* Add those to create a new PSBT */
10981099
psbt = psbt_using_utxos(tmpctx, ld->wallet, utxos, locktime,

wallet/wallet.c

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -573,13 +573,29 @@ struct utxo *wallet_utxo_get(const tal_t *ctx, struct wallet *w,
573573
return utxo;
574574
}
575575

576+
static u32 calc_feerate(struct amount_sat excess_sats,
577+
struct amount_sat output_sats_required,
578+
size_t weight)
579+
{
580+
struct amount_sat fee;
581+
u32 feerate;
582+
583+
if (!amount_sat_sub(&fee, excess_sats, output_sats_required))
584+
return 0;
585+
if (!amount_feerate(&feerate, fee, weight))
586+
abort();
587+
return feerate;
588+
}
589+
576590
/* Gather enough utxos to meet feerate, otherwise all we can. */
577591
struct utxo **wallet_utxo_boost(const tal_t *ctx,
578592
struct wallet *w,
579593
u32 blockheight,
580-
struct amount_sat fee_amount,
594+
struct amount_sat excess_sats,
595+
struct amount_sat output_sats_required,
581596
u32 feerate_target,
582-
size_t *weight)
597+
size_t *weight,
598+
bool *insufficient)
583599
{
584600
struct utxo **all_utxos = wallet_get_unspent_utxos(tmpctx, w);
585601
struct utxo **utxos = tal_arr(ctx, struct utxo *, 0);
@@ -588,20 +604,26 @@ struct utxo **wallet_utxo_boost(const tal_t *ctx,
588604
/* Select in random order */
589605
tal_arr_randomize(all_utxos, struct utxo *);
590606

591-
/* Can't overflow, it's from our tx! */
592-
if (!amount_feerate(&feerate, fee_amount, *weight))
593-
abort();
607+
feerate = calc_feerate(excess_sats, output_sats_required, *weight);
594608

595609
for (size_t i = 0; i < tal_count(all_utxos); i++) {
596610
u32 new_feerate;
597611
size_t new_weight;
598-
struct amount_sat new_fee_amount;
612+
struct amount_sat new_excess_sats;
599613
/* Convenience var */
600614
struct utxo *utxo = all_utxos[i];
601615

602616
/* Are we already happy? */
603-
if (feerate >= feerate_target)
604-
break;
617+
if (feerate >= feerate_target) {
618+
log_debug(w->log, "wallet_utxo_boost: got %zu UTXOs, excess %s (needed %s), weight %zu, feerate %u >= %u",
619+
tal_count(utxos),
620+
fmt_amount_sat(tmpctx, excess_sats),
621+
fmt_amount_sat(tmpctx, output_sats_required),
622+
*weight, feerate, feerate_target);
623+
if (insufficient)
624+
*insufficient = false;
625+
return utxos;
626+
}
605627

606628
/* Don't add reserved ones */
607629
if (utxo_is_reserved(utxo, blockheight))
@@ -612,24 +634,28 @@ struct utxo **wallet_utxo_boost(const tal_t *ctx,
612634
continue;
613635

614636
/* UTXOs must be sane amounts */
615-
if (!amount_sat_add(&new_fee_amount,
616-
fee_amount, utxo->amount))
637+
if (!amount_sat_add(&new_excess_sats,
638+
excess_sats, utxo->amount))
617639
abort();
618640

619641
new_weight = *weight + utxo_spend_weight(utxo, 0);
620-
if (!amount_feerate(&new_feerate, new_fee_amount, new_weight))
621-
abort();
642+
new_feerate = calc_feerate(new_excess_sats, output_sats_required,
643+
new_weight);
622644

623645
/* Don't add uneconomic ones! */
624646
if (new_feerate < feerate)
625647
continue;
626648

627649
feerate = new_feerate;
628650
*weight = new_weight;
629-
fee_amount = new_fee_amount;
651+
excess_sats = new_excess_sats;
630652
tal_arr_expand(&utxos, tal_steal(utxos, utxo));
631653
}
632654

655+
log_debug(w->log, "wallet_utxo_boost: fell short, returning %zu UTXOs",
656+
tal_count(utxos));
657+
if (insufficient)
658+
*insufficient = true;
633659
return utxos;
634660
}
635661

wallet/wallet.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -570,19 +570,23 @@ struct utxo *wallet_utxo_get(const tal_t *ctx, struct wallet *w,
570570
* @ctx: context to tal return array from
571571
* @w: the wallet
572572
* @blockheight: current height (to determine reserved status)
573-
* @fee_amount: amount already paying in fees
573+
* @excess_sats: how much excess it's already got.
574+
* @output_sats_required: minimum amount required to output
574575
* @feerate_target: feerate we want, in perkw.
575576
* @weight: (in)existing weight before any utxos added, (out)final weight with utxos added.
577+
* @insufficient: (out) if non-NULL, set true if we run out of utxos, otherwise false.
576578
*
577579
* May not meet the feerate, but will spend all available utxos to try.
578580
* You may also need to create change, as it may exceed.
579581
*/
580582
struct utxo **wallet_utxo_boost(const tal_t *ctx,
581583
struct wallet *w,
582584
u32 blockheight,
583-
struct amount_sat fee_amount,
585+
struct amount_sat excess_sats,
586+
struct amount_sat output_sats_required,
584587
u32 feerate_target,
585-
size_t *weight);
588+
size_t *weight,
589+
bool *insufficient);
586590

587591
/**
588592
* wallet_can_spend - Do we have the private key matching this scriptpubkey?

0 commit comments

Comments
 (0)