Skip to content

Commit 65a145f

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 a8f75cc commit 65a145f

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,9 +1091,10 @@ static bool consider_onchain_htlc_tx_rebroadcast(struct channel *channel,
10911091
utxos = wallet_utxo_boost(tmpctx,
10921092
ld->wallet,
10931093
get_block_height(ld->topology),
1094+
AMOUNT_SAT(0),
10941095
bitcoin_tx_compute_fee(newtx),
10951096
feerate,
1096-
&weight);
1097+
&weight, NULL);
10971098

10981099
/* Add those to create a new PSBT */
10991100
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
@@ -574,13 +574,29 @@ struct utxo *wallet_utxo_get(const tal_t *ctx, struct wallet *w,
574574
return utxo;
575575
}
576576

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

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

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

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

607629
/* Don't add reserved ones */
608630
if (utxo_is_reserved(utxo, blockheight))
@@ -613,24 +635,28 @@ struct utxo **wallet_utxo_boost(const tal_t *ctx,
613635
continue;
614636

615637
/* UTXOs must be sane amounts */
616-
if (!amount_sat_add(&new_fee_amount,
617-
fee_amount, utxo->amount))
638+
if (!amount_sat_add(&new_excess_sats,
639+
excess_sats, utxo->amount))
618640
abort();
619641

620642
new_weight = *weight + utxo_spend_weight(utxo, 0);
621-
if (!amount_feerate(&new_feerate, new_fee_amount, new_weight))
622-
abort();
643+
new_feerate = calc_feerate(new_excess_sats, output_sats_required,
644+
new_weight);
623645

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

628650
feerate = new_feerate;
629651
*weight = new_weight;
630-
fee_amount = new_fee_amount;
652+
excess_sats = new_excess_sats;
631653
tal_arr_expand(&utxos, tal_steal(utxos, utxo));
632654
}
633655

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

wallet/wallet.h

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

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

0 commit comments

Comments
 (0)