diff --git a/bitcoin/script.c b/bitcoin/script.c index 63974644a34c..ab023b19eee2 100644 --- a/bitcoin/script.c +++ b/bitcoin/script.c @@ -550,13 +550,19 @@ bool is_p2tr(const u8 *script, size_t script_len, u8 xonly_pubkey[32]) return true; } -bool is_known_scripttype(const u8 *script, size_t script_len) -{ - return is_p2wpkh(script, script_len, NULL) - || is_p2wsh(script, script_len, NULL) - || is_p2sh(script, script_len, NULL) - || is_p2pkh(script, script_len, NULL) - || is_p2tr(script, script_len, NULL); +enum scriptpubkey_type scriptpubkey_type(const u8 *script, size_t script_len) +{ + if (is_p2wpkh(script, script_len, NULL)) + return scriptpubkey_type_p2wpkh; + if (is_p2wsh(script, script_len, NULL)) + return scriptpubkey_type_p2wsh; + if (is_p2sh(script, script_len, NULL)) + return scriptpubkey_type_p2sh; + if (is_p2pkh(script, script_len, NULL)) + return scriptpubkey_type_p2pkh; + if (is_p2tr(script, script_len, NULL)) + return scriptpubkey_type_p2tr; + return scriptpubkey_type_unknown; } bool is_known_segwit_scripttype(const u8 *script, size_t script_len) diff --git a/bitcoin/script.h b/bitcoin/script.h index 5b96d696ff15..f0df5f9d3113 100644 --- a/bitcoin/script.h +++ b/bitcoin/script.h @@ -13,6 +13,16 @@ struct ripemd160; struct rel_locktime; struct abs_locktime; +enum scriptpubkey_type { + scriptpubkey_type_unknown = 0, + scriptpubkey_type_p2pk, + scriptpubkey_type_p2pkh, + scriptpubkey_type_p2sh, + scriptpubkey_type_p2wpkh, + scriptpubkey_type_p2wsh, + scriptpubkey_type_p2tr, +}; + /* tal_count() gives the length of the script. */ u8 *bitcoin_redeem_2of2(const tal_t *ctx, const struct pubkey *key1, @@ -173,8 +183,14 @@ bool is_p2wpkh(const u8 *script, size_t script_len, struct bitcoin_address *addr /* Is this a taproot output? (extract xonly_pubkey bytes if not NULL) */ bool is_p2tr(const u8 *script, size_t script_len, u8 xonly_pubkey[32]); +/* What type of script is this? */ +enum scriptpubkey_type scriptpubkey_type(const u8 *script, size_t script_len); + /* Is this one of the above script types? */ -bool is_known_scripttype(const u8 *script, size_t script_len); +static inline bool is_known_scripttype(const u8 *script, size_t script_len) +{ + return scriptpubkey_type(script, script_len) != scriptpubkey_type_unknown; +} /* Is this a witness script type? */ bool is_known_segwit_scripttype(const u8 *script, size_t script_len); diff --git a/bitcoin/tx.c b/bitcoin/tx.c index cee06b032b40..1af7bcbccd45 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -912,17 +912,25 @@ size_t bitcoin_tx_input_weight(bool p2sh, size_t witness_weight) return weight; } -size_t bitcoin_tx_simple_input_witness_weight(void) +size_t bitcoin_tx_simple_input_witness_weight(enum scriptpubkey_type spend_type) { - /* Account for witness (1 byte count + sig + key) */ - return 1 + (bitcoin_tx_input_sig_weight() + 1 + 33); + size_t witness_weight = 1; /* byte count */ + + /* All spend types include a signature */ + witness_weight += bitcoin_tx_input_sig_weight(); + + /* All spend types except P2TR include a public key */ + if (spend_type != scriptpubkey_type_p2tr) + witness_weight += 1 + 33; + + return witness_weight; } -/* We only do segwit inputs, and we assume witness is sig + key */ -size_t bitcoin_tx_simple_input_weight(bool p2sh) +/* We only do segwit inputs */ +size_t bitcoin_tx_simple_input_weight(enum scriptpubkey_type spend_type) { - return bitcoin_tx_input_weight(p2sh, - bitcoin_tx_simple_input_witness_weight()); + return bitcoin_tx_input_weight(spend_type == scriptpubkey_type_p2sh, + bitcoin_tx_simple_input_witness_weight(spend_type)); } size_t bitcoin_tx_2of2_input_witness_weight(void) diff --git a/bitcoin/tx.h b/bitcoin/tx.h index 860b635ff741..3633fa7fae1d 100644 --- a/bitcoin/tx.h +++ b/bitcoin/tx.h @@ -17,6 +17,7 @@ struct wally_psbt; struct ripemd160; +enum scriptpubkey_type; struct bitcoin_txid { struct sha256_double shad; @@ -319,10 +320,10 @@ size_t bitcoin_tx_input_sig_weight(void); size_t bitcoin_tx_input_weight(bool p2sh, size_t witness_weight); /* The witness weight for a simple (sig + key) input */ -size_t bitcoin_tx_simple_input_witness_weight(void); +size_t bitcoin_tx_simple_input_witness_weight(enum scriptpubkey_type spend_type); /* We only do segwit inputs, and we assume witness is sig + key */ -size_t bitcoin_tx_simple_input_weight(bool p2sh); +size_t bitcoin_tx_simple_input_weight(enum scriptpubkey_type spend_type); /* The witness for our 2of2 input (closing or commitment tx). */ size_t bitcoin_tx_2of2_input_witness_weight(void); diff --git a/common/utxo.c b/common/utxo.c index a28e99cd3b79..ffd4488fdf88 100644 --- a/common/utxo.c +++ b/common/utxo.c @@ -1,4 +1,5 @@ #include "config.h" +#include #include #include @@ -64,7 +65,9 @@ struct utxo *fromwire_utxo(const tal_t *ctx, const u8 **ptr, size_t *max) size_t utxo_spend_weight(const struct utxo *utxo, size_t min_witness_weight) { - size_t wit_weight = bitcoin_tx_simple_input_witness_weight(); + size_t wit_weight = bitcoin_tx_simple_input_witness_weight( + scriptpubkey_type(utxo->scriptPubkey, + tal_bytelen(utxo->scriptPubkey))); /* If the min is less than what we'd use for a 'normal' tx, * we return the value with the greater added/calculated */ if (wit_weight < min_witness_weight) diff --git a/plugins/funder_policy.c b/plugins/funder_policy.c index 4d94bf267da8..cb93c9d8a20a 100644 --- a/plugins/funder_policy.c +++ b/plugins/funder_policy.c @@ -128,8 +128,9 @@ default_lease_rates(const tal_t *ctx) /* Let's set our default max weight to two inputs + an output * (use helpers b/c elements) */ + /* Assume worst case although Taproot inputs will be lighter */ rates->funding_weight - = 2 * bitcoin_tx_simple_input_weight(false) + = 2 * bitcoin_tx_simple_input_weight(scriptpubkey_type_p2wpkh) + bitcoin_tx_output_weight(BITCOIN_SCRIPTPUBKEY_P2WPKH_LEN); return rates;