diff --git a/src/hash.rs b/src/hash.rs index 9eafa5dfb..78069a659 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use std::fmt; use std::ops; use std::hash::{Hash, Hasher}; -use std::ops::{Index, IndexMut, Deref, DerefMut, BitOr, BitAnd, BitXor}; +use std::ops::{Index, IndexMut, Deref, DerefMut, BitOr, BitOrAssign, BitAnd, BitXor}; use std::cmp::{PartialOrd, Ordering}; use rustc_serialize::hex::*; use error::EthcoreError; @@ -19,6 +19,8 @@ use uint::U256; /// Note: types implementing `FixedHash` must be also `BytesConvertable`. pub trait FixedHash: Sized + BytesConvertable + Populatable { fn new() -> Self; + /// Synonym for `new()`. Prefer to new as it's more readable. + fn zero() -> Self; fn random() -> Self; fn randomize(&mut self); fn size() -> usize; @@ -64,6 +66,10 @@ macro_rules! impl_hash { $from([0; $size]) } + fn zero() -> $from { + $from([0; $size]) + } + fn random() -> $from { let mut hash = $from::new(); hash.randomize(); @@ -299,6 +305,15 @@ macro_rules! impl_hash { } } + /// Moving BitOrAssign + impl<'a> BitOrAssign<&'a $from> for $from { + fn bitor_assign(&mut self, rhs: &'a Self) { + for i in 0..$size { + self.0[i] = self.0[i] | rhs.0[i]; + } + } + } + /// BitAnd on references impl <'a> BitAnd for &'a $from { type Output = $from; @@ -417,6 +432,11 @@ impl_hash!(H520, 65); impl_hash!(H1024, 128); impl_hash!(H2048, 256); +/// Constant address for point 0. Often used as a default. +pub static ZERO_ADDRESS: Address = Address([0x00; 20]); +/// Constant 256-bit datum for 0. Often used as a default. +pub static ZERO_H256: H256 = H256([0x00; 32]); + #[cfg(test)] mod tests { use hash::*; diff --git a/src/lib.rs b/src/lib.rs index 4827860c6..de2cdbdf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![feature(op_assign_traits)] //! Ethcore-util library //! //! ### Rust version: diff --git a/src/triehash.rs b/src/triehash.rs index de54bb3a7..66f9072b8 100644 --- a/src/triehash.rs +++ b/src/triehash.rs @@ -29,11 +29,8 @@ pub fn ordered_trie_root(input: Vec>) -> H256 { // first put elements into btree to sort them by nibbles // optimize it later .into_iter() - .fold(BTreeMap::new(), | mut acc, vec | { - let len = acc.len(); - acc.insert(rlp::encode(&len), vec); - acc - }) + .enumerate() + .fold(BTreeMap::new(), | mut acc, (i, vec) | { acc.insert(rlp::encode(&i), vec); acc }) // then move them to a vector .into_iter() .map(|(k, v)| (as_nibbles(&k), v) ) diff --git a/src/uint.rs b/src/uint.rs index 7fc11e2df..6fc8d19e1 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -424,6 +424,17 @@ macro_rules! construct_uint { } } + impl fmt::Display for $name { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let &$name(ref data) = self; + try!(write!(f, "0x")); + for ch in data.iter().rev() { + try!(write!(f, "{:02x}", ch)); + } + Ok(()) + } + } + impl Hash for $name { fn hash(&self, state: &mut H) where H: Hasher { unsafe { state.write(::std::slice::from_raw_parts(self.0.as_ptr() as *mut u8, self.0.len() * 8)); }