From f5c4abd0f39dd658e42c25fa3fa3e7e7e150a92e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 7 Jan 2019 15:54:59 +0100 Subject: [PATCH] Use primitive-types crate to unify Parity Ethereum primitives (#1187) * Unify primitive types with parity-ethereum * Update primtive-types patch version * Fix merge issue * Add necessary fixed-hash features * Fix node-primitives compile * Reexport impl_serde::serialize as bytes to avoid path changes --- substrate/Cargo.lock | 40 ++++- substrate/core/primitives/Cargo.toml | 19 +-- substrate/core/primitives/src/authority_id.rs | 1 - substrate/core/primitives/src/bytes.rs | 158 ------------------ substrate/core/primitives/src/hash.rs | 60 +------ substrate/core/primitives/src/hexdisplay.rs | 3 +- substrate/core/primitives/src/lib.rs | 14 +- substrate/core/primitives/src/uint.rs | 50 +----- 8 files changed, 55 insertions(+), 290 deletions(-) delete mode 100644 substrate/core/primitives/src/bytes.rs diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index dfab26f9a2..749a8764f7 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -999,6 +999,23 @@ dependencies = [ "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "impl-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "impl-serde" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "indexmap" version = "1.0.2" @@ -2177,6 +2194,18 @@ dependencies = [ "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "primitive-types" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro-hack" version = "0.4.1" @@ -3621,15 +3650,15 @@ dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3637,7 +3666,6 @@ dependencies = [ "sr-std 0.1.0", "substrate-serializer 0.1.0", "twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4353,7 +4381,7 @@ name = "twox-hash" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4378,6 +4406,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4800,6 +4829,8 @@ dependencies = [ "checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c" "checksum hyper 0.12.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c49a75385d35ff5e9202755f09beb0b878a05c4c363fcc52b23eeb5dcb6782cc" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum impl-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c88568d828291c50eed30cd7fb9f8e688ad0013620186fa3e777b9f206c79f2" +"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" @@ -4904,6 +4935,7 @@ dependencies = [ "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum pretty_assertions 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28ea5118e2f41bfbc974b28d88c07621befd1fa5d6ec23549be96302a1a59dd2" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" +"checksum primitive-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f47c18b4601125931d69fcf7b000c2c16a304e4f84d58218d6470b4502e00b58" "checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" "checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" diff --git a/substrate/core/primitives/Cargo.toml b/substrate/core/primitives/Cargo.toml index 1489b046ba..72fd73f5b4 100644 --- a/substrate/core/primitives/Cargo.toml +++ b/substrate/core/primitives/Cargo.toml @@ -4,17 +4,16 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -crunchy = { version = "0.2", default-features = false } sr-std = { path = "../sr-std", default-features = false } parity-codec = { version = "2.1", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } -fixed-hash = { version = "0.3.0", default-features = false } rustc-hex = { version = "2.0", default-features = false } serde = { version = "1.0", default-features = false } serde_derive = { version = "1.0", optional = true } -uint = { version = "0.5.0-beta", default-features = false } twox-hash = { version = "1.1.0", optional = true } byteorder = { version = "1.1", default-features = false } +primitive-types = { version = "0.1", default-features = false, features = ["codec"] } +impl-serde = { version = "0.1", optional = true } wasmi = { version = "0.4.2", optional = true } hash-db = { git = "https://github.com/paritytech/trie", default-features = false } hash256-std-hasher = { git = "https://github.com/paritytech/trie", default-features = false } @@ -32,14 +31,14 @@ heapsize = "0.4" [features] default = ["std"] std = [ - "crunchy/std", "wasmi", - "uint/std", - "fixed-hash/std", - "fixed-hash/heapsize", - "fixed-hash/byteorder", - "fixed-hash/rustc-hex", - "fixed-hash/libc", + "primitive-types/std", + "primitive-types/serde", + "primitive-types/heapsize", + "primitive-types/byteorder", + "primitive-types/rustc-hex", + "primitive-types/libc", + "impl-serde", "parity-codec/std", "hash256-std-hasher/std", "hash-db/std", diff --git a/substrate/core/primitives/src/authority_id.rs b/substrate/core/primitives/src/authority_id.rs index 9f5e3c26ac..9a6abf1f03 100644 --- a/substrate/core/primitives/src/authority_id.rs +++ b/substrate/core/primitives/src/authority_id.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . - #[cfg(feature = "std")] use serde::{Serialize, Serializer, Deserialize, Deserializer}; use H256; diff --git a/substrate/core/primitives/src/bytes.rs b/substrate/core/primitives/src/bytes.rs deleted file mode 100644 index ea375a2530..0000000000 --- a/substrate/core/primitives/src/bytes.rs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2017-2018 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Simple type for representing Vec with regards to serde. - -use core::fmt; - -use serde::{de, Serializer, Deserializer}; - -#[cfg(not(feature = "std"))] -mod alloc_types { - pub use ::alloc::string::String; - pub use ::alloc::vec::Vec; -} - -#[cfg(feature = "std")] -mod alloc_types { - pub use ::std::vec::Vec; - pub use ::std::string::String; -} - -pub use self::alloc_types::*; - -/// Serializes a slice of bytes. -pub fn serialize(bytes: &[u8], serializer: S) -> Result where - S: Serializer, -{ - let hex: String = ::rustc_hex::ToHex::to_hex(bytes); - serializer.serialize_str(&format!("0x{}", hex)) -} - -/// Serialize a slice of bytes as uint. -/// -/// The representation will have all leading zeros trimmed. -pub fn serialize_uint(bytes: &[u8], serializer: S) -> Result 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"); - } - - let hex: String = ::rustc_hex::ToHex::to_hex(bytes); - let has_leading_zero = !hex.is_empty() && &hex[0..1] == "0"; - serializer.serialize_str( - &format!("0x{}", if has_leading_zero { &hex[1..] } else { &hex }) - ) -} - -/// Expected length of bytes vector. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] -pub enum ExpectedLen { - /// Any length in bytes. - #[cfg_attr(not(feature = "std"), allow(unused))] - Any, - /// Exact length in bytes. - Exact(usize), - /// A bytes length between (min; max]. - Between(usize, usize), -} - -impl fmt::Display for ExpectedLen { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - ExpectedLen::Any => write!(fmt, "even length"), - ExpectedLen::Exact(v) => write!(fmt, "length of {}", v * 2), - ExpectedLen::Between(min, max) => write!(fmt, "length between ({}; {}]", min * 2, max * 2), - } - } -} - -/// Deserialize into vector of bytes. -#[cfg(feature = "std")] -pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where - D: Deserializer<'de>, -{ - deserialize_check_len(deserializer, ExpectedLen::Any) -} - -/// Deserialize into vector of bytes with additional size check. -pub fn deserialize_check_len<'de, D>(deserializer: D, len: ExpectedLen) -> Result, D::Error> where - D: Deserializer<'de>, -{ - struct Visitor { - len: ExpectedLen, - } - - impl<'a> de::Visitor<'a> for Visitor { - type Value = Vec; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "a 0x-prefixed hex string with {}", self.len) - } - - fn visit_str(self, v: &str) -> Result { - if v.len() < 2 || &v[0..2] != "0x" { - return Err(E::custom("prefix is missing")) - } - - let is_len_valid = match self.len { - // just make sure that we have all nibbles - ExpectedLen::Any => v.len() % 2 == 0, - ExpectedLen::Exact(len) => v.len() == 2 * len + 2, - ExpectedLen::Between(min, max) => v.len() <= 2 * max + 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::Between(..) if v.len() % 2 != 0 => { - ::rustc_hex::FromHex::from_hex(&*format!("0{}", &v[2..])) - }, - _ => ::rustc_hex::FromHex::from_hex(&v[2..]) - }; - - #[cfg(feature = "std")] - fn format_err(e: ::rustc_hex::FromHexError) -> String { - format!("invalid hex value: {:?}", e) - } - - #[cfg(not(feature = "std"))] - fn format_err(e: ::rustc_hex::FromHexError) -> String { - match e { - ::rustc_hex::InvalidHexLength => format!("invalid hex value: invalid length"), - ::rustc_hex::InvalidHexCharacter(c, p) => - format!("invalid hex value: invalid character {} at position {}", c, p), - } - } - - bytes.map_err(|e| E::custom(format_err(e))) - } - - #[cfg(feature = "std")] - fn visit_string(self, v: String) -> Result { - self.visit_str(&v) - } - } - // TODO [ToDr] Use raw bytes if we switch to RLP / binencoding - // (visit_bytes, visit_bytes_buf) - deserializer.deserialize_str(Visitor { len }) -} diff --git a/substrate/core/primitives/src/hash.rs b/substrate/core/primitives/src/hash.rs index 8d04df2684..98a906861f 100644 --- a/substrate/core/primitives/src/hash.rs +++ b/substrate/core/primitives/src/hash.rs @@ -16,65 +16,7 @@ //! A fixed hash type. -#[cfg(feature = "std")] -use serde::{Serialize, Serializer, Deserialize, Deserializer}; - -#[cfg(feature = "std")] -use bytes; - -macro_rules! impl_rest { - ($name: ident, $len: expr) => { - #[cfg(feature = "std")] - impl Serialize for $name { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - bytes::serialize(&self.0, serializer) - } - } - - #[cfg(feature = "std")] - impl<'de> Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - bytes::deserialize_check_len(deserializer, bytes::ExpectedLen::Exact($len)) - .map(|x| $name::from_slice(&x)) - } - } - - impl ::codec::Encode for $name { - fn using_encoded R>(&self, f: F) -> R { - self.0.using_encoded(f) - } - } - impl ::codec::Decode for $name { - fn decode(input: &mut I) -> Option { - <[u8; $len] as ::codec::Decode>::decode(input).map($name) - } - } - - #[cfg(feature = "std")] - impl From for $name { - fn from(val: u64) -> Self { - Self::from_low_u64_be(val) - } - } - } -} - -construct_fixed_hash!{ - /// Fixed-size uninterpreted hash type with 20 bytes (160 bits) size. - pub struct H160(20); -} -construct_fixed_hash!{ - /// Fixed-size uninterpreted hash type with 32 bytes (256 bits) size. - pub struct H256(32); -} -construct_fixed_hash!{ - /// Fixed-size uninterpreted hash type with 64 bytes (512 bits) size. - pub struct H512(64); -} - -impl_rest!(H160, 20); -impl_rest!(H256, 32); -impl_rest!(H512, 64); +pub use primitive_types::{H160, H256, H512}; /// Hash conversion. Used to convert between unbound associated hash types in traits, /// implemented by the same hash type. diff --git a/substrate/core/primitives/src/hexdisplay.rs b/substrate/core/primitives/src/hexdisplay.rs index f02b0f19b7..b202fdf2e3 100644 --- a/substrate/core/primitives/src/hexdisplay.rs +++ b/substrate/core/primitives/src/hexdisplay.rs @@ -57,7 +57,7 @@ impl AsBytesRef for [u8] { fn as_bytes_ref(&self) -> &[u8] { &self } } -impl AsBytesRef for ::bytes::Vec { +impl AsBytesRef for Vec { fn as_bytes_ref(&self) -> &[u8] { &self } } @@ -91,4 +91,3 @@ pub fn ascii_format(asciish: &[u8]) -> String { } r } - diff --git a/substrate/core/primitives/src/lib.rs b/substrate/core/primitives/src/lib.rs index 1bbfaafb24..83f6a8d0bc 100644 --- a/substrate/core/primitives/src/lib.rs +++ b/substrate/core/primitives/src/lib.rs @@ -21,12 +21,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(alloc))] -#[macro_use] -extern crate crunchy; -#[macro_use] -extern crate fixed_hash; -#[macro_use] -extern crate uint as uint_crate; +extern crate primitive_types; #[macro_use] extern crate parity_codec_derive; @@ -51,6 +46,10 @@ extern crate untrusted; #[macro_use] extern crate hex_literal; +#[cfg(feature = "std")] +#[macro_use] +extern crate impl_serde; + #[cfg(feature = "std")] #[macro_use] extern crate serde_derive; @@ -84,7 +83,8 @@ use rstd::prelude::*; use rstd::ops::Deref; #[cfg(feature = "std")] -pub mod bytes; +pub use impl_serde::serialize as bytes; + #[cfg(feature = "std")] pub mod hashing; #[cfg(feature = "std")] diff --git a/substrate/core/primitives/src/uint.rs b/substrate/core/primitives/src/uint.rs index 4727ed54bd..0d46e81eff 100644 --- a/substrate/core/primitives/src/uint.rs +++ b/substrate/core/primitives/src/uint.rs @@ -16,55 +16,7 @@ //! An unsigned fixed-size integer. -#[cfg(feature = "std")] -use serde::{Serialize, Serializer, Deserialize, Deserializer}; - -#[cfg(feature = "std")] -use bytes; - -macro_rules! impl_serde { - ($name: ident, $len: expr) => { - #[cfg(feature = "std")] - impl Serialize for $name { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - let mut bytes = [0u8; $len * 8]; - self.to_big_endian(&mut bytes); - bytes::serialize_uint(&bytes, serializer) - } - } - - #[cfg(feature = "std")] - impl<'de> Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - bytes::deserialize_check_len(deserializer, bytes::ExpectedLen::Between(0, $len * 8)) - .map(|x| (&*x).into()) - } - } - } -} - -macro_rules! impl_codec { - ($name: ident, $len: expr) => { - impl ::codec::Encode for $name { - fn using_encoded R>(&self, f: F) -> R { - let mut bytes = [0u8; $len * 8]; - self.to_little_endian(&mut bytes); - bytes.using_encoded(f) - } - } - - impl ::codec::Decode for $name { - fn decode(input: &mut I) -> Option { - <[u8; $len * 8] as ::codec::Decode>::decode(input) - .map(|b| $name::from_little_endian(&b)) - } - } - } -} - -construct_uint!(U256, 4); -impl_serde!(U256, 4); -impl_codec!(U256, 4); +pub use primitive_types::U256; #[cfg(test)] mod tests {