From 62b9c1b14f8dbd0715e018a11355129eb8fc258c Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 5 Jul 2016 15:16:27 +0200 Subject: [PATCH] util cleanup (#1474) * removed old json-tests * simplify folds in triehash.rs * removed unused json_aid * removed unused squeeze.rs * json branching tests for trie * loading trie consensus tests --- Cargo.lock | 9 - ethcore/src/json_tests/mod.rs | 1 + ethcore/src/json_tests/trie.rs | 69 +++ json/src/bytes.rs | 43 +- json/src/lib.rs.in | 1 + json/src/trie/input.rs | 155 ++++++ .../src/util.rs => json/src/trie/mod.rs | 15 +- json/src/trie/test.rs | 43 ++ json/src/trie/trie.rs | 30 + util/Cargo.toml | 1 - util/json-tests/Cargo.toml | 8 - util/json-tests/README.md | 15 - util/json-tests/json/.DS_Store | Bin 6148 -> 0 bytes util/json-tests/json/rlp/README.md | 39 -- .../json/rlp/stream/bytestring0.json | 10 - .../json/rlp/stream/bytestring1.json | 10 - .../json/rlp/stream/bytestring7.json | 10 - util/json-tests/json/rlp/stream/catdog.json | 10 - util/json-tests/json/rlp/stream/empty.json | 9 - .../json/rlp/stream/empty_lists.json | 38 -- util/json-tests/json/rlp/stream/integer.json | 10 - .../json/rlp/stream/list_of_empty_data.json | 22 - .../json/rlp/stream/list_of_empty_data2.json | 19 - util/json-tests/json/rlp/stream/longlist.json | 521 ------------------ .../json/rlp/stream/longstring.json | 10 - util/json-tests/json/trie/README.md | 35 -- util/json-tests/json/trie/basic.json | 11 - util/json-tests/json/trie/branching.json | 229 -------- util/json-tests/json/trie/dogs.json | 21 - util/json-tests/json/trie/empty.json | 4 - util/json-tests/json/trie/empty_values.json | 44 -- util/json-tests/json/trie/foo.json | 16 - util/json-tests/json/trie/jeff.json | 58 -- util/json-tests/src/lib.rs | 82 --- util/json-tests/src/rlp.rs | 68 --- util/json-tests/src/trie.rs | 105 ---- util/src/json_aid.rs | 154 ------ util/src/lib.rs | 4 - util/src/rlp/tests.rs | 23 - util/src/squeeze.rs | 84 --- util/src/trie/triedbmut.rs | 90 ++- util/src/triehash.rs | 37 +- 42 files changed, 425 insertions(+), 1738 deletions(-) create mode 100644 ethcore/src/json_tests/trie.rs create mode 100644 json/src/trie/input.rs rename util/json-tests/src/util.rs => json/src/trie/mod.rs (80%) create mode 100644 json/src/trie/test.rs create mode 100644 json/src/trie/trie.rs delete mode 100644 util/json-tests/Cargo.toml delete mode 100644 util/json-tests/README.md delete mode 100644 util/json-tests/json/.DS_Store delete mode 100644 util/json-tests/json/rlp/README.md delete mode 100644 util/json-tests/json/rlp/stream/bytestring0.json delete mode 100644 util/json-tests/json/rlp/stream/bytestring1.json delete mode 100644 util/json-tests/json/rlp/stream/bytestring7.json delete mode 100644 util/json-tests/json/rlp/stream/catdog.json delete mode 100644 util/json-tests/json/rlp/stream/empty.json delete mode 100644 util/json-tests/json/rlp/stream/empty_lists.json delete mode 100644 util/json-tests/json/rlp/stream/integer.json delete mode 100644 util/json-tests/json/rlp/stream/list_of_empty_data.json delete mode 100644 util/json-tests/json/rlp/stream/list_of_empty_data2.json delete mode 100644 util/json-tests/json/rlp/stream/longlist.json delete mode 100644 util/json-tests/json/rlp/stream/longstring.json delete mode 100644 util/json-tests/json/trie/README.md delete mode 100644 util/json-tests/json/trie/basic.json delete mode 100644 util/json-tests/json/trie/branching.json delete mode 100644 util/json-tests/json/trie/dogs.json delete mode 100644 util/json-tests/json/trie/empty.json delete mode 100644 util/json-tests/json/trie/empty_values.json delete mode 100644 util/json-tests/json/trie/foo.json delete mode 100644 util/json-tests/json/trie/jeff.json delete mode 100644 util/json-tests/src/lib.rs delete mode 100644 util/json-tests/src/rlp.rs delete mode 100644 util/json-tests/src/trie.rs delete mode 100644 util/src/json_aid.rs delete mode 100644 util/src/squeeze.rs diff --git a/Cargo.lock b/Cargo.lock index 5071da96b..703935bff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -390,7 +390,6 @@ dependencies = [ "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "igd 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "json-tests 0.1.0", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -609,14 +608,6 @@ dependencies = [ "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "json-tests" -version = "0.1.0" -dependencies = [ - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "jsonrpc-core" version = "2.0.7" diff --git a/ethcore/src/json_tests/mod.rs b/ethcore/src/json_tests/mod.rs index df67de76d..841db229e 100644 --- a/ethcore/src/json_tests/mod.rs +++ b/ethcore/src/json_tests/mod.rs @@ -23,3 +23,4 @@ mod state; mod chain; mod homestead_state; mod homestead_chain; +mod trie; diff --git a/ethcore/src/json_tests/trie.rs b/ethcore/src/json_tests/trie.rs new file mode 100644 index 000000000..2d23ff7d2 --- /dev/null +++ b/ethcore/src/json_tests/trie.rs @@ -0,0 +1,69 @@ +// 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 . + +use ethjson; +use util::{H256, MemoryDB, TrieMut, TrieSpec, TrieFactory}; + +fn test_trie(json: &[u8], trie: TrieSpec) -> Vec { + let tests = ethjson::trie::Test::load(json).unwrap(); + let factory = TrieFactory::new(trie); + let mut result = vec![]; + + for (name, test) in tests.into_iter() { + let mut memdb = MemoryDB::new(); + let mut root = H256::default(); + let mut t = factory.create(&mut memdb, &mut root); + + for (key, value) in test.input.data.into_iter() { + let key: Vec = key.into(); + let value: Vec = value.map_or_else(Vec::new, Into::into); + t.insert(&key, &value); + } + + if *t.root() != test.root.into() { + result.push(format!("Trie test '{:?}' failed.", name)); + } + } + + for i in &result { + println!("FAILED: {}", i); + } + + result +} + +mod generic { + use util::TrieSpec; + + fn do_json_test(json: &[u8]) -> Vec { + super::test_trie(json, TrieSpec::Generic) + } + + declare_test!{TrieTests_trietest, "TrieTests/trietest"} + declare_test!{TrieTests_trieanyorder, "TrieTests/trieanyorder"} +} + +mod secure { + use util::TrieSpec; + + fn do_json_test(json: &[u8]) -> Vec { + super::test_trie(json, TrieSpec::Secure) + } + + declare_test!{TrieTests_hex_encoded_secure, "TrieTests/hex_encoded_securetrie_test"} + declare_test!{TrieTests_trietest_secure, "TrieTests/trietest_secureTrie"} + declare_test!{TrieTests_trieanyorder_secure, "TrieTests/trieanyorder_secureTrie"} +} diff --git a/json/src/bytes.rs b/json/src/bytes.rs index 18dc73844..7741b8d3b 100644 --- a/json/src/bytes.rs +++ b/json/src/bytes.rs @@ -16,15 +16,23 @@ //! Lenient bytes json deserialization for test json files. +use std::str::FromStr; +use std::ops::Deref; use rustc_serialize::hex::FromHex; use serde::{Deserialize, Deserializer, Error}; use serde::de::Visitor; -use std::ops::Deref; /// Lenient bytes json deserialization for test json files. -#[derive(Default, Debug, PartialEq, Clone)] +#[derive(Default, Debug, PartialEq, Eq, Clone, PartialOrd, Ord)] pub struct Bytes(Vec); +impl Bytes { + /// Creates bytes struct. + pub fn new(v: Vec) -> Self { + Bytes(v) + } +} + impl Into> for Bytes { fn into(self) -> Vec { self.0 @@ -39,6 +47,25 @@ impl Deref for Bytes { } } +impl FromStr for Bytes { + type Err = String; + + fn from_str(value: &str) -> Result { + let v = match value.len() { + 0 => vec![], + 2 if value.starts_with("0x") => vec![], + _ if value.starts_with("0x") && value.len() % 2 == 1 => { + let v = "0".to_owned() + &value[2..]; + FromHex::from_hex(v.as_ref() as &str).unwrap_or(vec![]), + }, + _ if value.starts_with("0x") => FromHex::from_hex(&value[2..]).unwrap_or(vec![]), + _ => FromHex::from_hex(value).unwrap_or(vec![]), + }; + + Ok(Bytes(v)) + } +} + impl Deserialize for Bytes { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer { @@ -52,17 +79,7 @@ impl Visitor for BytesVisitor { type Value = Bytes; fn visit_str(&mut self, value: &str) -> Result where E: Error { - let v = match value.len() { - 0 => vec![], - 2 if value.starts_with("0x") => vec![], - _ if value.starts_with("0x") && value.len() % 2 == 1 => { - let v = "0".to_owned() + &value[2..]; - FromHex::from_hex(v.as_ref() as &str).unwrap_or(vec![]), - }, - _ if value.starts_with("0x") => FromHex::from_hex(&value[2..]).unwrap_or(vec![]), - _ => FromHex::from_hex(value).unwrap_or(vec![]), - }; - Ok(Bytes(v)) + Bytes::from_str(value).map_err(Error::custom) } fn visit_string(&mut self, value: String) -> Result where E: Error { diff --git a/json/src/lib.rs.in b/json/src/lib.rs.in index 73adaf07a..541629305 100644 --- a/json/src/lib.rs.in +++ b/json/src/lib.rs.in @@ -24,6 +24,7 @@ pub mod uint; pub mod bytes; pub mod blockchain; pub mod spec; +pub mod trie; pub mod vm; pub mod maybe; pub mod state; diff --git a/json/src/trie/input.rs b/json/src/trie/input.rs new file mode 100644 index 000000000..326f42dba --- /dev/null +++ b/json/src/trie/input.rs @@ -0,0 +1,155 @@ +// 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 . + +//! Trie test input deserialization. + +use std::collections::BTreeMap; +use std::str::FromStr; +use bytes::Bytes; +use serde::{Deserialize, Deserializer, Error}; +use serde::de::{Visitor, MapVisitor, SeqVisitor}; + +/// Trie test input. +#[derive(Debug, PartialEq)] +pub struct Input { + /// Input params. + pub data: BTreeMap>, +} + +impl Deserialize for Input { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer + { + deserializer.deserialize(InputVisitor) + } +} + +struct InputVisitor; + +impl Visitor for InputVisitor { + type Value = Input; + + fn visit_map(&mut self, mut visitor: V) -> Result where V: MapVisitor { + let mut result = BTreeMap::new(); + + loop { + let key_str: Option = try!(visitor.visit_key()); + let key = match key_str { + Some(ref k) if k.starts_with("0x") => try!(Bytes::from_str(k).map_err(Error::custom)), + Some(k) => Bytes::new(k.into_bytes()), + None => { break; } + }; + + let val_str: Option = try!(visitor.visit_value()); + let val = match val_str { + Some(ref v) if v.starts_with("0x") => Some(try!(Bytes::from_str(v).map_err(Error::custom))), + Some(v) => Some(Bytes::new(v.into_bytes())), + None => None, + }; + + result.insert(key, val); + } + + try!(visitor.end()); + + let input = Input { + data: result + }; + + Ok(input) + } + + fn visit_seq(&mut self, mut visitor: V) -> Result where V: SeqVisitor { + let mut result = BTreeMap::new(); + + loop { + let keyval: Option>> = try!(visitor.visit()); + let keyval = match keyval { + Some(k) => k, + _ => { break; }, + }; + + if keyval.len() != 2 { + return Err(Error::custom("Invalid key value pair.")); + } + + let ref key_str: Option = keyval[0]; + let ref val_str: Option = keyval[1]; + + let key = match *key_str { + Some(ref k) if k.starts_with("0x") => try!(Bytes::from_str(k).map_err(Error::custom)), + Some(ref k) => Bytes::new(k.clone().into_bytes()), + None => { break; } + }; + + let val = match *val_str { + Some(ref v) if v.starts_with("0x") => Some(try!(Bytes::from_str(v).map_err(Error::custom))), + Some(ref v) => Some(Bytes::new(v.clone().into_bytes())), + None => None, + }; + + result.insert(key, val); + } + + try!(visitor.end()); + + let input = Input { + data: result + }; + + Ok(input) + } +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + use serde_json; + use bytes::Bytes; + use super::Input; + + #[test] + fn input_deserialization_from_map() { + let s = r#"{ + "0x0045" : "0x0123456789", + "be" : "e", + "0x0a" : null + }"#; + + let input: Input = serde_json::from_str(s).unwrap(); + let mut map = BTreeMap::new(); + map.insert(Bytes::new(vec![0, 0x45]), Some(Bytes::new(vec![0x01, 0x23, 0x45, 0x67, 0x89]))); + map.insert(Bytes::new(vec![0x62, 0x65]), Some(Bytes::new(vec![0x65]))); + map.insert(Bytes::new(vec![0x0a]), None); + assert_eq!(input.data, map); + } + + #[test] + fn input_deserialization_from_array() { + let s = r#"[ + ["0x0045", "0x0123456789"], + ["be", "e"], + ["0x0a", null] + ]"#; + + let input: Input = serde_json::from_str(s).unwrap(); + let mut map = BTreeMap::new(); + map.insert(Bytes::new(vec![0, 0x45]), Some(Bytes::new(vec![0x01, 0x23, 0x45, 0x67, 0x89]))); + map.insert(Bytes::new(vec![0x62, 0x65]), Some(Bytes::new(vec![0x65]))); + map.insert(Bytes::new(vec![0x0a]), None); + assert_eq!(input.data, map); + } +} diff --git a/util/json-tests/src/util.rs b/json/src/trie/mod.rs similarity index 80% rename from util/json-tests/src/util.rs rename to json/src/trie/mod.rs index f8beb269a..1c5d30067 100644 --- a/util/json-tests/src/util.rs +++ b/json/src/trie/mod.rs @@ -14,11 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use rustc_serialize::hex::FromHex; +//! Trie test deserialization. -pub fn hex_or_string(s: &str) -> Vec { - match s.starts_with("0x") { - true => s[2..].from_hex().unwrap(), - false => From::from(s) - } -} +mod input; +mod trie; +mod test; + +pub use self::input::Input; +pub use self::trie::Trie; +pub use self::test::Test; diff --git a/json/src/trie/test.rs b/json/src/trie/test.rs new file mode 100644 index 000000000..19becd5ee --- /dev/null +++ b/json/src/trie/test.rs @@ -0,0 +1,43 @@ +// 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 . + +//! TransactionTest test deserializer. + +use std::collections::BTreeMap; +use std::io::Read; +use serde_json; +use serde_json::Error; +use trie::Trie; + +/// TransactionTest test deserializer. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Test(BTreeMap); + +impl IntoIterator for Test { + type Item = as IntoIterator>::Item; + type IntoIter = as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl Test { + /// Loads test from json. + pub fn load(reader: R) -> Result where R: Read { + serde_json::from_reader(reader) + } +} diff --git a/json/src/trie/trie.rs b/json/src/trie/trie.rs new file mode 100644 index 000000000..c04498591 --- /dev/null +++ b/json/src/trie/trie.rs @@ -0,0 +1,30 @@ +// 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 . + +//! Trie test deserialization. + +use hash::H256; +use trie::Input; + +/// Trie test deserialization. +#[derive(Debug, Deserialize, PartialEq)] +pub struct Trie { + /// Trie test input. + #[serde(rename="in")] + pub input: Input, + /// Trie root hash. + pub root: H256, +} diff --git a/util/Cargo.toml b/util/Cargo.toml index 4f0f321f3..07a0713e3 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -29,7 +29,6 @@ slab = "0.2" sha3 = { path = "sha3" } serde = "0.7.0" clippy = { version = "0.0.78", optional = true} -json-tests = { path = "json-tests" } igd = "0.4.2" ethcore-devtools = { path = "../devtools" } libc = "0.2.7" diff --git a/util/json-tests/Cargo.toml b/util/json-tests/Cargo.toml deleted file mode 100644 index 3185e2e59..000000000 --- a/util/json-tests/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "json-tests" -version = "0.1.0" -authors = ["debris "] - -[dependencies] -rustc-serialize = "0.3" -glob = "*" diff --git a/util/json-tests/README.md b/util/json-tests/README.md deleted file mode 100644 index 9e6915ca3..000000000 --- a/util/json-tests/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# How to write json test file? - -Cause it's very hard to write generic json test files, each subdirectory should follow its own -convention. BUT all json files `within` same directory should be consistent. - -### Test files should always contain a single test with input and output. - -```json -{ - input: ..., - output: ... -} -``` - -As a reference, please use trietests. diff --git a/util/json-tests/json/.DS_Store b/util/json-tests/json/.DS_Store deleted file mode 100644 index 5ddc63de7e78f0f09186cf46a2ff1cf2b9cae2aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mVfW*>~F$)La1`&c2Z~+8}2?+#Z&(V4QSt!h?LeG-@#ZIlZZ)j=} z(e?AR66r-`1~vIYIqf#4$mI7QhFYo8^+Vg;}!TM!kPMk^St>SKu2 zy&WuhT}`%Nw2S8Op?PPuDF&v|E?SVlv^p5502LT0&_&+c`M-sKoBszbOsN1B_%j7` zy4h{kc&R*FKVHx3`>fi!!9l+q;q4~?i5. - -extern crate rustc_serialize; -extern crate glob; - -use std::str::from_utf8; -use std::path::*; -use std::io::prelude::*; -use std::fs::File; -use glob::glob; -use rustc_serialize::*; - -mod util; -pub mod trie; -pub mod rlp; - -pub trait JsonTest: Sized { - type Input; - type Output; - - fn new(data: &[u8]) -> Self; - fn input(&self) -> Self::Input; - fn output(&self) -> Self::Output; -} - -pub struct JsonLoader { - json: json::Json -} - -impl JsonTest for JsonLoader { - type Input = json::Json; - type Output = json::Json; - - fn new(data: &[u8]) -> Self { - JsonLoader { - json: json::Json::from_str(from_utf8(data).unwrap()).unwrap() - } - } - fn input(&self) -> Self::Input { - self.json.as_object().unwrap()["input"].clone() - } - - fn output(&self) -> Self::Output { - self.json.as_object().unwrap()["output"].clone() - } -} - -pub fn execute_test(data: &[u8], f: &mut F) where T: JsonTest, F: FnMut(T::Input, T::Output) { - let test = T::new(data); - f(test.input(), test.output()) -} - -pub fn execute_test_from_file(path: &Path, f: &mut F) where T: JsonTest, F: FnMut(T::Input, T::Output) { - let mut file = File::open(path).unwrap(); - let mut buffer = vec![]; - let _ = file.read_to_end(&mut buffer); - let test = T::new(&buffer); - f(test.input(), test.output()) -} - -pub fn execute_tests_from_directory(pattern: &str, f: &mut F) where T: JsonTest, F: FnMut(String, T::Input, T::Output) { - for path in glob(pattern).unwrap().filter_map(Result::ok) { - execute_test_from_file::(&path, &mut | input, output | { - f(path.to_str().unwrap().to_string(), input, output); - }); - } -} - diff --git a/util/json-tests/src/rlp.rs b/util/json-tests/src/rlp.rs deleted file mode 100644 index 0b8e4c904..000000000 --- a/util/json-tests/src/rlp.rs +++ /dev/null @@ -1,68 +0,0 @@ -// 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 . - -//! json rlp tests -use rustc_serialize::*; -use super::{JsonTest, JsonLoader}; -use util::*; - -pub enum Operation { - Append(Vec), - AppendList(usize), - AppendRaw(Vec, usize), - AppendEmpty -} - -impl Into for json::Json { - fn into(self) -> Operation { - let obj = self.as_object().unwrap(); - match obj["operation"].as_string().unwrap().as_ref() { - "append" => Operation::Append(hex_or_string(obj["value"].as_string().unwrap())), - "append_list" => Operation::AppendList(obj["len"].as_u64().unwrap() as usize), - "append_raw" => Operation::AppendRaw(hex_or_string(obj["value"].as_string().unwrap()), obj["len"].as_u64().unwrap() as usize), - "append_empty" => Operation::AppendEmpty, - other => { panic!("Unsupported opertation: {}", other); } - } - } -} - -pub struct RlpStreamTest { - loader: JsonLoader -} - -impl JsonTest for RlpStreamTest { - type Input = Vec; - type Output = Vec; - - fn new(data: &[u8]) -> Self { - RlpStreamTest { - loader: JsonLoader::new(data) - } - } - - fn input(&self) -> Self::Input { - self.loader.input().as_array().unwrap() - .iter() - .cloned() - .map(|i| i.into()) - .collect() - } - - fn output(&self) -> Self::Output { - hex_or_string(self.loader.output().as_string().unwrap()) - } -} - diff --git a/util/json-tests/src/trie.rs b/util/json-tests/src/trie.rs deleted file mode 100644 index a060167af..000000000 --- a/util/json-tests/src/trie.rs +++ /dev/null @@ -1,105 +0,0 @@ -// 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 . - -//! json trie tests -use std::collections::HashMap; -use rustc_serialize::*; -use super::{JsonTest, JsonLoader}; -use util::*; - -#[derive(RustcDecodable)] -struct RawOperation { - operation: String, - key: String, - value: Option -} - -pub enum Operation { - Insert(Vec, Vec), - Remove(Vec) -} - -impl Into for RawOperation { - fn into(self) -> Operation { - match self.operation.as_ref() { - "insert" => Operation::Insert(hex_or_string(&self.key), hex_or_string(&self.value.unwrap())), - "remove" => Operation::Remove(hex_or_string(&self.key)), - other => panic!("invalid operation type: {}", other) - } - } -} - -pub struct TrieTest { - loader: JsonLoader -} - -impl JsonTest for TrieTest { - type Input = Vec; - type Output = Vec; - - fn new(data: &[u8]) -> Self { - TrieTest { - loader: JsonLoader::new(data) - } - } - - fn input(&self) -> Self::Input { - let mut decoder = json::Decoder::new(self.loader.input()); - let raw: Vec = Decodable::decode(&mut decoder).unwrap(); - raw.into_iter() - .map(|i| i.into()) - .collect() - } - - fn output(&self) -> Self::Output { - hex_or_string(self.loader.output().as_string().unwrap()) - } -} - -pub struct TriehashTest { - trietest: TrieTest -} - -impl JsonTest for TriehashTest { - type Input = Vec<(Vec, Vec)>; - type Output = Vec; - - fn new(data: &[u8]) -> Self { - TriehashTest { - trietest: TrieTest::new(data) - } - } - - fn input(&self) -> Self::Input { - self.trietest.input() - .into_iter() - .fold(HashMap::new(), | mut map, o | { - match o { - Operation::Insert(k, v) => map.insert(k, v), - Operation::Remove(k) => map.remove(&k) - }; - map - }) - .into_iter() - .map(|p| { p }) - .collect() - } - - fn output(&self) -> Self::Output { - self.trietest.output() - } -} - diff --git a/util/src/json_aid.rs b/util/src/json_aid.rs deleted file mode 100644 index 7bf940b99..000000000 --- a/util/src/json_aid.rs +++ /dev/null @@ -1,154 +0,0 @@ -// 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 . - -use common::*; - -/// Remove the `"0x"`, if present, from the left of `s`, returning the remaining slice. -pub fn clean(s: &str) -> &str { - if s.len() >= 2 && &s[0..2] == "0x" { - &s[2..] - } else { - s - } -} - -fn u256_from_str(s: &str) -> U256 { - if s.len() >= 2 && &s[0..2] == "0x" { - U256::from_str(&s[2..]).unwrap_or_else(|_| U256::zero()) - } else { - U256::from_dec_str(s).unwrap_or_else(|_| U256::zero()) - } -} - -impl FromJson for Bytes { - fn from_json(json: &Json) -> Self { - match *json { - Json::String(ref s) => match s.len() % 2 { - 0 => FromHex::from_hex(clean(s)).unwrap_or_else(|_| vec![]), - _ => FromHex::from_hex(&("0".to_owned() + &(clean(s).to_owned()))[..]).unwrap_or_else(|_| vec![]), - }, - _ => vec![], - } - } -} - -impl FromJson for BTreeMap { - fn from_json(json: &Json) -> Self { - match *json { - Json::Object(ref o) => o.iter().map(|(key, value)| (u256_from_str(key).into(), U256::from_json(value).into())).collect(), - _ => BTreeMap::new(), - } - } -} - -impl FromJson for Vec where T: FromJson { - fn from_json(json: &Json) -> Self { - match *json { - Json::Array(ref o) => o.iter().map(|x|T::from_json(x)).collect(), - _ => Vec::new(), - } - } -} - -impl FromJson for Option where T: FromJson { - fn from_json(json: &Json) -> Self { - match *json { - Json::String(ref o) if o.is_empty() => None, - Json::Null => None, - _ => Some(FromJson::from_json(json)), - } - } -} - -impl FromJson for u64 { - fn from_json(json: &Json) -> Self { - U256::from_json(json).low_u64() - } -} - -impl FromJson for u32 { - fn from_json(json: &Json) -> Self { - U256::from_json(json).low_u64() as u32 - } -} - -impl FromJson for u16 { - fn from_json(json: &Json) -> Self { - U256::from_json(json).low_u64() as u16 - } -} - -#[test] -fn u256_from_json() { - let j = Json::from_str("{ \"dec\": \"10\", \"hex\": \"0x0a\", \"int\": 10 }").unwrap(); - - let v: U256 = xjson!(&j["dec"]); - assert_eq!(U256::from(10), v); - let v: U256 = xjson!(&j["hex"]); - assert_eq!(U256::from(10), v); - let v: U256 = xjson!(&j["int"]); - assert_eq!(U256::from(10), v); -} - -#[test] -fn h256_from_json() { - let j = Json::from_str("{ \"with\": \"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\", \"without\": \"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\" }").unwrap(); - - let v: H256 = xjson!(&j["with"]); - assert_eq!(H256::from_str("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").unwrap(), v); - let v: H256 = xjson!(&j["without"]); - assert_eq!(H256::from_str("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").unwrap(), v); -} - -#[test] -fn vec_u256_from_json() { - let j = Json::from_str("{ \"array\": [ \"10\", \"0x0a\", 10] }").unwrap(); - - let v: Vec = xjson!(&j["array"]); - assert_eq!(vec![U256::from(10); 3], v); -} - -#[test] -fn vec_h256_from_json() { - let j = Json::from_str("{ \"array\": [ \"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\", \"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\"] }").unwrap(); - - let v: Vec = xjson!(&j["array"]); - assert_eq!(vec![H256::from_str("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").unwrap(); 2], v); -} - -#[test] -fn simple_types() { - let j = Json::from_str("{ \"null\": null, \"empty\": \"\", \"int\": 42, \"dec\": \"42\", \"hex\": \"0x2a\" }").unwrap(); - let v: u16 = xjson!(&j["int"]); - assert_eq!(42u16, v); - let v: u32 = xjson!(&j["dec"]); - assert_eq!(42u32, v); - let v: u64 = xjson!(&j["hex"]); - assert_eq!(42u64, v); -} - -#[test] -fn option_types() { - let j = Json::from_str("{ \"null\": null, \"empty\": \"\", \"int\": 42, \"dec\": \"42\", \"hex\": \"0x2a\" }").unwrap(); - let v: Option = xjson!(&j["int"]); - assert_eq!(Some(42u16), v); - let v: Option = xjson!(&j["dec"]); - assert_eq!(Some(42u16), v); - let v: Option = xjson!(&j["null"]); - assert_eq!(None, v); - let v: Option = xjson!(&j["empty"]); - assert_eq!(None, v); -} diff --git a/util/src/lib.rs b/util/src/lib.rs index 009b50782..2e4561d83 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -131,7 +131,6 @@ pub mod bytes; pub mod rlp; pub mod misc; pub mod using_queue; -mod json_aid; pub mod vector; pub mod sha3; pub mod hashdb; @@ -147,7 +146,6 @@ pub mod trie; pub mod nibbleslice; pub mod nibblevec; mod heapsizeof; -pub mod squeeze; pub mod semantic_version; pub mod io; pub mod network; @@ -161,7 +159,6 @@ mod timer; pub use common::*; pub use misc::*; pub use using_queue::*; -pub use json_aid::*; pub use rlp::*; pub use hashdb::*; pub use memorydb::*; @@ -172,7 +169,6 @@ pub use crypto::*; pub use triehash::*; pub use trie::*; pub use nibbleslice::*; -pub use squeeze::*; pub use semantic_version::*; pub use network::*; pub use io::*; diff --git a/util/src/rlp/tests.rs b/util/src/rlp/tests.rs index 3df2f2d97..3d9ed40f1 100644 --- a/util/src/rlp/tests.rs +++ b/util/src/rlp/tests.rs @@ -14,9 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -extern crate json_tests; -use self::json_tests::execute_tests_from_directory; -use self::json_tests::rlp as rlptest; use std::{fmt, cmp}; use std::str::FromStr; use rlp; @@ -340,26 +337,6 @@ fn decode_untrusted_vector_of_vectors_str() { run_decode_tests(tests); } -#[test] -fn test_rlp_json() { - println!("Json rlp test: "); - execute_tests_from_directory::("json-tests/json/rlp/stream/*.json", &mut | file, input, output | { - println!("file: {}", file); - - let mut stream = RlpStream::new(); - for operation in input.into_iter() { - match operation { - rlptest::Operation::Append(ref v) => stream.append(v), - rlptest::Operation::AppendList(len) => stream.begin_list(len), - rlptest::Operation::AppendRaw(ref raw, len) => stream.append_raw(raw, len), - rlptest::Operation::AppendEmpty => stream.append_empty_data() - }; - } - - assert_eq!(stream.out(), output); - }); -} - #[test] fn test_decoding_array() { let v = vec![5u16, 2u16]; diff --git a/util/src/squeeze.rs b/util/src/squeeze.rs deleted file mode 100644 index 69aab9728..000000000 --- a/util/src/squeeze.rs +++ /dev/null @@ -1,84 +0,0 @@ -// 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 . - -//! Helper module that should be used to randomly squeeze -//! caches to a given size in bytes -//! -//! ``` -//! extern crate heapsize; -//! extern crate ethcore_util as util; -//! use std::collections::HashMap; -//! use std::mem::size_of; -//! use heapsize::HeapSizeOf; -//! use util::squeeze::Squeeze; -//! -//! fn main() { -//! let initial_size = 60; -//! let mut map: HashMap = HashMap::with_capacity(initial_size); -//! assert!(map.capacity() >= initial_size); -//! for i in 0..initial_size { -//! map.insert(i as u8, i as u8); -//! } -//! -//! assert_eq!(map.heap_size_of_children(), map.capacity() * 2 * size_of::()); -//! assert_eq!(map.len(), initial_size); -//! let initial_heap_size = map.heap_size_of_children(); -//! -//! // squeeze it to size of key and value -//! map.squeeze(2 * size_of::()); -//! assert_eq!(map.len(), 1); -//! -//! // its likely that heap size was reduced, but we can't be 100% sure -//! assert!(initial_heap_size >= map.heap_size_of_children()); -//! } -//! ``` - -use std::collections::HashMap; -use std::hash::Hash; -use heapsize::HeapSizeOf; - -/// Should be used to squeeze collections to certain size in bytes -pub trait Squeeze { - /// Try to reduce collection size to `size` bytes - fn squeeze(&mut self, size: usize); -} - -impl Squeeze for HashMap where K: Eq + Hash + Clone + HeapSizeOf, T: HeapSizeOf { - fn squeeze(&mut self, size: usize) { - if self.is_empty() { - return - } - - let size_of_entry = self.heap_size_of_children() / self.capacity(); - let all_entries = size_of_entry * self.len(); - let mut shrinked_size = all_entries; - - while !self.is_empty() && shrinked_size > size { - // could be optimized - let key = self.keys().next().unwrap().clone(); - self.remove(&key); - shrinked_size -= size_of_entry; - } - - self.shrink_to_fit(); - - // if we squeezed something, but not enough, squeeze again - if all_entries != shrinked_size && self.heap_size_of_children() > size { - self.squeeze(size); - } - } -} - diff --git a/util/src/trie/triedbmut.rs b/util/src/trie/triedbmut.rs index 4d46814c0..859bc52e1 100644 --- a/util/src/trie/triedbmut.rs +++ b/util/src/trie/triedbmut.rs @@ -676,8 +676,6 @@ impl<'db> fmt::Debug for TrieDBMut<'db> { #[cfg(test)] mod tests { - extern crate json_tests; - use self::json_tests::{trie, execute_tests_from_directory}; use triehash::*; use hash::*; use hashdb::*; @@ -858,6 +856,21 @@ mod tests { ])); } + #[test] + fn insert_out_of_order() { + let mut memdb = MemoryDB::new(); + let mut root = H256::new(); + let mut t = TrieDBMut::new(&mut memdb, &mut root); + t.insert(&[0xf1u8, 0x23], &[0xf1u8, 0x23]); + t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); + t.insert(&[0x81u8, 0x23], &[0x81u8, 0x23]); + assert_eq!(*t.root(), trie_root(vec![ + (vec![0x01u8, 0x23], vec![0x01u8, 0x23]), + (vec![0x81u8, 0x23], vec![0x81u8, 0x23]), + (vec![0xf1u8, 0x23], vec![0xf1u8, 0x23]), + ])); + } + #[test] fn insert_value_into_branch_root() { let mut memdb = MemoryDB::new(); @@ -1063,23 +1076,64 @@ mod tests { } #[test] - fn test_trie_json() { - println!("Json trie test: "); - execute_tests_from_directory::("json-tests/json/trie/*.json", &mut | file, input, output | { - println!("file: {}", file); + fn branching_test() { + use std::str::FromStr; + use rustc_serialize::hex::FromHex; - let mut memdb = MemoryDB::new(); - let mut root = H256::new(); - let mut t = TrieDBMut::new(&mut memdb, &mut root); - for operation in input.into_iter() { - match operation { - trie::Operation::Insert(key, value) => t.insert(&key, &value), - trie::Operation::Remove(key) => t.remove(&key) - } - } - - assert_eq!(*t.root(), H256::from_slice(&output)); - }); + let mut memdb = MemoryDB::new(); + let mut root = H256::new(); + let mut t = TrieDBMut::new(&mut memdb, &mut root); + t.insert(&"04110d816c380812a427968ece99b1c963dfbce6".from_hex().unwrap(), b"something"); + t.insert(&"095e7baea6a6c7c4c2dfeb977efac326af552d87".from_hex().unwrap(), b"something"); + t.insert(&"0a517d755cebbf66312b30fff713666a9cb917e0".from_hex().unwrap(), b"something"); + t.insert(&"24dd378f51adc67a50e339e8031fe9bd4aafab36".from_hex().unwrap(), b"something"); + t.insert(&"293f982d000532a7861ab122bdc4bbfd26bf9030".from_hex().unwrap(), b"something"); + t.insert(&"2cf5732f017b0cf1b1f13a1478e10239716bf6b5".from_hex().unwrap(), b"something"); + t.insert(&"31c640b92c21a1f1465c91070b4b3b4d6854195f".from_hex().unwrap(), b"something"); + t.insert(&"37f998764813b136ddf5a754f34063fd03065e36".from_hex().unwrap(), b"something"); + t.insert(&"37fa399a749c121f8a15ce77e3d9f9bec8020d7a".from_hex().unwrap(), b"something"); + t.insert(&"4f36659fa632310b6ec438dea4085b522a2dd077".from_hex().unwrap(), b"something"); + t.insert(&"62c01474f089b07dae603491675dc5b5748f7049".from_hex().unwrap(), b"something"); + t.insert(&"729af7294be595a0efd7d891c9e51f89c07950c7".from_hex().unwrap(), b"something"); + t.insert(&"83e3e5a16d3b696a0314b30b2534804dd5e11197".from_hex().unwrap(), b"something"); + t.insert(&"8703df2417e0d7c59d063caa9583cb10a4d20532".from_hex().unwrap(), b"something"); + t.insert(&"8dffcd74e5b5923512916c6a64b502689cfa65e1".from_hex().unwrap(), b"something"); + t.insert(&"95a4d7cccb5204733874fa87285a176fe1e9e240".from_hex().unwrap(), b"something"); + t.insert(&"99b2fcba8120bedd048fe79f5262a6690ed38c39".from_hex().unwrap(), b"something"); + t.insert(&"a4202b8b8afd5354e3e40a219bdc17f6001bf2cf".from_hex().unwrap(), b"something"); + t.insert(&"a94f5374fce5edbc8e2a8697c15331677e6ebf0b".from_hex().unwrap(), b"something"); + t.insert(&"a9647f4a0a14042d91dc33c0328030a7157c93ae".from_hex().unwrap(), b"something"); + t.insert(&"aa6cffe5185732689c18f37a7f86170cb7304c2a".from_hex().unwrap(), b"something"); + t.insert(&"aae4a2e3c51c04606dcb3723456e58f3ed214f45".from_hex().unwrap(), b"something"); + t.insert(&"c37a43e940dfb5baf581a0b82b351d48305fc885".from_hex().unwrap(), b"something"); + t.insert(&"d2571607e241ecf590ed94b12d87c94babe36db6".from_hex().unwrap(), b"something"); + t.insert(&"f735071cbee190d76b704ce68384fc21e389fbe7".from_hex().unwrap(), b"something"); + t.insert(&"04110d816c380812a427968ece99b1c963dfbce6".from_hex().unwrap(), &[]); + t.insert(&"095e7baea6a6c7c4c2dfeb977efac326af552d87".from_hex().unwrap(), &[]); + t.insert(&"0a517d755cebbf66312b30fff713666a9cb917e0".from_hex().unwrap(), &[]); + t.insert(&"24dd378f51adc67a50e339e8031fe9bd4aafab36".from_hex().unwrap(), &[]); + t.insert(&"293f982d000532a7861ab122bdc4bbfd26bf9030".from_hex().unwrap(), &[]); + t.insert(&"2cf5732f017b0cf1b1f13a1478e10239716bf6b5".from_hex().unwrap(), &[]); + t.insert(&"31c640b92c21a1f1465c91070b4b3b4d6854195f".from_hex().unwrap(), &[]); + t.insert(&"37f998764813b136ddf5a754f34063fd03065e36".from_hex().unwrap(), &[]); + t.insert(&"37fa399a749c121f8a15ce77e3d9f9bec8020d7a".from_hex().unwrap(), &[]); + t.insert(&"4f36659fa632310b6ec438dea4085b522a2dd077".from_hex().unwrap(), &[]); + t.insert(&"62c01474f089b07dae603491675dc5b5748f7049".from_hex().unwrap(), &[]); + t.insert(&"729af7294be595a0efd7d891c9e51f89c07950c7".from_hex().unwrap(), &[]); + t.insert(&"83e3e5a16d3b696a0314b30b2534804dd5e11197".from_hex().unwrap(), &[]); + t.insert(&"8703df2417e0d7c59d063caa9583cb10a4d20532".from_hex().unwrap(), &[]); + t.insert(&"8dffcd74e5b5923512916c6a64b502689cfa65e1".from_hex().unwrap(), &[]); + t.insert(&"95a4d7cccb5204733874fa87285a176fe1e9e240".from_hex().unwrap(), &[]); + t.insert(&"99b2fcba8120bedd048fe79f5262a6690ed38c39".from_hex().unwrap(), &[]); + t.insert(&"a4202b8b8afd5354e3e40a219bdc17f6001bf2cf".from_hex().unwrap(), &[]); + t.insert(&"a94f5374fce5edbc8e2a8697c15331677e6ebf0b".from_hex().unwrap(), &[]); + t.insert(&"a9647f4a0a14042d91dc33c0328030a7157c93ae".from_hex().unwrap(), &[]); + t.insert(&"aa6cffe5185732689c18f37a7f86170cb7304c2a".from_hex().unwrap(), &[]); + t.insert(&"aae4a2e3c51c04606dcb3723456e58f3ed214f45".from_hex().unwrap(), &[]); + t.insert(&"c37a43e940dfb5baf581a0b82b351d48305fc885".from_hex().unwrap(), &[]); + t.insert(&"d2571607e241ecf590ed94b12d87c94babe36db6".from_hex().unwrap(), &[]); + t.insert(&"f735071cbee190d76b704ce68384fc21e389fbe7".from_hex().unwrap(), &[]); + assert_eq!(*t.root(), H256::from_str("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").unwrap()); } #[test] diff --git a/util/src/triehash.rs b/util/src/triehash.rs index 54ea6f702..f5f4e2123 100644 --- a/util/src/triehash.rs +++ b/util/src/triehash.rs @@ -46,7 +46,8 @@ pub fn ordered_trie_root(input: Vec>) -> H256 { // optimize it later .into_iter() .enumerate() - .fold(BTreeMap::new(), | mut acc, (i, vec) | { acc.insert(rlp::encode(&i).to_vec(), vec); acc }) + .map(|(i, vec)| (rlp::encode(&i).to_vec(), vec)) + .collect::>() // then move them to a vector .into_iter() .map(|(k, v)| (as_nibbles(&k), v) ) @@ -78,10 +79,7 @@ pub fn trie_root(input: Vec<(Vec, Vec)>) -> H256 { let gen_input = input // first put elements into btree to sort them and to remove duplicates .into_iter() - .fold(BTreeMap::new(), | mut acc, (k, v) | { - acc.insert(k, v); - acc - }) + .collect::>() // then move them to a vector .into_iter() .map(|(k, v)| (as_nibbles(&k), v) ) @@ -97,7 +95,7 @@ pub fn trie_root(input: Vec<(Vec, Vec)>) -> H256 { /// use std::str::FromStr; /// use util::triehash::*; /// use util::hash::*; -/// +/// /// fn main() { /// let v = vec![ /// (From::from("doe"), From::from("reindeer")), @@ -113,10 +111,8 @@ pub fn sec_trie_root(input: Vec<(Vec, Vec)>) -> H256 { let gen_input = input // first put elements into btree to sort them and to remove duplicates .into_iter() - .fold(BTreeMap::new(), | mut acc, (k, v) | { - acc.insert(k.sha3().to_vec(), v); - acc - }) + .map(|(k, v)| (k.sha3().to_vec(), v)) + .collect::>() // then move them to a vector .into_iter() .map(|(k, v)| (as_nibbles(&k), v) ) @@ -324,10 +320,16 @@ fn test_hex_prefix_encode() { #[cfg(test)] mod tests { - extern crate json_tests; - use self::json_tests::*; - use hash::*; - use triehash::*; + use std::str::FromStr; + use hash::H256; + use super::trie_root; + + #[test] + fn simple_test() { + assert_eq!(trie_root(vec![ + (b"A".to_vec(), b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".to_vec()) + ]), H256::from_str("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab").unwrap()); + } #[test] fn test_triehash_out_of_order() { @@ -343,11 +345,4 @@ mod tests { ])); } - #[test] - fn test_triehash_json() { - execute_tests_from_directory::("json-tests/json/trie/*.json", &mut | file, input, output | { - println!("file: {}, output: {:?}", file, output); - assert_eq!(trie_root(input), H256::from_slice(&output)); - }); - } }