get rid of populatable and bytesconvertable traits (#2019)

This commit is contained in:
Robert Habermeier 2016-09-01 12:23:31 +02:00 committed by Arkadiy Paronyan
parent 3439c06a1c
commit 9a5668f802
17 changed files with 54 additions and 203 deletions

View File

@ -127,14 +127,14 @@ impl Impl for EcRecover {
let s = H256::from_slice(&input[96..128]); let s = H256::from_slice(&input[96..128]);
let bit = match v[31] { let bit = match v[31] {
27 | 28 if &v.as_slice()[..31] == &[0; 31] => v[31] - 27, 27 | 28 if &v.0[..31] == &[0; 31] => v[31] - 27,
_ => return, _ => return,
}; };
let s = Signature::from_rsv(&r, &s, bit); let s = Signature::from_rsv(&r, &s, bit);
if s.is_valid() { if s.is_valid() {
if let Ok(p) = ec_recover(&s, &hash) { if let Ok(p) = ec_recover(&s, &hash) {
let r = p.as_slice().sha3(); let r = p.sha3();
let out_len = min(output.len(), 32); let out_len = min(output.len(), 32);

View File

@ -28,7 +28,7 @@ use ethkey::Error as EthkeyError;
pub use types::executed::{ExecutionError, CallError}; pub use types::executed::{ExecutionError, CallError};
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone, Copy)]
/// Errors concerning transaction processing. /// Errors concerning transaction processing.
pub enum TransactionError { pub enum TransactionError {
/// Transaction is already imported to the queue /// Transaction is already imported to the queue
@ -87,7 +87,7 @@ impl fmt::Display for TransactionError {
} }
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Clone, Copy, Eq)]
/// Errors concerning block processing. /// Errors concerning block processing.
pub enum BlockError { pub enum BlockError {
/// Block has too many uncles. /// Block has too many uncles.
@ -185,7 +185,7 @@ impl fmt::Display for BlockError {
} }
} }
#[derive(Debug, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
/// Import to the block queue result /// Import to the block queue result
pub enum ImportError { pub enum ImportError {
/// Already in the block chain. /// Already in the block chain.

View File

@ -76,7 +76,7 @@ impl<Gas: CostType> Gasometer<Gas> {
instructions::SSTORE => { instructions::SSTORE => {
let address = H256::from(stack.peek(0)); let address = H256::from(stack.peek(0));
let newval = stack.peek(1); let newval = stack.peek(1);
let val = U256::from(ext.storage_at(&address).as_slice()); let val = U256::from(&*ext.storage_at(&address));
let gas = if val.is_zero() && !newval.is_zero() { let gas = if val.is_zero() && !newval.is_zero() {
schedule.sstore_set_gas schedule.sstore_set_gas

View File

@ -403,18 +403,18 @@ impl<Cost: CostType> Interpreter<Cost> {
let offset = stack.pop_back(); let offset = stack.pop_back();
let size = stack.pop_back(); let size = stack.pop_back();
let sha3 = self.mem.read_slice(offset, size).sha3(); let sha3 = self.mem.read_slice(offset, size).sha3();
stack.push(U256::from(sha3.as_slice())); stack.push(U256::from(&*sha3));
}, },
instructions::SLOAD => { instructions::SLOAD => {
let key = H256::from(&stack.pop_back()); let key = H256::from(&stack.pop_back());
let word = U256::from(ext.storage_at(&key).as_slice()); let word = U256::from(&*ext.storage_at(&key));
stack.push(word); stack.push(word);
}, },
instructions::SSTORE => { instructions::SSTORE => {
let address = H256::from(&stack.pop_back()); let address = H256::from(&stack.pop_back());
let val = stack.pop_back(); let val = stack.pop_back();
let current_val = U256::from(ext.storage_at(&address).as_slice()); let current_val = U256::from(&*ext.storage_at(&address));
// Increase refund for clear // Increase refund for clear
if !self.is_zero(&current_val) && self.is_zero(&val) { if !self.is_zero(&current_val) && self.is_zero(&val) {
ext.inc_sstore_clears(); ext.inc_sstore_clears();
@ -491,7 +491,7 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::BLOCKHASH => { instructions::BLOCKHASH => {
let block_number = stack.pop_back(); let block_number = stack.pop_back();
let block_hash = ext.blockhash(&block_number); let block_hash = ext.blockhash(&block_number);
stack.push(U256::from(block_hash.as_slice())); stack.push(U256::from(&*block_hash));
}, },
instructions::COINBASE => { instructions::COINBASE => {
stack.push(address_to_u256(ext.env_info().author.clone())); stack.push(address_to_u256(ext.env_info().author.clone()));
@ -807,7 +807,7 @@ fn u256_to_address(value: &U256) -> Address {
#[inline] #[inline]
fn address_to_u256(value: Address) -> U256 { fn address_to_u256(value: Address) -> U256 {
U256::from(H256::from(value).as_slice()) U256::from(&*H256::from(value))
} }
#[test] #[test]

View File

@ -57,7 +57,7 @@ impl PodAccount {
let mut stream = RlpStream::new_list(4); let mut stream = RlpStream::new_list(4);
stream.append(&self.nonce); stream.append(&self.nonce);
stream.append(&self.balance); stream.append(&self.balance);
stream.append(&sec_trie_root(self.storage.iter().map(|(k, v)| (k.to_vec(), encode(&U256::from(v.as_slice())).to_vec())).collect())); stream.append(&sec_trie_root(self.storage.iter().map(|(k, v)| (k.to_vec(), encode(&U256::from(&**v)).to_vec())).collect()));
stream.append(&self.code.as_ref().unwrap_or(&vec![]).sha3()); stream.append(&self.code.as_ref().unwrap_or(&vec![]).sha3());
stream.out() stream.out()
} }
@ -71,7 +71,7 @@ impl PodAccount {
let mut r = H256::new(); let mut r = H256::new();
let mut t = SecTrieDBMut::new(db, &mut r); let mut t = SecTrieDBMut::new(db, &mut r);
for (k, v) in &self.storage { for (k, v) in &self.storage {
if let Err(e) = t.insert(k, &encode(&U256::from(v.as_slice()))) { if let Err(e) = t.insert(k, &encode(&U256::from(&**v))) {
warn!("Encountered potential DB corruption: {}", e); warn!("Encountered potential DB corruption: {}", e);
} }
} }

View File

@ -231,7 +231,7 @@ impl Spec {
{ {
let mut t = SecTrieDBMut::new(db, &mut root); let mut t = SecTrieDBMut::new(db, &mut root);
for (address, account) in self.genesis_state.get().iter() { for (address, account) in self.genesis_state.get().iter() {
try!(t.insert(address.as_slice(), &account.rlp())); try!(t.insert(&**address, &account.rlp()));
} }
} }
for (address, account) in self.genesis_state.get().iter() { for (address, account) in self.genesis_state.get().iter() {

View File

@ -287,7 +287,7 @@ impl Account {
// so we can call overloaded `to_bytes` method // so we can call overloaded `to_bytes` method
let res = match v.is_zero() { let res = match v.is_zero() {
true => t.remove(k), true => t.remove(k),
false => t.insert(k, &encode(&U256::from(v.as_slice()))), false => t.insert(k, &encode(&U256::from(&*v))),
}; };
if let Err(e) = res { if let Err(e) = res {

View File

@ -98,12 +98,10 @@ impl AccountDiff {
// TODO: refactor into something nicer. // TODO: refactor into something nicer.
fn interpreted_hash(u: &H256) -> String { fn interpreted_hash(u: &H256) -> String {
use util::bytes::*;
if u <= &H256::from(0xffffffff) { if u <= &H256::from(0xffffffff) {
format!("{} = 0x{:x}", U256::from(u.as_slice()).low_u32(), U256::from(u.as_slice()).low_u32()) format!("{} = 0x{:x}", U256::from(&**u).low_u32(), U256::from(&**u).low_u32())
} else if u <= &H256::from(u64::max_value()) { } else if u <= &H256::from(u64::max_value()) {
format!("{} = 0x{:x}", U256::from(u.as_slice()).low_u64(), U256::from(u.as_slice()).low_u64()) format!("{} = 0x{:x}", U256::from(&**u).low_u64(), U256::from(&**u).low_u64())
// } else if u <= &H256::from("0xffffffffffffffffffffffffffffffffffffffff") { // } else if u <= &H256::from("0xffffffffffffffffffffffffffffffffffffffff") {
// format!("@{}", Address::from(u)) // format!("@{}", Address::from(u))
} else { } else {
@ -113,7 +111,7 @@ fn interpreted_hash(u: &H256) -> String {
impl fmt::Display for AccountDiff { impl fmt::Display for AccountDiff {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use util::bytes::*; use util::bytes::ToPretty;
match self.nonce { match self.nonce {
Diff::Born(ref x) => try!(write!(f, " non {}", x)), Diff::Born(ref x) => try!(write!(f, " non {}", x)),

View File

@ -18,9 +18,8 @@
use ipc::binary::{BinaryConvertError, BinaryConvertable}; use ipc::binary::{BinaryConvertError, BinaryConvertable};
use error::{TransactionError, Error}; use error::{TransactionError, Error};
use util::Populatable;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
/// Represents the result of importing transaction. /// Represents the result of importing transaction.
pub enum TransactionImportResult { pub enum TransactionImportResult {
/// Transaction was imported to current queue. /// Transaction was imported to current queue.

View File

@ -16,7 +16,6 @@
//! Binary representation of types //! Binary representation of types
use util::bytes::Populatable;
use util::{U256, U512, H256, H2048, Address}; use util::{U256, U512, H256, H2048, Address};
use std::mem; use std::mem;
use std::collections::{VecDeque, BTreeMap}; use std::collections::{VecDeque, BTreeMap};
@ -706,14 +705,21 @@ pub fn serialize<T: BinaryConvertable>(t: &T) -> Result<Vec<u8>, BinaryError> {
#[macro_export] #[macro_export]
macro_rules! binary_fixed_size { macro_rules! binary_fixed_size {
($target_ty: ty) => { ($target_ty: ty) => {
impl BinaryConvertable for $target_ty { impl BinaryConvertable for $target_ty where $target_ty: Copy {
fn from_bytes(bytes: &[u8], _length_stack: &mut ::std::collections::VecDeque<usize>) -> Result<Self, BinaryConvertError> { fn from_bytes(bytes: &[u8], _length_stack: &mut ::std::collections::VecDeque<usize>) -> Result<Self, BinaryConvertError> {
match bytes.len().cmp(&::std::mem::size_of::<$target_ty>()) { let size = ::std::mem::size_of::<$target_ty>();
match bytes.len().cmp(&size) {
::std::cmp::Ordering::Equal => (), ::std::cmp::Ordering::Equal => (),
_ => return Err(BinaryConvertError::size(::std::mem::size_of::<$target_ty>(), bytes.len())), _ => return Err(BinaryConvertError::size(size, bytes.len())),
}; };
let mut res: Self = unsafe { ::std::mem::uninitialized() }; let res: Self = unsafe {
res.copy_raw(bytes); let mut temp = ::std::mem::zeroed();
let temp_ptr = &mut temp as *mut _ as *mut u8;
::std::ptr::copy_nonoverlapping(bytes.as_ptr(), temp_ptr, size);
temp
};
Ok(res) Ok(res)
} }
@ -731,14 +737,14 @@ macro_rules! binary_fixed_size {
} }
/// Fixed-sized version of Handshake struct /// Fixed-sized version of Handshake struct
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BinHandshake { pub struct BinHandshake {
api_version: BinVersion, api_version: BinVersion,
protocol_version: BinVersion, protocol_version: BinVersion,
} }
/// Shorten version of semver Version without `pre` and `build` information /// Shorten version of semver Version without `pre` and `build` information
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BinVersion { pub struct BinVersion {
pub major: u64, pub major: u64,
pub minor: u64, pub minor: u64,

View File

@ -17,7 +17,7 @@
use std::sync::Arc; use std::sync::Arc;
use network::{NetworkProtocolHandler, NetworkService, NetworkContext, PeerId, use network::{NetworkProtocolHandler, NetworkService, NetworkContext, PeerId,
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError}; NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError};
use util::{U256, H256, Populatable}; use util::{U256, H256};
use io::{TimerToken}; use io::{TimerToken};
use ethcore::client::{BlockChainClient, ChainNotify}; use ethcore::client::{BlockChainClient, ChainNotify};
use ethcore::header::BlockNumber; use ethcore::header::BlockNumber;
@ -32,7 +32,7 @@ use parking_lot::RwLock;
pub const ETH_PROTOCOL: &'static str = "eth"; pub const ETH_PROTOCOL: &'static str = "eth";
/// Sync configuration /// Sync configuration
#[derive(Debug, Clone)] #[derive(Debug, Clone, Copy)]
pub struct SyncConfig { pub struct SyncConfig {
/// Max blocks to download ahead /// Max blocks to download ahead
pub max_download_ahead_blocks: usize, pub max_download_ahead_blocks: usize,

View File

@ -156,7 +156,7 @@ pub enum SyncState {
} }
/// Syncing status and statistics /// Syncing status and statistics
#[derive(Clone)] #[derive(Clone, Copy)]
pub struct SyncStatus { pub struct SyncStatus {
/// State /// State
pub state: SyncState, pub state: SyncState,

View File

@ -14,26 +14,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Unified interfaces for bytes operations on basic types //! General bytes-related utilities.
//! //!
//! # Examples //! Includes a pretty-printer for bytes, in the form of `ToPretty` and `PrettySlice`
//! ```rust //! as
//! extern crate ethcore_util as util;
//!
//! fn bytes_convertable() {
//! use util::bytes::BytesConvertable;
//!
//! let arr = [0; 5];
//! let slice: &[u8] = arr.as_slice();
//! }
//!
//! fn main() {
//! bytes_convertable();
//! }
//! ```
use std::fmt; use std::fmt;
use std::slice;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
/// Slice pretty print helper /// Slice pretty print helper
@ -71,20 +57,9 @@ pub trait ToPretty {
} }
} }
impl<'a> ToPretty for &'a [u8] { impl<T: AsRef<[u8]>> ToPretty for T {
fn pretty(&self) -> PrettySlice { fn pretty(&self) -> PrettySlice {
PrettySlice(self) PrettySlice(self.as_ref())
}
}
impl<'a> ToPretty for &'a Bytes {
fn pretty(&self) -> PrettySlice {
PrettySlice(self.as_slice())
}
}
impl ToPretty for Bytes {
fn pretty(&self) -> PrettySlice {
PrettySlice(self.as_slice())
} }
} }
@ -116,128 +91,5 @@ impl <'a> DerefMut for BytesRef<'a> {
} }
} }
/// Vector of bytes /// Vector of bytes.
pub type Bytes = Vec<u8>; pub type Bytes = Vec<u8>;
/// Slice of bytes to underlying memory
pub trait BytesConvertable {
/// Get the underlying byte-wise representation of the value.
fn as_slice(&self) -> &[u8];
/// Get a copy of the underlying byte-wise representation.
fn to_bytes(&self) -> Bytes { self.as_slice().to_vec() }
}
impl<T> BytesConvertable for T where T: AsRef<[u8]> {
fn as_slice(&self) -> &[u8] { self.as_ref() }
}
#[test]
fn bytes_convertable() {
assert_eq!(vec![0x12u8, 0x34].as_slice(), &[0x12u8, 0x34]);
assert!([0u8; 0].as_slice().is_empty());
}
/// Simple trait to allow for raw population of a Sized object from a byte slice.
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]) {
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_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 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];
}
impl<T> 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 T as *mut u8, mem::size_of::<T>())
}
}
}
impl<T> 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::<T>() * self.len())
}
}
}
#[test]
fn fax_raw() {
let mut x = [255u8; 4];
x.copy_raw(&[1u8; 2][..]);
assert_eq!(x, [1u8, 1, 255, 255]);
let mut x = [255u8; 4];
x.copy_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]);
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.copy_raw(&[1u8; 2][..]);
assert_eq!(&x[..], [1u8, 1, 255, 255]);
let mut x = [255u8; 4];
x.copy_raw(&[1u8; 6][..]);
assert_eq!(&x[..], [1u8, 1, 1, 1]);
}
#[test]
fn populate_big_types() {
use hash::*;
let a: H160 = "ffffffffffffffffffffffffffffffffffffffff".into();
let mut h: H256 = 0x69.into();
h.populate_raw_from(&a);
assert_eq!(h, "ffffffffffffffffffffffffffffffffffffffff000000000000000000000000".into());
let mut h: H256 = 0x69.into();
h.copy_raw_from(&a);
assert_eq!(h, "ffffffffffffffffffffffffffffffffffffffff000000000000000000000069".into());
}

View File

@ -74,7 +74,7 @@ impl fmt::Display for UtilError {
} }
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
/// Error indicating an expected value was not found. /// Error indicating an expected value was not found.
pub struct Mismatch<T: fmt::Debug> { pub struct Mismatch<T: fmt::Debug> {
/// Value expected. /// Value expected.
@ -89,7 +89,7 @@ impl<T: fmt::Debug + fmt::Display> fmt::Display for Mismatch<T> {
} }
} }
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
/// Error indicating value found is outside of a valid range. /// Error indicating value found is outside of a valid range.
pub struct OutOfBounds<T: fmt::Debug> { pub struct OutOfBounds<T: fmt::Debug> {
/// Minimum allowed value. /// Minimum allowed value.

View File

@ -95,7 +95,7 @@ impl EarlyMergeDB {
} }
fn morph_key(key: &H256, index: u8) -> Bytes { fn morph_key(key: &H256, index: u8) -> Bytes {
let mut ret = key.to_bytes(); let mut ret = (&**key).to_owned();
ret.push(index); ret.push(index);
ret ret
} }

View File

@ -296,8 +296,8 @@ fn memorydb_denote() {
for _ in 0..1000 { for _ in 0..1000 {
let r = H256::random(); let r = H256::random();
let k = r.sha3(); let k = r.sha3();
let (v, rc) = m.denote(&k, r.to_bytes()); let (v, rc) = m.denote(&k, r.to_vec());
assert_eq!(v, r.as_slice()); assert_eq!(v, &*r);
assert_eq!(rc, 0); assert_eq!(rc, 0);
} }

View File

@ -18,16 +18,13 @@
extern crate sha3 as sha3_ext; extern crate sha3 as sha3_ext;
use std::io; use std::io;
use std::mem::uninitialized;
use tiny_keccak::Keccak; use tiny_keccak::Keccak;
use bytes::{BytesConvertable, Populatable};
use hash::{H256, FixedHash}; use hash::{H256, FixedHash};
use self::sha3_ext::*; use self::sha3_ext::*;
/// Get the SHA3 (i.e. Keccak) hash of the empty bytes string. /// Get the SHA3 (i.e. Keccak) hash of the empty bytes string.
pub const SHA3_EMPTY: H256 = H256( [0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, 0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70] ); pub const SHA3_EMPTY: H256 = H256( [0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, 0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70] );
/// Types implementing this trait are sha3able. /// Types implementing this trait are sha3able.
/// ///
/// ``` /// ```
@ -50,17 +47,16 @@ pub trait Hashable {
} }
} }
impl<T> Hashable for T where T: BytesConvertable { impl<T> Hashable for T where T: AsRef<[u8]> {
fn sha3(&self) -> H256 { fn sha3(&self) -> H256 {
unsafe { let mut ret: H256 = H256::zero();
let mut ret: H256 = uninitialized(); self.sha3_into(&mut *ret);
self.sha3_into(ret.as_slice_mut()); ret
ret
}
} }
fn sha3_into(&self, dest: &mut [u8]) { fn sha3_into(&self, dest: &mut [u8]) {
let input: &[u8] = self.as_ref();
unsafe { unsafe {
let input: &[u8] = self.as_slice();
sha3_256(dest.as_mut_ptr(), dest.len(), input.as_ptr(), input.len()); sha3_256(dest.as_mut_ptr(), dest.len(), input.as_ptr(), input.len());
} }
} }