Merge rust-bitcoin/rust-bitcoin#3443: Input weight prediction helpers for nested P2WPKH
aa1fd5f44c
Update the doc for InputWeightPrediction::weight() (spacebear)8fd53c8ecf
Add nested P2WPKH helpers to InputWeightPrediction (spacebear) Pull request description: Following up on https://github.com/rust-bitcoin/rust-bitcoin/issues/630#issuecomment-2392050517. I amended the docstring on `InputWeightPrediction::weight()` to clarify that it only returns the signature weight. I'm not sure what the rationale was for only returning partial input weight, and if there are any arguments against something like `InputWeightPrediction::total_weight()` which returns `self.weight() + Weight::from_non_witness_data_size(32 + 4 + 4)` (and maybe deprecate `weight()` eventually to prevent misuse). ACKs for top commit: apoelstra: ACKaa1fd5f44c
successfully ran local tests tcharding: ACKaa1fd5f44c
Tree-SHA512: 9bdd882164a80a1a1a44c593750aa59e470f2928c0380d4d53a0409add597844cf11945785264ebd6b281029b3f2ef1be6c77e1e9cd148192dbd601df30a60ae
This commit is contained in:
commit
78bcca71ca
|
@ -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.
|
||||||
///
|
///
|
||||||
|
@ -1270,8 +1304,8 @@ impl InputWeightPrediction {
|
||||||
InputWeightPrediction { script_size, witness_size }
|
InputWeightPrediction { script_size, witness_size }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tallies the total weight added to a transaction by an input with this weight prediction,
|
/// Computes the **signature weight** added to a transaction by an input with this weight prediction,
|
||||||
/// not counting potential witness flag bytes or the witness count varint.
|
/// not counting the prevout (txid, index), sequence, potential witness flag bytes or the witness count varint.
|
||||||
pub const fn weight(&self) -> Weight {
|
pub const fn weight(&self) -> Weight {
|
||||||
Weight::from_wu_usize(self.script_size * 4 + self.witness_size)
|
Weight::from_wu_usize(self.script_size * 4 + self.witness_size)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue