diff --git a/src/blockdata/block.rs b/src/blockdata/block.rs index f67e8586..2fff8f03 100644 --- a/src/blockdata/block.rs +++ b/src/blockdata/block.rs @@ -22,7 +22,7 @@ use util; use util::Error::{BlockBadTarget, BlockBadProofOfWork}; -use util::hash::{BitcoinHash, bitcoin_merkle_root}; +use util::hash::bitcoin_merkle_root; use hashes::{Hash, HashEngine}; use hash_types::{Wtxid, BlockHash, TxMerkleNode, WitnessMerkleNode, WitnessCommitment}; use util::uint::Uint256; @@ -61,6 +61,11 @@ pub struct Block { } impl Block { + /// Return the block hash. + pub fn block_hash(&self) -> BlockHash { + self.header.block_hash() + } + /// check if merkle root of header matches merkle root of the transaction list pub fn check_merkle_root (&self) -> bool { self.header.merkle_root == self.merkle_root() @@ -122,6 +127,13 @@ impl Block { } impl BlockHeader { + /// Return the block hash. + pub fn block_hash(&self) -> BlockHash { + let mut engine = BlockHash::engine(); + self.consensus_encode(&mut engine).expect("engines don't error"); + BlockHash::from_engine(engine) + } + /// Computes the target [0, T] that a blockhash must land in to be valid pub fn target(&self) -> Uint256 { // This is a floating-point "compact" encoding originally used by @@ -174,7 +186,7 @@ impl BlockHeader { if target != required_target { return Err(BlockBadTarget); } - let data: [u8; 32] = self.bitcoin_hash().into_inner(); + let data: [u8; 32] = self.block_hash().into_inner(); let mut ret = [0u64; 4]; util::endian::bytes_to_u64_slice_le(&data, &mut ret); let hash = &Uint256(ret); @@ -193,19 +205,6 @@ impl BlockHeader { } } -impl BitcoinHash for BlockHeader { - fn bitcoin_hash(&self) -> BlockHash { - use consensus::encode::serialize; - BlockHash::hash(&serialize(self)) - } -} - -impl BitcoinHash for Block { - fn bitcoin_hash(&self) -> BlockHash { - self.header.bitcoin_hash() - } -} - impl_consensus_encoding!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce); impl_consensus_encoding!(Block, header, txdata); serde_struct_impl!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce); diff --git a/src/blockdata/constants.rs b/src/blockdata/constants.rs index 23622918..a5056c8f 100644 --- a/src/blockdata/constants.rs +++ b/src/blockdata/constants.rs @@ -151,7 +151,6 @@ mod test { use consensus::encode::serialize; use blockdata::constants::{genesis_block, bitcoin_genesis_tx}; use blockdata::constants::{MAX_SEQUENCE, COIN_VALUE}; - use util::hash::BitcoinHash; #[test] fn bitcoin_genesis_first_transaction() { @@ -186,7 +185,7 @@ mod test { assert_eq!(gen.header.time, 1231006505); assert_eq!(gen.header.bits, 0x1d00ffff); assert_eq!(gen.header.nonce, 2083236893); - assert_eq!(format!("{:x}", gen.header.bitcoin_hash()), + assert_eq!(format!("{:x}", gen.header.block_hash()), "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f".to_string()); } @@ -200,7 +199,7 @@ mod test { assert_eq!(gen.header.time, 1296688602); assert_eq!(gen.header.bits, 0x1d00ffff); assert_eq!(gen.header.nonce, 414098458); - assert_eq!(format!("{:x}", gen.header.bitcoin_hash()), + assert_eq!(format!("{:x}", gen.header.block_hash()), "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943".to_string()); } } diff --git a/src/lib.rs b/src/lib.rs index 6ba26f92..f122b931 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,7 +97,6 @@ pub use util::address::Address; pub use util::address::AddressType; pub use util::amount::Amount; pub use util::amount::SignedAmount; -pub use util::hash::BitcoinHash; pub use util::key::PrivateKey; pub use util::key::PublicKey; pub use util::merkleblock::MerkleBlock; diff --git a/src/util/bip158.rs b/src/util/bip158.rs index 1d71d01d..b7154bfe 100644 --- a/src/util/bip158.rs +++ b/src/util/bip158.rs @@ -59,7 +59,6 @@ use blockdata::transaction::OutPoint; use consensus::{Decodable, Encodable}; use consensus::encode::VarInt; use util::endian; -use util::hash::BitcoinHash; /// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845 const P: u8 = 19; @@ -155,7 +154,7 @@ pub struct BlockFilterWriter<'a> { impl<'a> BlockFilterWriter<'a> { /// Create a block filter writer pub fn new(writer: &'a mut io::Write, block: &'a Block) -> BlockFilterWriter<'a> { - let block_hash_as_int = block.bitcoin_hash().into_inner(); + let block_hash_as_int = block.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]); let writer = GCSFilterWriter::new(writer, k0, k1, M, P); @@ -559,7 +558,7 @@ mod test { for t in testdata.iter().skip(1) { 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); + assert_eq!(block.block_hash(), block_hash); let scripts = t.get(3).unwrap().as_array().unwrap(); let previous_filter_id = FilterHash::from_hex(&t.get(4).unwrap().as_str().unwrap()).unwrap(); let filter_content = hex::decode(&t.get(5).unwrap().as_str().unwrap().as_bytes()).unwrap(); @@ -584,7 +583,7 @@ mod test { assert_eq!(test_filter.content, filter.content); - let block_hash = &block.header.bitcoin_hash(); + let block_hash = &block.block_hash(); assert!(filter.match_all(block_hash, &mut txmap.iter() .filter_map(|(_, s)| if !s.is_empty() { Some(s.as_bytes()) } else { None })).unwrap()); diff --git a/src/util/hash.rs b/src/util/hash.rs index 0de4731f..ba7b6d20 100644 --- a/src/util/hash.rs +++ b/src/util/hash.rs @@ -75,9 +75,3 @@ pub fn bitcoin_merkle_root(mut iter: I) -> T } bitcoin_merkle_root_inline(&mut alloc) } - -/// Objects which are referred to by hash -pub trait BitcoinHash { - /// Produces a Sha256dHash which can be used to refer to the object - fn bitcoin_hash(&self) -> T; -} diff --git a/src/util/merkleblock.rs b/src/util/merkleblock.rs index 3dca69d8..b1365751 100644 --- a/src/util/merkleblock.rs +++ b/src/util/merkleblock.rs @@ -502,7 +502,7 @@ mod tests { use secp256k1::rand::prelude::*; use consensus::encode::{deserialize, serialize}; - use util::hash::{bitcoin_merkle_root, BitcoinHash}; + use util::hash::bitcoin_merkle_root; use util::merkleblock::{MerkleBlock, PartialMerkleTree}; use {hex, Block}; @@ -616,7 +616,7 @@ mod tests { af156d6fc30b55fad4112df2b95531e68114e9ad10011e72f7b7cfdb025700"; let mb: MerkleBlock = deserialize(&hex::decode(mb_hex).unwrap()).unwrap(); - assert_eq!(get_block_13b8a().bitcoin_hash(), mb.header.bitcoin_hash()); + assert_eq!(get_block_13b8a().block_hash(), mb.header.block_hash()); assert_eq!( mb.header.merkle_root, mb.txn.extract_matches(&mut vec![], &mut vec![]).unwrap() @@ -645,7 +645,7 @@ mod tests { let merkle_block = MerkleBlock::from_block(&block, &txids); - assert_eq!(merkle_block.header.bitcoin_hash(), block.bitcoin_hash()); + assert_eq!(merkle_block.header.block_hash(), block.block_hash()); let mut matches: Vec = vec![]; let mut index: Vec = vec![]; @@ -678,7 +678,7 @@ mod tests { let merkle_block = MerkleBlock::from_block(&block, &txids); - assert_eq!(merkle_block.header.bitcoin_hash(), block.bitcoin_hash()); + assert_eq!(merkle_block.header.block_hash(), block.block_hash()); let mut matches: Vec = vec![]; let mut index: Vec = vec![];