Skip to content

Commit

Permalink
only 3 tests failing for arithmetic tests
Browse files Browse the repository at this point in the history
  • Loading branch information
max-wickham committed Mar 24, 2024
1 parent 646a29f commit 77efcee
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 40 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ sha3 = "0.10.8"
test_gen = { path = "./test_gen" }
thiserror = "1.0.58"
num256 = "0.5.1"
lazy_static = "1.4.0"
73 changes: 52 additions & 21 deletions src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ use crate::runtime;
// use crate::main;
use crate::state::memory::Memory;
use crate::state::stack::Stack;
use crate::util::{self, h256_to_u256, int256_to_uint256, keccak256, u256_to_array, u256_to_h256, u256_to_uint256, uint256_to_int256};
use crate::util::{
self, h256_to_u256, int256_to_uint256, keccak256, u256_to_array, u256_to_h256, u256_to_uint256, uint256_to_int256, MAX_UINT256, MAX_UINT256_COMPLEMENT, ZERO
};
use crate::{bytecode_spec::opcodes, runtime::Runtime};
use num256::{Int256, Uint256};
use paste::paste;
use primitive_types::U256;
const ZERO: U256 = U256::zero();
#[derive(Clone)]
struct Transaction {
pub origin: U256,
Expand Down Expand Up @@ -225,11 +226,20 @@ impl EVMContext {
self.stack.push(U256::zero());
},
_ => {
let a : Int256 = Uint256::from(TryInto::<[u8;32]>::try_into(u256_to_array(a)).unwrap()).try_into().unwrap();
let b : Int256 = Uint256::from(TryInto::<[u8;32]>::try_into(u256_to_array(b)).unwrap()).try_into().unwrap();
let result: Uint256 = int256_to_uint256(a / b);
let result = U256::from(result.to_be_bytes());
self.stack.push(result);
let a = u256_to_uint256(a);
let b = u256_to_uint256(b);
// Handle overflow case of -1 * MAX_POSITIVE
if a == *MAX_UINT256_COMPLEMENT && b == *MAX_UINT256 {
self.stack.push(U256::from(MAX_UINT256_COMPLEMENT.to_be_bytes()));
}
else {
let a = uint256_to_int256(a);
let b = uint256_to_int256(b);
let result: Uint256 = int256_to_uint256(a / b);
let result = U256::from(result.to_be_bytes());
self.stack.push(result);
}

}
}
self.gas_usage += 5;
Expand Down Expand Up @@ -257,8 +267,7 @@ impl EVMContext {
_ => {
let a = uint256_to_int256(u256_to_uint256(a));
let b = uint256_to_int256(u256_to_uint256(b));
println!("a: {}, b: {}, {}", a, b, (a.rem(b) + b).rem(b));
let result: Uint256 = int256_to_uint256((a.rem(b) + b).rem(b));
let result: Uint256 = int256_to_uint256(a.rem(b));
let result = U256::from(result.to_be_bytes());
self.stack.push(result);
}
Expand Down Expand Up @@ -302,16 +311,20 @@ impl EVMContext {

opcodes::SIGNEXTEND => {
let (x, y) = (self.stack.pop(), self.stack.pop());
// X is the number of bytes of the input lower_mask
if x > U256::from(31) {
self.stack.push(y);
} else {
let t = U256::from(248) - x * 8;
let sign = y & (U256::from(1 as u64) << t);
if sign == U256::zero() {
let lower_mask = x << t - 1;
let sign = y >> (x*8 + 7) & U256::from(1 as u64);
let lower_mask = if x == U256::from(31) {
U256::max_value()
} else {
(U256::from(1) << ((x+1)*8)) - 1
};
if sign == ZERO {
self.stack.push(y & lower_mask);
} else {
let higher_mask = !(x << t - 1);
let higher_mask = !lower_mask;
self.stack.push(y | higher_mask);
}
}
Expand All @@ -332,14 +345,18 @@ impl EVMContext {

opcodes::SLT => {
let (a, b) = (self.stack.pop(), self.stack.pop());
self.stack.push(U256::from(((a.as_u64() as i64) < (b.as_u64() as i64)) as u64));
let a = uint256_to_int256(u256_to_uint256(a));
let b = uint256_to_int256(u256_to_uint256(b));
self.stack.push(U256::from((a < b) as u64));
self.gas_usage += 3;
},

opcodes::SGT => {
// debug!("SGT");
let (a, b) = (self.stack.pop(), self.stack.pop());
self.stack.push(U256::from(((a.as_u64() as i64) > (b.as_u64() as i64)) as u64));
let a = uint256_to_int256(u256_to_uint256(a));
let b = uint256_to_int256(u256_to_uint256(b));
self.stack.push(U256::from((a > b) as u64));
self.gas_usage += 3;
},

Expand Down Expand Up @@ -382,19 +399,32 @@ impl EVMContext {

opcodes::BYTE => {
let (i, x) = (self.stack.pop(), self.stack.pop());
println!("i: {}, x: {}", i, x);
if i > U256::from(31) {
self.stack.push(U256::zero());
} else {
self.stack.push((x >> (U256::from(248) - i * 8)) & (0xFF as u64).into());
}
self.gas_usage += 3;
},

opcodes::SHL => {
let (shift, value) = (self.stack.pop(), self.stack.pop());
self.stack.push(value << shift);
if shift > 31.into() {
self.stack.push(U256::zero());
} else {
self.stack.push(value << shift);
}
self.gas_usage += 3;
},

opcodes::SHR => {
let (shift, value) = (self.stack.pop(), self.stack.pop());
self.stack.push(value >> shift);
if shift > 31.into() {
self.stack.push(U256::zero());
} else {
self.stack.push(value >> shift);
}
self.gas_usage += 3;
},

Expand Down Expand Up @@ -642,15 +672,16 @@ impl EVMContext {

opcodes::SSTORE => {
let (key, value) = (self.stack.pop(), self.stack.pop());
if runtime.is_hot_index(self.contract_address, key){
} else {
println!("key value {}, {}", key, value);
if !runtime.is_hot_index(self.contract_address, key){
self.gas_usage += 2100;
runtime.mark_hot_index(self.contract_address, key);
}
let base_dynamic_gas;
if !runtime.storage(self.contract_address).contains_key(&u256_to_h256(key)) && value.eq(&U256::zero()) {
println!("This case");
base_dynamic_gas = 100;

// runtime.set_storage(self.contract_address, key, u256_to_h256(value));
}
else {
base_dynamic_gas = if (runtime.storage(self.contract_address).contains_key(&u256_to_h256(key))
Expand Down
2 changes: 1 addition & 1 deletion src/state/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use primitive_types::U256;

use crate::util::u256_to_array;

const STACK_SIZE: usize = 1024;
const STACK_SIZE: usize = 1024* 32;

pub struct Stack {
data: [u8; STACK_SIZE],
Expand Down
42 changes: 30 additions & 12 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
use std::{ops::Not, str::FromStr};

use lazy_static::lazy_static;
use num256::{Int256, Uint256};
use primitive_types::{H256,U256};
use primitive_types::{H256, U256};
use sha3::{Digest, Keccak256};

pub const ZERO: U256 = U256::zero();
lazy_static! {
pub static ref MAX_UINT256_COMPLEMENT: Uint256 = Uint256::from_str(
"57896044618658097711785492504343953926634992332820282019728792003956564819968"
)
.unwrap();
pub static ref MAX_UINT256: Uint256 = Uint256::from_str(
"115792089237316195423570985008687907853269984665640564039457584007913129639935"
)
.unwrap();
pub static ref MIN_INT256: Int256 = Int256::from_str(
"-57896044618658097711785492504343953926634992332820282019728792003956564819968"
)
.unwrap();
}

fn vec_to_fixed_array(bytes: Vec<u8>) -> [u8; 32] {
let mut result = [0u8; 32];
let len = bytes.len().min(32); // Take minimum to avoid out-of-bounds access
// Copy bytes into the result array
// Copy bytes into the result array
result[..len].copy_from_slice(&bytes[..len]);
result
}
Expand All @@ -16,7 +33,6 @@ pub fn keccak256_u256(addr: U256) -> H256 {
keccak256(&u256_to_array(addr).to_vec())
}


pub fn keccak256(bytes: &Vec<u8>) -> H256 {
let result: Vec<u8> = Keccak256::digest(bytes).to_vec();
H256::from_slice(vec_to_fixed_array(result).as_slice())
Expand All @@ -30,33 +46,36 @@ pub fn bytes_for_u256(num: &U256) -> usize {
}

pub fn h256_to_u256(v: H256) -> U256 {
U256::from_big_endian(&v[..])
U256::from_big_endian(&v[..])
}

pub fn u256_to_h256(v: U256) -> H256 {
let mut r = H256::default();
v.to_big_endian(&mut r[..]);
r
let mut r = H256::default();
v.to_big_endian(&mut r[..]);
r
}

pub fn u256_to_array(v: U256) -> [u8; 32] {
let mut x: [u8;32] = [0;32];
let mut x: [u8; 32] = [0; 32];
v.to_big_endian(&mut x);
x
}

pub fn u256_to_uint256(v: U256) -> Uint256 {
Uint256::from(TryInto::<[u8;32]>::try_into(u256_to_array(v)).unwrap()).try_into().unwrap()
Uint256::from(TryInto::<[u8; 32]>::try_into(u256_to_array(v)).unwrap())
.try_into()
.unwrap()
}

pub fn uint256_to_int256(v: Uint256) -> Int256 {
if v > Uint256::from_str("57896044618658097711785492504343953926634992332820282019728792003956564819967").unwrap() {
if v == *MAX_UINT256_COMPLEMENT {
*MIN_INT256
} else if v > *MAX_UINT256_COMPLEMENT {
let mut twos_complement = v.to_be_bytes();
for elem in twos_complement.iter_mut() {
*elem = !*elem;
}
let twos_complement = Uint256::from(twos_complement) + Uint256::from(1 as u64);

twos_complement.to_int256().unwrap() * Int256::from(-1)
} else {
v.to_int256().unwrap()
Expand All @@ -78,7 +97,6 @@ pub fn int256_to_uint256(v: Int256) -> Uint256 {
}
}


#[macro_export]
macro_rules! gas_usage_change {
($($code:tt)*) => {
Expand Down
12 changes: 6 additions & 6 deletions tests/official_tests/official_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,14 @@ pub fn run_test(test: &TestState, debug: bool) {
assert_eq!(runtime.state_root_hash(), test.post.hash);
}

generate_official_tests_from_folder!(
"./tests/official_tests/tests/GeneralStateTests/VMTests/vmArithmeticTest"
);
// generate_official_tests_from_folder!(
// "./tests/official_tests/tests/GeneralStateTests/VMTests/vmArithmeticTest"
// );

// generate_official_tests_from_folder!(
// "./tests/official_tests/tests/GeneralStateTests/stRandom"
// );

// generate_official_tests_from_file!(
// "./tests/official_tests/tests/GeneralStateTests/VMTests/vmArithmeticTest/arith.json"
// );
generate_official_tests_from_file!(
"./tests/official_tests/tests/GeneralStateTests/VMTests/vmArithmeticTest/fib.json"
);

0 comments on commit 77efcee

Please sign in to comment.