mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-13 02:58:21 +01:00
lightningd: separate routine to gather utxos and create anchor.
We're going to call this twice. But this patch also takes care that a failed attempt to create an anchor doesn't alter other variables! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
0332babdb9
commit
737ae8e1eb
1 changed files with 73 additions and 43 deletions
|
@ -211,7 +211,7 @@ struct anchor_details *create_anchor_details(const tal_t *ctx,
|
||||||
/* total_weight includes the commitment tx we're trying to push! */
|
/* total_weight includes the commitment tx we're trying to push! */
|
||||||
static struct wally_psbt *anchor_psbt(const tal_t *ctx,
|
static struct wally_psbt *anchor_psbt(const tal_t *ctx,
|
||||||
struct channel *channel,
|
struct channel *channel,
|
||||||
struct one_anchor *anch,
|
const struct one_anchor *anch,
|
||||||
struct utxo **utxos,
|
struct utxo **utxos,
|
||||||
u32 feerate_target,
|
u32 feerate_target,
|
||||||
size_t total_weight)
|
size_t total_weight)
|
||||||
|
@ -255,16 +255,54 @@ static struct wally_psbt *anchor_psbt(const tal_t *ctx,
|
||||||
return psbt;
|
return psbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get UTXOs, create a PSBT to spend this */
|
||||||
|
static struct wally_psbt *try_anchor_psbt(const tal_t *ctx,
|
||||||
|
struct channel *channel,
|
||||||
|
const struct one_anchor *anch,
|
||||||
|
u32 feerate_target,
|
||||||
|
size_t base_weight,
|
||||||
|
size_t *total_weight,
|
||||||
|
struct amount_sat *fee_spent,
|
||||||
|
u32 *feerate,
|
||||||
|
struct utxo ***utxos)
|
||||||
|
{
|
||||||
|
struct lightningd *ld = channel->peer->ld;
|
||||||
|
struct wally_psbt *psbt;
|
||||||
|
struct amount_sat fee;
|
||||||
|
|
||||||
|
/* Ask for some UTXOs which could meet this feerate */
|
||||||
|
*total_weight = base_weight;
|
||||||
|
*utxos = wallet_utxo_boost(ctx,
|
||||||
|
ld->wallet,
|
||||||
|
get_block_height(ld->topology),
|
||||||
|
anch->info.commitment_fee,
|
||||||
|
feerate_target,
|
||||||
|
total_weight);
|
||||||
|
|
||||||
|
/* Create a new candidate PSBT */
|
||||||
|
psbt = anchor_psbt(ctx, channel, anch, *utxos, feerate_target,
|
||||||
|
*total_weight);
|
||||||
|
*fee_spent = psbt_compute_fee(psbt);
|
||||||
|
|
||||||
|
/* Add in base commitment fee to calculate *overall* package feerate */
|
||||||
|
if (!amount_sat_add(&fee, *fee_spent, anch->info.commitment_fee))
|
||||||
|
abort();
|
||||||
|
if (!amount_feerate(feerate, fee, *total_weight))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
return psbt;
|
||||||
|
}
|
||||||
|
|
||||||
/* If it's possible and worth it, return signed tx. Otherwise NULL. */
|
/* If it's possible and worth it, return signed tx. Otherwise NULL. */
|
||||||
static struct bitcoin_tx *spend_anchor(const tal_t *ctx,
|
static struct bitcoin_tx *spend_anchor(const tal_t *ctx,
|
||||||
struct channel *channel,
|
struct channel *channel,
|
||||||
struct one_anchor *anch)
|
struct one_anchor *anch)
|
||||||
{
|
{
|
||||||
struct lightningd *ld = channel->peer->ld;
|
struct lightningd *ld = channel->peer->ld;
|
||||||
struct utxo **utxos COMPILER_WANTS_INIT("gcc -O3 CI");
|
size_t base_weight, psbt_weight;
|
||||||
size_t base_weight, weight;
|
struct amount_sat psbt_fee, diff;
|
||||||
struct amount_sat fee, diff;
|
|
||||||
struct bitcoin_tx *tx;
|
struct bitcoin_tx *tx;
|
||||||
|
struct utxo **psbt_utxos;
|
||||||
struct wally_psbt *psbt, *signed_psbt;
|
struct wally_psbt *psbt, *signed_psbt;
|
||||||
struct amount_msat total_value;
|
struct amount_msat total_value;
|
||||||
const u8 *msg;
|
const u8 *msg;
|
||||||
|
@ -282,30 +320,23 @@ static struct bitcoin_tx *spend_anchor(const tal_t *ctx,
|
||||||
for (int i = tal_count(anch->adet->vals) - 1; i >= 0; --i) {
|
for (int i = tal_count(anch->adet->vals) - 1; i >= 0; --i) {
|
||||||
const struct deadline_value *val = &anch->adet->vals[i];
|
const struct deadline_value *val = &anch->adet->vals[i];
|
||||||
u32 feerate, feerate_target;
|
u32 feerate, feerate_target;
|
||||||
|
size_t weight;
|
||||||
|
struct amount_sat fee;
|
||||||
struct wally_psbt *candidate_psbt;
|
struct wally_psbt *candidate_psbt;
|
||||||
|
struct utxo **utxos;
|
||||||
|
|
||||||
|
|
||||||
/* Calculate the total value for the current deadline
|
|
||||||
* and all the following */
|
|
||||||
if (!amount_msat_accumulate(&total_value, val->msat))
|
if (!amount_msat_accumulate(&total_value, val->msat))
|
||||||
return NULL;
|
abort();
|
||||||
|
|
||||||
feerate_target = feerate_for_target(ld->topology, val->block);
|
feerate_target = feerate_for_target(ld->topology, val->block);
|
||||||
|
candidate_psbt = try_anchor_psbt(tmpctx, channel, anch,
|
||||||
/* Ask for some UTXOs which could meet this feerate */
|
|
||||||
weight = base_weight;
|
|
||||||
utxos = wallet_utxo_boost(tmpctx,
|
|
||||||
ld->wallet,
|
|
||||||
get_block_height(ld->topology),
|
|
||||||
anch->info.commitment_fee,
|
|
||||||
feerate_target,
|
feerate_target,
|
||||||
&weight);
|
base_weight,
|
||||||
|
&weight,
|
||||||
/* Create a new candidate PSBT */
|
&fee,
|
||||||
candidate_psbt = anchor_psbt(tmpctx, channel, anch, utxos, feerate_target, weight);
|
&feerate,
|
||||||
if (!candidate_psbt)
|
&utxos);
|
||||||
continue;
|
|
||||||
|
|
||||||
fee = psbt_compute_fee(candidate_psbt);
|
|
||||||
|
|
||||||
/* Is it even worth spending this fee to meet the deadline? */
|
/* Is it even worth spending this fee to meet the deadline? */
|
||||||
if (!amount_msat_greater_sat(total_value, fee)) {
|
if (!amount_msat_greater_sat(total_value, fee)) {
|
||||||
|
@ -318,13 +349,6 @@ static struct bitcoin_tx *spend_anchor(const tal_t *ctx,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add in base commitment fee */
|
|
||||||
if (!amount_sat_add(&fee,
|
|
||||||
fee, anch->info.commitment_fee))
|
|
||||||
abort();
|
|
||||||
if (!amount_feerate(&feerate, fee, weight))
|
|
||||||
abort();
|
|
||||||
|
|
||||||
if (feerate < feerate_target) {
|
if (feerate < feerate_target) {
|
||||||
/* We might have had lower feerates which worked: only complain if
|
/* We might have had lower feerates which worked: only complain if
|
||||||
* we have *nothing* */
|
* we have *nothing* */
|
||||||
|
@ -339,6 +363,9 @@ static struct bitcoin_tx *spend_anchor(const tal_t *ctx,
|
||||||
"We want to bump commit_tx to feerate %uperkw, but can only bump to %uperkw with %zu UTXOs!",
|
"We want to bump commit_tx to feerate %uperkw, but can only bump to %uperkw with %zu UTXOs!",
|
||||||
feerate_target, feerate, tal_count(utxos));
|
feerate_target, feerate, tal_count(utxos));
|
||||||
psbt = candidate_psbt;
|
psbt = candidate_psbt;
|
||||||
|
psbt_fee = fee;
|
||||||
|
psbt_weight = weight;
|
||||||
|
psbt_utxos = utxos;
|
||||||
/* We don't expect to do any better at higher feerates */
|
/* We don't expect to do any better at higher feerates */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -349,6 +376,9 @@ static struct bitcoin_tx *spend_anchor(const tal_t *ctx,
|
||||||
fmt_amount_msat(tmpctx, val->msat),
|
fmt_amount_msat(tmpctx, val->msat),
|
||||||
val->block, feerate);
|
val->block, feerate);
|
||||||
psbt = candidate_psbt;
|
psbt = candidate_psbt;
|
||||||
|
psbt_fee = fee;
|
||||||
|
psbt_weight = weight;
|
||||||
|
psbt_utxos = utxos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No psbt was worth it? */
|
/* No psbt was worth it? */
|
||||||
|
@ -357,27 +387,27 @@ static struct bitcoin_tx *spend_anchor(const tal_t *ctx,
|
||||||
|
|
||||||
/* Higher enough than previous to be valid RBF?
|
/* Higher enough than previous to be valid RBF?
|
||||||
* We assume 1 sat per vbyte as minrelayfee */
|
* We assume 1 sat per vbyte as minrelayfee */
|
||||||
if (!amount_sat_sub(&diff, fee, anch->anchor_spend_fee)
|
if (!amount_sat_sub(&diff, psbt_fee, anch->anchor_spend_fee)
|
||||||
|| amount_sat_less(diff, amount_sat(weight / 4)))
|
|| amount_sat_less(diff, amount_sat(psbt_weight / 4)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
log_debug(channel->log,
|
log_debug(channel->log,
|
||||||
"Anchorspend for %s commit tx fee %s (w=%zu), commit_tx fee %s (w=%u):"
|
"Anchorspend for %s commit tx fee %s (w=%zu), commit_tx fee %s (w=%u):"
|
||||||
" package feerate %"PRIu64" perkw",
|
" package feerate %"PRIu64" perkw",
|
||||||
anch->commit_side == LOCAL ? "local" : "remote",
|
anch->commit_side == LOCAL ? "local" : "remote",
|
||||||
fmt_amount_sat(tmpctx, fee),
|
fmt_amount_sat(tmpctx, psbt_fee),
|
||||||
weight - anch->info.commitment_weight,
|
psbt_weight - anch->info.commitment_weight,
|
||||||
fmt_amount_sat(tmpctx, anch->info.commitment_fee),
|
fmt_amount_sat(tmpctx, anch->info.commitment_fee),
|
||||||
anch->info.commitment_weight,
|
anch->info.commitment_weight,
|
||||||
(fee.satoshis + anch->info.commitment_fee.satoshis) /* Raw: debug log */
|
(psbt_fee.satoshis + anch->info.commitment_fee.satoshis) /* Raw: debug log */
|
||||||
* 1000 / weight);
|
* 1000 / psbt_weight);
|
||||||
|
|
||||||
/* OK, HSM, sign it! */
|
/* OK, HSM, sign it! */
|
||||||
msg = towire_hsmd_sign_anchorspend(NULL,
|
msg = towire_hsmd_sign_anchorspend(NULL,
|
||||||
&channel->peer->id,
|
&channel->peer->id,
|
||||||
channel->dbid,
|
channel->dbid,
|
||||||
cast_const2(const struct utxo **,
|
cast_const2(const struct utxo **,
|
||||||
utxos),
|
psbt_utxos),
|
||||||
psbt);
|
psbt);
|
||||||
msg = hsm_sync_req(tmpctx, ld, take(msg));
|
msg = hsm_sync_req(tmpctx, ld, take(msg));
|
||||||
if (!fromwire_hsmd_sign_anchorspend_reply(tmpctx, msg, &signed_psbt))
|
if (!fromwire_hsmd_sign_anchorspend_reply(tmpctx, msg, &signed_psbt))
|
||||||
|
@ -389,14 +419,14 @@ static struct bitcoin_tx *spend_anchor(const tal_t *ctx,
|
||||||
fmt_wally_psbt(tmpctx, signed_psbt));
|
fmt_wally_psbt(tmpctx, signed_psbt));
|
||||||
log_broken(channel->log, "Before signing PSBT was %s",
|
log_broken(channel->log, "Before signing PSBT was %s",
|
||||||
fmt_wally_psbt(tmpctx, psbt));
|
fmt_wally_psbt(tmpctx, psbt));
|
||||||
for (size_t i = 0; i < tal_count(utxos); i++) {
|
for (size_t i = 0; i < tal_count(psbt_utxos); i++) {
|
||||||
const struct unilateral_close_info *ci = utxos[i]->close_info;
|
const struct unilateral_close_info *ci = psbt_utxos[i]->close_info;
|
||||||
|
|
||||||
log_broken(channel->log, "UTXO %zu: %s amt=%s keyidx=%u",
|
log_broken(channel->log, "UTXO %zu: %s amt=%s keyidx=%u",
|
||||||
i,
|
i,
|
||||||
fmt_bitcoin_outpoint(tmpctx, &utxos[i]->outpoint),
|
fmt_bitcoin_outpoint(tmpctx, &psbt_utxos[i]->outpoint),
|
||||||
fmt_amount_sat(tmpctx, utxos[i]->amount),
|
fmt_amount_sat(tmpctx, psbt_utxos[i]->amount),
|
||||||
utxos[i]->keyindex);
|
psbt_utxos[i]->keyindex);
|
||||||
if (ci) {
|
if (ci) {
|
||||||
log_broken(channel->log,
|
log_broken(channel->log,
|
||||||
"... close from channel %"PRIu64" peer %s (%s) commitment %s csv %u",
|
"... close from channel %"PRIu64" peer %s (%s) commitment %s csv %u",
|
||||||
|
@ -411,7 +441,7 @@ static struct bitcoin_tx *spend_anchor(const tal_t *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update fee so we know for next time */
|
/* Update fee so we know for next time */
|
||||||
anch->anchor_spend_fee = fee;
|
anch->anchor_spend_fee = psbt_fee;
|
||||||
|
|
||||||
tx = tal(ctx, struct bitcoin_tx);
|
tx = tal(ctx, struct bitcoin_tx);
|
||||||
tx->chainparams = chainparams;
|
tx->chainparams = chainparams;
|
||||||
|
|
Loading…
Add table
Reference in a new issue