elements: unify overhead calculation.

And in particular, fix onchaind grinding code which used the
actual number of inputs and outputs (which already includes the
fee output); that breaks with the next patch which fixes other
calculations.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2022-01-26 12:42:28 +10:30
committed by Christian Decker
parent c88dc7883e
commit 8a8d7c4243
6 changed files with 49 additions and 61 deletions

View File

@@ -1,6 +1,5 @@
#include "config.h"
#include <assert.h>
#include <bitcoin/chainparams.h>
#include <bitcoin/psbt.h>
#include <bitcoin/script.h>
#include <ccan/str/hex/hex.h>

View File

@@ -1,9 +1,10 @@
#ifndef LIGHTNING_BITCOIN_TX_H
#define LIGHTNING_BITCOIN_TX_H
#include "config.h"
#include "shadouble.h"
#include "signature.h"
#include "varint.h"
#include <bitcoin/chainparams.h>
#include <bitcoin/shadouble.h>
#include <bitcoin/signature.h>
#include <bitcoin/varint.h>
#include <ccan/structeq/structeq.h>
#include <common/amount.h>
#include <wally_transaction.h>
@@ -230,6 +231,36 @@ bool elements_wtx_output_is_fee(const struct wally_tx *tx, int outnum);
*/
bool elements_tx_output_is_fee(const struct bitcoin_tx *tx, int outnum);
/** Attempt to compute the elements overhead given a base bitcoin size.
*
* The overhead consists of 2 empty proofs for the transaction, 6 bytes of
* proofs per input and 35 bytes per output. In addition the explicit fee
* output will add 9 bytes and the per output overhead as well.
*/
static inline size_t elements_tx_overhead(const struct chainparams *chainparams,
size_t incount, size_t outcount)
{
size_t overhead;
if (!chainparams->is_elements)
return 0;
/* Each transaction has surjection and rangeproof (both empty
* for us as long as we use unblinded L-BTC transactions). */
overhead = 2 * 4;
/* For elements we also need to add the fee output and the
* overhead for rangeproofs into the mix. */
overhead += (8 + 1) * 4; /* Bitcoin style output */
/* All outputs have a bit of elements overhead (incl fee) */
overhead += (32 + 1 + 1 + 1) * 4 * (outcount + 1); /* Elements added fields */
/* Inputs have 6 bytes of blank proofs attached. */
overhead += 6 * incount;
return overhead;
}
/**
* Calculate the fees for this transaction
*/

View File

@@ -78,7 +78,7 @@ penalty_tx_create(const tal_t *ctx,
/* Worst-case sig is 73 bytes */
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript);
weight = elements_add_overhead(weight, 1, 1);
weight += elements_tx_overhead(chainparams, 1, 1);
fee = amount_tx_fee(penalty_feerate, weight);
if (!amount_sat_add(&min_out, dust_limit, fee))

View File

@@ -2,6 +2,7 @@
#define LIGHTNING_COMMON_HTLC_TX_H
#include "config.h"
#include <bitcoin/chainparams.h>
#include <bitcoin/tx.h>
#include <common/htlc.h>
#include <common/utils.h>
@@ -12,34 +13,6 @@ struct preimage;
struct pubkey;
struct ripemd160;
/** Attempt to compute the elements overhead given a base bitcoin size.
*
* The overhead consists of 2 empty proofs for the transaction, 6 bytes of
* proofs per input and 35 bytes per output. In addition the explicit fee
* output will add 9 bytes and the per output overhead as well.
*/
/* FIXME: This seems to be a generalization of the logic in initial_commit_tx.h
* and should be in bitcoin/tx.h */
static inline size_t elements_add_overhead(size_t weight, size_t incount,
size_t outcount)
{
if (chainparams->is_elements) {
/* Each transaction has surjection and rangeproof (both empty
* for us as long as we use unblinded L-BTC transactions). */
weight += 2 * 4;
/* For elements we also need to add the fee output and the
* overhead for rangeproofs into the mix. */
weight += (8 + 1) * 4; /* Bitcoin style output */
/* All outputs have a bit of elements overhead */
weight += (32 + 1 + 1 + 1) * 4 * (outcount + 1); /* Elements added fields */
/* Inputs have 6 bytes of blank proofs attached. */
weight += 6 * incount;
}
return weight;
}
static inline struct amount_sat htlc_timeout_fee(u32 feerate_per_kw,
bool option_anchor_outputs)
{
@@ -56,7 +29,8 @@ static inline struct amount_sat htlc_timeout_fee(u32 feerate_per_kw,
base = 666;
else
base = 663;
return amount_tx_fee(elements_add_overhead(base, 1, 1), feerate_per_kw);
return amount_tx_fee(base + elements_tx_overhead(chainparams, 1, 1),
feerate_per_kw);
}
static inline struct amount_sat htlc_success_fee(u32 feerate_per_kw,
@@ -75,7 +49,8 @@ static inline struct amount_sat htlc_success_fee(u32 feerate_per_kw,
base = 706;
else
base = 703;
return amount_tx_fee(elements_add_overhead(base, 1, 1), feerate_per_kw);
return amount_tx_fee(base + elements_tx_overhead(chainparams, 1, 1),
feerate_per_kw);
}
/* Create HTLC-success tx to spend a received HTLC commitment tx

View File

@@ -4,6 +4,7 @@
#include "config.h"
#include <bitcoin/chainparams.h>
#include <bitcoin/pubkey.h>
#include <bitcoin/tx.h>
#include <common/htlc.h>
#include <common/utils.h>
@@ -47,26 +48,8 @@ static inline size_t commit_tx_base_weight(size_t num_untrimmed_htlcs,
*/
weight += 172 * num_untrimmed_htlcs;
if (chainparams->is_elements) {
/* Each transaction has surjection and rangeproof (both empty
* for us as long as we use unblinded L-BTC transactions). */
weight += 2 * 4;
/* Inputs have 6 bytes of blank proofs attached. This TX only
* has a single input. */
weight += 6;
/* Each direct output has a bit more weight to it */
weight += (32 + 1 + 1 + 1) * 4 * 2; /* Elements added fields */
/* Each HTLC output also carries a bit more weight */
weight += (32 + 1 + 1 + 1) * 4 * num_untrimmed_htlcs;
/* For elements we also need to add the fee output and the
* overhead for rangeproofs into the mix. */
weight += (8 + 1) * 4; /* Bitcoin style output */
weight += (32 + 1 + 1 + 1) * 4; /* Elements added fields */
}
/* Extra fields for Elements */
weight += elements_tx_overhead(chainparams, 1, 1);
return weight;
}

View File

@@ -441,8 +441,7 @@ static bool set_htlc_timeout_fee(struct bitcoin_tx *tx,
weight = 666;
else
weight = 663;
weight = elements_add_overhead(weight, tx->wtx->num_inputs,
tx->wtx->num_outputs);
weight += elements_tx_overhead(chainparams, 1, 1);
assert(amount_asset_is_main(&asset));
amount = amount_asset_to_sat(&asset);
@@ -491,15 +490,16 @@ static void set_htlc_success_fee(struct bitcoin_tx *tx,
else
weight = 703;
weight = elements_add_overhead(weight, tx->wtx->num_inputs,
tx->wtx->num_outputs);
weight += elements_tx_overhead(chainparams, 1, 1);
if (amount_sat_eq(fee, AMOUNT_SAT(UINT64_MAX))) {
if (!grind_htlc_tx_fee(&fee, tx, remotesig, wscript, weight))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"htlc_success_fee can't be found "
"for tx %s, signature %s, wscript %s",
"for tx %s (weight %zu, feerate %u-%u), signature %s, wscript %s",
type_to_string(tmpctx, struct bitcoin_tx,
tx),
weight,
min_possible_feerate, max_possible_feerate,
type_to_string(tmpctx,
struct bitcoin_signature,
remotesig),
@@ -596,7 +596,7 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx,
/* Worst-case sig is 73 bytes */
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript);
weight = elements_add_overhead(weight, 1, 1);
weight += elements_tx_overhead(chainparams, 1, 1);
fee = amount_tx_fee(feerate, weight);
/* Result is trivial? Spend with small feerate, but don't wait