From 806de37cecaed353121f37fb81a867dfdb3dfa01 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 8 Jan 2016 11:02:32 +0100 Subject: [PATCH 1/5] Additional docs. --- src/bytes.rs | 42 +++++++++++++++++++++++++++++++++++++++--- src/crypto.rs | 2 -- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/bytes.rs b/src/bytes.rs index 91b0e849c..e6f71d446 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -35,6 +35,7 @@ //! ``` use std::fmt; +use std::slice; use std::cmp::Ordering; use std::error::Error as StdError; use uint::{U128, U256}; @@ -313,21 +314,56 @@ impl FromBytes for T where T: FixedHash { } } -// TODO: tests and additional docs for these two. - /// Simple trait to allow for raw population of a Sized object from a byte slice. pub trait Populatable { - /// Populate self from byte slice `d` in a raw fashion. + /// Copies a bunch of bytes `d` to `self`, overwriting as necessary. + /// + /// If `d` is smaller, zero-out the remaining bytes. fn populate_raw(&mut self, d: &[u8]); + + /// Copies a bunch of bytes `d` to `self`, overwriting as necessary. + /// + /// If `d` is smaller, will leave some bytes untouched. + fn copy_from_raw(&mut self, d: &[u8]); } impl Populatable for T where T: Sized { fn populate_raw(&mut self, d: &[u8]) { use std::mem; use std::slice; + unsafe { + let mut s = slice::from_raw_parts_mut(self as *mut T as *mut u8, mem::size_of::()); + for i in 0..s.len() { + s[i] = if i < d.len() {d[i]} else {0}; + } + }; + } + + fn copy_from_raw(&mut self, d: &[u8]) { + use std::mem; use std::io::Write; unsafe { slice::from_raw_parts_mut(self as *mut T as *mut u8, mem::size_of::()) }.write(&d).unwrap(); } } + +//impl Populatable for slice {} + +#[test] +fn copy_from_raw() { + let mut x = [255u8; 4]; + x.copy_from_raw(&[1u8; 2][..]); + assert_eq!(x, [1u8, 1, 255, 255]); + x.copy_from_raw(&[1u8; 6][..]); + assert_eq!(x, [1u8, 1, 1, 1]); +} + +#[test] +fn populate_raw() { + let mut x = [255u8; 4]; + x.populate_raw(&[1u8; 2][..]); + assert_eq!(x, [1u8, 1, 0, 0]); + x.populate_raw(&[1u8; 6][..]); + assert_eq!(x, [1u8, 1, 1, 1]); +} \ No newline at end of file diff --git a/src/crypto.rs b/src/crypto.rs index 9a1203921..70b3d0d0b 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -168,8 +168,6 @@ pub fn verify(public: &Public, signature: &Signature, message: &H256) -> Result< #[cfg(test)] mod tests { - - use std::str::FromStr; use hash::*; use crypto::*; From f0da76df7c7ba51f437669063d8853d9c8a39282 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 8 Jan 2016 11:43:11 +0100 Subject: [PATCH 2/5] API cleanups. --- src/bytes.rs | 86 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/src/bytes.rs b/src/bytes.rs index e6f71d446..7eae51a44 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -319,43 +319,68 @@ pub trait Populatable { /// Copies a bunch of bytes `d` to `self`, overwriting as necessary. /// /// If `d` is smaller, zero-out the remaining bytes. - fn populate_raw(&mut self, d: &[u8]); + fn populate_raw(&mut self, d: &[u8]) { + let mut s = self.as_slice_mut(); + for i in 0..s.len() { + s[i] = if i < d.len() {d[i]} else {0}; + } + } /// Copies a bunch of bytes `d` to `self`, overwriting as necessary. /// /// If `d` is smaller, will leave some bytes untouched. - fn copy_from_raw(&mut self, d: &[u8]); + fn fax_raw(&mut self, d: &[u8]) { + use std::io::Write; + self.as_slice_mut().write(&d).unwrap(); + } + + /// Copies a bunch of bytes `d` to `self`, overwriting as necessary. + /// + /// If `d` is smaller, will leave some bytes untouched. + fn fax_right_raw(&mut self, d: &[u8]) { + use std::io::Write; + self.as_slice_mut().write(&d).unwrap(); + } + + /// Copies the raw representation of an object `d` to `self`, overwriting as necessary. + /// + /// If `d` is smaller, zero-out the remaining bytes. + fn populate_raw_from(&mut self, d: &BytesConvertable) { self.populate_raw(d.as_slice()); } + + /// Copies the raw representation of an object `d` to `self`, overwriting as necessary. + /// + /// If `d` is smaller, will leave some bytes untouched. + fn fax_raw_from(&mut self, d: &BytesConvertable) { self.populate_raw(d.as_slice()); } + + /// Get the raw slice for this object. + fn as_slice_mut(&mut self) -> &mut [u8]; } impl Populatable for T where T: Sized { - fn populate_raw(&mut self, d: &[u8]) { + fn as_slice_mut(&mut self) -> &mut [u8] { use std::mem; - use std::slice; - unsafe { - let mut s = slice::from_raw_parts_mut(self as *mut T as *mut u8, mem::size_of::()); - for i in 0..s.len() { - s[i] = if i < d.len() {d[i]} else {0}; - } - }; - } - - fn copy_from_raw(&mut self, d: &[u8]) { - use std::mem; - use std::io::Write; unsafe { slice::from_raw_parts_mut(self as *mut T as *mut u8, mem::size_of::()) - }.write(&d).unwrap(); + } } } -//impl Populatable for slice {} +impl Populatable for [T] where T: Sized { + fn as_slice_mut(&mut self) -> &mut [u8] { + use std::mem; + unsafe { + slice::from_raw_parts_mut(self.as_mut_ptr() as *mut u8, mem::size_of::() * self.len()) + } + } +} #[test] -fn copy_from_raw() { +fn fax_raw() { let mut x = [255u8; 4]; - x.copy_from_raw(&[1u8; 2][..]); + x.fax_raw(&[1u8; 2][..]); assert_eq!(x, [1u8, 1, 255, 255]); - x.copy_from_raw(&[1u8; 6][..]); + let mut x = [255u8; 4]; + x.fax_raw(&[1u8; 6][..]); assert_eq!(x, [1u8, 1, 1, 1]); } @@ -364,6 +389,27 @@ fn populate_raw() { let mut x = [255u8; 4]; x.populate_raw(&[1u8; 2][..]); assert_eq!(x, [1u8, 1, 0, 0]); + let mut x = [255u8; 4]; x.populate_raw(&[1u8; 6][..]); assert_eq!(x, [1u8, 1, 1, 1]); +} + +#[test] +fn populate_raw_dyn() { + let mut x = [255u8; 4]; + x.populate_raw(&[1u8; 2][..]); + assert_eq!(&x[..], [1u8, 1, 0, 0]); + let mut x = [255u8; 4]; + x.populate_raw(&[1u8; 6][..]); + assert_eq!(&x[..], [1u8, 1, 1, 1]); +} + +#[test] +fn fax_raw_dyn() { + let mut x = [255u8; 4]; + x.fax_raw(&[1u8; 2][..]); + assert_eq!(&x[..], [1u8, 1, 255, 255]); + let mut x = [255u8; 4]; + x.fax_raw(&[1u8; 6][..]); + assert_eq!(&x[..], [1u8, 1, 1, 1]); } \ No newline at end of file From 3018c4a28a68072ff71b6229c7ddb491b1a541f6 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 8 Jan 2016 11:52:46 +0100 Subject: [PATCH 3/5] Additional Populatable API tweaks. --- src/hash.rs | 9 ++------- src/sha3.rs | 4 ++-- src/trie/triedbmut.rs | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/hash.rs b/src/hash.rs index e6f9a61c7..2fb4b71e6 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -10,19 +10,18 @@ use rustc_serialize::hex::*; use error::EthcoreError; use rand::Rng; use rand::os::OsRng; -use bytes::BytesConvertable; +use bytes::{BytesConvertable,Populatable}; use math::log2; use uint::U256; /// Trait for a fixed-size byte array to be used as the output of hash functions. /// /// Note: types implementing `FixedHash` must be also `BytesConvertable`. -pub trait FixedHash: Sized + BytesConvertable { +pub trait FixedHash: Sized + BytesConvertable + Populatable { fn new() -> Self; fn random() -> Self; fn randomize(&mut self); fn size() -> usize; - fn as_slice_mut(&mut self) -> &mut [u8]; fn from_slice(src: &[u8]) -> Self; fn clone_from_slice(&mut self, src: &[u8]) -> usize; fn shift_bloom<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash; @@ -78,10 +77,6 @@ macro_rules! impl_hash { $size } - fn as_slice_mut(&mut self) -> &mut [u8] { - &mut self.0 - } - // TODO: remove once slice::clone_from_slice is stable #[inline] fn clone_from_slice(&mut self, src: &[u8]) -> usize { diff --git a/src/sha3.rs b/src/sha3.rs index e1337c5f7..f3faa4e3b 100644 --- a/src/sha3.rs +++ b/src/sha3.rs @@ -2,8 +2,8 @@ use std::mem::uninitialized; use tiny_keccak::Keccak; -use bytes::BytesConvertable; -use hash::{FixedHash, H256}; +use bytes::{BytesConvertable,Populatable}; +use hash::H256; /// Types implementing this trait are sha3able. /// diff --git a/src/trie/triedbmut.rs b/src/trie/triedbmut.rs index e04b7c758..a51e56a83 100644 --- a/src/trie/triedbmut.rs +++ b/src/trie/triedbmut.rs @@ -668,7 +668,7 @@ mod tests { use env_logger; use rand::random; use std::collections::HashSet; - use bytes::{ToPretty,Bytes}; + use bytes::{ToPretty,Bytes,Populatable}; use super::super::node::*; use super::super::trietraits::*; From f81fb2de51dcd710e7dc6ec9757eb810d939604e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 8 Jan 2016 12:02:26 +0100 Subject: [PATCH 4/5] Fix and some tests for opaque types in populatable. --- src/bytes.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/bytes.rs b/src/bytes.rs index 7eae51a44..133de416b 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -334,14 +334,6 @@ pub trait Populatable { self.as_slice_mut().write(&d).unwrap(); } - /// Copies a bunch of bytes `d` to `self`, overwriting as necessary. - /// - /// If `d` is smaller, will leave some bytes untouched. - fn fax_right_raw(&mut self, d: &[u8]) { - use std::io::Write; - self.as_slice_mut().write(&d).unwrap(); - } - /// Copies the raw representation of an object `d` to `self`, overwriting as necessary. /// /// If `d` is smaller, zero-out the remaining bytes. @@ -350,7 +342,7 @@ pub trait Populatable { /// Copies the raw representation of an object `d` to `self`, overwriting as necessary. /// /// If `d` is smaller, will leave some bytes untouched. - fn fax_raw_from(&mut self, d: &BytesConvertable) { self.populate_raw(d.as_slice()); } + fn fax_raw_from(&mut self, d: &BytesConvertable) { self.fax_raw(d.as_slice()); } /// Get the raw slice for this object. fn as_slice_mut(&mut self) -> &mut [u8]; @@ -412,4 +404,16 @@ fn fax_raw_dyn() { let mut x = [255u8; 4]; x.fax_raw(&[1u8; 6][..]); assert_eq!(&x[..], [1u8, 1, 1, 1]); +} + +#[test] +fn populate_big_types() { + use hash::*; + let a = address_from_hex("ffffffffffffffffffffffffffffffffffffffff"); + let mut h = h256_from_u64(0x69); + h.populate_raw_from(&a); + assert_eq!(h, h256_from_hex("ffffffffffffffffffffffffffffffffffffffff000000000000000000000000")); + let mut h = h256_from_u64(0x69); + h.fax_raw_from(&a); + assert_eq!(h, h256_from_hex("ffffffffffffffffffffffffffffffffffffffff000000000000000000000069")); } \ No newline at end of file From e4ed6467a92354e739f2d1b3aabfd6d4562a7d11 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 8 Jan 2016 12:05:38 +0100 Subject: [PATCH 5/5] Fixes and renaming fax->copy. --- src/bytes.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bytes.rs b/src/bytes.rs index 133de416b..5ffc72c08 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -329,7 +329,7 @@ pub trait Populatable { /// Copies a bunch of bytes `d` to `self`, overwriting as necessary. /// /// If `d` is smaller, will leave some bytes untouched. - fn fax_raw(&mut self, d: &[u8]) { + fn copy_raw(&mut self, d: &[u8]) { use std::io::Write; self.as_slice_mut().write(&d).unwrap(); } @@ -342,7 +342,7 @@ pub trait Populatable { /// Copies the raw representation of an object `d` to `self`, overwriting as necessary. /// /// If `d` is smaller, will leave some bytes untouched. - fn fax_raw_from(&mut self, d: &BytesConvertable) { self.fax_raw(d.as_slice()); } + fn copy_raw_from(&mut self, d: &BytesConvertable) { self.copy_raw(d.as_slice()); } /// Get the raw slice for this object. fn as_slice_mut(&mut self) -> &mut [u8]; @@ -369,10 +369,10 @@ impl Populatable for [T] where T: Sized { #[test] fn fax_raw() { let mut x = [255u8; 4]; - x.fax_raw(&[1u8; 2][..]); + x.copy_raw(&[1u8; 2][..]); assert_eq!(x, [1u8, 1, 255, 255]); let mut x = [255u8; 4]; - x.fax_raw(&[1u8; 6][..]); + x.copy_raw(&[1u8; 6][..]); assert_eq!(x, [1u8, 1, 1, 1]); } @@ -399,10 +399,10 @@ fn populate_raw_dyn() { #[test] fn fax_raw_dyn() { let mut x = [255u8; 4]; - x.fax_raw(&[1u8; 2][..]); + x.copy_raw(&[1u8; 2][..]); assert_eq!(&x[..], [1u8, 1, 255, 255]); let mut x = [255u8; 4]; - x.fax_raw(&[1u8; 6][..]); + x.copy_raw(&[1u8; 6][..]); assert_eq!(&x[..], [1u8, 1, 1, 1]); } @@ -414,6 +414,6 @@ fn populate_big_types() { h.populate_raw_from(&a); assert_eq!(h, h256_from_hex("ffffffffffffffffffffffffffffffffffffffff000000000000000000000000")); let mut h = h256_from_u64(0x69); - h.fax_raw_from(&a); + h.copy_raw_from(&a); assert_eq!(h, h256_from_hex("ffffffffffffffffffffffffffffffffffffffff000000000000000000000069")); } \ No newline at end of file