Remove the BitcoinHash trait

Replaced by a `block_hash` method on both `Block` and `BlockHeader`.
This commit is contained in:
Steven Roose 2020-01-10 11:34:16 +00:00
parent 2cba81935d
commit 8e52b8ce4d
No known key found for this signature in database
GPG Key ID: 2F2A88D7F8D68E87
6 changed files with 23 additions and 33 deletions

View File

@ -22,7 +22,7 @@
use util; use util;
use util::Error::{BlockBadTarget, BlockBadProofOfWork}; use util::Error::{BlockBadTarget, BlockBadProofOfWork};
use util::hash::{BitcoinHash, bitcoin_merkle_root}; use util::hash::bitcoin_merkle_root;
use hashes::{Hash, HashEngine}; use hashes::{Hash, HashEngine};
use hash_types::{Wtxid, BlockHash, TxMerkleNode, WitnessMerkleNode, WitnessCommitment}; use hash_types::{Wtxid, BlockHash, TxMerkleNode, WitnessMerkleNode, WitnessCommitment};
use util::uint::Uint256; use util::uint::Uint256;
@ -61,6 +61,11 @@ pub struct Block {
} }
impl 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 /// check if merkle root of header matches merkle root of the transaction list
pub fn check_merkle_root (&self) -> bool { pub fn check_merkle_root (&self) -> bool {
self.header.merkle_root == self.merkle_root() self.header.merkle_root == self.merkle_root()
@ -122,6 +127,13 @@ impl Block {
} }
impl BlockHeader { 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 /// Computes the target [0, T] that a blockhash must land in to be valid
pub fn target(&self) -> Uint256 { pub fn target(&self) -> Uint256 {
// This is a floating-point "compact" encoding originally used by // This is a floating-point "compact" encoding originally used by
@ -174,7 +186,7 @@ impl BlockHeader {
if target != required_target { if target != required_target {
return Err(BlockBadTarget); 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]; let mut ret = [0u64; 4];
util::endian::bytes_to_u64_slice_le(&data, &mut ret); util::endian::bytes_to_u64_slice_le(&data, &mut ret);
let hash = &Uint256(ret); let hash = &Uint256(ret);
@ -193,19 +205,6 @@ impl BlockHeader {
} }
} }
impl BitcoinHash<BlockHash> for BlockHeader {
fn bitcoin_hash(&self) -> BlockHash {
use consensus::encode::serialize;
BlockHash::hash(&serialize(self))
}
}
impl BitcoinHash<BlockHash> 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!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);
impl_consensus_encoding!(Block, header, txdata); impl_consensus_encoding!(Block, header, txdata);
serde_struct_impl!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce); serde_struct_impl!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);

View File

@ -151,7 +151,6 @@ mod test {
use consensus::encode::serialize; use consensus::encode::serialize;
use blockdata::constants::{genesis_block, bitcoin_genesis_tx}; use blockdata::constants::{genesis_block, bitcoin_genesis_tx};
use blockdata::constants::{MAX_SEQUENCE, COIN_VALUE}; use blockdata::constants::{MAX_SEQUENCE, COIN_VALUE};
use util::hash::BitcoinHash;
#[test] #[test]
fn bitcoin_genesis_first_transaction() { fn bitcoin_genesis_first_transaction() {
@ -186,7 +185,7 @@ mod test {
assert_eq!(gen.header.time, 1231006505); assert_eq!(gen.header.time, 1231006505);
assert_eq!(gen.header.bits, 0x1d00ffff); assert_eq!(gen.header.bits, 0x1d00ffff);
assert_eq!(gen.header.nonce, 2083236893); 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()); "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f".to_string());
} }
@ -200,7 +199,7 @@ mod test {
assert_eq!(gen.header.time, 1296688602); assert_eq!(gen.header.time, 1296688602);
assert_eq!(gen.header.bits, 0x1d00ffff); assert_eq!(gen.header.bits, 0x1d00ffff);
assert_eq!(gen.header.nonce, 414098458); 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()); "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943".to_string());
} }
} }

View File

@ -97,7 +97,6 @@ pub use util::address::Address;
pub use util::address::AddressType; pub use util::address::AddressType;
pub use util::amount::Amount; pub use util::amount::Amount;
pub use util::amount::SignedAmount; pub use util::amount::SignedAmount;
pub use util::hash::BitcoinHash;
pub use util::key::PrivateKey; pub use util::key::PrivateKey;
pub use util::key::PublicKey; pub use util::key::PublicKey;
pub use util::merkleblock::MerkleBlock; pub use util::merkleblock::MerkleBlock;

View File

@ -59,7 +59,6 @@ use blockdata::transaction::OutPoint;
use consensus::{Decodable, Encodable}; use consensus::{Decodable, Encodable};
use consensus::encode::VarInt; use consensus::encode::VarInt;
use util::endian; use util::endian;
use util::hash::BitcoinHash;
/// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845 /// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845
const P: u8 = 19; const P: u8 = 19;
@ -155,7 +154,7 @@ pub struct BlockFilterWriter<'a> {
impl<'a> BlockFilterWriter<'a> { impl<'a> BlockFilterWriter<'a> {
/// Create a block filter writer /// Create a block filter writer
pub fn new(writer: &'a mut io::Write, block: &'a Block) -> BlockFilterWriter<'a> { 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 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 k1 = endian::slice_to_u64_le(&block_hash_as_int[8..16]);
let writer = GCSFilterWriter::new(writer, k0, k1, M, P); let writer = GCSFilterWriter::new(writer, k0, k1, M, P);
@ -559,7 +558,7 @@ mod test {
for t in testdata.iter().skip(1) { for t in testdata.iter().skip(1) {
let block_hash = BlockHash::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(); 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 scripts = t.get(3).unwrap().as_array().unwrap();
let previous_filter_id = FilterHash::from_hex(&t.get(4).unwrap().as_str().unwrap()).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(); 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); 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() assert!(filter.match_all(block_hash, &mut txmap.iter()
.filter_map(|(_, s)| if !s.is_empty() { Some(s.as_bytes()) } else { None })).unwrap()); .filter_map(|(_, s)| if !s.is_empty() { Some(s.as_bytes()) } else { None })).unwrap());

View File

@ -75,9 +75,3 @@ pub fn bitcoin_merkle_root<T, I>(mut iter: I) -> T
} }
bitcoin_merkle_root_inline(&mut alloc) bitcoin_merkle_root_inline(&mut alloc)
} }
/// Objects which are referred to by hash
pub trait BitcoinHash<T: Hash> {
/// Produces a Sha256dHash which can be used to refer to the object
fn bitcoin_hash(&self) -> T;
}

View File

@ -502,7 +502,7 @@ mod tests {
use secp256k1::rand::prelude::*; use secp256k1::rand::prelude::*;
use consensus::encode::{deserialize, serialize}; use consensus::encode::{deserialize, serialize};
use util::hash::{bitcoin_merkle_root, BitcoinHash}; use util::hash::bitcoin_merkle_root;
use util::merkleblock::{MerkleBlock, PartialMerkleTree}; use util::merkleblock::{MerkleBlock, PartialMerkleTree};
use {hex, Block}; use {hex, Block};
@ -616,7 +616,7 @@ mod tests {
af156d6fc30b55fad4112df2b95531e68114e9ad10011e72f7b7cfdb025700"; af156d6fc30b55fad4112df2b95531e68114e9ad10011e72f7b7cfdb025700";
let mb: MerkleBlock = deserialize(&hex::decode(mb_hex).unwrap()).unwrap(); 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!( assert_eq!(
mb.header.merkle_root, mb.header.merkle_root,
mb.txn.extract_matches(&mut vec![], &mut vec![]).unwrap() mb.txn.extract_matches(&mut vec![], &mut vec![]).unwrap()
@ -645,7 +645,7 @@ mod tests {
let merkle_block = MerkleBlock::from_block(&block, &txids); 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<Txid> = vec![]; let mut matches: Vec<Txid> = vec![];
let mut index: Vec<u32> = vec![]; let mut index: Vec<u32> = vec![];
@ -678,7 +678,7 @@ mod tests {
let merkle_block = MerkleBlock::from_block(&block, &txids); 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<Txid> = vec![]; let mut matches: Vec<Txid> = vec![];
let mut index: Vec<u32> = vec![]; let mut index: Vec<u32> = vec![];