Pass hash types by value

We should pass `Copy` types by value not by reference. Pass the hash
types by value.
This commit is contained in:
Tobin C. Harding 2024-01-25 18:27:37 +11:00
parent d063cc1d5c
commit 8fd583b069
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
11 changed files with 33 additions and 33 deletions

View File

@ -163,7 +163,7 @@ fn main() {
// The change output is locked to a key controlled by us. // The change output is locked to a key controlled by us.
let change = TxOut { let change = TxOut {
value: CHANGE_AMOUNT, value: CHANGE_AMOUNT,
script_pubkey: ScriptBuf::new_p2wpkh(&pk_change.wpubkey_hash()), // Change comes back to us. script_pubkey: ScriptBuf::new_p2wpkh(pk_change.wpubkey_hash()), // Change comes back to us.
}; };
// The transaction we want to sign and broadcast. // The transaction we want to sign and broadcast.
@ -196,14 +196,14 @@ fn main() {
psbt.inputs = vec![ psbt.inputs = vec![
Input { Input {
witness_utxo: Some(utxos[0].clone()), witness_utxo: Some(utxos[0].clone()),
redeem_script: Some(ScriptBuf::new_p2wpkh(&wpkhs[0])), redeem_script: Some(ScriptBuf::new_p2wpkh(wpkhs[0])),
bip32_derivation: bip32_derivations[0].clone(), bip32_derivation: bip32_derivations[0].clone(),
sighash_type: Some(ty), sighash_type: Some(ty),
..Default::default() ..Default::default()
}, },
Input { Input {
witness_utxo: Some(utxos[1].clone()), witness_utxo: Some(utxos[1].clone()),
redeem_script: Some(ScriptBuf::new_p2wpkh(&wpkhs[1])), redeem_script: Some(ScriptBuf::new_p2wpkh(wpkhs[1])),
bip32_derivation: bip32_derivations[1].clone(), bip32_derivation: bip32_derivations[1].clone(),
sighash_type: Some(ty), sighash_type: Some(ty),
..Default::default() ..Default::default()

View File

@ -206,7 +206,7 @@ impl WatchOnly {
let pk = self.input_xpub.to_pub(); let pk = self.input_xpub.to_pub();
let wpkh = pk.wpubkey_hash(); let wpkh = pk.wpubkey_hash();
let redeem_script = ScriptBuf::new_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

@ -37,7 +37,7 @@ fn compute_sighash_p2wpkh(raw_tx: &[u8], inp_idx: usize, value: u64) {
let pk = CompressedPublicKey::from_slice(pk_bytes).expect("failed to parse pubkey"); let pk = CompressedPublicKey::from_slice(pk_bytes).expect("failed to parse pubkey");
let wpkh = pk.wpubkey_hash(); let wpkh = pk.wpubkey_hash();
println!("Script pubkey hash: {:x}", wpkh); println!("Script pubkey hash: {:x}", wpkh);
let spk = ScriptBuf::new_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

@ -28,7 +28,7 @@ fn main() {
// Get an unspent output that is locked to the key above that we control. // Get an unspent output that is locked to the key above that we control.
// In a real application these would come from the chain. // In a real application these would come from the chain.
let (dummy_out_point, dummy_utxo) = dummy_unspent_transaction_output(&wpkh); let (dummy_out_point, dummy_utxo) = dummy_unspent_transaction_output(wpkh);
// The input for the transaction we are constructing. // The input for the transaction we are constructing.
let input = TxIn { let input = TxIn {
@ -44,7 +44,7 @@ fn main() {
// The change output is locked to a key controlled by us. // The change output is locked to a key controlled by us.
let change = TxOut { let change = TxOut {
value: CHANGE_AMOUNT, value: CHANGE_AMOUNT,
script_pubkey: ScriptBuf::new_p2wpkh(&wpkh), // Change comes back to us. script_pubkey: ScriptBuf::new_p2wpkh(wpkh), // Change comes back to us.
}; };
// The transaction we want to sign and broadcast. // The transaction we want to sign and broadcast.
@ -115,7 +115,7 @@ fn receivers_address() -> Address {
/// ///
/// This output is locked to keys that we control, in a real application this would be a valid /// This output is locked to keys that we control, in a real application this would be a valid
/// output taken from a transaction that appears in the chain. /// output taken from a transaction that appears in the chain.
fn dummy_unspent_transaction_output(wpkh: &WPubkeyHash) -> (OutPoint, TxOut) { fn dummy_unspent_transaction_output(wpkh: WPubkeyHash) -> (OutPoint, TxOut) {
let script_pubkey = ScriptBuf::new_p2wpkh(wpkh); let script_pubkey = ScriptBuf::new_p2wpkh(wpkh);
let out_point = OutPoint { let out_point = OutPoint {

View File

@ -599,8 +599,8 @@ impl Address {
pub fn script_pubkey(&self) -> ScriptBuf { pub fn script_pubkey(&self) -> ScriptBuf {
use AddressInner::*; use AddressInner::*;
match self.0 { match self.0 {
P2pkh { ref hash, network: _ } => ScriptBuf::new_p2pkh(hash), P2pkh { hash, network: _ } => ScriptBuf::new_p2pkh(hash),
P2sh { ref hash, network: _ } => ScriptBuf::new_p2sh(hash), P2sh { hash, network: _ } => ScriptBuf::new_p2sh(hash),
Segwit { ref program, hrp: _ } => { Segwit { ref program, hrp: _ } => {
let prog = program.program(); let prog = program.program();
let version = program.version(); let version = program.version();
@ -650,7 +650,7 @@ impl Address {
(*pubkey_hash.as_byte_array() == *payload) (*pubkey_hash.as_byte_array() == *payload)
|| (xonly_pubkey.serialize() == *payload) || (xonly_pubkey.serialize() == *payload)
|| (*segwit_redeem_hash(&pubkey_hash).as_byte_array() == *payload) || (*segwit_redeem_hash(pubkey_hash).as_byte_array() == *payload)
} }
/// Returns true if the supplied xonly public key can be used to derive the address. /// Returns true if the supplied xonly public key can be used to derive the address.
@ -878,7 +878,7 @@ impl FromStr for Address<NetworkUnchecked> {
} }
/// Convert a byte array of a pubkey hash into a segwit redeem hash /// Convert a byte array of a pubkey hash into a segwit redeem hash
fn segwit_redeem_hash(pubkey_hash: &PubkeyHash) -> crate::hashes::hash160::Hash { fn segwit_redeem_hash(pubkey_hash: PubkeyHash) -> crate::hashes::hash160::Hash {
let mut sha_engine = sha256::Hash::engine(); let mut sha_engine = sha256::Hash::engine();
sha_engine.input(&[0, 20]); sha_engine.input(&[0, 20]);
sha_engine.input(pubkey_hash.as_ref()); sha_engine.input(pubkey_hash.as_ref());

View File

@ -114,7 +114,7 @@ pub struct BlockFilter {
impl FilterHash { impl FilterHash {
/// Computes the filter header from a filter hash and previous filter header. /// Computes the filter header from a filter hash and previous filter header.
pub fn filter_header(&self, previous_filter_header: &FilterHeader) -> FilterHeader { pub fn filter_header(&self, previous_filter_header: FilterHeader) -> FilterHeader {
let mut header_data = [0u8; 64]; let mut header_data = [0u8; 64];
header_data[0..32].copy_from_slice(&self[..]); header_data[0..32].copy_from_slice(&self[..]);
header_data[32..64].copy_from_slice(&previous_filter_header[..]); header_data[32..64].copy_from_slice(&previous_filter_header[..]);
@ -145,13 +145,13 @@ impl BlockFilter {
/// Computes this filter's ID in a chain of filters (see [BIP 157]). /// Computes this filter's ID in a chain of filters (see [BIP 157]).
/// ///
/// [BIP 157]: <https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#Filter_Headers> /// [BIP 157]: <https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#Filter_Headers>
pub fn filter_header(&self, previous_filter_header: &FilterHeader) -> FilterHeader { pub fn filter_header(&self, previous_filter_header: FilterHeader) -> FilterHeader {
let filter_hash = FilterHash::hash(self.content.as_slice()); let filter_hash = FilterHash::hash(self.content.as_slice());
filter_hash.filter_header(previous_filter_header) filter_hash.filter_header(previous_filter_header)
} }
/// Returns true if any query matches against this [`BlockFilter`]. /// Returns true if any query matches against this [`BlockFilter`].
pub fn match_any<I>(&self, block_hash: &BlockHash, query: I) -> Result<bool, Error> pub fn match_any<I>(&self, block_hash: BlockHash, query: I) -> Result<bool, Error>
where where
I: Iterator, I: Iterator,
I::Item: Borrow<[u8]>, I::Item: Borrow<[u8]>,
@ -161,7 +161,7 @@ impl BlockFilter {
} }
/// Returns true if all queries match against this [`BlockFilter`]. /// Returns true if all queries match against this [`BlockFilter`].
pub fn match_all<I>(&self, block_hash: &BlockHash, query: I) -> Result<bool, Error> pub fn match_all<I>(&self, block_hash: BlockHash, query: I) -> Result<bool, Error>
where where
I: Iterator, I: Iterator,
I::Item: Borrow<[u8]>, I::Item: Borrow<[u8]>,
@ -234,7 +234,7 @@ pub struct BlockFilterReader {
impl BlockFilterReader { impl BlockFilterReader {
/// Creates a new [`BlockFilterReader`] from `block_hash`. /// Creates a new [`BlockFilterReader`] from `block_hash`.
pub fn new(block_hash: &BlockHash) -> BlockFilterReader { pub fn new(block_hash: BlockHash) -> BlockFilterReader {
let block_hash_as_int = block_hash.to_byte_array(); let block_hash_as_int = block_hash.to_byte_array();
let k0 = u64::from_le_bytes(block_hash_as_int[0..8].try_into().expect("8 byte slice")); let k0 = u64::from_le_bytes(block_hash_as_int[0..8].try_into().expect("8 byte slice"));
let k1 = u64::from_le_bytes(block_hash_as_int[8..16].try_into().expect("8 byte slice")); let k1 = u64::from_le_bytes(block_hash_as_int[8..16].try_into().expect("8 byte slice"));
@ -614,7 +614,7 @@ mod test {
let block_hash = &block.block_hash(); let block_hash = &block.block_hash();
assert!(filter assert!(filter
.match_all( .match_all(
block_hash, *block_hash,
&mut txmap.iter().filter_map(|(_, s)| if !s.is_empty() { &mut txmap.iter().filter_map(|(_, s)| if !s.is_empty() {
Some(s.as_bytes()) Some(s.as_bytes())
} else { } else {
@ -627,12 +627,12 @@ mod test {
let query = [script]; let query = [script];
if !script.is_empty() { if !script.is_empty() {
assert!(filter assert!(filter
.match_any(block_hash, &mut query.iter().map(|s| s.as_bytes())) .match_any(*block_hash, &mut query.iter().map(|s| s.as_bytes()))
.unwrap()); .unwrap());
} }
} }
assert_eq!(filter_header, filter.filter_header(&previous_filter_header)); assert_eq!(filter_header, filter.filter_header(previous_filter_header));
} }
} }

View File

@ -270,7 +270,7 @@ impl Block {
if witness_vec.len() == 1 && witness_vec[0].len() == 32 { if witness_vec.len() == 1 && witness_vec[0].len() == 32 {
if let Some(witness_root) = self.witness_root() { if let Some(witness_root) = self.witness_root() {
return commitment return commitment
== Self::compute_witness_commitment(&witness_root, witness_vec[0]); == Self::compute_witness_commitment(witness_root, witness_vec[0]);
} }
} }
} }
@ -286,7 +286,7 @@ impl Block {
/// Computes the witness commitment for the block's transaction list. /// Computes the witness commitment for the block's transaction list.
pub fn compute_witness_commitment( pub fn compute_witness_commitment(
witness_root: &WitnessMerkleNode, witness_root: WitnessMerkleNode,
witness_reserved_value: &[u8], witness_reserved_value: &[u8],
) -> WitnessCommitment { ) -> WitnessCommitment {
let mut encoder = WitnessCommitment::engine(); let mut encoder = WitnessCommitment::engine();

View File

@ -153,7 +153,7 @@ impl Script {
/// script"). /// script").
#[inline] #[inline]
pub fn to_p2wsh(&self) -> Result<ScriptBuf, WitnessScriptSizeError> { pub fn to_p2wsh(&self) -> Result<ScriptBuf, WitnessScriptSizeError> {
self.wscript_hash().map(|hash| ScriptBuf::new_p2wsh(&hash)) self.wscript_hash().map(ScriptBuf::new_p2wsh)
} }
/// 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
@ -383,7 +383,7 @@ impl Script {
/// Computes the P2SH output corresponding to this redeem script. /// Computes the P2SH output corresponding to this redeem script.
pub fn to_p2sh(&self) -> Result<ScriptBuf, RedeemScriptSizeError> { pub fn to_p2sh(&self) -> Result<ScriptBuf, RedeemScriptSizeError> {
self.script_hash().map(|hash| ScriptBuf::new_p2sh(&hash)) self.script_hash().map(ScriptBuf::new_p2sh)
} }
/// Returns the script code used for spending a P2WPKH output if this script is a script pubkey /// Returns the script code used for spending a P2WPKH output if this script is a script pubkey

View File

@ -81,7 +81,7 @@ impl ScriptBuf {
} }
/// Generates P2PKH-type of scriptPubkey. /// Generates P2PKH-type of scriptPubkey.
pub fn new_p2pkh(pubkey_hash: &PubkeyHash) -> Self { pub fn new_p2pkh(pubkey_hash: PubkeyHash) -> Self {
Builder::new() Builder::new()
.push_opcode(OP_DUP) .push_opcode(OP_DUP)
.push_opcode(OP_HASH160) .push_opcode(OP_HASH160)
@ -92,7 +92,7 @@ impl ScriptBuf {
} }
/// Generates P2SH-type of scriptPubkey with a given hash of the redeem script. /// Generates P2SH-type of scriptPubkey with a given hash of the redeem script.
pub fn new_p2sh(script_hash: &ScriptHash) -> Self { pub fn new_p2sh(script_hash: ScriptHash) -> Self {
Builder::new() Builder::new()
.push_opcode(OP_HASH160) .push_opcode(OP_HASH160)
.push_slice(script_hash) .push_slice(script_hash)
@ -101,13 +101,13 @@ impl ScriptBuf {
} }
/// Generates P2WPKH-type of scriptPubkey. /// Generates P2WPKH-type of scriptPubkey.
pub fn new_p2wpkh(pubkey_hash: &WPubkeyHash) -> Self { 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_p2wsh(script_hash: &WScriptHash) -> Self { 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)
} }

View File

@ -204,19 +204,19 @@ fn script_generators() {
assert!(ScriptBuf::new_p2pk(pubkey).is_p2pk()); assert!(ScriptBuf::new_p2pk(pubkey).is_p2pk());
let pubkey_hash = PubkeyHash::hash(&pubkey.inner.serialize()); let pubkey_hash = PubkeyHash::hash(&pubkey.inner.serialize());
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_p2wpkh(&wpubkey_hash).is_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().expect("script is less than 520 bytes"); let script_hash = script.script_hash().expect("script is less than 520 bytes");
let p2sh = ScriptBuf::new_p2sh(&script_hash); let p2sh = ScriptBuf::new_p2sh(script_hash);
assert!(p2sh.is_p2sh()); assert!(p2sh.is_p2sh());
assert_eq!(script.to_p2sh().unwrap(), p2sh); assert_eq!(script.to_p2sh().unwrap(), p2sh);
let wscript_hash = script.wscript_hash().expect("script is less than 10,000 bytes"); let wscript_hash = script.wscript_hash().expect("script is less than 10,000 bytes");
let p2wsh = ScriptBuf::new_p2wsh(&wscript_hash); let p2wsh = ScriptBuf::new_p2wsh(wscript_hash);
assert!(p2wsh.is_p2wsh()); assert!(p2wsh.is_p2wsh());
assert_eq!(script.to_p2wsh().unwrap(), p2wsh); assert_eq!(script.to_p2wsh().unwrap(), p2wsh);

View File

@ -2271,7 +2271,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_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);