Replaced all hash160, sha256 and sha256d with the new hash types throughout the code

Embedding Txid's in the doc exaples
This commit is contained in:
Dr Maxim Orlovsky 2019-11-30 17:26:52 +01:00
parent 5ef39e34fa
commit 5f4f629bb1
7 changed files with 60 additions and 54 deletions

View File

@ -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<BlockHash> 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<BlockHash> for Block {
fn bitcoin_hash(&self) -> BlockHash {
self.header.bitcoin_hash()
}
}

View File

@ -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()
}

View File

@ -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<Txid> 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)
}
}

View File

@ -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 {

View File

@ -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<Item=&[u8]>) -> Result<bool, Error> {
pub fn match_any(&self, block_hash: &BlockHash, query: &mut Iterator<Item=&[u8]>) -> Result<bool, Error> {
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<Item=&[u8]>) -> Result<bool, Error> {
pub fn match_all(&self, block_hash: &BlockHash, query: &mut Iterator<Item=&[u8]>) -> Result<bool, Error> {
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::<Value>(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 {

View File

@ -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>) -> sha256d::Hash {
pub fn bitcoin_merkle_root(data: Vec<Txid>) -> 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>) -> 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<T: Hash> {
/// Produces a Sha256dHash which can be used to refer to the object
fn bitcoin_hash(&self) -> sha256d::Hash;
fn bitcoin_hash(&self) -> T;
}

View File

@ -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<sha256d::Hash> = vec![];
//! let mut matches: Vec<Txid> = vec![];
//! let mut index: Vec<u32> = 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<sha256d::Hash> = [
/// let txids: Vec<Txid> = [
/// "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<sha256d::Hash>,
matches: &mut Vec<Txid>,
indexes: &mut Vec<u32>,
) -> Result<sha256d::Hash, MerkleBlockError> {
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<sha256d::Hash>,
matches: &mut Vec<Txid>,
indexes: &mut Vec<u32>,
) -> Result<sha256d::Hash, MerkleBlockError> {
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<sha256d::Hash> = vec![];
/// let mut matches: Vec<Txid> = vec![];
/// let mut index: Vec<u32> = 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<sha256d::Hash>) -> Self {
pub fn from_block(block: &Block, match_txids: &HashSet<Txid>) -> Self {
let header = block.header;
let mut matches: Vec<bool> = Vec::with_capacity(block.txdata.len());
let mut hashes: Vec<sha256d::Hash> = Vec::with_capacity(block.txdata.len());
let mut hashes: Vec<Txid> = 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<sha256d::Hash>,
matches: &mut Vec<Txid>,
indexes: &mut Vec<u32>,
) -> 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::<Vec<_>>();
// 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<Txid> = 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<sha256d::Hash> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 10]
let txids: Vec<Txid> = [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<sha256d::Hash> = [
let txids: Vec<Txid> = [
"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<sha256d::Hash> = vec![];
let mut matches: Vec<Txid> = vec![];
let mut index: Vec<u32> = 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<sha256d::Hash> = vec![];
let mut matches: Vec<Txid> = vec![];
let mut index: Vec<u32> = vec![];
assert_eq!(