Merge branch 'master' of github.com:gavofyork/ethcore-util
This commit is contained in:
commit
5a889a35be
@ -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" }
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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;
|
||||||
|
47
src/rlp.rs
47
src/rlp.rs
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
src/sha3.rs
14
src/sha3.rs
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user