bloomable trait
This commit is contained in:
parent
efca92b766
commit
a1867a7ba6
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
use util::hash::*;
|
use util::hash::*;
|
||||||
use util::sha3::*;
|
use util::sha3::*;
|
||||||
|
use util::bloom::Bloomable;
|
||||||
use client::BlockID;
|
use client::BlockID;
|
||||||
use log_entry::LogEntry;
|
use log_entry::LogEntry;
|
||||||
use ipc::binary::BinaryConvertError;
|
use ipc::binary::BinaryConvertError;
|
||||||
|
@ -19,8 +19,9 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use util::{H256, Address, Bytes, HeapSizeOf, FixedHash, Hashable};
|
use util::{H256, Address, Bytes, HeapSizeOf, Hashable};
|
||||||
use util::rlp::*;
|
use util::rlp::*;
|
||||||
|
use util::bloom::Bloomable;
|
||||||
use ipc::binary::BinaryConvertError;
|
use ipc::binary::BinaryConvertError;
|
||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
|
@ -20,8 +20,9 @@ use std::ops::Range;
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use bloomchain::{Filter as BloomFilter, Bloom, Number};
|
use bloomchain::{Filter as BloomFilter, Bloom, Number};
|
||||||
use util::{Address, FixedHash};
|
use util::Address;
|
||||||
use util::sha3::Hashable;
|
use util::sha3::Hashable;
|
||||||
|
use util::bloom::Bloomable;
|
||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
use trace::flat::FlatTrace;
|
use trace::flat::FlatTrace;
|
||||||
use types::trace_types::trace::{Action, Res};
|
use types::trace_types::trace::{Action, Res};
|
||||||
@ -137,8 +138,9 @@ impl Filter {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::{FixedHash, Address};
|
use util::Address;
|
||||||
use util::sha3::Hashable;
|
use util::sha3::Hashable;
|
||||||
|
use util::bloom::Bloomable;
|
||||||
use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide};
|
use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide};
|
||||||
use trace::flat::FlatTrace;
|
use trace::flat::FlatTrace;
|
||||||
use trace::{Filter, AddressesFilter};
|
use trace::{Filter, AddressesFilter};
|
||||||
|
@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
//! Tracing datatypes.
|
//! Tracing datatypes.
|
||||||
|
|
||||||
use util::{U256, Bytes, Address, FixedHash};
|
use util::{U256, Bytes, Address};
|
||||||
use util::rlp::*;
|
use util::rlp::*;
|
||||||
use util::sha3::Hashable;
|
use util::sha3::Hashable;
|
||||||
|
use util::bloom::Bloomable;
|
||||||
use action_params::ActionParams;
|
use action_params::ActionParams;
|
||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
use types::executed::CallType;
|
use types::executed::CallType;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! General hash types, a fixed-size raw-data type used as the output of hash functions.
|
//! General hash types, a fixed-size raw-data type used as the output of hash functions.
|
||||||
|
|
||||||
use std::{ops, fmt, cmp, mem};
|
use std::{ops, fmt, cmp};
|
||||||
use std::cmp::*;
|
use std::cmp::*;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
use std::hash::{Hash, Hasher, BuildHasherDefault};
|
use std::hash::{Hash, Hasher, BuildHasherDefault};
|
||||||
@ -28,7 +28,7 @@ use rustc_serialize::hex::{FromHex, FromHexError};
|
|||||||
use uint::{Uint, U256};
|
use uint::{Uint, U256};
|
||||||
|
|
||||||
/// Trait for a fixed-size byte array to be used as the output of hash functions.
|
/// Trait for a fixed-size byte array to be used as the output of hash functions.
|
||||||
pub trait FixedHash: Sized + FromStr + Default + DerefMut<Target = [u8]> {
|
pub trait FixedHash: Sized {
|
||||||
/// Create a new, zero-initialised, instance.
|
/// Create a new, zero-initialised, instance.
|
||||||
fn new() -> Self;
|
fn new() -> Self;
|
||||||
/// Synonym for `new()`. Prefer to new as it's more readable.
|
/// Synonym for `new()`. Prefer to new as it's more readable.
|
||||||
@ -45,14 +45,6 @@ pub trait FixedHash: Sized + FromStr + Default + DerefMut<Target = [u8]> {
|
|||||||
fn clone_from_slice(&mut self, src: &[u8]) -> usize;
|
fn clone_from_slice(&mut self, src: &[u8]) -> usize;
|
||||||
/// Copy the data of this object into some mutable slice of length `len()`.
|
/// Copy the data of this object into some mutable slice of length `len()`.
|
||||||
fn copy_to(&self, dest: &mut [u8]);
|
fn copy_to(&self, dest: &mut [u8]);
|
||||||
/// When interpreting self as a bloom output, augment (bit-wise OR) with the a bloomed version of `b`.
|
|
||||||
fn shift_bloomed<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash;
|
|
||||||
/// Same as `shift_bloomed` except that `self` is consumed and a new value returned.
|
|
||||||
fn with_bloomed<T>(mut self, b: &T) -> Self where T: FixedHash { self.shift_bloomed(b); self }
|
|
||||||
/// Bloom the current value using the bloom parameter `m`.
|
|
||||||
fn bloom_part<T>(&self, m: usize) -> T where T: FixedHash;
|
|
||||||
/// Check to see whether this hash, interpreted as a bloom, contains the value `b` when bloomed.
|
|
||||||
fn contains_bloomed<T>(&self, b: &T) -> bool where T: FixedHash;
|
|
||||||
/// Returns `true` if all bits set in `b` are also set in `self`.
|
/// Returns `true` if all bits set in `b` are also set in `self`.
|
||||||
fn contains<'a>(&'a self, b: &'a Self) -> bool;
|
fn contains<'a>(&'a self, b: &'a Self) -> bool;
|
||||||
/// Returns `true` if no bits are set.
|
/// Returns `true` if no bits are set.
|
||||||
@ -70,16 +62,6 @@ pub fn clean_0x(s: &str) -> &str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns log2.
|
|
||||||
pub fn log2(x: usize) -> u32 {
|
|
||||||
if x <= 1 {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let n = x.leading_zeros();
|
|
||||||
mem::size_of::<usize>() as u32 * 8 - n
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_hash {
|
macro_rules! impl_hash {
|
||||||
($from: ident, $size: expr) => {
|
($from: ident, $size: expr) => {
|
||||||
#[derive(Eq)]
|
#[derive(Eq)]
|
||||||
@ -158,54 +140,6 @@ macro_rules! impl_hash {
|
|||||||
dest[..min].copy_from_slice(&self.0[..min]);
|
dest[..min].copy_from_slice(&self.0[..min]);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
self.0 = new_self.0;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bloom_part<T>(&self, m: usize) -> T where T: FixedHash {
|
|
||||||
// numbers of bits
|
|
||||||
// TODO: move it to some constant
|
|
||||||
let p = 3;
|
|
||||||
|
|
||||||
let bloom_bits = m * 8;
|
|
||||||
let mask = bloom_bits - 1;
|
|
||||||
let bloom_bytes = (log2(bloom_bits) + 7) / 8;
|
|
||||||
|
|
||||||
// must be a power of 2
|
|
||||||
assert_eq!(m & (m - 1), 0);
|
|
||||||
// out of range
|
|
||||||
assert!(p * bloom_bytes <= $size);
|
|
||||||
|
|
||||||
// return type
|
|
||||||
let mut ret = T::new();
|
|
||||||
|
|
||||||
// 'ptr' to out slice
|
|
||||||
let mut ptr = 0;
|
|
||||||
|
|
||||||
// set p number of bits,
|
|
||||||
// p is equal 3 according to yellowpaper
|
|
||||||
for _ in 0..p {
|
|
||||||
let mut index = 0 as usize;
|
|
||||||
for _ in 0..bloom_bytes {
|
|
||||||
index = (index << 8) | self.0[ptr] as usize;
|
|
||||||
ptr += 1;
|
|
||||||
}
|
|
||||||
index &= mask;
|
|
||||||
ret[m - 1 - index / 8] |= 1 << (index % 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
fn contains_bloomed<T>(&self, b: &T) -> bool where T: FixedHash {
|
|
||||||
let bp: Self = b.bloom_part($size);
|
|
||||||
self.contains(&bp)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn contains<'a>(&'a self, b: &'a Self) -> bool {
|
fn contains<'a>(&'a self, b: &'a Self) -> bool {
|
||||||
&(b & self) == b
|
&(b & self) == b
|
||||||
}
|
}
|
||||||
@ -415,9 +349,6 @@ macro_rules! impl_hash {
|
|||||||
pub fn hex(&self) -> String {
|
pub fn hex(&self) -> String {
|
||||||
format!("{:?}", self)
|
format!("{:?}", self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct new instance equal to the bloomed value of `b`.
|
|
||||||
pub fn from_bloomed<T>(b: &T) -> Self where T: FixedHash { b.bloom_part($size) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for $from {
|
impl Default for $from {
|
||||||
@ -609,29 +540,6 @@ mod tests {
|
|||||||
assert_eq!(a | b, c);
|
assert_eq!(a | b, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[ignore]
|
|
||||||
fn shift_bloomed() {
|
|
||||||
//use sha3::Hashable;
|
|
||||||
|
|
||||||
//let bloom = H2048::from_str("00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
|
||||||
//let address = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap();
|
|
||||||
//let topic = H256::from_str("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap();
|
|
||||||
|
|
||||||
//let mut my_bloom = H2048::new();
|
|
||||||
//assert!(!my_bloom.contains_bloomed(&address.sha3()));
|
|
||||||
//assert!(!my_bloom.contains_bloomed(&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_bloomed(&topic.sha3());
|
|
||||||
//assert_eq!(my_bloom, bloom);
|
|
||||||
//assert!(my_bloom.contains_bloomed(&address.sha3()));
|
|
||||||
//assert!(my_bloom.contains_bloomed(&topic.sha3()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_and_to_address() {
|
fn from_and_to_address() {
|
||||||
let address = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap();
|
let address = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap();
|
||||||
|
145
util/src/bloom.rs
Normal file
145
util/src/bloom.rs
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Bloom operations.
|
||||||
|
|
||||||
|
use std::mem;
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
use {H64, Address, H256, H512, H520, H2048, FixedHash};
|
||||||
|
|
||||||
|
/// Returns log2.
|
||||||
|
pub fn log2(x: usize) -> u32 {
|
||||||
|
if x <= 1 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let n = x.leading_zeros();
|
||||||
|
mem::size_of::<usize>() as u32 * 8 - n
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bloom operations.
|
||||||
|
pub trait Bloomable: Sized + Default + DerefMut<Target = [u8]> {
|
||||||
|
/// When interpreting self as a bloom output, augment (bit-wise OR) with the a bloomed version of `b`.
|
||||||
|
fn shift_bloomed<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: Bloomable;
|
||||||
|
|
||||||
|
/// Same as `shift_bloomed` except that `self` is consumed and a new value returned.
|
||||||
|
fn with_bloomed<T>(mut self, b: &T) -> Self where T: Bloomable {
|
||||||
|
self.shift_bloomed(b);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct new instance equal to the bloomed value of `b`.
|
||||||
|
fn from_bloomed<T>(b: &T) -> Self where T: Bloomable;
|
||||||
|
|
||||||
|
/// Bloom the current value using the bloom parameter `m`.
|
||||||
|
fn bloom_part<T>(&self, m: usize) -> T where T: Bloomable;
|
||||||
|
|
||||||
|
/// Check to see whether this hash, interpreted as a bloom, contains the value `b` when bloomed.
|
||||||
|
fn contains_bloomed<T>(&self, b: &T) -> bool where T: Bloomable;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_bloomable_for_hash {
|
||||||
|
($name: ident, $size: expr) => {
|
||||||
|
impl Bloomable for $name {
|
||||||
|
fn shift_bloomed<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: Bloomable {
|
||||||
|
let bp: Self = b.bloom_part($size);
|
||||||
|
let new_self = &bp | self;
|
||||||
|
|
||||||
|
self.0 = new_self.0;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bloom_part<T>(&self, m: usize) -> T where T: Bloomable + Default {
|
||||||
|
// numbers of bits
|
||||||
|
// TODO: move it to some constant
|
||||||
|
let p = 3;
|
||||||
|
|
||||||
|
let bloom_bits = m * 8;
|
||||||
|
let mask = bloom_bits - 1;
|
||||||
|
let bloom_bytes = (log2(bloom_bits) + 7) / 8;
|
||||||
|
|
||||||
|
// must be a power of 2
|
||||||
|
assert_eq!(m & (m - 1), 0);
|
||||||
|
// out of range
|
||||||
|
assert!(p * bloom_bytes <= $size);
|
||||||
|
|
||||||
|
// return type
|
||||||
|
let mut ret = T::default();
|
||||||
|
|
||||||
|
// 'ptr' to out slice
|
||||||
|
let mut ptr = 0;
|
||||||
|
|
||||||
|
// set p number of bits,
|
||||||
|
// p is equal 3 according to yellowpaper
|
||||||
|
for _ in 0..p {
|
||||||
|
let mut index = 0 as usize;
|
||||||
|
for _ in 0..bloom_bytes {
|
||||||
|
index = (index << 8) | self.0[ptr] as usize;
|
||||||
|
ptr += 1;
|
||||||
|
}
|
||||||
|
index &= mask;
|
||||||
|
ret[m - 1 - index / 8] |= 1 << (index % 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn contains_bloomed<T>(&self, b: &T) -> bool where T: Bloomable {
|
||||||
|
let bp: Self = b.bloom_part($size);
|
||||||
|
self.contains(&bp)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_bloomed<T>(b: &T) -> Self where T: Bloomable {
|
||||||
|
b.bloom_part($size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_bloomable_for_hash!(H64, 8);
|
||||||
|
impl_bloomable_for_hash!(Address, 20);
|
||||||
|
impl_bloomable_for_hash!(H256, 32);
|
||||||
|
impl_bloomable_for_hash!(H512, 64);
|
||||||
|
impl_bloomable_for_hash!(H520, 65);
|
||||||
|
impl_bloomable_for_hash!(H2048, 256);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use {Address, H256, H2048};
|
||||||
|
use sha3::Hashable;
|
||||||
|
use super::Bloomable;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shift_bloomed() {
|
||||||
|
let bloom: H2048 = "00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".parse().unwrap();
|
||||||
|
let address: Address = "ef2d6d194084c2de36e0dabfce45d046b37d1106".parse().unwrap();
|
||||||
|
let topic: H256 = "02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc".parse().unwrap();
|
||||||
|
|
||||||
|
let mut my_bloom = H2048::default();
|
||||||
|
assert!(!my_bloom.contains_bloomed(&address.sha3()));
|
||||||
|
assert!(!my_bloom.contains_bloomed(&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_bloomed(&topic.sha3());
|
||||||
|
assert_eq!(my_bloom, bloom);
|
||||||
|
assert!(my_bloom.contains_bloomed(&address.sha3()));
|
||||||
|
assert!(my_bloom.contains_bloomed(&topic.sha3()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -117,6 +117,7 @@ pub extern crate using_queue;
|
|||||||
pub extern crate table;
|
pub extern crate table;
|
||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
|
|
||||||
|
pub mod bloom;
|
||||||
pub mod standard;
|
pub mod standard;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod from_json;
|
pub mod from_json;
|
||||||
|
Loading…
Reference in New Issue
Block a user