diff --git a/src/blockdata/block.rs b/src/blockdata/block.rs index 2da30ba4..24a4dbd5 100644 --- a/src/blockdata/block.rs +++ b/src/blockdata/block.rs @@ -26,7 +26,7 @@ use util; use util::Error::{BlockBadTarget, BlockBadProofOfWork}; use util::hash::{BitcoinHash, MerkleRoot, bitcoin_merkle_root}; use util::uint::Uint256; -use hash_types::BlockHash; +use hash_types::{Txid, BlockHash}; use consensus::encode::Encodable; use network::constants::Network; use blockdata::transaction::Transaction; @@ -105,7 +105,7 @@ impl Block { /// Merkle root of transactions hashed for witness pub fn witness_root(&self) -> sha256d::Hash { - let mut txhashes = vec!(sha256d::Hash::default()); + let mut txhashes = vec!(Txid::default()); txhashes.extend(self.txdata.iter().skip(1).map(|t|t.bitcoin_hash())); bitcoin_merkle_root(txhashes) } @@ -189,15 +189,15 @@ impl BlockHeader { } } -impl BitcoinHash for BlockHeader { - fn bitcoin_hash(&self) -> sha256d::Hash { +impl BitcoinHash for BlockHeader { + fn bitcoin_hash(&self) -> BlockHash { use consensus::encode::serialize; - sha256d::Hash::hash(&serialize(self)) + BlockHash::hash(&serialize(self)) } } -impl BitcoinHash for Block { - fn bitcoin_hash(&self) -> sha256d::Hash { +impl BitcoinHash for Block { + fn bitcoin_hash(&self) -> BlockHash { self.header.bitcoin_hash() } } diff --git a/src/blockdata/script.rs b/src/blockdata/script.rs index 0d51be5e..76c5ca74 100644 --- a/src/blockdata/script.rs +++ b/src/blockdata/script.rs @@ -29,9 +29,10 @@ use std::{error, fmt, io}; #[cfg(feature = "serde")] use serde; +use hash_types::WScriptHash; use blockdata::opcodes; use consensus::{encode, Decodable, Encodable}; -use hashes::{hash160, sha256, Hash}; +use hashes::{hash160, Hash}; #[cfg(feature="bitcoinconsensus")] use bitcoinconsensus; #[cfg(feature="bitcoinconsensus")] use std::convert; #[cfg(feature="bitcoinconsensus")] use OutPoint; @@ -242,7 +243,7 @@ impl Script { /// script") pub fn to_v0_p2wsh(&self) -> Script { Builder::new().push_int(0) - .push_slice(&sha256::Hash::hash(&self.0)[..]) + .push_slice(&WScriptHash::hash(&self.0)[..]) .into_script() } diff --git a/src/blockdata/transaction.rs b/src/blockdata/transaction.rs index 3fce302c..3efb5652 100644 --- a/src/blockdata/transaction.rs +++ b/src/blockdata/transaction.rs @@ -287,7 +287,7 @@ impl Transaction { input: self.input.iter().map(|txin| TxIn { script_sig: Script::new(), witness: vec![], .. *txin }).collect(), output: self.output.clone(), }; - cloned_tx.bitcoin_hash() + cloned_tx.bitcoin_hash().into() } /// Computes the txid. For non-segwit transactions this will be identical @@ -438,11 +438,11 @@ impl Transaction { } } -impl BitcoinHash for Transaction { - fn bitcoin_hash(&self) -> sha256d::Hash { +impl BitcoinHash for Transaction { + fn bitcoin_hash(&self) -> Txid { let mut enc = sha256d::Hash::engine(); self.consensus_encode(&mut enc).unwrap(); - sha256d::Hash::from_engine(enc) + Txid::from_engine(enc) } } diff --git a/src/util/address.rs b/src/util/address.rs index d7f22380..f9528403 100644 --- a/src/util/address.rs +++ b/src/util/address.rs @@ -44,7 +44,7 @@ use std::fmt::{self, Display, Formatter}; use std::str::FromStr; use bech32; -use hashes::{hash160, sha256, Hash}; +use hashes::{hash160, Hash}; use hash_types::{PubkeyHash, ScriptHash, WScriptHash}; use blockdata::opcodes; @@ -309,7 +309,7 @@ impl Address { pub fn p2shwsh(script: &script::Script, network: Network) -> Address { let ws = script::Builder::new() .push_int(0) - .push_slice(&sha256::Hash::hash(&script[..])[..]) + .push_slice(&WScriptHash::hash(&script[..])[..]) .into_script(); Address { diff --git a/src/util/bip158.rs b/src/util/bip158.rs index bc2504ff..84a97eb1 100644 --- a/src/util/bip158.rs +++ b/src/util/bip158.rs @@ -50,6 +50,7 @@ use std::error; use std::fmt::{Display, Formatter}; use std::io::Cursor; +use hash_types::BlockHash; use hashes::{Hash, sha256d, siphash24}; use blockdata::block::Block; @@ -133,13 +134,13 @@ impl BlockFilter { } /// match any query pattern - pub fn match_any(&self, block_hash: &sha256d::Hash, query: &mut Iterator) -> Result { + pub fn match_any(&self, block_hash: &BlockHash, query: &mut Iterator) -> Result { let filter_reader = BlockFilterReader::new(block_hash); filter_reader.match_any(&mut Cursor::new(self.content.as_slice()), query) } /// match all query pattern - pub fn match_all(&self, block_hash: &sha256d::Hash, query: &mut Iterator) -> Result { + pub fn match_all(&self, block_hash: &BlockHash, query: &mut Iterator) -> Result { let filter_reader = BlockFilterReader::new(block_hash); filter_reader.match_all(&mut Cursor::new(self.content.as_slice()), query) } @@ -206,7 +207,7 @@ pub struct BlockFilterReader { impl BlockFilterReader { /// Create a block filter reader - pub fn new(block_hash: &sha256d::Hash) -> BlockFilterReader { + pub fn new(block_hash: &BlockHash) -> BlockFilterReader { let block_hash_as_int = block_hash.into_inner(); let k0 = endian::slice_to_u64_le(&block_hash_as_int[0..8]); let k1 = endian::slice_to_u64_le(&block_hash_as_int[8..16]); @@ -523,6 +524,7 @@ mod test { use std::collections::{HashSet, HashMap}; use std::io::Cursor; + use hash_types::BlockHash; use hashes::hex::FromHex; use super::*; @@ -555,7 +557,7 @@ mod test { let testdata = serde_json::from_str::(data).unwrap().as_array().unwrap().clone(); for t in testdata.iter().skip(1) { - let block_hash = sha256d::Hash::from_hex(&t.get(1).unwrap().as_str().unwrap()).unwrap(); + let block_hash = BlockHash::from_hex(&t.get(1).unwrap().as_str().unwrap()).unwrap(); let block: Block = deserialize(hex::decode(&t.get(2).unwrap().as_str().unwrap().as_bytes()).unwrap().as_slice()).unwrap(); assert_eq!(block.bitcoin_hash(), block_hash); let scripts = t.get(3).unwrap().as_array().unwrap(); @@ -583,7 +585,7 @@ mod test { assert_eq!(test_filter.content, filter.content); let block_hash = &block.header.bitcoin_hash(); - assert!(filter.match_all(&block_hash, &mut txmap.iter() + assert!(filter.match_all(block_hash, &mut txmap.iter() .filter_map(|(_, s)| if !s.is_empty() { Some(s.as_bytes()) } else { None })).unwrap()); for (_, script) in &txmap { diff --git a/src/util/hash.rs b/src/util/hash.rs index 64bdbd2d..d4bd19bb 100644 --- a/src/util/hash.rs +++ b/src/util/hash.rs @@ -18,6 +18,7 @@ use std::cmp::min; use std::default::Default; +use hash_types::Txid; use hashes::{sha256d, Hash}; use consensus::encode::Encodable; @@ -30,13 +31,13 @@ pub trait MerkleRoot { } /// Calculates the merkle root of a list of txids hashes directly -pub fn bitcoin_merkle_root(data: Vec) -> sha256d::Hash { +pub fn bitcoin_merkle_root(data: Vec) -> sha256d::Hash { // Base case if data.len() < 1 { return Default::default(); } if data.len() < 2 { - return data[0]; + return data[0].into(); } // Recursion let mut next = vec![]; @@ -46,13 +47,13 @@ pub fn bitcoin_merkle_root(data: Vec) -> sha256d::Hash { let mut encoder = sha256d::Hash::engine(); data[idx1].consensus_encode(&mut encoder).unwrap(); data[idx2].consensus_encode(&mut encoder).unwrap(); - next.push(sha256d::Hash::from_engine(encoder)); + next.push(Txid::from_engine(encoder)); } bitcoin_merkle_root(next) } /// Objects which are referred to by hash -pub trait BitcoinHash { +pub trait BitcoinHash { /// Produces a Sha256dHash which can be used to refer to the object - fn bitcoin_hash(&self) -> sha256d::Hash; + fn bitcoin_hash(&self) -> T; } diff --git a/src/util/merkleblock.rs b/src/util/merkleblock.rs index 9f56c8f0..2b11193e 100644 --- a/src/util/merkleblock.rs +++ b/src/util/merkleblock.rs @@ -26,7 +26,7 @@ //! //! ```rust //! extern crate bitcoin; -//! use bitcoin::hashes::sha256d; +//! use bitcoin::hash_types::Txid; //! use bitcoin::hashes::hex::FromHex; //! use bitcoin::{Block, MerkleBlock}; //! @@ -41,12 +41,12 @@ //! let mb: MerkleBlock = bitcoin::consensus::deserialize(&mb_bytes).unwrap(); //! //! // Authenticate and extract matched transaction ids -//! let mut matches: Vec = vec![]; +//! let mut matches: Vec = vec![]; //! let mut index: Vec = vec![]; //! assert!(mb.extract_matches(&mut matches, &mut index).is_ok()); //! assert_eq!(1, matches.len()); //! assert_eq!( -//! sha256d::Hash::from_hex( +//! Txid::from_hex( //! "5a4ebf66822b0b2d56bd9dc64ece0bc38ee7844a23ff1d7320a88c5fdb2ad3e2").unwrap(), //! matches[0] //! ); @@ -58,6 +58,7 @@ use std::collections::HashSet; use std::io; +use hash_types::Txid; use hashes::{sha256d, Hash}; use blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT}; @@ -133,18 +134,18 @@ impl PartialMerkleTree { /// /// ```rust /// extern crate bitcoin; - /// use bitcoin::hashes::sha256d; + /// use bitcoin::hash_types::Txid; /// use bitcoin::hashes::hex::FromHex; /// use bitcoin::util::merkleblock::PartialMerkleTree; /// /// # fn main() { /// // Block 80000 - /// let txids: Vec = [ + /// let txids: Vec = [ /// "c06fbab289f723c6261d3030ddb6be121f7d2508d77862bb1e484f5cd7f92b25", /// "5a4ebf66822b0b2d56bd9dc64ece0bc38ee7844a23ff1d7320a88c5fdb2ad3e2", /// ] /// .iter() - /// .map(|hex| sha256d::Hash::from_hex(hex).unwrap()) + /// .map(|hex| Txid::from_hex(hex).unwrap()) /// .collect(); /// /// // Select the second transaction @@ -153,7 +154,7 @@ impl PartialMerkleTree { /// assert!(tree.extract_matches(&mut vec![], &mut vec![]).is_ok()); /// # } /// ``` - pub fn from_txids(txids: &[sha256d::Hash], matches: &[bool]) -> Self { + pub fn from_txids(txids: &[Txid], matches: &[bool]) -> Self { // We can never have zero txs in a merkle block, we always need the coinbase tx assert_ne!(txids.len(), 0); assert_eq!(txids.len(), matches.len()); @@ -178,7 +179,7 @@ impl PartialMerkleTree { /// returns the merkle root, or error in case of failure pub fn extract_matches( &self, - matches: &mut Vec, + matches: &mut Vec, indexes: &mut Vec, ) -> Result { matches.clear(); @@ -231,10 +232,10 @@ impl PartialMerkleTree { } /// Calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves) - fn calc_hash(&self, height: u32, pos: u32, txids: &[sha256d::Hash]) -> sha256d::Hash { + fn calc_hash(&self, height: u32, pos: u32, txids: &[Txid]) -> sha256d::Hash { if height == 0 { // Hash at height 0 is the txid itself - txids[pos as usize] + txids[pos as usize].into() } else { // Calculate left hash let left = self.calc_hash(height - 1, pos * 2, txids); @@ -254,7 +255,7 @@ impl PartialMerkleTree { &mut self, height: u32, pos: u32, - txids: &[sha256d::Hash], + txids: &[Txid], matches: &[bool], ) { // Determine whether this node is the parent of at least one matched txid @@ -270,7 +271,7 @@ impl PartialMerkleTree { if height == 0 || !parent_of_match { // If at height 0, or nothing interesting below, store hash and stop let hash = self.calc_hash(height, pos, txids); - self.hashes.push(hash); + self.hashes.push(hash.into()); } else { // Otherwise, don't store any hash, but descend into the subtrees self.traverse_and_build(height - 1, pos * 2, txids, matches); @@ -288,7 +289,7 @@ impl PartialMerkleTree { pos: u32, bits_used: &mut u32, hash_used: &mut u32, - matches: &mut Vec, + matches: &mut Vec, indexes: &mut Vec, ) -> Result { if *bits_used as usize >= self.bits.len() { @@ -305,7 +306,7 @@ impl PartialMerkleTree { *hash_used += 1; if height == 0 && parent_of_match { // in case of height 0, we have a matched txid - matches.push(hash); + matches.push(hash.into()); indexes.push(pos); } Ok(hash) @@ -407,7 +408,7 @@ impl MerkleBlock { /// /// ```rust /// extern crate bitcoin; - /// use bitcoin::hashes::sha256d; + /// use bitcoin::hash_types::Txid; /// use bitcoin::hashes::hex::FromHex; /// use bitcoin::{Block, MerkleBlock}; /// @@ -426,23 +427,23 @@ impl MerkleBlock { /// let block: Block = bitcoin::consensus::deserialize(&block_bytes).unwrap(); /// /// // Create a merkle block containing a single transaction - /// let txid = sha256d::Hash::from_hex( + /// let txid = Txid::from_hex( /// "5a4ebf66822b0b2d56bd9dc64ece0bc38ee7844a23ff1d7320a88c5fdb2ad3e2").unwrap(); /// let match_txids = vec![txid].into_iter().collect(); /// let mb = MerkleBlock::from_block(&block, &match_txids); /// /// // Authenticate and extract matched transaction ids - /// let mut matches: Vec = vec![]; + /// let mut matches: Vec = vec![]; /// let mut index: Vec = vec![]; /// assert!(mb.extract_matches(&mut matches, &mut index).is_ok()); /// assert_eq!(txid, matches[0]); /// # } /// ``` - pub fn from_block(block: &Block, match_txids: &HashSet) -> Self { + pub fn from_block(block: &Block, match_txids: &HashSet) -> Self { let header = block.header; let mut matches: Vec = Vec::with_capacity(block.txdata.len()); - let mut hashes: Vec = Vec::with_capacity(block.txdata.len()); + let mut hashes: Vec = Vec::with_capacity(block.txdata.len()); for hash in block.txdata.iter().map(BitcoinHash::bitcoin_hash) { matches.push(match_txids.contains(&hash)); @@ -458,7 +459,7 @@ impl MerkleBlock { /// returns Ok(()) on success, or error in case of failure pub fn extract_matches( &self, - matches: &mut Vec, + matches: &mut Vec, indexes: &mut Vec, ) -> Result<(), MerkleBlockError> { let merkle_root = self.txn.extract_matches(matches, indexes)?; @@ -495,6 +496,7 @@ impl Decodable for MerkleBlock { mod tests { use std::cmp::min; + use hash_types::Txid; use hashes::hex::{FromHex, ToHex}; use hashes::{sha256d, Hash}; use secp256k1::rand::prelude::*; @@ -512,7 +514,7 @@ mod tests { for num_tx in tx_counts { // Create some fake tx ids let txids = (1..num_tx + 1) // change to `1..=num_tx` when min Rust >= 1.26.0 - .map(|i| sha256d::Hash::from_hex(&format!("{:064x}", i)).unwrap()) + .map(|i| Txid::from_hex(&format!("{:064x}", i)).unwrap()) .collect::>(); // Calculate the merkle root and height @@ -555,7 +557,7 @@ mod tests { deserialize(&serialized).expect("Could not deserialize own data"); // Extract merkle root and matched txids from copy - let mut match_txid2 = vec![]; + let mut match_txid2: Vec = vec![]; let mut indexes = vec![]; let merkle_root_2 = pmt2 .extract_matches(&mut match_txid2, &mut indexes) @@ -585,9 +587,9 @@ mod tests { #[test] fn pmt_malleability() { // Create some fake tx ids with the last 2 hashes repeating - let txids: Vec = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 10] + let txids: Vec = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 10] .iter() - .map(|i| sha256d::Hash::from_hex(&format!("{:064x}", i)).unwrap()) + .map(|i| Txid::from_hex(&format!("{:064x}", i)).unwrap()) .collect(); let matches = vec![ @@ -628,12 +630,12 @@ mod tests { fn merkleblock_construct_from_txids_found() { let block = get_block_13b8a(); - let txids: Vec = [ + let txids: Vec = [ "74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20", "f9fc751cb7dc372406a9f8d738d5e6f8f63bab71986a39cf36ee70ee17036d07", ] .iter() - .map(|hex| sha256d::Hash::from_hex(hex).unwrap()) + .map(|hex| Txid::from_hex(hex).unwrap()) .collect(); let txid1 = txids[0]; @@ -644,7 +646,7 @@ mod tests { assert_eq!(merkle_block.header.bitcoin_hash(), block.bitcoin_hash()); - let mut matches: Vec = vec![]; + let mut matches: Vec = vec![]; let mut index: Vec = vec![]; assert_eq!( @@ -670,14 +672,14 @@ mod tests { let block = get_block_13b8a(); let txids = ["c0ffee00003bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"] .iter() - .map(|hex| sha256d::Hash::from_hex(hex).unwrap()) + .map(|hex| Txid::from_hex(hex).unwrap()) .collect(); let merkle_block = MerkleBlock::from_block(&block, &txids); assert_eq!(merkle_block.header.bitcoin_hash(), block.bitcoin_hash()); - let mut matches: Vec = vec![]; + let mut matches: Vec = vec![]; let mut index: Vec = vec![]; assert_eq!(