Merge rust-bitcoin/rust-bitcoin#1994: Remove redundant segwit version from function names

bc398204bf Remove redundant segwit version from function names (Tobin C. Harding)

Pull request description:

  A P2TR output does not need to be clarified with version 1, it is implicit. As with p2wpkh/p2wsh and version 0.

  Remove redundant version identifiers from function names, deprecating the originals.

ACKs for top commit:
  apoelstra:
    ACK bc398204bf

Tree-SHA512: 49806c564badca25ce02161445b2b41497b565f2002aa1edfc0cf0c57b38683480deec0d9b682e18dc7e59c22128e0b641abcccc2cbedd0b5603cbcbf2fd26df
This commit is contained in:
Andrew Poelstra 2023-09-21 15:39:13 +00:00
commit 36805b5283
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
7 changed files with 92 additions and 35 deletions

View File

@ -203,7 +203,7 @@ impl WatchOnly {
let pk = self.input_xpub.to_pub(); let pk = self.input_xpub.to_pub();
let wpkh = pk.wpubkey_hash().expect("a compressed pubkey"); let wpkh = pk.wpubkey_hash().expect("a compressed pubkey");
let redeem_script = ScriptBuf::new_v0_p2wpkh(&wpkh); let redeem_script = ScriptBuf::new_p2wpkh(&wpkh);
input.redeem_script = Some(redeem_script); input.redeem_script = Some(redeem_script);
let fingerprint = self.master_fingerprint; let fingerprint = self.master_fingerprint;

View File

@ -38,7 +38,7 @@ fn compute_sighash_p2wpkh(raw_tx: &[u8], inp_idx: usize, value: u64) {
let pk = PublicKey::from_slice(pk_bytes).expect("failed to parse pubkey"); let pk = PublicKey::from_slice(pk_bytes).expect("failed to parse pubkey");
let wpkh = pk.wpubkey_hash().expect("compressed key"); let wpkh = pk.wpubkey_hash().expect("compressed key");
println!("Script pubkey hash: {:x}", wpkh); println!("Script pubkey hash: {:x}", wpkh);
let spk = ScriptBuf::new_v0_p2wpkh(&wpkh); let spk = ScriptBuf::new_p2wpkh(&wpkh);
let mut cache = sighash::SighashCache::new(&tx); let mut cache = sighash::SighashCache::new(&tx);
let sighash = cache let sighash = cache

View File

@ -397,7 +397,7 @@ impl BenefactorWallet {
.finalize(&self.secp, internal_keypair.x_only_public_key().0) .finalize(&self.secp, internal_keypair.x_only_public_key().0)
.expect("Should be finalizable"); .expect("Should be finalizable");
self.current_spend_info = Some(taproot_spend_info.clone()); self.current_spend_info = Some(taproot_spend_info.clone());
let script_pubkey = ScriptBuf::new_v1_p2tr( let script_pubkey = ScriptBuf::new_p2tr(
&self.secp, &self.secp,
taproot_spend_info.internal_key(), taproot_spend_info.internal_key(),
taproot_spend_info.merkle_root(), taproot_spend_info.merkle_root(),
@ -496,7 +496,7 @@ impl BenefactorWallet {
.expect("Should be finalizable"); .expect("Should be finalizable");
self.current_spend_info = Some(taproot_spend_info.clone()); self.current_spend_info = Some(taproot_spend_info.clone());
let prevout_script_pubkey = input.witness_utxo.as_ref().unwrap().script_pubkey.clone(); let prevout_script_pubkey = input.witness_utxo.as_ref().unwrap().script_pubkey.clone();
let output_script_pubkey = ScriptBuf::new_v1_p2tr( let output_script_pubkey = ScriptBuf::new_p2tr(
&self.secp, &self.secp,
taproot_spend_info.internal_key(), taproot_spend_info.internal_key(),
taproot_spend_info.merkle_root(), taproot_spend_info.merkle_root(),

View File

@ -148,19 +148,37 @@ impl Script {
/// Computes the P2WSH output corresponding to this witnessScript (aka the "witness redeem /// Computes the P2WSH output corresponding to this witnessScript (aka the "witness redeem
/// script"). /// script").
#[inline] #[inline]
pub fn to_v0_p2wsh(&self) -> ScriptBuf { ScriptBuf::new_v0_p2wsh(&self.wscript_hash()) } #[deprecated(since = "0.31.0", note = "use to_p2wsh instead")]
pub fn to_v0_p2wsh(&self) -> ScriptBuf { self.to_p2wsh() }
/// Computes the P2WSH output corresponding to this witnessScript (aka the "witness redeem
/// script").
#[inline]
pub fn to_p2wsh(&self) -> ScriptBuf { ScriptBuf::new_p2wsh(&self.wscript_hash()) }
/// Computes P2TR output with a given internal key and a single script spending path equal to /// Computes P2TR output with a given internal key and a single script spending path equal to
/// the current script, assuming that the script is a Tapscript. /// the current script, assuming that the script is a Tapscript.
#[inline] #[inline]
#[deprecated(since = "0.31.0", note = "use to_p2tr instead")]
pub fn to_v1_p2tr<C: Verification>( pub fn to_v1_p2tr<C: Verification>(
&self, &self,
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
internal_key: UntweakedPublicKey, internal_key: UntweakedPublicKey,
) -> ScriptBuf {
self.to_p2tr(secp, internal_key)
}
/// Computes P2TR output with a given internal key and a single script spending path equal to
/// the current script, assuming that the script is a Tapscript.
#[inline]
pub fn to_p2tr<C: Verification>(
&self,
secp: &Secp256k1<C>,
internal_key: UntweakedPublicKey,
) -> ScriptBuf { ) -> ScriptBuf {
let leaf_hash = self.tapscript_leaf_hash(); let leaf_hash = self.tapscript_leaf_hash();
let merkle_root = TapNodeHash::from(leaf_hash); let merkle_root = TapNodeHash::from(leaf_hash);
ScriptBuf::new_v1_p2tr(secp, internal_key, Some(merkle_root)) ScriptBuf::new_p2tr(secp, internal_key, Some(merkle_root))
} }
/// Returns witness version of the script, if any, assuming the script is a `scriptPubkey`. /// Returns witness version of the script, if any, assuming the script is a `scriptPubkey`.
@ -293,7 +311,12 @@ impl Script {
/// Checks whether a script pubkey is a P2WSH output. /// Checks whether a script pubkey is a P2WSH output.
#[inline] #[inline]
pub fn is_v0_p2wsh(&self) -> bool { #[deprecated(since = "0.31.0", note = "use is_p2wsh instead")]
pub fn is_v0_p2wsh(&self) -> bool { self.is_p2wsh() }
/// Checks whether a script pubkey is a P2WSH output.
#[inline]
pub fn is_p2wsh(&self) -> bool {
self.0.len() == 34 self.0.len() == 34
&& self.witness_version() == Some(WitnessVersion::V0) && self.witness_version() == Some(WitnessVersion::V0)
&& self.0[1] == OP_PUSHBYTES_32.to_u8() && self.0[1] == OP_PUSHBYTES_32.to_u8()
@ -301,14 +324,19 @@ impl Script {
/// Checks whether a script pubkey is a P2WPKH output. /// Checks whether a script pubkey is a P2WPKH output.
#[inline] #[inline]
pub fn is_v0_p2wpkh(&self) -> bool { #[deprecated(since = "0.31.0", note = "use is_p2wpkh instead")]
pub fn is_v0_p2wpkh(&self) -> bool { self.is_p2wpkh() }
/// Checks whether a script pubkey is a P2WPKH output.
#[inline]
pub fn is_p2wpkh(&self) -> bool {
self.0.len() == 22 self.0.len() == 22
&& self.witness_version() == Some(WitnessVersion::V0) && self.witness_version() == Some(WitnessVersion::V0)
&& self.0[1] == OP_PUSHBYTES_20.to_u8() && self.0[1] == OP_PUSHBYTES_20.to_u8()
} }
pub(crate) fn v0_p2wpkh(&self) -> Option<&[u8; 20]> { pub(crate) fn p2wpkh(&self) -> Option<&[u8; 20]> {
if self.is_v0_p2wpkh() { if self.is_p2wpkh() {
Some(self.0[2..].try_into().expect("is_v0_p2wpkh checks the length")) Some(self.0[2..].try_into().expect("is_v0_p2wpkh checks the length"))
} else { } else {
None None
@ -317,7 +345,12 @@ impl Script {
/// Checks whether a script pubkey is a P2TR output. /// Checks whether a script pubkey is a P2TR output.
#[inline] #[inline]
pub fn is_v1_p2tr(&self) -> bool { #[deprecated(since = "0.31.0", note = "use is_p2tr instead")]
pub fn is_v1_p2tr(&self) -> bool { self.is_p2tr() }
/// Checks whether a script pubkey is a P2TR output.
#[inline]
pub fn is_p2tr(&self) -> bool {
self.0.len() == 34 self.0.len() == 34
&& self.witness_version() == Some(WitnessVersion::V1) && self.witness_version() == Some(WitnessVersion::V1)
&& self.0[1] == OP_PUSHBYTES_32.to_u8() && self.0[1] == OP_PUSHBYTES_32.to_u8()
@ -356,7 +389,7 @@ impl Script {
/// ///
/// [BIP143]: <https://github.com/bitcoin/bips/blob/99701f68a88ce33b2d0838eb84e115cef505b4c2/bip-0143.mediawiki> /// [BIP143]: <https://github.com/bitcoin/bips/blob/99701f68a88ce33b2d0838eb84e115cef505b4c2/bip-0143.mediawiki>
pub fn p2wpkh_script_code(&self) -> Option<ScriptBuf> { pub fn p2wpkh_script_code(&self) -> Option<ScriptBuf> {
self.v0_p2wpkh().map(|wpkh| { self.p2wpkh().map(|wpkh| {
Builder::new() Builder::new()
.push_opcode(OP_DUP) .push_opcode(OP_DUP)
.push_opcode(OP_HASH160) .push_opcode(OP_HASH160)

View File

@ -99,23 +99,42 @@ impl ScriptBuf {
} }
/// Generates P2WPKH-type of scriptPubkey. /// Generates P2WPKH-type of scriptPubkey.
pub fn new_v0_p2wpkh(pubkey_hash: &WPubkeyHash) -> Self { #[deprecated(since = "0.31.0", note = "use new_p2wpkh instead")]
pub fn new_v0_p2wpkh(pubkey_hash: &WPubkeyHash) -> Self { Self::new_p2wpkh(pubkey_hash) }
/// Generates P2WPKH-type of scriptPubkey.
pub fn new_p2wpkh(pubkey_hash: &WPubkeyHash) -> Self {
// pubkey hash is 20 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv0) // pubkey hash is 20 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv0)
ScriptBuf::new_witness_program_unchecked(WitnessVersion::V0, pubkey_hash) ScriptBuf::new_witness_program_unchecked(WitnessVersion::V0, pubkey_hash)
} }
/// Generates P2WSH-type of scriptPubkey with a given hash of the redeem script. /// Generates P2WSH-type of scriptPubkey with a given hash of the redeem script.
pub fn new_v0_p2wsh(script_hash: &WScriptHash) -> Self { #[deprecated(since = "0.31.0", note = "use new_p2wsh instead")]
pub fn new_v0_p2wsh(script_hash: &WScriptHash) -> Self { Self::new_p2wsh(script_hash) }
/// Generates P2WSH-type of scriptPubkey with a given hash of the redeem script.
pub fn new_p2wsh(script_hash: &WScriptHash) -> Self {
// script hash is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv0) // script hash is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv0)
ScriptBuf::new_witness_program_unchecked(WitnessVersion::V0, script_hash) ScriptBuf::new_witness_program_unchecked(WitnessVersion::V0, script_hash)
} }
/// Generates P2TR for script spending path using an internal public key and some optional /// Generates P2TR for script spending path using an internal public key and some optional
/// script tree merkle root. /// script tree merkle root.
#[deprecated(since = "0.31.0", note = "use new_p2tr instead")]
pub fn new_v1_p2tr<C: Verification>( pub fn new_v1_p2tr<C: Verification>(
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
internal_key: UntweakedPublicKey, internal_key: UntweakedPublicKey,
merkle_root: Option<TapNodeHash>, merkle_root: Option<TapNodeHash>,
) -> Self {
Self::new_p2tr(secp, internal_key, merkle_root)
}
/// Generates P2TR for script spending path using an internal public key and some optional
/// script tree merkle root.
pub fn new_p2tr<C: Verification>(
secp: &Secp256k1<C>,
internal_key: UntweakedPublicKey,
merkle_root: Option<TapNodeHash>,
) -> Self { ) -> Self {
let (output_key, _) = internal_key.tap_tweak(secp, merkle_root); let (output_key, _) = internal_key.tap_tweak(secp, merkle_root);
// output key is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv1) // output key is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv1)
@ -123,7 +142,13 @@ impl ScriptBuf {
} }
/// Generates P2TR for key spending path for a known [`TweakedPublicKey`]. /// Generates P2TR for key spending path for a known [`TweakedPublicKey`].
#[deprecated(since = "0.31.0", note = "use new_p2tr_tweaked instead")]
pub fn new_v1_p2tr_tweaked(output_key: TweakedPublicKey) -> Self { pub fn new_v1_p2tr_tweaked(output_key: TweakedPublicKey) -> Self {
Self::new_p2tr_tweaked(output_key)
}
/// Generates P2TR for key spending path for a known [`TweakedPublicKey`].
pub fn new_p2tr_tweaked(output_key: TweakedPublicKey) -> Self {
// output key is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv1) // output key is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv1)
ScriptBuf::new_witness_program_unchecked(WitnessVersion::V1, output_key.serialize()) ScriptBuf::new_witness_program_unchecked(WitnessVersion::V1, output_key.serialize())
} }
@ -139,8 +164,7 @@ impl ScriptBuf {
/// Generates P2WSH-type of scriptPubkey with a given [`WitnessVersion`] and the program bytes. /// Generates P2WSH-type of scriptPubkey with a given [`WitnessVersion`] and the program bytes.
/// Does not do any checks on version or program length. /// Does not do any checks on version or program length.
/// ///
/// Convenience method used by `new_v0_p2wpkh`, `new_v0_p2wsh`, `new_v1_p2tr`, and /// Convenience method used by `new_p2wpkh`, `new_p2wsh`, `new_p2tr`, and `new_p2tr_tweaked`.
/// `new_v1_p2tr_tweaked`.
fn new_witness_program_unchecked<T: AsRef<PushBytes>>( fn new_witness_program_unchecked<T: AsRef<PushBytes>>(
version: WitnessVersion, version: WitnessVersion,
program: T, program: T,

View File

@ -208,7 +208,7 @@ fn script_generators() {
assert!(ScriptBuf::new_p2pkh(&pubkey_hash).is_p2pkh()); assert!(ScriptBuf::new_p2pkh(&pubkey_hash).is_p2pkh());
let wpubkey_hash = WPubkeyHash::hash(&pubkey.inner.serialize()); let wpubkey_hash = WPubkeyHash::hash(&pubkey.inner.serialize());
assert!(ScriptBuf::new_v0_p2wpkh(&wpubkey_hash).is_v0_p2wpkh()); assert!(ScriptBuf::new_p2wpkh(&wpubkey_hash).is_p2wpkh());
let script = Builder::new().push_opcode(OP_NUMEQUAL).push_verify().into_script(); let script = Builder::new().push_opcode(OP_NUMEQUAL).push_verify().into_script();
let script_hash = script.script_hash(); let script_hash = script.script_hash();
@ -217,9 +217,9 @@ fn script_generators() {
assert_eq!(script.to_p2sh(), p2sh); assert_eq!(script.to_p2sh(), p2sh);
let wscript_hash = script.wscript_hash(); let wscript_hash = script.wscript_hash();
let p2wsh = ScriptBuf::new_v0_p2wsh(&wscript_hash); let p2wsh = ScriptBuf::new_p2wsh(&wscript_hash);
assert!(p2wsh.is_v0_p2wsh()); assert!(p2wsh.is_p2wsh());
assert_eq!(script.to_v0_p2wsh(), p2wsh); assert_eq!(script.to_p2wsh(), p2wsh);
// Test data are taken from the second output of // Test data are taken from the second output of
// 2ccb3a1f745eb4eefcf29391460250adda5fab78aaddb902d25d3cd97d9d8e61 transaction // 2ccb3a1f745eb4eefcf29391460250adda5fab78aaddb902d25d3cd97d9d8e61 transaction
@ -525,8 +525,8 @@ fn p2sh_p2wsh_conversion() {
let expected_witout = let expected_witout =
ScriptBuf::from_hex("0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64") ScriptBuf::from_hex("0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64")
.unwrap(); .unwrap();
assert!(redeem_script.to_v0_p2wsh().is_v0_p2wsh()); assert!(redeem_script.to_p2wsh().is_p2wsh());
assert_eq!(redeem_script.to_v0_p2wsh(), expected_witout); assert_eq!(redeem_script.to_p2wsh(), expected_witout);
// p2sh // p2sh
let redeem_script = ScriptBuf::from_hex("0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8").unwrap(); let redeem_script = ScriptBuf::from_hex("0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8").unwrap();
@ -543,9 +543,9 @@ fn p2sh_p2wsh_conversion() {
let expected_out = let expected_out =
ScriptBuf::from_hex("a914f386c2ba255cc56d20cfa6ea8b062f8b5994551887").unwrap(); ScriptBuf::from_hex("a914f386c2ba255cc56d20cfa6ea8b062f8b5994551887").unwrap();
assert!(redeem_script.to_p2sh().is_p2sh()); assert!(redeem_script.to_p2sh().is_p2sh());
assert!(redeem_script.to_p2sh().to_v0_p2wsh().is_v0_p2wsh()); assert!(redeem_script.to_p2sh().to_p2wsh().is_p2wsh());
assert_eq!(redeem_script.to_v0_p2wsh(), expected_witout); assert_eq!(redeem_script.to_p2wsh(), expected_witout);
assert_eq!(redeem_script.to_v0_p2wsh().to_p2sh(), expected_out); assert_eq!(redeem_script.to_p2wsh().to_p2sh(), expected_out);
} }
macro_rules! unwrap_all { macro_rules! unwrap_all {
@ -648,7 +648,7 @@ fn defult_dust_value_tests() {
// Check that our dust_value() calculator correctly calculates the dust limit on common // Check that our dust_value() calculator correctly calculates the dust limit on common
// well-known scriptPubKey types. // well-known scriptPubKey types.
let script_p2wpkh = Builder::new().push_int(0).push_slice([42; 20]).into_script(); let script_p2wpkh = Builder::new().push_int(0).push_slice([42; 20]).into_script();
assert!(script_p2wpkh.is_v0_p2wpkh()); assert!(script_p2wpkh.is_p2wpkh());
assert_eq!(script_p2wpkh.dust_value(), crate::Amount::from_sat(294)); assert_eq!(script_p2wpkh.dust_value(), crate::Amount::from_sat(294));
let script_p2pkh = Builder::new() let script_p2pkh = Builder::new()

View File

@ -439,25 +439,25 @@ impl Psbt {
return Ok(OutputType::Bare); return Ok(OutputType::Bare);
} }
if spk.is_v0_p2wpkh() { if spk.is_p2wpkh() {
return Ok(OutputType::Wpkh); return Ok(OutputType::Wpkh);
} }
if spk.is_v0_p2wsh() { if spk.is_p2wsh() {
return Ok(OutputType::Wsh); return Ok(OutputType::Wsh);
} }
if spk.is_p2sh() { if spk.is_p2sh() {
if input.redeem_script.as_ref().map(|s| s.is_v0_p2wpkh()).unwrap_or(false) { if input.redeem_script.as_ref().map(|s| s.is_p2wpkh()).unwrap_or(false) {
return Ok(OutputType::ShWpkh); return Ok(OutputType::ShWpkh);
} }
if input.redeem_script.as_ref().map(|x| x.is_v0_p2wsh()).unwrap_or(false) { if input.redeem_script.as_ref().map(|x| x.is_p2wsh()).unwrap_or(false) {
return Ok(OutputType::ShWsh); return Ok(OutputType::ShWsh);
} }
return Ok(OutputType::Sh); return Ok(OutputType::Sh);
} }
if spk.is_v1_p2tr() { if spk.is_p2tr() {
return Ok(OutputType::Tr); return Ok(OutputType::Tr);
} }
@ -1351,7 +1351,7 @@ mod tests {
let expected_out = let expected_out =
ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap(); ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap();
assert!(redeem_script.is_v0_p2wpkh()); assert!(redeem_script.is_p2wpkh());
assert_eq!( assert_eq!(
redeem_script.to_p2sh(), redeem_script.to_p2sh(),
psbt.inputs[1].witness_utxo.as_ref().unwrap().script_pubkey psbt.inputs[1].witness_utxo.as_ref().unwrap().script_pubkey
@ -1397,7 +1397,7 @@ mod tests {
let expected_out = let expected_out =
ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap(); ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap();
assert!(redeem_script.is_v0_p2wpkh()); assert!(redeem_script.is_p2wpkh());
assert_eq!( assert_eq!(
redeem_script.to_p2sh(), redeem_script.to_p2sh(),
psbt.inputs[1].witness_utxo.as_ref().unwrap().script_pubkey psbt.inputs[1].witness_utxo.as_ref().unwrap().script_pubkey
@ -1422,7 +1422,7 @@ mod tests {
let expected_out = let expected_out =
ScriptBuf::from_hex("a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87").unwrap(); ScriptBuf::from_hex("a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87").unwrap();
assert!(redeem_script.is_v0_p2wsh()); assert!(redeem_script.is_p2wsh());
assert_eq!( assert_eq!(
redeem_script.to_p2sh(), redeem_script.to_p2sh(),
psbt.inputs[0].witness_utxo.as_ref().unwrap().script_pubkey psbt.inputs[0].witness_utxo.as_ref().unwrap().script_pubkey
@ -1867,7 +1867,7 @@ mod tests {
// First input we can spend. See comment above on key_map for why we use defaults here. // First input we can spend. See comment above on key_map for why we use defaults here.
let txout_wpkh = TxOut { let txout_wpkh = TxOut {
value: Amount::from_sat(10), value: Amount::from_sat(10),
script_pubkey: ScriptBuf::new_v0_p2wpkh(&WPubkeyHash::hash(&pk.to_bytes())), script_pubkey: ScriptBuf::new_p2wpkh(&WPubkeyHash::hash(&pk.to_bytes())),
}; };
psbt.inputs[0].witness_utxo = Some(txout_wpkh); psbt.inputs[0].witness_utxo = Some(txout_wpkh);