diff --git a/Cargo.toml b/Cargo.toml index 65ea8508f..13295f766 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ rocksdb = "0.2.1" lazy_static = "0.1.*" secp256k1 = "0.5.1" rust-crypto = "0.2.34" +elastic-array = "0.4" [dev-dependencies] json-tests = { path = "json-tests" } diff --git a/benches/trie.rs b/benches/trie.rs index 0b7055bde..2865c5778 100644 --- a/benches/trie.rs +++ b/benches/trie.rs @@ -7,13 +7,10 @@ extern crate ethcore_util; extern crate log; use test::Bencher; -use rand::random; -//use ethcore_util::BytesConvertable; use ethcore_util::hash::*; use ethcore_util::bytes::*; use ethcore_util::trie::*; use ethcore_util::sha3::*; -use ethcore_util::ToBytes::*; fn random_word(alphabet: &[u8], min_count: usize, diff_count: usize, seed: &mut H256) -> Vec { @@ -121,7 +118,7 @@ fn insertions_six_low(b: &mut Bencher) { fn sha3x1000(b: &mut Bencher) { b.iter(||{ let mut seed = H256::new(); - for i in 0..1000 { + for _ in 0..1000 { seed = seed.sha3() } }) diff --git a/src/lib.rs b/src/lib.rs index 6366d682e..883cac2f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,7 @@ extern crate time; extern crate crypto as rcrypto; extern crate secp256k1; extern crate arrayvec; +extern crate elastic_array; pub mod macros; pub mod error; diff --git a/src/rlp.rs b/src/rlp.rs index a7543aae5..d0dece3ba 100644 --- a/src/rlp.rs +++ b/src/rlp.rs @@ -32,8 +32,8 @@ use std::fmt; use std::cell::Cell; -use std::collections::LinkedList; use std::error::Error as StdError; +use elastic_array::*; use bytes::{ToBytes, FromBytes, FromBytesError}; use vector::InsertSlice; @@ -759,7 +759,7 @@ impl Decoder for BasicDecoder { } } -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] struct ListInfo { position: usize, current: usize, @@ -778,7 +778,7 @@ impl ListInfo { /// Appendable rlp encoder. pub struct RlpStream { - unfinished_lists: LinkedList, + unfinished_lists: ElasticArray16, encoder: BasicEncoder, } @@ -786,7 +786,7 @@ impl RlpStream { /// Initializes instance of empty `RlpStream`. pub fn new() -> RlpStream { RlpStream { - unfinished_lists: LinkedList::new(), + unfinished_lists: ElasticArray16::new(), encoder: BasicEncoder::new(), } } @@ -844,8 +844,12 @@ impl RlpStream { // we may finish, if the appended list len is equal 0 self.encoder.bytes.push(0xc0u8); self.note_appended(1); - } - _ => self.unfinished_lists.push_back(ListInfo::new(position, len)), + }, + _ => { + // reserve at least double size of the len + //self.encoder.bytes.reserve(len * 2); + self.unfinished_lists.push(ListInfo::new(position, len)); + }, } // return chainable self @@ -879,7 +883,7 @@ impl RlpStream { /// Appends raw (pre-serialised) RLP data. Use with caution. Chainable. pub fn append_raw<'a>(&'a mut self, bytes: &[u8], item_count: usize) -> &'a mut RlpStream { // push raw items - self.encoder.bytes.extend(bytes); + self.encoder.bytes.append_slice(bytes); // try to finish and prepend the length self.note_appended(item_count); @@ -926,7 +930,7 @@ impl RlpStream { /// assert_eq!(out, vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']); /// } pub fn is_finished(&self) -> bool { - self.unfinished_lists.back().is_none() + self.unfinished_lists.len() == 0 } /// Streams out encoded bytes. @@ -934,14 +938,19 @@ impl RlpStream { /// panic! if stream is not finished. pub fn out(self) -> Vec { match self.is_finished() { - true => self.encoder.out(), + true => self.encoder.out().to_vec(), false => panic!() } } /// Try to finish lists fn note_appended(&mut self, inserted_items: usize) -> () { - let should_finish = match self.unfinished_lists.back_mut() { + if self.unfinished_lists.len() == 0 { + return; + } + + let back = self.unfinished_lists.len() - 1; + let should_finish = match self.unfinished_lists.get_mut(back) { None => false, Some(ref mut x) => { x.current += inserted_items; @@ -953,7 +962,7 @@ impl RlpStream { }; if should_finish { - let x = self.unfinished_lists.pop_back().unwrap(); + let x = self.unfinished_lists.pop().unwrap(); let len = self.encoder.bytes.len() - x.position; self.encoder.insert_list_len_at_pos(len, x.position); self.note_appended(1); @@ -977,7 +986,7 @@ pub fn encode(object: &E) -> Vec where E: Encodable { let mut encoder = BasicEncoder::new(); object.encode(&mut encoder); - encoder.out() + encoder.out().to_vec() } pub trait Encodable { @@ -1030,12 +1039,12 @@ impl Encodable for Vec { } struct BasicEncoder { - bytes: Vec, + bytes: ElasticArray1024, } impl BasicEncoder { fn new() -> BasicEncoder { - BasicEncoder { bytes: vec![] } + BasicEncoder { bytes: ElasticArray1024::new() } } /// inserts list prefix at given position @@ -1054,7 +1063,7 @@ impl BasicEncoder { } /// get encoded value - fn out(self) -> Vec { + fn out(self) -> ElasticArray1024 { self.bytes } } @@ -1065,17 +1074,17 @@ impl Encoder for BasicEncoder { // just 0 0 => self.bytes.push(0x80u8), // byte is its own encoding - 1 if bytes[0] < 0x80 => self.bytes.extend(bytes), + 1 if bytes[0] < 0x80 => self.bytes.append_slice(bytes), // (prefix + length), followed by the string len @ 1 ... 55 => { self.bytes.push(0x80u8 + len as u8); - self.bytes.extend(bytes); + self.bytes.append_slice(bytes); } // (prefix + length of length), followed by the length, followd by the string len => { self.bytes.push(0xb7 + len.to_bytes_len() as u8); - self.bytes.extend(len.to_bytes()); - self.bytes.extend(bytes); + self.bytes.append_slice(&len.to_bytes()); + self.bytes.append_slice(bytes); } } } diff --git a/src/sha3.rs b/src/sha3.rs index 11d7ca274..b3676720c 100644 --- a/src/sha3.rs +++ b/src/sha3.rs @@ -1,8 +1,22 @@ +//! Wrapper around tiny-keccak crate. + use std::mem::uninitialized; use tiny_keccak::Keccak; use bytes::BytesConvertable; use hash::{FixedHash, H256}; +/// Types implementing this trait are sha3able. +/// +/// ``` +/// extern crate ethcore_util as util; +/// use std::str::FromStr; +/// use util::sha3::*; +/// use util::hash::*; +/// +/// fn main() { +/// assert_eq!([0u8; 0].sha3(), H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap()); +/// } +/// ``` pub trait Hashable { fn sha3(&self) -> H256; } diff --git a/src/triehash.rs b/src/triehash.rs index 93d21aacc..eea79e9d4 100644 --- a/src/triehash.rs +++ b/src/triehash.rs @@ -1,4 +1,4 @@ -//! Generete trie root. +//! Generetes trie root. //! //! This module should be used to generate trie root hash. @@ -10,7 +10,6 @@ use rlp; use rlp::RlpStream; use vector::SharedPrefix; -// todo: verify if example for ordered_trie_root is valid /// Generates a trie root hash for a vector of values /// /// ```rust