Some obvious evm & uint optimizations (#1576)
* fix name and tests for endians * using renamed func * zero and sign opt
This commit is contained in:
parent
d7caae2241
commit
e15f631ec7
@ -94,13 +94,7 @@ impl Memory for Vec<u8> {
|
||||
|
||||
fn write(&mut self, offset: U256, value: U256) {
|
||||
let off = offset.low_u64() as usize;
|
||||
let mut val = value;
|
||||
|
||||
let end = off + 32;
|
||||
for pos in 0..32 {
|
||||
self[end - pos - 1] = val.low_u64() as u8;
|
||||
val = val >> 8;
|
||||
}
|
||||
value.to_big_endian(&mut self[off..off+32]);
|
||||
}
|
||||
|
||||
fn write_byte(&mut self, offset: U256, value: U256) {
|
||||
|
@ -303,9 +303,9 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
let out_size = stack.pop_back();
|
||||
|
||||
// Add stipend (only CALL|CALLCODE when value > 0)
|
||||
let call_gas = call_gas + value.map_or_else(|| Cost::from(0), |val| match val > U256::zero() {
|
||||
true => Cost::from(ext.schedule().call_stipend),
|
||||
false => Cost::from(0)
|
||||
let call_gas = call_gas + value.map_or_else(|| Cost::from(0), |val| match val.is_zero() {
|
||||
false => Cost::from(ext.schedule().call_stipend),
|
||||
true => Cost::from(0)
|
||||
});
|
||||
|
||||
// Get sender & receive addresses, check if we have balance
|
||||
@ -550,7 +550,7 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
}
|
||||
|
||||
fn is_zero(&self, val: &U256) -> bool {
|
||||
&U256::zero() == val
|
||||
val.is_zero()
|
||||
}
|
||||
|
||||
fn bool_to_u256(&self, val: bool) -> U256 {
|
||||
@ -782,7 +782,8 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
}
|
||||
|
||||
fn get_and_reset_sign(value: U256) -> (U256, bool) {
|
||||
let sign = (value >> 255).low_u64() == 1;
|
||||
let U256(arr) = value;
|
||||
let sign = arr[3].leading_zeros() == 0;
|
||||
(set_sign(value, sign), sign)
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ macro_rules! impl_uint {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: serde::Serializer {
|
||||
let mut hex = "0x".to_owned();
|
||||
let mut bytes = [0u8; 8 * $size];
|
||||
self.0.to_raw_bytes(&mut bytes);
|
||||
self.0.to_big_endian(&mut bytes);
|
||||
let len = cmp::max((self.0.bits() + 7) / 8, 1);
|
||||
hex.push_str(&bytes[bytes.len() - len..].to_hex());
|
||||
serializer.serialize_str(&hex)
|
||||
|
@ -524,9 +524,8 @@ pub trait Uint: Sized + Default + FromStr + From<u64> + fmt::Debug + fmt::Displa
|
||||
fn bit(&self, index: usize) -> bool;
|
||||
/// Return single byte
|
||||
fn byte(&self, index: usize) -> u8;
|
||||
/// Get this Uint as slice of bytes
|
||||
fn to_raw_bytes(&self, bytes: &mut[u8]);
|
||||
|
||||
/// Convert U256 to the sequence of bytes with a big endian
|
||||
fn to_big_endian(&self, bytes: &mut[u8]);
|
||||
/// Create `Uint(10**n)`
|
||||
fn exp10(n: usize) -> Self;
|
||||
/// Return eponentation `self**other`. Panic on overflow.
|
||||
@ -551,6 +550,9 @@ pub trait Uint: Sized + Default + FromStr + From<u64> + fmt::Debug + fmt::Displa
|
||||
|
||||
/// Returns negation of this `Uint` and overflow (always true)
|
||||
fn overflowing_neg(self) -> (Self, bool);
|
||||
|
||||
/// Returns
|
||||
fn is_zero(&self) -> bool;
|
||||
}
|
||||
|
||||
macro_rules! construct_uint {
|
||||
@ -616,6 +618,13 @@ macro_rules! construct_uint {
|
||||
arr[0]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
let &$name(ref arr) = self;
|
||||
for i in 0..$n_words { if arr[i] != 0 { return false; } }
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Return the least number of bits needed to represent the number
|
||||
#[inline]
|
||||
fn bits(&self) -> usize {
|
||||
@ -638,7 +647,7 @@ macro_rules! construct_uint {
|
||||
(arr[index / 8] >> (((index % 8)) * 8)) as u8
|
||||
}
|
||||
|
||||
fn to_raw_bytes(&self, bytes: &mut[u8]) {
|
||||
fn to_big_endian(&self, bytes: &mut[u8]) {
|
||||
assert!($n_words * 8 == bytes.len());
|
||||
let &$name(ref arr) = self;
|
||||
for i in 0..bytes.len() {
|
||||
@ -1454,7 +1463,7 @@ mod tests {
|
||||
let hex = "8090a0b0c0d0e0f00910203040506077583a2cf8264910e1436bda32571012f0";
|
||||
let uint = U256::from_str(hex).unwrap();
|
||||
let mut bytes = [0u8; 32];
|
||||
uint.to_raw_bytes(&mut bytes);
|
||||
uint.to_big_endian(&mut bytes);
|
||||
let uint2 = U256::from(&bytes[..]);
|
||||
assert_eq!(uint, uint2);
|
||||
}
|
||||
@ -2021,6 +2030,44 @@ mod tests {
|
||||
assert!(overflow);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn big_endian() {
|
||||
let source = U256([1, 0, 0, 0]);
|
||||
let mut target = vec![0u8; 32];
|
||||
|
||||
assert_eq!(source, U256::from(1));
|
||||
|
||||
source.to_big_endian(&mut target);
|
||||
assert_eq!(
|
||||
vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8],
|
||||
target);
|
||||
|
||||
let source = U256([512, 0, 0, 0]);
|
||||
let mut target = vec![0u8; 32];
|
||||
|
||||
source.to_big_endian(&mut target);
|
||||
assert_eq!(
|
||||
vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8],
|
||||
target);
|
||||
|
||||
let source = U256([0, 512, 0, 0]);
|
||||
let mut target = vec![0u8; 32];
|
||||
|
||||
source.to_big_endian(&mut target);
|
||||
assert_eq!(
|
||||
vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8],
|
||||
target);
|
||||
|
||||
let source = U256::from_str("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20").unwrap();
|
||||
source.to_big_endian(&mut target);
|
||||
assert_eq!(
|
||||
vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20],
|
||||
target);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
||||
|
@ -445,7 +445,7 @@ macro_rules! impl_hash {
|
||||
impl From<U256> for H256 {
|
||||
fn from(value: U256) -> H256 {
|
||||
let mut ret = H256::new();
|
||||
value.to_raw_bytes(&mut ret);
|
||||
value.to_big_endian(&mut ret);
|
||||
ret
|
||||
}
|
||||
}
|
||||
@ -453,7 +453,7 @@ impl From<U256> for H256 {
|
||||
impl<'a> From<&'a U256> for H256 {
|
||||
fn from(value: &'a U256) -> H256 {
|
||||
let mut ret: H256 = H256::new();
|
||||
value.to_raw_bytes(&mut ret);
|
||||
value.to_big_endian(&mut ret);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user