diff --git a/bitcoin/examples/taproot-psbt.rs b/bitcoin/examples/taproot-psbt.rs index 66f6b796..6827e0af 100644 --- a/bitcoin/examples/taproot-psbt.rs +++ b/bitcoin/examples/taproot-psbt.rs @@ -425,7 +425,7 @@ impl BenefactorWallet { version: transaction::Version::TWO, lock_time, input: vec![TxIn { - previous_output: OutPoint { txid: tx.txid(), vout: 0 }, + previous_output: OutPoint { txid: tx.compute_txid(), vout: 0 }, script_sig: ScriptBuf::new(), sequence: bitcoin::Sequence(0xFFFFFFFD), // enable locktime and opt-in RBF witness: Witness::default(), @@ -568,7 +568,7 @@ impl BenefactorWallet { version: transaction::Version::TWO, lock_time, input: vec![TxIn { - previous_output: OutPoint { txid: tx.txid(), vout: 0 }, + previous_output: OutPoint { txid: tx.compute_txid(), vout: 0 }, script_sig: ScriptBuf::new(), sequence: bitcoin::Sequence(0xFFFFFFFD), // enable locktime and opt-in RBF witness: Witness::default(), diff --git a/bitcoin/src/bip152.rs b/bitcoin/src/bip152.rs index 376e9877..5171b859 100644 --- a/bitcoin/src/bip152.rs +++ b/bitcoin/src/bip152.rs @@ -219,8 +219,8 @@ impl HeaderAndShortIds { } else { short_ids.push(ShortId::with_siphash_keys( &match version { - 1 => tx.txid().to_raw_hash(), - 2 => tx.wtxid().to_raw_hash(), + 1 => tx.compute_txid().to_raw_hash(), + 2 => tx.compute_wtxid().to_raw_hash(), _ => unreachable!(), }, siphash_keys, diff --git a/bitcoin/src/blockdata/block.rs b/bitcoin/src/blockdata/block.rs index b8e7f5a8..a12e648e 100644 --- a/bitcoin/src/blockdata/block.rs +++ b/bitcoin/src/blockdata/block.rs @@ -289,7 +289,7 @@ impl Block { /// Computes the transaction merkle root. pub fn compute_merkle_root(&self) -> Option { - let hashes = self.txdata.iter().map(|obj| obj.txid().to_raw_hash()); + let hashes = self.txdata.iter().map(|obj| obj.compute_txid().to_raw_hash()); merkle_tree::calculate_root(hashes).map(|h| h.into()) } @@ -311,7 +311,7 @@ impl Block { // Replace the first hash with zeroes. Wtxid::all_zeros().to_raw_hash() } else { - t.wtxid().to_raw_hash() + t.compute_wtxid().to_raw_hash() } }); merkle_tree::calculate_root(hashes).map(|h| h.into()) @@ -491,7 +491,7 @@ mod tests { let block: Block = deserialize(&hex!(BLOCK_HEX)).unwrap(); let cb_txid = "d574f343976d8e70d91cb278d21044dd8a396019e6db70755a0a50e4783dba38"; - assert_eq!(block.coinbase().unwrap().txid().to_string(), cb_txid); + assert_eq!(block.coinbase().unwrap().compute_txid().to_string(), cb_txid); assert_eq!(block.bip34_block_height(), Ok(100_000)); diff --git a/bitcoin/src/blockdata/constants.rs b/bitcoin/src/blockdata/constants.rs index a74e029a..07fcfc85 100644 --- a/bitcoin/src/blockdata/constants.rs +++ b/bitcoin/src/blockdata/constants.rs @@ -88,7 +88,7 @@ fn bitcoin_genesis_tx() -> Transaction { /// Constructs and returns the genesis block. pub fn genesis_block(network: Network) -> Block { let txdata = vec![bitcoin_genesis_tx()]; - let hash: sha256d::Hash = txdata[0].txid().into(); + let hash: sha256d::Hash = txdata[0].compute_txid().into(); let merkle_root = hash.into(); match network { Network::Bitcoin => Block { @@ -213,7 +213,7 @@ mod test { assert_eq!(gen.lock_time, absolute::LockTime::ZERO); assert_eq!( - gen.wtxid().to_string(), + gen.compute_wtxid().to_string(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b" ); } diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs index adad9084..d07448ce 100644 --- a/bitcoin/src/blockdata/transaction.rs +++ b/bitcoin/src/blockdata/transaction.rs @@ -679,11 +679,21 @@ impl Transaction { /// Maximum transaction weight for Bitcoin Core 25.0. pub const MAX_STANDARD_WEIGHT: Weight = Weight::from_wu(400_000); + /// Computes a "normalized TXID" which does not include any signatures. + /// + /// This method is deprecated. Use `compute_ntxid` instead. + #[deprecated( + since = "0.31.0", + note = "ntxid has been renamed to compute_ntxid to note that it's computationally expensive. use compute_ntxid() instead." + )] + pub fn ntxid(&self) -> sha256d::Hash { self.compute_ntxid() } + /// Computes a "normalized TXID" which does not include any signatures. /// /// This gives a way to identify a transaction that is "the same" as /// another in the sense of having same inputs and outputs. - pub fn ntxid(&self) -> sha256d::Hash { + #[doc(alias = "ntxid")] + pub fn compute_ntxid(&self) -> sha256d::Hash { let cloned_tx = Transaction { version: self.version, lock_time: self.lock_time, @@ -698,15 +708,25 @@ impl Transaction { .collect(), output: self.output.clone(), }; - cloned_tx.txid().into() + cloned_tx.compute_txid().into() } + /// Computes the [`Txid`]. + /// + /// This method is deprecated. Use `compute_txid` instead. + #[deprecated( + since = "0.31.0", + note = "txid has been renamed to compute_txid to note that it's computationally expensive. use compute_txid() instead." + )] + pub fn txid(&self) -> Txid { self.compute_txid() } + /// Computes the [`Txid`]. /// /// Hashes the transaction **excluding** the segwit data (i.e. the marker, flag bytes, and the /// witness fields themselves). For non-segwit transactions which do not have any segwit data, - /// this will be equal to [`Transaction::wtxid()`]. - pub fn txid(&self) -> Txid { + /// this will be equal to [`Transaction::compute_wtxid()`]. + #[doc(alias = "txid")] + pub fn compute_txid(&self) -> Txid { let mut enc = Txid::engine(); self.version.consensus_encode(&mut enc).expect("engines don't error"); self.input.consensus_encode(&mut enc).expect("engines don't error"); @@ -715,12 +735,22 @@ impl Transaction { Txid::from_engine(enc) } + /// Computes the segwit version of the transaction id. + /// + /// This method is deprecated. Use `compute_wtxid` instead. + #[deprecated( + since = "0.31.0", + note = "wtxid has been renamed to compute_wtxid to note that it's computationally expensive. use compute_wtxid() instead." + )] + pub fn wtxid(&self) -> Wtxid { self.compute_wtxid() } + /// Computes the segwit version of the transaction id. /// /// Hashes the transaction **including** all segwit data (i.e. the marker, flag bytes, and the /// witness fields themselves). For non-segwit transactions which do not have any segwit data, /// this will be equal to [`Transaction::txid()`]. - pub fn wtxid(&self) -> Wtxid { + #[doc(alias = "wtxid")] + pub fn compute_wtxid(&self) -> Wtxid { let mut enc = Wtxid::engine(); self.consensus_encode(&mut enc).expect("engines don't error"); Wtxid::from_engine(enc) @@ -1235,19 +1265,19 @@ impl Decodable for Transaction { } impl From for Txid { - fn from(tx: Transaction) -> Txid { tx.txid() } + fn from(tx: Transaction) -> Txid { tx.compute_txid() } } impl From<&Transaction> for Txid { - fn from(tx: &Transaction) -> Txid { tx.txid() } + fn from(tx: &Transaction) -> Txid { tx.compute_txid() } } impl From for Wtxid { - fn from(tx: Transaction) -> Wtxid { tx.wtxid() } + fn from(tx: Transaction) -> Wtxid { tx.compute_wtxid() } } impl From<&Transaction> for Wtxid { - fn from(tx: &Transaction) -> Wtxid { tx.wtxid() } + fn from(tx: &Transaction) -> Wtxid { tx.compute_wtxid() } } /// Computes the value of an output accounting for the cost of spending it. @@ -1730,11 +1760,11 @@ mod tests { assert_eq!(realtx.lock_time, absolute::LockTime::ZERO); assert_eq!( - format!("{:x}", realtx.txid()), + format!("{:x}", realtx.compute_txid()), "a6eab3c14ab5272a58a5ba91505ba1a4b6d7a3a9fcbd187b6cd99a7b6d548cb7".to_string() ); assert_eq!( - format!("{:x}", realtx.wtxid()), + format!("{:x}", realtx.compute_wtxid()), "a6eab3c14ab5272a58a5ba91505ba1a4b6d7a3a9fcbd187b6cd99a7b6d548cb7".to_string() ); assert_eq!(realtx.weight().to_wu() as usize, tx_bytes.len() * WITNESS_SCALE_FACTOR); @@ -1781,11 +1811,11 @@ mod tests { assert_eq!(realtx.lock_time, absolute::LockTime::ZERO); assert_eq!( - format!("{:x}", realtx.txid()), + format!("{:x}", realtx.compute_txid()), "f5864806e3565c34d1b41e716f72609d00b55ea5eac5b924c9719a842ef42206".to_string() ); assert_eq!( - format!("{:x}", realtx.wtxid()), + format!("{:x}", realtx.compute_wtxid()), "80b7d8a82d5d5bf92905b06f2014dd699e03837ca172e3a59d51426ebbe3e7f5".to_string() ); const EXPECTED_WEIGHT: Weight = Weight::from_wu(442); @@ -1856,17 +1886,17 @@ mod tests { let tx_bytes = hex!("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"); let mut tx: Transaction = deserialize(&tx_bytes).unwrap(); - let old_ntxid = tx.ntxid(); + let old_ntxid = tx.compute_ntxid(); assert_eq!( format!("{:x}", old_ntxid), "c3573dbea28ce24425c59a189391937e00d255150fa973d59d61caf3a06b601d" ); // changing sigs does not affect it tx.input[0].script_sig = ScriptBuf::new(); - assert_eq!(old_ntxid, tx.ntxid()); + assert_eq!(old_ntxid, tx.compute_ntxid()); // changing pks does tx.output[0].script_pubkey = ScriptBuf::new(); - assert!(old_ntxid != tx.ntxid()); + assert!(old_ntxid != tx.compute_ntxid()); } #[test] @@ -1905,11 +1935,11 @@ mod tests { let tx: Transaction = deserialize(&tx_bytes).unwrap(); assert_eq!( - format!("{:x}", tx.wtxid()), + format!("{:x}", tx.compute_wtxid()), "d6ac4a5e61657c4c604dcde855a1db74ec6b3e54f32695d72c5e11c7761ea1b4" ); assert_eq!( - format!("{:x}", tx.txid()), + format!("{:x}", tx.compute_txid()), "9652aa62b0e748caeec40c4cb7bc17c6792435cc3dfe447dd1ca24f912a1c6ec" ); assert_eq!(tx.weight(), Weight::from_wu(2718)); @@ -1926,11 +1956,11 @@ mod tests { let tx: Transaction = deserialize(&tx_bytes).unwrap(); assert_eq!( - format!("{:x}", tx.wtxid()), + format!("{:x}", tx.compute_wtxid()), "971ed48a62c143bbd9c87f4bafa2ef213cfa106c6e140f111931d0be307468dd" ); assert_eq!( - format!("{:x}", tx.txid()), + format!("{:x}", tx.compute_txid()), "971ed48a62c143bbd9c87f4bafa2ef213cfa106c6e140f111931d0be307468dd" ); } @@ -2015,9 +2045,9 @@ mod tests { .as_slice()).unwrap(); let mut spent = HashMap::new(); - spent.insert(spent1.txid(), spent1); - spent.insert(spent2.txid(), spent2); - spent.insert(spent3.txid(), spent3); + spent.insert(spent1.compute_txid(), spent1); + spent.insert(spent2.compute_txid(), spent2); + spent.insert(spent3.compute_txid(), spent3); let mut spent2 = spent.clone(); let mut spent3 = spent.clone(); diff --git a/bitcoin/src/merkle_tree/block.rs b/bitcoin/src/merkle_tree/block.rs index 402ffaab..827d06d5 100644 --- a/bitcoin/src/merkle_tree/block.rs +++ b/bitcoin/src/merkle_tree/block.rs @@ -103,7 +103,7 @@ impl MerkleBlock { where F: Fn(&Txid) -> bool, { - let block_txids: Vec<_> = block.txdata.iter().map(Transaction::txid).collect(); + let block_txids: Vec<_> = block.txdata.iter().map(Transaction::compute_txid).collect(); Self::from_header_txids_with_predicate(&block.header, &block_txids, match_txids) } diff --git a/bitcoin/src/merkle_tree/mod.rs b/bitcoin/src/merkle_tree/mod.rs index 0e79117a..c3929d42 100644 --- a/bitcoin/src/merkle_tree/mod.rs +++ b/bitcoin/src/merkle_tree/mod.rs @@ -125,7 +125,7 @@ mod tests { let block: Block = deserialize(&segwit_block[..]).expect("Failed to deserialize block"); assert!(block.check_merkle_root()); // Sanity check. - let hashes_iter = block.txdata.iter().map(|obj| obj.txid().to_raw_hash()); + let hashes_iter = block.txdata.iter().map(|obj| obj.compute_txid().to_raw_hash()); let mut hashes_array: [sha256d::Hash; 15] = [Hash::all_zeros(); 15]; for (i, hash) in hashes_iter.clone().enumerate() { diff --git a/bitcoin/src/psbt/error.rs b/bitcoin/src/psbt/error.rs index 2e41332a..0243cf96 100644 --- a/bitcoin/src/psbt/error.rs +++ b/bitcoin/src/psbt/error.rs @@ -127,8 +127,8 @@ impl fmt::Display for Error { UnexpectedUnsignedTx { expected: ref e, actual: ref a } => write!( f, "different unsigned transaction: expected {}, actual {}", - e.txid(), - a.txid() + e.compute_txid(), + a.compute_txid() ), NonStandardSighashType(ref sht) => write!(f, "non-standard sighash type: {}", sht), InvalidHash(ref e) => write_err!(f, "invalid hash when parsing slice"; e), diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs index 26ed4993..23df1b0e 100644 --- a/bitcoin/src/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -1597,7 +1597,7 @@ mod tests { let tx_input = &psbt.unsigned_tx.input[0]; let psbt_non_witness_utxo = psbt.inputs[0].non_witness_utxo.as_ref().unwrap(); - assert_eq!(tx_input.previous_output.txid, psbt_non_witness_utxo.txid()); + assert_eq!(tx_input.previous_output.txid, psbt_non_witness_utxo.compute_txid()); assert!(psbt_non_witness_utxo.output[tx_input.previous_output.vout as usize] .script_pubkey .is_p2pkh()); @@ -1664,7 +1664,7 @@ mod tests { let tx = &psbt.unsigned_tx; assert_eq!( - tx.txid(), + tx.compute_txid(), "75c5c9665a570569ad77dd1279e6fd4628a093c4dcbf8d41532614044c14c115".parse().unwrap(), );