diff --git a/Cargo.lock b/Cargo.lock index b126d3d35..d53c197cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -543,6 +543,7 @@ dependencies = [ "table 0.1.0", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.1.0", "using_queue 0.1.0", "vm 0.1.0", "wasm 0.1.0", @@ -672,6 +673,7 @@ dependencies = [ "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.1.0", "vm 0.1.0", ] @@ -807,6 +809,7 @@ dependencies = [ "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.1.0", "vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -922,6 +925,7 @@ dependencies = [ "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.1.0", ] [[package]] @@ -3106,6 +3110,15 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "triehash" +version = "0.1.0" +dependencies = [ + "ethcore-bigint 0.1.3", + "hash 0.1.0", + "rlp 0.2.0", +] + [[package]] name = "typeable" version = "0.1.2" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 5b37d96ca..71326e163 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -63,6 +63,7 @@ bloomable = { path = "../util/bloomable" } vm = { path = "vm" } wasm = { path = "wasm" } hash = { path = "../util/hash" } +triehash = { path = "../util/triehash" } semantic_version = { path = "../util/semantic_version" } [dev-dependencies] diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index 46ae3afe0..4232413fb 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -34,6 +34,7 @@ serde_derive = "1.0" parking_lot = "0.4" stats = { path = "../../util/stats" } hash = { path = "../../util/hash" } +triehash = { path = "../../util/triehash" } [features] default = [] diff --git a/ethcore/light/src/cht.rs b/ethcore/light/src/cht.rs index 7f2ccc3a8..78b45cafc 100644 --- a/ethcore/light/src/cht.rs +++ b/ethcore/light/src/cht.rs @@ -130,7 +130,7 @@ pub fn compute_root(cht_num: u64, iterable: I) -> Option } if v.len() == SIZE as usize { - Some(::util::triehash::trie_root(v)) + Some(::triehash::trie_root(v)) } else { None } diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index 5d9a5ae32..b7842e055 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -86,6 +86,7 @@ extern crate stats; extern crate time; extern crate vm; extern crate hash; +extern crate triehash; #[cfg(feature = "ipc")] extern crate ethcore_ipc as ipc; diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index 3a38ec974..2dae37555 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -709,7 +709,7 @@ impl Body { pub fn check_response(&self, cache: &Mutex<::cache::Cache>, body: &encoded::Body) -> Result { // check the integrity of the the body against the header let header = self.0.as_ref()?; - let tx_root = ::util::triehash::ordered_trie_root(body.rlp().at(0).iter().map(|r| r.as_raw().to_vec())); + let tx_root = ::triehash::ordered_trie_root(body.rlp().at(0).iter().map(|r| r.as_raw().to_vec())); if tx_root != header.transactions_root() { return Err(Error::WrongTrieRoot(header.transactions_root(), tx_root)); } @@ -739,7 +739,7 @@ impl BlockReceipts { /// Check a response with receipts against the stored header. pub fn check_response(&self, cache: &Mutex<::cache::Cache>, receipts: &[Receipt]) -> Result, Error> { let receipts_root = self.0.as_ref()?.receipts_root(); - let found_root = ::util::triehash::ordered_trie_root(receipts.iter().map(|r| ::rlp::encode(r).into_vec())); + let found_root = ::triehash::ordered_trie_root(receipts.iter().map(|r| ::rlp::encode(r).into_vec())); match receipts_root == found_root { true => { @@ -936,7 +936,7 @@ mod tests { }).collect::>(); let mut header = Header::new(); - let receipts_root = ::util::triehash::ordered_trie_root( + let receipts_root = ::triehash::ordered_trie_root( receipts.iter().map(|x| ::rlp::encode(x).into_vec()) ); diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 5181dff1f..a48dfbcb7 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -20,9 +20,10 @@ use std::cmp; use std::sync::Arc; use std::collections::HashSet; use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; +use triehash::ordered_trie_root; use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError}; -use util::{Bytes, Address, U256, H256, ordered_trie_root}; +use util::{Bytes, Address, U256, H256}; use util::error::{Mismatch, OutOfBounds}; use basic_types::{LogBloom, Seal}; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index dc186818a..82fb448d9 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -353,7 +353,7 @@ impl ValidatorSet for ValidatorSafeContract { // ensure receipts match header. // TODO: optimize? these were just decoded. - let found_root = ::util::triehash::ordered_trie_root( + let found_root = ::triehash::ordered_trie_root( receipts.iter().map(::rlp::encode).map(|x| x.to_vec()) ); if found_root != *old_header.receipts_root() { diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 7d175ad7a..02211ed77 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -104,6 +104,7 @@ extern crate rand; extern crate rlp; extern crate hash; extern crate heapsize; +extern crate triehash; extern crate ansi_term; extern crate semantic_version; diff --git a/ethcore/src/pod_account.rs b/ethcore/src/pod_account.rs index b8606008c..f8c658deb 100644 --- a/ethcore/src/pod_account.rs +++ b/ethcore/src/pod_account.rs @@ -18,6 +18,7 @@ use std::fmt; use std::collections::BTreeMap; use itertools::Itertools; use hash::{keccak}; +use triehash::sec_trie_root; use util::*; use state::Account; use ethjson; diff --git a/ethcore/src/pod_state.rs b/ethcore/src/pod_state.rs index 5a0265dc1..e35e602b2 100644 --- a/ethcore/src/pod_state.rs +++ b/ethcore/src/pod_state.rs @@ -19,6 +19,7 @@ use std::fmt; use std::collections::BTreeMap; use itertools::Itertools; +use triehash::sec_trie_root; use util::*; use pod_account::{self, PodAccount}; use types::state_diff::StateDiff; diff --git a/ethcore/src/snapshot/block.rs b/ethcore/src/snapshot/block.rs index fa4b3c19f..2ef54b53b 100644 --- a/ethcore/src/snapshot/block.rs +++ b/ethcore/src/snapshot/block.rs @@ -23,7 +23,7 @@ use hash::keccak; use views::BlockView; use rlp::{DecoderError, RlpStream, UntrustedRlp}; use util::{Bytes, H256}; -use util::triehash::ordered_trie_root; +use triehash::ordered_trie_root; const HEADER_FIELDS: usize = 8; const BLOCK_FIELDS: usize = 2; @@ -190,7 +190,7 @@ mod tests { b.transactions.push(t2.into()); let receipts_root = b.header.receipts_root().clone(); - b.header.set_transactions_root(::util::triehash::ordered_trie_root( + b.header.set_transactions_root(::triehash::ordered_trie_root( b.transactions.iter().map(::rlp::encode).map(|out| out.into_vec()) )); diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index 2bf154fc4..7e0b896c4 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -222,7 +222,7 @@ impl Rebuilder for PowRebuilder { use views::BlockView; use snapshot::verify_old_block; use util::U256; - use util::triehash::ordered_trie_root; + use triehash::ordered_trie_root; let rlp = UntrustedRlp::new(chunk); let item_count = rlp.item_count()?; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index f9290309c..eb055fd4a 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -23,6 +23,7 @@ use std::collections::HashSet; use hash::keccak; +use triehash::ordered_trie_root; use heapsize::HeapSizeOf; use util::*; use engines::Engine; @@ -269,6 +270,7 @@ fn verify_block_integrity(block: &[u8], transactions_root: &H256, uncles_hash: & mod tests { use std::collections::{BTreeMap, HashMap}; use hash::keccak; + use triehash::ordered_trie_root; use util::*; use ethkey::{Random, Generator}; use header::*; diff --git a/sync/Cargo.toml b/sync/Cargo.toml index 5fb3628df..0e1bd3d5b 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -19,6 +19,7 @@ ethcore-light = { path = "../ethcore/light"} ethcore = { path = "../ethcore" } rlp = { path = "../util/rlp" } hash = { path = "../util/hash" } +triehash = { path = "../util/triehash" } clippy = { version = "0.0.103", optional = true} log = "0.3" env_logger = "0.4" diff --git a/sync/src/blocks.rs b/sync/src/blocks.rs index 77cb206c8..a07d9dfd0 100644 --- a/sync/src/blocks.rs +++ b/sync/src/blocks.rs @@ -19,6 +19,7 @@ use std::collections::hash_map::Entry; use smallvec::SmallVec; use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; use heapsize::HeapSizeOf; +use triehash::ordered_trie_root; use util::*; use rlp::*; use network::NetworkError; diff --git a/sync/src/lib.rs b/sync/src/lib.rs index 237d6c437..b5f97c6bc 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -39,6 +39,7 @@ extern crate smallvec; extern crate rlp; extern crate ipnetwork; extern crate hash; +extern crate triehash; extern crate ethcore_light as light; diff --git a/util/Cargo.toml b/util/Cargo.toml index d04450053..e4e95bad7 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -33,6 +33,7 @@ ethcore-bloom-journal = { path = "bloom" } regex = "0.2" lru-cache = "0.1.0" ethcore-logger = { path = "../logger" } +triehash = { path = "triehash" } [features] default = [] diff --git a/util/benches/trie.rs b/util/benches/trie.rs index 2ae10cf39..20b0858aa 100644 --- a/util/benches/trie.rs +++ b/util/benches/trie.rs @@ -17,6 +17,7 @@ #![feature(test)] extern crate test; +extern crate triehash; extern crate ethcore_util; #[macro_use] extern crate log; @@ -27,7 +28,7 @@ use ethcore_util::hash::*; use ethcore_util::bytes::*; use ethcore_util::trie::*; use ethcore_util::memorydb::*; -use ethcore_util::triehash::*; +use triehash::*; use hash::keccak; fn random_word(alphabet: &[u8], min_count: usize, diff_count: usize, seed: &mut H256) -> Vec { diff --git a/util/src/lib.rs b/util/src/lib.rs index 61fc616da..710a96127 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -117,14 +117,12 @@ pub mod common; pub mod error; pub mod bytes; pub mod misc; -pub mod vector; pub mod hashdb; pub mod memorydb; pub mod migration; pub mod overlaydb; pub mod journaldb; pub mod kvdb; -pub mod triehash; pub mod trie; pub mod nibbleslice; pub mod nibblevec; @@ -136,12 +134,10 @@ pub use hashdb::*; pub use memorydb::MemoryDB; pub use overlaydb::*; pub use journaldb::JournalDB; -pub use triehash::*; pub use trie::{Trie, TrieMut, TrieDB, TrieDBMut, TrieFactory, TrieError, SecTrieDB, SecTrieDBMut}; pub use kvdb::*; pub use error::*; pub use bytes::*; -pub use vector::*; pub use bigint::prelude::*; pub use bigint::hash; diff --git a/util/src/trie/triedbmut.rs b/util/src/trie/triedbmut.rs index fa23ca756..14d7f4f81 100644 --- a/util/src/trie/triedbmut.rs +++ b/util/src/trie/triedbmut.rs @@ -937,7 +937,8 @@ impl<'a> Drop for TrieDBMut<'a> { #[cfg(test)] mod tests { - use triehash::trie_root; + extern crate triehash; + use self::triehash::trie_root; use hashdb::*; use memorydb::*; use super::*; diff --git a/util/src/vector.rs b/util/src/vector.rs deleted file mode 100644 index 951d396c7..000000000 --- a/util/src/vector.rs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (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 . - -//! Vector extensions. - -/// Returns len of prefix shared with elem -/// -/// ```rust -/// extern crate ethcore_util as util; -/// use util::vector::SharedPrefix; -/// -/// fn main () { -/// let a = vec![1,2,3,3,5]; -/// let b = vec![1,2,3]; -/// assert_eq!(a.shared_prefix_len(&b), 3); -/// } -/// ``` -pub trait SharedPrefix { - /// Get common prefix length - fn shared_prefix_len(&self, elem: &[T]) -> usize; -} - -impl SharedPrefix for [T] where T: Eq { - fn shared_prefix_len(&self, elem: &[T]) -> usize { - use std::cmp; - let len = cmp::min(self.len(), elem.len()); - (0..len).take_while(|&i| self[i] == elem[i]).count() - } -} - -#[cfg(test)] -mod test { - use vector::SharedPrefix; - - #[test] - fn test_shared_prefix() { - let a = vec![1,2,3,4,5,6]; - let b = vec![4,2,3,4,5,6]; - assert_eq!(a.shared_prefix_len(&b), 0); - } - - #[test] - fn test_shared_prefix2() { - let a = vec![1,2,3,3,5]; - let b = vec![1,2,3]; - assert_eq!(a.shared_prefix_len(&b), 3); - } - - #[test] - fn test_shared_prefix3() { - let a = vec![1,2,3,4,5,6]; - let b = vec![1,2,3,4,5,6]; - assert_eq!(a.shared_prefix_len(&b), 6); - } -} diff --git a/util/triehash/Cargo.toml b/util/triehash/Cargo.toml new file mode 100644 index 000000000..cc18a6ea8 --- /dev/null +++ b/util/triehash/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "triehash" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +rlp = { path = "../rlp" } +ethcore-bigint = { path = "../bigint" } +hash = { path = "../hash" } diff --git a/util/src/triehash.rs b/util/triehash/src/lib.rs similarity index 79% rename from util/src/triehash.rs rename to util/triehash/src/lib.rs index fa790f3f4..d166aa5d0 100644 --- a/util/src/triehash.rs +++ b/util/triehash/src/lib.rs @@ -18,26 +18,31 @@ //! //! This module should be used to generate trie root hash. +extern crate ethcore_bigint; +extern crate hash; +extern crate rlp; + use std::collections::BTreeMap; use std::cmp; -use hash::*; -use keccak::keccak; -use rlp; +use ethcore_bigint::hash::H256; +use hash::keccak; use rlp::RlpStream; -use vector::SharedPrefix; + +fn shared_prefix_len(first: &[T], second: &[T]) -> usize { + let len = cmp::min(first.len(), second.len()); + (0..len).take_while(|&i| first[i] == second[i]).count() +} /// Generates a trie root hash for a vector of values /// /// ```rust -/// extern crate ethcore_util as util; -/// use std::str::FromStr; -/// use util::triehash::*; -/// use util::hash::*; +/// extern crate triehash; +/// use triehash::ordered_trie_root; /// /// fn main() { /// let v = vec![From::from("doe"), From::from("reindeer")]; /// let root = "e766d5d51b89dc39d981b41bda63248d7abce4f0225eefd023792a540bcffee3"; -/// assert_eq!(ordered_trie_root(v), H256::from_str(root).unwrap()); +/// assert_eq!(ordered_trie_root(v), root.parse().unwrap()); /// } /// ``` pub fn ordered_trie_root(input: I) -> H256 @@ -61,10 +66,8 @@ pub fn ordered_trie_root(input: I) -> H256 /// Generates a trie root hash for a vector of key-values /// /// ```rust -/// extern crate ethcore_util as util; -/// use std::str::FromStr; -/// use util::triehash::*; -/// use util::hash::*; +/// extern crate triehash; +/// use triehash::trie_root; /// /// fn main() { /// let v = vec![ @@ -74,7 +77,7 @@ pub fn ordered_trie_root(input: I) -> H256 /// ]; /// /// let root = "8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3"; -/// assert_eq!(trie_root(v), H256::from_str(root).unwrap()); +/// assert_eq!(trie_root(v), root.parse().unwrap()); /// } /// ``` pub fn trie_root(input: I) -> H256 @@ -95,10 +98,8 @@ pub fn trie_root(input: I) -> H256 /// Generates a key-hashed (secure) trie root hash for a vector of key-values. /// /// ```rust -/// extern crate ethcore_util as util; -/// use std::str::FromStr; -/// use util::triehash::*; -/// use util::hash::*; +/// extern crate triehash; +/// use triehash::sec_trie_root; /// /// fn main() { /// let v = vec![ @@ -108,7 +109,7 @@ pub fn trie_root(input: I) -> H256 /// ]; /// /// let root = "d4cd937e4a4368d7931a9cf51686b7e10abb3dce38a39000fd7902a092b64585"; -/// assert_eq!(sec_trie_root(v), H256::from_str(root).unwrap()); +/// assert_eq!(sec_trie_root(v), root.parse().unwrap()); /// } /// ``` pub fn sec_trie_root(input: Vec<(Vec, Vec)>) -> H256 { @@ -216,7 +217,7 @@ fn hash256rlp(input: &[(Vec, Vec)], pre_len: usize, stream: &mut RlpStre .skip(1) // get minimum number of shared nibbles between first and each successive .fold(key.len(), | acc, &(ref k, _) | { - cmp::min(key.shared_prefix_len(k), acc) + cmp::min(shared_prefix_len(key, k), acc) }); // if shared prefix is higher than current prefix append its @@ -288,50 +289,49 @@ fn test_nibbles() { assert_eq!(as_nibbles(&v), e); } -#[test] -fn test_hex_prefix_encode() { - let v = vec![0, 0, 1, 2, 3, 4, 5]; - let e = vec![0x10, 0x01, 0x23, 0x45]; - let h = hex_prefix_encode(&v, false); - assert_eq!(h, e); - - let v = vec![0, 1, 2, 3, 4, 5]; - let e = vec![0x00, 0x01, 0x23, 0x45]; - let h = hex_prefix_encode(&v, false); - assert_eq!(h, e); - - let v = vec![0, 1, 2, 3, 4, 5]; - let e = vec![0x20, 0x01, 0x23, 0x45]; - let h = hex_prefix_encode(&v, true); - assert_eq!(h, e); - - let v = vec![1, 2, 3, 4, 5]; - let e = vec![0x31, 0x23, 0x45]; - let h = hex_prefix_encode(&v, true); - assert_eq!(h, e); - - let v = vec![1, 2, 3, 4]; - let e = vec![0x00, 0x12, 0x34]; - let h = hex_prefix_encode(&v, false); - assert_eq!(h, e); - - let v = vec![4, 1]; - let e = vec![0x20, 0x41]; - let h = hex_prefix_encode(&v, true); - assert_eq!(h, e); -} #[cfg(test)] mod tests { - use std::str::FromStr; - use hash::H256; - use super::trie_root; + use super::{trie_root, shared_prefix_len, hex_prefix_encode}; + + #[test] + fn test_hex_prefix_encode() { + let v = vec![0, 0, 1, 2, 3, 4, 5]; + let e = vec![0x10, 0x01, 0x23, 0x45]; + let h = hex_prefix_encode(&v, false); + assert_eq!(h, e); + + let v = vec![0, 1, 2, 3, 4, 5]; + let e = vec![0x00, 0x01, 0x23, 0x45]; + let h = hex_prefix_encode(&v, false); + assert_eq!(h, e); + + let v = vec![0, 1, 2, 3, 4, 5]; + let e = vec![0x20, 0x01, 0x23, 0x45]; + let h = hex_prefix_encode(&v, true); + assert_eq!(h, e); + + let v = vec![1, 2, 3, 4, 5]; + let e = vec![0x31, 0x23, 0x45]; + let h = hex_prefix_encode(&v, true); + assert_eq!(h, e); + + let v = vec![1, 2, 3, 4]; + let e = vec![0x00, 0x12, 0x34]; + let h = hex_prefix_encode(&v, false); + assert_eq!(h, e); + + let v = vec![4, 1]; + let e = vec![0x20, 0x41]; + let h = hex_prefix_encode(&v, true); + assert_eq!(h, e); + } #[test] fn simple_test() { assert_eq!(trie_root(vec![ (b"A".to_vec(), b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".to_vec()) - ]), H256::from_str("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab").unwrap()); + ]), "d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab".parse().unwrap()); } #[test] @@ -348,4 +348,24 @@ mod tests { ])); } + #[test] + fn test_shared_prefix() { + let a = vec![1,2,3,4,5,6]; + let b = vec![4,2,3,4,5,6]; + assert_eq!(shared_prefix_len(&a, &b), 0); + } + + #[test] + fn test_shared_prefix2() { + let a = vec![1,2,3,3,5]; + let b = vec![1,2,3]; + assert_eq!(shared_prefix_len(&a, &b), 3); + } + + #[test] + fn test_shared_prefix3() { + let a = vec![1,2,3,4,5,6]; + let b = vec![1,2,3,4,5,6]; + assert_eq!(shared_prefix_len(&a, &b), 6); + } }