Merge branch 'master' of github.com:gavofyork/ethcore-util

This commit is contained in:
Gav Wood 2015-12-07 15:03:02 +01:00
commit 5a889a35be
6 changed files with 46 additions and 25 deletions

View File

@ -19,6 +19,7 @@ rocksdb = "0.2.1"
lazy_static = "0.1.*" lazy_static = "0.1.*"
secp256k1 = "0.5.1" secp256k1 = "0.5.1"
rust-crypto = "0.2.34" rust-crypto = "0.2.34"
elastic-array = "0.4"
[dev-dependencies] [dev-dependencies]
json-tests = { path = "json-tests" } json-tests = { path = "json-tests" }

View File

@ -7,13 +7,10 @@ extern crate ethcore_util;
extern crate log; extern crate log;
use test::Bencher; use test::Bencher;
use rand::random;
//use ethcore_util::BytesConvertable;
use ethcore_util::hash::*; use ethcore_util::hash::*;
use ethcore_util::bytes::*; use ethcore_util::bytes::*;
use ethcore_util::trie::*; use ethcore_util::trie::*;
use ethcore_util::sha3::*; use ethcore_util::sha3::*;
use ethcore_util::ToBytes::*;
fn random_word(alphabet: &[u8], min_count: usize, diff_count: usize, seed: &mut H256) -> Vec<u8> { fn random_word(alphabet: &[u8], min_count: usize, diff_count: usize, seed: &mut H256) -> Vec<u8> {
@ -121,7 +118,7 @@ fn insertions_six_low(b: &mut Bencher) {
fn sha3x1000(b: &mut Bencher) { fn sha3x1000(b: &mut Bencher) {
b.iter(||{ b.iter(||{
let mut seed = H256::new(); let mut seed = H256::new();
for i in 0..1000 { for _ in 0..1000 {
seed = seed.sha3() seed = seed.sha3()
} }
}) })

View File

@ -42,6 +42,7 @@ extern crate time;
extern crate crypto as rcrypto; extern crate crypto as rcrypto;
extern crate secp256k1; extern crate secp256k1;
extern crate arrayvec; extern crate arrayvec;
extern crate elastic_array;
pub mod macros; pub mod macros;
pub mod error; pub mod error;

View File

@ -32,8 +32,8 @@
use std::fmt; use std::fmt;
use std::cell::Cell; use std::cell::Cell;
use std::collections::LinkedList;
use std::error::Error as StdError; use std::error::Error as StdError;
use elastic_array::*;
use bytes::{ToBytes, FromBytes, FromBytesError}; use bytes::{ToBytes, FromBytes, FromBytesError};
use vector::InsertSlice; use vector::InsertSlice;
@ -759,7 +759,7 @@ impl Decoder for BasicDecoder {
} }
} }
#[derive(Debug)] #[derive(Debug, Copy, Clone)]
struct ListInfo { struct ListInfo {
position: usize, position: usize,
current: usize, current: usize,
@ -778,7 +778,7 @@ impl ListInfo {
/// Appendable rlp encoder. /// Appendable rlp encoder.
pub struct RlpStream { pub struct RlpStream {
unfinished_lists: LinkedList<ListInfo>, unfinished_lists: ElasticArray16<ListInfo>,
encoder: BasicEncoder, encoder: BasicEncoder,
} }
@ -786,7 +786,7 @@ impl RlpStream {
/// Initializes instance of empty `RlpStream`. /// Initializes instance of empty `RlpStream`.
pub fn new() -> RlpStream { pub fn new() -> RlpStream {
RlpStream { RlpStream {
unfinished_lists: LinkedList::new(), unfinished_lists: ElasticArray16::new(),
encoder: BasicEncoder::new(), encoder: BasicEncoder::new(),
} }
} }
@ -844,8 +844,12 @@ impl RlpStream {
// we may finish, if the appended list len is equal 0 // we may finish, if the appended list len is equal 0
self.encoder.bytes.push(0xc0u8); self.encoder.bytes.push(0xc0u8);
self.note_appended(1); 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 // return chainable self
@ -879,7 +883,7 @@ impl RlpStream {
/// Appends raw (pre-serialised) RLP data. Use with caution. Chainable. /// 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 { pub fn append_raw<'a>(&'a mut self, bytes: &[u8], item_count: usize) -> &'a mut RlpStream {
// push raw items // push raw items
self.encoder.bytes.extend(bytes); self.encoder.bytes.append_slice(bytes);
// try to finish and prepend the length // try to finish and prepend the length
self.note_appended(item_count); 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']); /// 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 { pub fn is_finished(&self) -> bool {
self.unfinished_lists.back().is_none() self.unfinished_lists.len() == 0
} }
/// Streams out encoded bytes. /// Streams out encoded bytes.
@ -934,14 +938,19 @@ impl RlpStream {
/// panic! if stream is not finished. /// panic! if stream is not finished.
pub fn out(self) -> Vec<u8> { pub fn out(self) -> Vec<u8> {
match self.is_finished() { match self.is_finished() {
true => self.encoder.out(), true => self.encoder.out().to_vec(),
false => panic!() false => panic!()
} }
} }
/// Try to finish lists /// Try to finish lists
fn note_appended(&mut self, inserted_items: usize) -> () { 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, None => false,
Some(ref mut x) => { Some(ref mut x) => {
x.current += inserted_items; x.current += inserted_items;
@ -953,7 +962,7 @@ impl RlpStream {
}; };
if should_finish { 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; let len = self.encoder.bytes.len() - x.position;
self.encoder.insert_list_len_at_pos(len, x.position); self.encoder.insert_list_len_at_pos(len, x.position);
self.note_appended(1); self.note_appended(1);
@ -977,7 +986,7 @@ pub fn encode<E>(object: &E) -> Vec<u8> where E: Encodable
{ {
let mut encoder = BasicEncoder::new(); let mut encoder = BasicEncoder::new();
object.encode(&mut encoder); object.encode(&mut encoder);
encoder.out() encoder.out().to_vec()
} }
pub trait Encodable { pub trait Encodable {
@ -1030,12 +1039,12 @@ impl Encodable for Vec<u8> {
} }
struct BasicEncoder { struct BasicEncoder {
bytes: Vec<u8>, bytes: ElasticArray1024<u8>,
} }
impl BasicEncoder { impl BasicEncoder {
fn new() -> BasicEncoder { fn new() -> BasicEncoder {
BasicEncoder { bytes: vec![] } BasicEncoder { bytes: ElasticArray1024::new() }
} }
/// inserts list prefix at given position /// inserts list prefix at given position
@ -1054,7 +1063,7 @@ impl BasicEncoder {
} }
/// get encoded value /// get encoded value
fn out(self) -> Vec<u8> { fn out(self) -> ElasticArray1024<u8> {
self.bytes self.bytes
} }
} }
@ -1065,17 +1074,17 @@ impl Encoder for BasicEncoder {
// just 0 // just 0
0 => self.bytes.push(0x80u8), 0 => self.bytes.push(0x80u8),
// byte is its own encoding // 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 // (prefix + length), followed by the string
len @ 1 ... 55 => { len @ 1 ... 55 => {
self.bytes.push(0x80u8 + len as u8); 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 // (prefix + length of length), followed by the length, followd by the string
len => { len => {
self.bytes.push(0xb7 + len.to_bytes_len() as u8); self.bytes.push(0xb7 + len.to_bytes_len() as u8);
self.bytes.extend(len.to_bytes()); self.bytes.append_slice(&len.to_bytes());
self.bytes.extend(bytes); self.bytes.append_slice(bytes);
} }
} }
} }

View File

@ -1,8 +1,22 @@
//! Wrapper around tiny-keccak crate.
use std::mem::uninitialized; use std::mem::uninitialized;
use tiny_keccak::Keccak; use tiny_keccak::Keccak;
use bytes::BytesConvertable; use bytes::BytesConvertable;
use hash::{FixedHash, H256}; 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 { pub trait Hashable {
fn sha3(&self) -> H256; fn sha3(&self) -> H256;
} }

View File

@ -1,4 +1,4 @@
//! Generete trie root. //! Generetes trie root.
//! //!
//! This module should be used to generate trie root hash. //! This module should be used to generate trie root hash.
@ -10,7 +10,6 @@ use rlp;
use rlp::RlpStream; use rlp::RlpStream;
use vector::SharedPrefix; use vector::SharedPrefix;
// todo: verify if example for ordered_trie_root is valid
/// Generates a trie root hash for a vector of values /// Generates a trie root hash for a vector of values
/// ///
/// ```rust /// ```rust