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:
parent
5ef39e34fa
commit
5f4f629bb1
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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!(
|
||||
|
|
Loading…
Reference in New Issue