Add nested P2WPKH helpers to InputWeightPrediction

Add helpers for input weight predictions corresponding to P2WPKH nested
in a P2SH output (nested segwit).
This commit is contained in:
spacebear 2024-10-03 19:32:57 -04:00
parent bb38aeb786
commit 8fd53c8ecf
No known key found for this signature in database
GPG Key ID: C80C3DF529D67F16
1 changed files with 38 additions and 0 deletions

View File

@ -1152,6 +1152,19 @@ impl InputWeightPrediction {
/// [signature grinding]: https://bitcoin.stackexchange.com/questions/111660/what-is-signature-grinding /// [signature grinding]: https://bitcoin.stackexchange.com/questions/111660/what-is-signature-grinding
pub const P2WPKH_MAX: Self = InputWeightPrediction::from_slice(0, &[72, 33]); pub const P2WPKH_MAX: Self = InputWeightPrediction::from_slice(0, &[72, 33]);
/// Input weight prediction corresponding to spending of [nested P2WPKH] output with the largest possible
/// DER-encoded signature.
///
/// If the input in your transaction uses nested P2WPKH you can use this instead of
/// [`InputWeightPrediction::new`].
///
/// This is useful when you **do not** use [signature grinding] and want to ensure you are not
/// under-paying. See [`ground_nested_p2wpkh`](Self::ground_nested_p2wpkh) if you do use signature grinding.
///
/// [nested P2WPKH]: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh-nested-in-bip16-p2sh
/// [signature grinding]: https://bitcoin.stackexchange.com/questions/111660/what-is-signature-grinding
pub const NESTED_P2WPKH_MAX: Self = InputWeightPrediction::from_slice(23, &[72, 33]);
/// Input weight prediction corresponding to spending of a P2PKH output with the largest possible /// Input weight prediction corresponding to spending of a P2PKH output with the largest possible
/// DER-encoded signature, and a compressed public key. /// DER-encoded signature, and a compressed public key.
/// ///
@ -1206,6 +1219,27 @@ impl InputWeightPrediction {
InputWeightPrediction::from_slice(0, &[der_signature_size, 33]) InputWeightPrediction::from_slice(0, &[der_signature_size, 33])
} }
/// Input weight prediction corresponding to spending of [nested P2WPKH] output using [signature
/// grinding].
///
/// If the input in your transaction uses P2WPKH and you use signature grinding you can use this
/// instead of [`InputWeightPrediction::new`]. See [`NESTED_P2WPKH_MAX`](Self::NESTED_P2WPKH_MAX) if you don't
/// use signature grinding.
///
/// Note: `bytes_to_grind` is usually `1` because of exponential cost of higher values.
///
/// # Panics
///
/// The funcion panics in const context and debug builds if `bytes_to_grind` is higher than 62.
///
/// [nested P2WPKH]: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh-nested-in-bip16-p2sh
/// [signature grinding]: https://bitcoin.stackexchange.com/questions/111660/what-is-signature-grinding
pub const fn ground_nested_p2wpkh(bytes_to_grind: usize) -> Self {
// Written to trigger const/debug panic for unreasonably high values.
let der_signature_size = 10 + (62 - bytes_to_grind);
InputWeightPrediction::from_slice(23, &[der_signature_size, 33])
}
/// Input weight prediction corresponding to spending of a P2PKH output using [signature /// Input weight prediction corresponding to spending of a P2PKH output using [signature
/// grinding], and a compressed public key. /// grinding], and a compressed public key.
/// ///
@ -2089,6 +2123,10 @@ mod tests {
InputWeightPrediction::ground_p2wpkh(0).weight(), InputWeightPrediction::ground_p2wpkh(0).weight(),
InputWeightPrediction::P2WPKH_MAX.weight() InputWeightPrediction::P2WPKH_MAX.weight()
); );
assert_eq!(
InputWeightPrediction::ground_nested_p2wpkh(0).weight(),
InputWeightPrediction::NESTED_P2WPKH_MAX.weight()
);
assert_eq!( assert_eq!(
InputWeightPrediction::ground_p2pkh_compressed(0).weight(), InputWeightPrediction::ground_p2pkh_compressed(0).weight(),
InputWeightPrediction::P2PKH_COMPRESSED_MAX.weight() InputWeightPrediction::P2PKH_COMPRESSED_MAX.weight()