diff --git a/src/consensus/encode.rs b/src/consensus/encode.rs index 2fc39b68..07b9853c 100644 --- a/src/consensus/encode.rs +++ b/src/consensus/encode.rs @@ -35,7 +35,7 @@ use std::io::{Cursor, Read, Write}; use hashes::hex::ToHex; use hashes::{sha256d, Hash}; -use hash_types::{BlockHash, FilterHash, TxMerkleNode}; +use hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader}; use util::endian; use util::psbt; @@ -593,6 +593,7 @@ macro_rules! impl_vec { } impl_vec!(BlockHash); impl_vec!(FilterHash); +impl_vec!(FilterHeader); impl_vec!(TxMerkleNode); impl_vec!(Transaction); impl_vec!(TxOut); diff --git a/src/hash_types.rs b/src/hash_types.rs index 3027008f..f50be4bd 100644 --- a/src/hash_types.rs +++ b/src/hash_types.rs @@ -50,7 +50,8 @@ hash_newtype!(WitnessMerkleNode, sha256d::Hash, 32, doc="A hash corresponding to hash_newtype!(WitnessCommitment, sha256d::Hash, 32, doc="A hash corresponding to the witness structure commitment in the coinbase transaction"); hash_newtype!(XpubIdentifier, hash160::Hash, 20, doc="XpubIdentifier as defined in BIP-32."); -hash_newtype!(FilterHash, sha256d::Hash, 32, doc="Bloom filter souble-SHA256 locator hash, as defined in BIP-168"); +hash_newtype!(FilterHash, sha256d::Hash, 32, doc="Filter hash, as defined in BIP-157"); +hash_newtype!(FilterHeader, sha256d::Hash, 32, doc="Filter header, as defined in BIP-157"); impl_hashencode!(Txid); @@ -60,3 +61,4 @@ impl_hashencode!(BlockHash); impl_hashencode!(TxMerkleNode); impl_hashencode!(WitnessMerkleNode); impl_hashencode!(FilterHash); +impl_hashencode!(FilterHeader); \ No newline at end of file diff --git a/src/network/message.rs b/src/network/message.rs index eda4ff53..5b045cef 100644 --- a/src/network/message.rs +++ b/src/network/message.rs @@ -397,7 +397,7 @@ mod test { NetworkMessage::GetCFilters(GetCFilters{filter_type: 2, start_height: 52, stop_hash: hash([42u8; 32]).into()}), NetworkMessage::CFilter(CFilter{filter_type: 7, block_hash: hash([25u8; 32]).into(), filter: vec![1,2,3]}), NetworkMessage::GetCFHeaders(GetCFHeaders{filter_type: 4, start_height: 102, stop_hash: hash([47u8; 32]).into()}), - NetworkMessage::CFHeaders(CFHeaders{filter_type: 13, stop_hash: hash([53u8; 32]).into(), previous_filter: hash([12u8; 32]).into(), filter_hashes: vec![hash([4u8; 32]).into(), hash([12u8; 32]).into()]}), + NetworkMessage::CFHeaders(CFHeaders{filter_type: 13, stop_hash: hash([53u8; 32]).into(), previous_filter_header: hash([12u8; 32]).into(), filter_hashes: vec![hash([4u8; 32]).into(), hash([12u8; 32]).into()]}), NetworkMessage::GetCFCheckpt(GetCFCheckpt{filter_type: 17, stop_hash: hash([25u8; 32]).into()}), NetworkMessage::CFCheckpt(CFCheckpt{filter_type: 27, stop_hash: hash([77u8; 32]).into(), filter_headers: vec![hash([3u8; 32]).into(), hash([99u8; 32]).into()]}), NetworkMessage::Alert(vec![45,66,3,2,6,8,9,12,3,130]), diff --git a/src/network/message_filter.rs b/src/network/message_filter.rs index 17d3318c..56be8b7f 100644 --- a/src/network/message_filter.rs +++ b/src/network/message_filter.rs @@ -2,7 +2,7 @@ //! BIP157 Client Side Block Filtering network messages //! -use hash_types::{BlockHash, FilterHash}; +use hash_types::{BlockHash, FilterHash, FilterHeader}; #[derive(PartialEq, Eq, Clone, Debug)] /// getcfilters message @@ -48,11 +48,11 @@ pub struct CFHeaders { /// The hash of the last block in the requested range pub stop_hash: BlockHash, /// The filter header preceding the first block in the requested range - pub previous_filter: FilterHash, + pub previous_filter_header: FilterHeader, /// The filter hashes for each block in the requested range pub filter_hashes: Vec, } -impl_consensus_encoding!(CFHeaders, filter_type, stop_hash, previous_filter, filter_hashes); +impl_consensus_encoding!(CFHeaders, filter_type, stop_hash, previous_filter_header, filter_hashes); #[derive(PartialEq, Eq, Clone, Debug)] /// getcfcheckpt message @@ -72,6 +72,6 @@ pub struct CFCheckpt { /// The hash of the last block in the requested range pub stop_hash: BlockHash, /// The filter headers at intervals of 1,000 - pub filter_headers: Vec, + pub filter_headers: Vec, } impl_consensus_encoding!(CFCheckpt, filter_type, stop_hash, filter_headers); diff --git a/src/util/bip158.rs b/src/util/bip158.rs index c556888c..db06a03d 100644 --- a/src/util/bip158.rs +++ b/src/util/bip158.rs @@ -53,7 +53,7 @@ use std::cmp::Ordering; use hashes::{Hash, siphash24}; -use hash_types::{BlockHash, FilterHash}; +use hash_types::{BlockHash, FilterHash, FilterHeader}; use blockdata::block::Block; use blockdata::script::Script; @@ -100,14 +100,21 @@ pub struct BlockFilter { pub content: Vec } +impl FilterHash { + /// compute the filter header from a filter hash and previous filter header + pub fn filter_header(&self, previous_filter_header: &FilterHeader) -> FilterHeader { + let mut header_data = [0u8; 64]; + header_data[0..32].copy_from_slice(&self[..]); + header_data[32..64].copy_from_slice(&previous_filter_header[..]); + FilterHeader::hash(&header_data) + } +} + impl BlockFilter { /// compute this filter's id in a chain of filters - pub fn filter_id(&self, previous_filter_id: &FilterHash) -> FilterHash { + pub fn filter_header(&self, previous_filter_header: &FilterHeader) -> FilterHeader { let filter_hash = FilterHash::hash(self.content.as_slice()); - let mut header_data = [0u8; 64]; - header_data[0..32].copy_from_slice(&filter_hash[..]); - header_data[32..64].copy_from_slice(&previous_filter_id[..]); - FilterHash::hash(&header_data) + filter_hash.filter_header(previous_filter_header) } /// create a new filter from pre-computed data @@ -555,9 +562,9 @@ mod test { let block: Block = deserialize(&Vec::from_hex(&t.get(2).unwrap().as_str().unwrap()).unwrap()).unwrap(); 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 previous_filter_header = FilterHeader::from_hex(&t.get(4).unwrap().as_str().unwrap()).unwrap(); let filter_content = Vec::from_hex(&t.get(5).unwrap().as_str().unwrap()).unwrap(); - let filter_id = FilterHash::from_hex(&t.get(6).unwrap().as_str().unwrap()).unwrap(); + let filter_header = FilterHeader::from_hex(&t.get(6).unwrap().as_str().unwrap()).unwrap(); let mut txmap = HashMap::new(); let mut si = scripts.iter(); @@ -590,7 +597,7 @@ mod test { } } - assert_eq!(filter_id, filter.filter_id(&previous_filter_id)); + assert_eq!(filter_header, filter.filter_header(&previous_filter_header)); } }