From ffc28bf49578e233b4ce259e406bf41b0a251ace Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 9 Jan 2016 23:47:46 +0100 Subject: [PATCH] Additional bloom-related functionality. RlpStandard for non-emit_*-based RlpStream extesions. --- src/chainfilter.rs | 8 ++++---- src/hash.rs | 30 +++++++++++++++++------------- src/rlp/mod.rs | 2 +- src/rlp/rlpstream.rs | 18 +++++++++++++++++- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/chainfilter.rs b/src/chainfilter.rs index 076263fbb..e1804c191 100644 --- a/src/chainfilter.rs +++ b/src/chainfilter.rs @@ -18,7 +18,7 @@ //! let filter = ChainFilter::new(&cache, index_size, bloom_levels); //! let block_number = 39; //! let mut bloom = H2048::new(); -//! bloom.shift_bloom(&address.sha3()); +//! bloom.shift_bloomed(&address.sha3()); //! filter.add_bloom(&bloom, block_number) //! }; //! @@ -296,14 +296,14 @@ impl<'a, D> ChainFilter<'a, D> where D: FilterDataSource /// Returns numbers of blocks that may contain Address. pub fn blocks_with_address(&self, address: &Address, from_block: usize, to_block: usize) -> Vec { let mut bloom = H2048::new(); - bloom.shift_bloom(&address.sha3()); + bloom.shift_bloomed(&address.sha3()); self.blocks_with_bloom(&bloom, from_block, to_block) } /// Returns numbers of blocks that may contain Topic. pub fn blocks_with_topic(&self, topic: &H256, from_block: usize, to_block: usize) -> Vec { let mut bloom = H2048::new(); - bloom.shift_bloom(&topic.sha3()); + bloom.shift_bloomed(&topic.sha3()); self.blocks_with_bloom(&bloom, from_block, to_block) } @@ -415,7 +415,7 @@ mod tests { let filter = ChainFilter::new(&cache, index_size, bloom_levels); let block_number = 23; let mut bloom = H2048::new(); - bloom.shift_bloom(&topic.sha3()); + bloom.shift_bloomed(&topic.sha3()); filter.add_bloom(&bloom, block_number) }; diff --git a/src/hash.rs b/src/hash.rs index 78069a659..e368e064a 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -27,9 +27,10 @@ pub trait FixedHash: Sized + BytesConvertable + Populatable { fn from_slice(src: &[u8]) -> Self; fn clone_from_slice(&mut self, src: &[u8]) -> usize; fn copy_to(&self, dest: &mut [u8]); - fn shift_bloom<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash; + fn shift_bloomed<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash; + fn with_bloomed(mut self, b: &T) -> Self where T: FixedHash { self.shift_bloomed(b); self } fn bloom_part(&self, m: usize) -> T where T: FixedHash; - fn contains_bloom(&self, b: &T) -> bool where T: FixedHash; + fn contains_bloomed(&self, b: &T) -> bool where T: FixedHash; fn contains<'a>(&'a self, b: &'a Self) -> bool; fn is_zero(&self) -> bool; } @@ -109,11 +110,12 @@ macro_rules! impl_hash { } } - fn shift_bloom<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash { + fn shift_bloomed<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash { let bp: Self = b.bloom_part($size); let new_self = &bp | self; // impl |= instead + // TODO: that's done now! unsafe { use std::{mem, ptr}; @@ -159,7 +161,7 @@ macro_rules! impl_hash { ret } - fn contains_bloom(&self, b: &T) -> bool where T: FixedHash { + fn contains_bloomed(&self, b: &T) -> bool where T: FixedHash { let bp: Self = b.bloom_part($size); self.contains(&bp) } @@ -367,6 +369,8 @@ macro_rules! impl_hash { pub fn hex(&self) -> String { format!("{}", self) } + + pub fn from_bloomed(b: &T) -> Self where T: FixedHash { b.bloom_part($size) } } } } @@ -468,7 +472,7 @@ mod tests { } #[test] - fn shift_bloom() { + fn shift_bloomed() { use sha3::Hashable; let bloom = H2048::from_str("00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); @@ -476,17 +480,17 @@ mod tests { let topic = H256::from_str("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); let mut my_bloom = H2048::new(); - assert!(!my_bloom.contains_bloom(&address.sha3())); - assert!(!my_bloom.contains_bloom(&topic.sha3())); + assert!(!my_bloom.contains_bloomed(&address.sha3())); + assert!(!my_bloom.contains_bloomed(&topic.sha3())); - my_bloom.shift_bloom(&address.sha3()); - assert!(my_bloom.contains_bloom(&address.sha3())); - assert!(!my_bloom.contains_bloom(&topic.sha3())); + my_bloom.shift_bloomed(&address.sha3()); + assert!(my_bloom.contains_bloomed(&address.sha3())); + assert!(!my_bloom.contains_bloomed(&topic.sha3())); - my_bloom.shift_bloom(&topic.sha3()); + my_bloom.shift_bloomed(&topic.sha3()); assert_eq!(my_bloom, bloom); - assert!(my_bloom.contains_bloom(&address.sha3())); - assert!(my_bloom.contains_bloom(&topic.sha3())); + assert!(my_bloom.contains_bloomed(&address.sha3())); + assert!(my_bloom.contains_bloomed(&topic.sha3())); } #[test] diff --git a/src/rlp/mod.rs b/src/rlp/mod.rs index 39cc3a7e7..fc0a4d288 100644 --- a/src/rlp/mod.rs +++ b/src/rlp/mod.rs @@ -43,7 +43,7 @@ pub use self::rlperrors::DecoderError; pub use self::rlptraits::{Decoder, Decodable, View, Stream, Encodable, Encoder}; pub use self::untrusted_rlp::{UntrustedRlp, UntrustedRlpIterator, PayloadInfo, Prototype}; pub use self::rlpin::{Rlp, RlpIterator}; -pub use self::rlpstream::{RlpStream}; +pub use self::rlpstream::{RlpStream,RlpStandard}; use super::hash::H256; pub const NULL_RLP: [u8; 1] = [0x80; 1]; diff --git a/src/rlp/rlpstream.rs b/src/rlp/rlpstream.rs index 97ae1b484..b8954ae6f 100644 --- a/src/rlp/rlpstream.rs +++ b/src/rlp/rlpstream.rs @@ -1,6 +1,8 @@ use elastic_array::*; -use bytes::ToBytes; +use bytes::{Bytes, ToBytes}; use rlp::{Stream, Encoder, Encodable}; +use hash::H256; +use sha3::*; #[derive(Debug, Copy, Clone)] struct ListInfo { @@ -213,6 +215,20 @@ impl Encoder for BasicEncoder { } } +pub trait RlpStandard { + fn rlp_append(&self, s: &mut RlpStream); + + fn rlp_bytes(&self) -> Bytes { + let mut s = RlpStream::new(); + self.rlp_append(&mut s); + s.out() + } + + fn rlp_sha3(&self) -> H256 { self.rlp_bytes().sha3() } +} + +// @debris TODO: implement Encoder for RlpStandard. + impl Encodable for T where T: ToBytes { fn encode(&self, encoder: &mut E) where E: Encoder { encoder.emit_value(&self.to_bytes())