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) {
|
fn write(&mut self, offset: U256, value: U256) {
|
||||||
let off = offset.low_u64() as usize;
|
let off = offset.low_u64() as usize;
|
||||||
let mut val = value;
|
value.to_big_endian(&mut self[off..off+32]);
|
||||||
|
|
||||||
let end = off + 32;
|
|
||||||
for pos in 0..32 {
|
|
||||||
self[end - pos - 1] = val.low_u64() as u8;
|
|
||||||
val = val >> 8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_byte(&mut self, offset: U256, value: U256) {
|
fn write_byte(&mut self, offset: U256, value: U256) {
|
||||||
|
@ -303,9 +303,9 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
let out_size = stack.pop_back();
|
let out_size = stack.pop_back();
|
||||||
|
|
||||||
// Add stipend (only CALL|CALLCODE when value > 0)
|
// 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() {
|
let call_gas = call_gas + value.map_or_else(|| Cost::from(0), |val| match val.is_zero() {
|
||||||
true => Cost::from(ext.schedule().call_stipend),
|
false => Cost::from(ext.schedule().call_stipend),
|
||||||
false => Cost::from(0)
|
true => Cost::from(0)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get sender & receive addresses, check if we have balance
|
// 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 {
|
fn is_zero(&self, val: &U256) -> bool {
|
||||||
&U256::zero() == val
|
val.is_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bool_to_u256(&self, val: bool) -> U256 {
|
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) {
|
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)
|
(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 {
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: serde::Serializer {
|
||||||
let mut hex = "0x".to_owned();
|
let mut hex = "0x".to_owned();
|
||||||
let mut bytes = [0u8; 8 * $size];
|
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);
|
let len = cmp::max((self.0.bits() + 7) / 8, 1);
|
||||||
hex.push_str(&bytes[bytes.len() - len..].to_hex());
|
hex.push_str(&bytes[bytes.len() - len..].to_hex());
|
||||||
serializer.serialize_str(&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;
|
fn bit(&self, index: usize) -> bool;
|
||||||
/// Return single byte
|
/// Return single byte
|
||||||
fn byte(&self, index: usize) -> u8;
|
fn byte(&self, index: usize) -> u8;
|
||||||
/// Get this Uint as slice of bytes
|
/// Convert U256 to the sequence of bytes with a big endian
|
||||||
fn to_raw_bytes(&self, bytes: &mut[u8]);
|
fn to_big_endian(&self, bytes: &mut[u8]);
|
||||||
|
|
||||||
/// Create `Uint(10**n)`
|
/// Create `Uint(10**n)`
|
||||||
fn exp10(n: usize) -> Self;
|
fn exp10(n: usize) -> Self;
|
||||||
/// Return eponentation `self**other`. Panic on overflow.
|
/// 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)
|
/// Returns negation of this `Uint` and overflow (always true)
|
||||||
fn overflowing_neg(self) -> (Self, bool);
|
fn overflowing_neg(self) -> (Self, bool);
|
||||||
|
|
||||||
|
/// Returns
|
||||||
|
fn is_zero(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! construct_uint {
|
macro_rules! construct_uint {
|
||||||
@ -616,6 +618,13 @@ macro_rules! construct_uint {
|
|||||||
arr[0]
|
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
|
/// Return the least number of bits needed to represent the number
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits(&self) -> usize {
|
fn bits(&self) -> usize {
|
||||||
@ -638,7 +647,7 @@ macro_rules! construct_uint {
|
|||||||
(arr[index / 8] >> (((index % 8)) * 8)) as u8
|
(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());
|
assert!($n_words * 8 == bytes.len());
|
||||||
let &$name(ref arr) = self;
|
let &$name(ref arr) = self;
|
||||||
for i in 0..bytes.len() {
|
for i in 0..bytes.len() {
|
||||||
@ -1454,7 +1463,7 @@ mod tests {
|
|||||||
let hex = "8090a0b0c0d0e0f00910203040506077583a2cf8264910e1436bda32571012f0";
|
let hex = "8090a0b0c0d0e0f00910203040506077583a2cf8264910e1436bda32571012f0";
|
||||||
let uint = U256::from_str(hex).unwrap();
|
let uint = U256::from_str(hex).unwrap();
|
||||||
let mut bytes = [0u8; 32];
|
let mut bytes = [0u8; 32];
|
||||||
uint.to_raw_bytes(&mut bytes);
|
uint.to_big_endian(&mut bytes);
|
||||||
let uint2 = U256::from(&bytes[..]);
|
let uint2 = U256::from(&bytes[..]);
|
||||||
assert_eq!(uint, uint2);
|
assert_eq!(uint, uint2);
|
||||||
}
|
}
|
||||||
@ -2021,6 +2030,44 @@ mod tests {
|
|||||||
assert!(overflow);
|
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]
|
#[test]
|
||||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
||||||
|
@ -445,7 +445,7 @@ macro_rules! impl_hash {
|
|||||||
impl From<U256> for H256 {
|
impl From<U256> for H256 {
|
||||||
fn from(value: U256) -> H256 {
|
fn from(value: U256) -> H256 {
|
||||||
let mut ret = H256::new();
|
let mut ret = H256::new();
|
||||||
value.to_raw_bytes(&mut ret);
|
value.to_big_endian(&mut ret);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -453,7 +453,7 @@ impl From<U256> for H256 {
|
|||||||
impl<'a> From<&'a U256> for H256 {
|
impl<'a> From<&'a U256> for H256 {
|
||||||
fn from(value: &'a U256) -> H256 {
|
fn from(value: &'a U256) -> H256 {
|
||||||
let mut ret: H256 = H256::new();
|
let mut ret: H256 = H256::new();
|
||||||
value.to_raw_bytes(&mut ret);
|
value.to_big_endian(&mut ret);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user