Remove serialize crate (replaced by serde) and use impl-serde in ethbloom
This commit is contained in:
parent
9a698b8272
commit
1564dc1f63
|
@ -11,9 +11,8 @@ repository = "https://github.com/paritytech/primitives"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tiny-keccak = "1.4"
|
tiny-keccak = "1.4"
|
||||||
crunchy = { version = "0.2.1", default-features = false, features = ["limit_256"] }
|
crunchy = { version = "0.2.1", default-features = false, features = ["limit_256"] }
|
||||||
fixed-hash = { version = "0.3", default_features = false }
|
fixed-hash = { version = "0.3", default-features = false }
|
||||||
ethereum-types-serialize = { version = "0.2.1", path = "../serialize", optional = true }
|
impl-serde = { version = "0.1", default-features = false, optional = true }
|
||||||
serde = { version = "1.0", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = { version = "0.4" }
|
rand = { version = "0.4" }
|
||||||
|
@ -23,4 +22,4 @@ hex-literal = "0.1.1"
|
||||||
default = ["std", "heapsize", "serialize", "fixed-hash/libc", "fixed-hash/rustc-hex"]
|
default = ["std", "heapsize", "serialize", "fixed-hash/libc", "fixed-hash/rustc-hex"]
|
||||||
std = ["fixed-hash/std", "crunchy/std"]
|
std = ["fixed-hash/std", "crunchy/std"]
|
||||||
heapsize = ["fixed-hash/heapsize"]
|
heapsize = ["fixed-hash/heapsize"]
|
||||||
serialize = ["std", "ethereum-types-serialize", "serde"]
|
serialize = ["std", "impl-serde"]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! extern crate ethbloom;
|
//! extern crate ethbloom;
|
||||||
//! #[macro_use] extern crate hex_literal;
|
//! #[macro_use] extern crate hex_literal;
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
//! ).unwrap();
|
//! ).unwrap();
|
||||||
//! let address = hex!("ef2d6d194084c2de36e0dabfce45d046b37d1106");
|
//! let address = hex!("ef2d6d194084c2de36e0dabfce45d046b37d1106");
|
||||||
//! let topic = hex!("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc");
|
//! let topic = hex!("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc");
|
||||||
//!
|
//!
|
||||||
//! let mut my_bloom = Bloom::default();
|
//! let mut my_bloom = Bloom::default();
|
||||||
//! assert!(!my_bloom.contains_input(Input::Raw(&address)));
|
//! assert!(!my_bloom.contains_input(Input::Raw(&address)));
|
||||||
//! assert!(!my_bloom.contains_input(Input::Raw(&topic)));
|
//! assert!(!my_bloom.contains_input(Input::Raw(&topic)));
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
//! my_bloom.accrue(Input::Raw(&address));
|
//! my_bloom.accrue(Input::Raw(&address));
|
||||||
//! assert!(my_bloom.contains_input(Input::Raw(&address)));
|
//! assert!(my_bloom.contains_input(Input::Raw(&address)));
|
||||||
//! assert!(!my_bloom.contains_input(Input::Raw(&topic)));
|
//! assert!(!my_bloom.contains_input(Input::Raw(&topic)));
|
||||||
//!
|
//!
|
||||||
//! my_bloom.accrue(Input::Raw(&topic));
|
//! my_bloom.accrue(Input::Raw(&topic));
|
||||||
//! assert!(my_bloom.contains_input(Input::Raw(&address)));
|
//! assert!(my_bloom.contains_input(Input::Raw(&address)));
|
||||||
//! assert!(my_bloom.contains_input(Input::Raw(&topic)));
|
//! assert!(my_bloom.contains_input(Input::Raw(&topic)));
|
||||||
|
@ -56,18 +56,13 @@ extern crate crunchy;
|
||||||
extern crate fixed_hash;
|
extern crate fixed_hash;
|
||||||
|
|
||||||
#[cfg(feature="serialize")]
|
#[cfg(feature="serialize")]
|
||||||
extern crate ethereum_types_serialize;
|
#[macro_use]
|
||||||
|
extern crate impl_serde;
|
||||||
#[cfg(feature="serialize")]
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate hex_literal;
|
extern crate hex_literal;
|
||||||
|
|
||||||
#[cfg(feature="serialize")]
|
|
||||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
|
||||||
|
|
||||||
use core::{ops, mem};
|
use core::{ops, mem};
|
||||||
use tiny_keccak::keccak256;
|
use tiny_keccak::keccak256;
|
||||||
|
|
||||||
|
@ -227,7 +222,7 @@ impl<'a> BloomRef<'a> {
|
||||||
let bloom: Bloom = input.into();
|
let bloom: Bloom = input.into();
|
||||||
self.contains_bloom(&bloom)
|
self.contains_bloom(&bloom)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_bloom<'b, B>(&self, bloom: B) -> bool where BloomRef<'b>: From<B> {
|
pub fn contains_bloom<'b, B>(&self, bloom: B) -> bool where BloomRef<'b>: From<B> {
|
||||||
let bloom_ref: BloomRef = bloom.into();
|
let bloom_ref: BloomRef = bloom.into();
|
||||||
assert_eq!(self.0.len(), BLOOM_SIZE);
|
assert_eq!(self.0.len(), BLOOM_SIZE);
|
||||||
|
@ -259,22 +254,8 @@ impl<'a> From<&'a Bloom> for BloomRef<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
impl Serialize for Bloom {
|
impl_fixed_hash_serde!(Bloom, BLOOM_SIZE);
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
|
||||||
let mut slice = [0u8; 2 + 2 * BLOOM_SIZE];
|
|
||||||
ethereum_types_serialize::serialize(&mut slice, &self.0, serializer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature="serialize")]
|
|
||||||
impl<'de> Deserialize<'de> for Bloom {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
|
|
||||||
let mut bytes = [0; BLOOM_SIZE];
|
|
||||||
ethereum_types_serialize::deserialize_check_len(deserializer, ethereum_types_serialize::ExpectedLen::Exact(&mut bytes))?;
|
|
||||||
Ok(Bloom(bytes))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "ethereum-types-serialize"
|
|
||||||
version = "0.2.1"
|
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
|
||||||
license = "MIT"
|
|
||||||
homepage = "https://github.com/paritytech/primitives"
|
|
||||||
description = "Ethereum types"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
serde = "1.0"
|
|
|
@ -1,144 +0,0 @@
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use serde::{de, Serializer, Deserializer};
|
|
||||||
|
|
||||||
static CHARS: &'static[u8] = b"0123456789abcdef";
|
|
||||||
|
|
||||||
fn to_hex<'a>(v: &'a mut [u8], bytes: &[u8], skip_leading_zero: bool) -> &'a str {
|
|
||||||
assert!(v.len() > 1 + bytes.len() * 2);
|
|
||||||
|
|
||||||
v[0] = b'0';
|
|
||||||
v[1] = b'x';
|
|
||||||
|
|
||||||
let mut idx = 2;
|
|
||||||
let first_nibble = bytes[0] >> 4;
|
|
||||||
if first_nibble != 0 || !skip_leading_zero {
|
|
||||||
v[idx] = CHARS[first_nibble as usize];
|
|
||||||
idx += 1;
|
|
||||||
}
|
|
||||||
v[idx] = CHARS[(bytes[0] & 0xf) as usize];
|
|
||||||
idx += 1;
|
|
||||||
|
|
||||||
for &byte in bytes.iter().skip(1) {
|
|
||||||
v[idx] = CHARS[(byte >> 4) as usize];
|
|
||||||
v[idx + 1] = CHARS[(byte & 0xf) as usize];
|
|
||||||
idx += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
::std::str::from_utf8(&v[0..idx]).expect("All characters are coming from CHARS")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serializes a slice of bytes.
|
|
||||||
pub fn serialize<S>(slice: &mut [u8], bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
serializer.serialize_str(to_hex(slice, bytes, false))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serialize a slice of bytes as uint.
|
|
||||||
///
|
|
||||||
/// The representation will have all leading zeros trimmed.
|
|
||||||
pub fn serialize_uint<S>(slice: &mut [u8], bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
let non_zero = bytes.iter().take_while(|b| **b == 0).count();
|
|
||||||
let bytes = &bytes[non_zero..];
|
|
||||||
if bytes.is_empty() {
|
|
||||||
return serializer.serialize_str("0x0");
|
|
||||||
}
|
|
||||||
|
|
||||||
serializer.serialize_str(to_hex(slice, bytes, true))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Expected length of bytes vector.
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
pub enum ExpectedLen<'a> {
|
|
||||||
/// Exact length in bytes.
|
|
||||||
Exact(&'a mut [u8]),
|
|
||||||
/// A bytes length between (min; slice.len()].
|
|
||||||
Between(usize, &'a mut [u8]),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> fmt::Display for ExpectedLen<'a> {
|
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
ExpectedLen::Exact(ref v) => write!(fmt, "length of {}", v.len() * 2),
|
|
||||||
ExpectedLen::Between(min, ref v) => write!(fmt, "length between ({}; {}]", min * 2, v.len() * 2),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deserialize into vector of bytes with additional size check.
|
|
||||||
/// Returns number of bytes written.
|
|
||||||
pub fn deserialize_check_len<'a, 'de, D>(deserializer: D, len: ExpectedLen<'a>) -> Result<usize, D::Error> where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
struct Visitor<'a> {
|
|
||||||
len: ExpectedLen<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b> de::Visitor<'b> for Visitor<'a> {
|
|
||||||
type Value = usize;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(formatter, "a 0x-prefixed hex string with {}", self.len)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
|
|
||||||
if v.len() < 2 || &v[0..2] != "0x" {
|
|
||||||
return Err(E::custom("prefix is missing"))
|
|
||||||
}
|
|
||||||
|
|
||||||
let is_len_valid = match self.len {
|
|
||||||
ExpectedLen::Exact(ref slice) => v.len() == 2 * slice.len() + 2,
|
|
||||||
ExpectedLen::Between(min, ref slice) => v.len() <= 2 * slice.len() + 2 && v.len() > 2 * min + 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
if !is_len_valid {
|
|
||||||
return Err(E::invalid_length(v.len() - 2, &self))
|
|
||||||
}
|
|
||||||
|
|
||||||
let bytes = match self.len {
|
|
||||||
ExpectedLen::Exact(slice) => slice,
|
|
||||||
ExpectedLen::Between(_, slice) => slice,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut modulus = v.len() % 2;
|
|
||||||
let mut buf = 0;
|
|
||||||
let mut pos = 0;
|
|
||||||
for (idx, byte) in v.bytes().enumerate().skip(2) {
|
|
||||||
buf <<= 4;
|
|
||||||
|
|
||||||
match byte {
|
|
||||||
b'A'...b'F' => buf |= byte - b'A' + 10,
|
|
||||||
b'a'...b'f' => buf |= byte - b'a' + 10,
|
|
||||||
b'0'...b'9' => buf |= byte - b'0',
|
|
||||||
b' '|b'\r'|b'\n'|b'\t' => {
|
|
||||||
buf >>= 4;
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let ch = v[idx..].chars().next().unwrap();
|
|
||||||
return Err(E::custom(&format!("invalid hex character: {}, at {}", ch, idx)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
modulus += 1;
|
|
||||||
if modulus == 2 {
|
|
||||||
modulus = 0;
|
|
||||||
bytes[pos] = buf;
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
|
|
||||||
self.visit_str(&v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.deserialize_str(Visitor { len })
|
|
||||||
}
|
|
Loading…
Reference in New Issue