From 8a8d7c4243107d8698e5172669ba163f575c331e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 Jan 2022 12:42:28 +1030 Subject: [PATCH] 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 --- bitcoin/tx.c | 1 - bitcoin/tx.h | 37 ++++++++++++++++++++++++++++++++++--- channeld/watchtower.c | 2 +- common/htlc_tx.h | 35 +++++------------------------------ common/initial_commit_tx.h | 23 +++-------------------- onchaind/onchaind.c | 12 ++++++------ 6 files changed, 49 insertions(+), 61 deletions(-) diff --git a/bitcoin/tx.c b/bitcoin/tx.c index 215d2e25f..9d89ec696 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -1,6 +1,5 @@ #include "config.h" #include -#include #include #include #include diff --git a/bitcoin/tx.h b/bitcoin/tx.h index 694cc4a75..170371094 100644 --- a/bitcoin/tx.h +++ b/bitcoin/tx.h @@ -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 +#include +#include +#include #include #include #include @@ -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 */ diff --git a/channeld/watchtower.c b/channeld/watchtower.c index a895dfc1d..20d273d65 100644 --- a/channeld/watchtower.c +++ b/channeld/watchtower.c @@ -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)) diff --git a/common/htlc_tx.h b/common/htlc_tx.h index f982757ea..c658ca6bd 100644 --- a/common/htlc_tx.h +++ b/common/htlc_tx.h @@ -2,6 +2,7 @@ #define LIGHTNING_COMMON_HTLC_TX_H #include "config.h" #include +#include #include #include @@ -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 diff --git a/common/initial_commit_tx.h b/common/initial_commit_tx.h index 798c5ac4a..e0bc3c645 100644 --- a/common/initial_commit_tx.h +++ b/common/initial_commit_tx.h @@ -4,6 +4,7 @@ #include "config.h" #include #include +#include #include #include @@ -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; } diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index 869c772ae..ecd60166a 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -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