diff --git a/.gitignore b/.gitignore index 53eaa21..2bb8d25 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target **/*.rs.bk +.idea diff --git a/Cargo.lock b/Cargo.lock index 9a37393..964051e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -594,7 +594,7 @@ dependencies = [ [[package]] name = "evm" -version = "0.30.0" +version = "0.30.1" dependencies = [ "environmental", "ethereum", @@ -639,6 +639,7 @@ dependencies = [ "ethjson", "evm", "hex", + "lazy_static", "parity-bytes", "parity-crypto", "primitive-types 0.10.1", diff --git a/ethcore-builtin/src/lib.rs b/ethcore-builtin/src/lib.rs index 43b2e89..6827a9d 100644 --- a/ethcore-builtin/src/lib.rs +++ b/ethcore-builtin/src/lib.rs @@ -115,6 +115,7 @@ struct Linear { #[derive(Debug)] struct ModexpPricer { divisor: u64, + is_eip_2565: bool, } impl Pricer for Linear { @@ -157,10 +158,43 @@ impl Pricer for AltBn128PairingPricer { impl Pricer for ModexpPricer { fn cost(&self, input: &[u8]) -> U256 { - let mut reader = input.chain(io::repeat(0)); - let mut buf = [0; 32]; + if self.is_eip_2565 { + let mut buf = [0; 32]; + let (base_len, exp_len, mod_len) = Self::read_lengths(input, &mut buf); + let exp = Self::read_exp(input, base_len, exp_len, &mut buf); + Self::eip_2565_cost( + self.divisor.into(), + base_len, + mod_len, + exp_len, + exp, + ) + } else { + Self::cost(self.divisor, input) + } + } +} - // read lengths as U256 here for accurate gas calculation. +impl ModexpPricer { + fn adjusted_exp_len(len: u64, exp_low: U256) -> u64 { + let bit_index = if exp_low.is_zero() { 0 } else { (255 - exp_low.leading_zeros()) as u64 }; + if len <= 32 { + bit_index + } else { + 8 * (len - 32) + bit_index + } + } + + fn mult_complexity(x: u64) -> u64 { + match x { + x if x <= 64 => x * x, + x if x <= 1024 => (x * x) / 4 + 96 * x - 3072, + x => (x * x) / 16 + 480 * x - 199_680, + } + } + + fn read_lengths(input: &[u8], buf: &mut [u8; 32]) -> (U256, U256, U256) { + let mut reader = input.chain(io::repeat(0)); let mut read_len = || { reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed"); U256::from_big_endian(&buf[..]) @@ -168,6 +202,35 @@ impl Pricer for ModexpPricer { let base_len = read_len(); let exp_len = read_len(); let mod_len = read_len(); + (base_len, exp_len, mod_len) + } + + fn read_exp(input: &[u8], base_len: U256, exp_len: U256, buf: &mut [u8; 32]) -> U256 { + let base_len = if base_len > U256::from(u32::MAX) { + return U256::zero(); + } else { + base_len.low_u64() + }; + if base_len + 96 >= input.len() as u64 { + U256::zero() + } else { + buf.iter_mut().for_each(|b| *b = 0); + let mut reader = input[(96 + base_len as usize)..].chain(io::repeat(0)); + let len = if exp_len < U256::from(32) { + exp_len.low_u64() as usize + } else { + 32 + }; + reader.read_exact(&mut buf[(32 - len)..]).expect("reading from zero-extended memory cannot fail; qed"); + U256::from_big_endian(&buf[..]) + } + } + + fn cost(divisor: u64, input: &[u8]) -> U256 { + let mut buf = [0; 32]; + + // read lengths as U256 here for accurate gas calculation. + let (base_len, exp_len, mod_len) = Self::read_lengths(input, &mut buf); if mod_len.is_zero() && base_len.is_zero() { return U256::zero() @@ -177,19 +240,13 @@ impl Pricer for ModexpPricer { if base_len > max_len || mod_len > max_len || exp_len > max_len { return U256::max_value(); } + + // read fist 32-byte word of the exponent. + let exp_low = Self::read_exp(input, base_len, exp_len, &mut buf); + let (base_len, exp_len, mod_len) = (base_len.low_u64(), exp_len.low_u64(), mod_len.low_u64()); let m = max(mod_len, base_len); - // read fist 32-byte word of the exponent. - let exp_low = if base_len + 96 >= input.len() as u64 { - U256::zero() - } else { - buf.iter_mut().for_each(|b| *b = 0); - let mut reader = input[(96 + base_len as usize)..].chain(io::repeat(0)); - let len = min(exp_len, 32) as usize; - reader.read_exact(&mut buf[(32 - len)..]).expect("reading from zero-extended memory cannot fail; qed"); - U256::from_big_endian(&buf[..]) - }; let adjusted_exp_len = Self::adjusted_exp_len(exp_len, exp_low); @@ -197,26 +254,40 @@ impl Pricer for ModexpPricer { if overflow { return U256::max_value(); } - (gas / self.divisor as u64).into() + (gas / divisor as u64).into() } -} -impl ModexpPricer { - fn adjusted_exp_len(len: u64, exp_low: U256) -> u64 { - let bit_index = if exp_low.is_zero() { 0 } else { (255 - exp_low.leading_zeros()) as u64 }; - if len <= 32 { - bit_index + fn eip_2565_mul_complexity(base_length: U256, modulus_length: U256) -> U256 { + let max_length = std::cmp::max(base_length, modulus_length); + let words = { // div_ceil(max_length, 8); + let tmp = max_length / 8; + if (max_length % 8).is_zero() { + tmp + } else { + tmp + 1 + } + }; + words.saturating_mul(words) + } + + fn eip_2565_iter_count(exponent_length: U256, exponent: U256) -> U256 { + let thirty_two = U256::from(32); + let it = if exponent_length <= thirty_two && exponent.is_zero() { + U256::zero() + } else if exponent_length <= thirty_two { + U256::from(exponent.bits()) - U256::from(1) } else { - 8 * (len - 32) + bit_index - } + // else > 32 + U256::from(8).saturating_mul(exponent_length - thirty_two) + .saturating_add(U256::from(exponent.bits()).saturating_sub(U256::from(1))) + }; + std::cmp::max(it, U256::one()) } - fn mult_complexity(x: u64) -> u64 { - match x { - x if x <= 64 => x * x, - x if x <= 1024 => (x * x) / 4 + 96 * x - 3072, - x => (x * x) / 16 + 480 * x - 199_680, - } + fn eip_2565_cost(divisor: U256, base_length: U256, modulus_length: U256, exponent_length: U256, exponent: U256) -> U256 { + let multiplication_complexity = Self::eip_2565_mul_complexity(base_length, modulus_length); + let iteration_count = Self::eip_2565_iter_count(exponent_length, exponent); + std::cmp::max(U256::from(200), multiplication_complexity.saturating_mul(iteration_count) / divisor) } } @@ -406,7 +477,8 @@ impl From for Pricing { 10 } else { exp.divisor - } + }, + is_eip_2565: exp.is_eip_2565, }) } ethjson::spec::builtin::Pricing::AltBn128Pairing(pricer) => { @@ -1359,7 +1431,7 @@ mod tests { #[test] fn modexp() { let f = Builtin { - pricer: btreemap![0 => Pricing::Modexp(ModexpPricer { divisor: 20 })], + pricer: btreemap![0 => Pricing::Modexp(ModexpPricer { divisor: 20, is_eip_2565: false })], native: EthereumBuiltin::from_str("modexp").unwrap(), }; diff --git a/ethjson/src/spec/builtin.rs b/ethjson/src/spec/builtin.rs index 9a66c3a..eeae5ec 100644 --- a/ethjson/src/spec/builtin.rs +++ b/ethjson/src/spec/builtin.rs @@ -37,6 +37,8 @@ pub struct Linear { pub struct Modexp { /// Price divisor. pub divisor: u64, + /// Use price scheme from EIP-2565 + pub is_eip_2565: bool, } /// Pricing for constant alt_bn128 operations (ECADD and ECMUL) @@ -273,7 +275,7 @@ mod tests { let s = r#"{ "name": "late_start", "activate_at": 100000, - "pricing": { "modexp": { "divisor": 5 } } + "pricing": { "modexp": { "divisor": 5, "is_eip_2565": false } } }"#; let builtin: Builtin = serde_json::from_str::(s).unwrap().into(); @@ -281,7 +283,7 @@ mod tests { assert_eq!(builtin.pricing, btreemap![ 100_000 => PricingAt { info: None, - price: Pricing::Modexp(Modexp { divisor: 5 }) + price: Pricing::Modexp(Modexp { divisor: 5, is_eip_2565: false }) } ]); } diff --git a/ethjson/src/spec/spec.rs b/ethjson/src/spec/spec.rs index 182bf95..8862634 100644 --- a/ethjson/src/spec/spec.rs +++ b/ethjson/src/spec/spec.rs @@ -40,8 +40,10 @@ pub enum ForkSpec { ConstantinopleFix, /// Istanbul (#9,069,000, 2019-12-08) Istanbul, - /// Berlin (To be announced) + /// Berlin (#12,244,000, 2021-04-15) Berlin, + /// London (To be announced) + London, /// Byzantium transition test-net EIP158ToByzantiumAt5, /// Homestead transition test-net diff --git a/ethjson/src/test_helpers/state.rs b/ethjson/src/test_helpers/state.rs index 170366e..78fb82b 100644 --- a/ethjson/src/test_helpers/state.rs +++ b/ethjson/src/test_helpers/state.rs @@ -52,6 +52,9 @@ pub struct State { pub struct MultiTransaction { /// Transaction data set. pub data: Vec, + /// Access lists (see EIP-2930) + #[serde(default)] + pub access_lists: Vec, /// Gas limit set. pub gas_limit: Vec, /// Gas price. @@ -70,8 +73,14 @@ pub struct MultiTransaction { impl MultiTransaction { /// Build transaction with given indexes. pub fn select(&self, indexes: &PostStateIndexes) -> Transaction { + let data_index = indexes.data as usize; + let access_list = if data_index < self.access_lists.len() { + self.access_lists[data_index].iter().map(|a| (a.address, a.storage_keys.clone())).collect() + } else { + Vec::new() + }; Transaction { - data: self.data[indexes.data as usize].clone(), + data: self.data[data_index].clone(), gas_limit: self.gas_limit[indexes.gas as usize], gas_price: self.gas_price, nonce: self.nonce, @@ -81,10 +90,25 @@ impl MultiTransaction { s: Default::default(), v: Default::default(), secret: self.secret.clone(), + access_list, } } } +/// Type alias for access lists (see EIP-2930) +pub type AccessList = Vec; + +/// Access list tuple (see https://eips.ethereum.org/EIPS/eip-2930). +/// Example test spec: https://github.com/ethereum/tests/blob/5490db3ff58d371c0c74826280256ba016b0bd5c/GeneralStateTests/stExample/accessListExample.json +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AccessListTuple { + /// Address to access + pub address: Address, + /// Keys (slots) to access at that address + pub storage_keys: Vec, +} + /// State test indexes deserialization. #[derive(Debug, PartialEq, Deserialize)] pub struct PostStateIndexes { diff --git a/ethjson/src/transaction.rs b/ethjson/src/transaction.rs index 8f54261..e3d984a 100644 --- a/ethjson/src/transaction.rs +++ b/ethjson/src/transaction.rs @@ -25,6 +25,9 @@ use serde::Deserialize; pub struct Transaction { /// Transaction data. pub data: Bytes, + /// Transaction access list (see EIP-2930). + #[serde(default)] + pub access_list: Vec<(Address, Vec)>, /// Gas limit. pub gas_limit: Uint, /// Gas price. diff --git a/evm b/evm index 9631bf3..2ebb883 160000 --- a/evm +++ b/evm @@ -1 +1 @@ -Subproject commit 9631bf3c24566dcce29889644dc464b999e2e220 +Subproject commit 2ebb88320a1f951ed637339d57d31a533c9fa59e diff --git a/jsontests/Cargo.toml b/jsontests/Cargo.toml index 409c8ba..78a6f68 100644 --- a/jsontests/Cargo.toml +++ b/jsontests/Cargo.toml @@ -23,3 +23,4 @@ rlp = "0.5" sha3 = "0.8" parity-bytes = "0.1" env_logger = "0.8" +lazy_static = "1.4.0" diff --git a/jsontests/res/berlin_builtins.json b/jsontests/res/berlin_builtins.json new file mode 100644 index 0000000..66d77e8 --- /dev/null +++ b/jsontests/res/berlin_builtins.json @@ -0,0 +1,52 @@ +{ + "0000000000000000000000000000000000000001": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000005": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 3, "is_eip_2565": true } } }, + "0000000000000000000000000000000000000006": { + "name": "alt_bn128_add", + "pricing": { + "0": { + "price": { "alt_bn128_const_operations": { "price": 500 }} + }, + "0": { + "info": "EIP 1108 transition", + "price": { "alt_bn128_const_operations": { "price": 150 }} + } + } + }, + "0000000000000000000000000000000000000007": { + "name": "alt_bn128_mul", + "pricing": { + "0": { + "price": { "alt_bn128_const_operations": { "price": 40000 }} + }, + "0": { + "info": "EIP 1108 transition", + "price": { "alt_bn128_const_operations": { "price": 6000 }} + } + } + }, + "0000000000000000000000000000000000000008": { + "name": "alt_bn128_pairing", + "pricing": { + "0": { + "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} + }, + "0": { + "info": "EIP 1108 transition", + "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} + } + } + }, + "0000000000000000000000000000000000000009": { + "name": "blake2_f", + "activate_at": "0x00", + "pricing": { + "blake2_f": { + "gas_per_round": 1 + } + } + } +} diff --git a/jsontests/res/ethtests b/jsontests/res/ethtests index 63c2b72..5490db3 160000 --- a/jsontests/res/ethtests +++ b/jsontests/res/ethtests @@ -1 +1 @@ -Subproject commit 63c2b72ff9d81a07c03dac46977218156cd136bf +Subproject commit 5490db3ff58d371c0c74826280256ba016b0bd5c diff --git a/jsontests/res/istanbul_builtins.json b/jsontests/res/istanbul_builtins.json index caef5b3..02e6de7 100644 --- a/jsontests/res/istanbul_builtins.json +++ b/jsontests/res/istanbul_builtins.json @@ -3,7 +3,7 @@ "0000000000000000000000000000000000000002": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } }, "0000000000000000000000000000000000000003": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } }, "0000000000000000000000000000000000000004": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } }, - "0000000000000000000000000000000000000005": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } }, + "0000000000000000000000000000000000000005": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20, "is_eip_2565": false } } }, "0000000000000000000000000000000000000006": { "name": "alt_bn128_add", "pricing": { diff --git a/jsontests/src/state.rs b/jsontests/src/state.rs index 7283564..4920511 100644 --- a/jsontests/src/state.rs +++ b/jsontests/src/state.rs @@ -1,11 +1,13 @@ use std::collections::BTreeMap; use std::convert::TryInto; +use ethjson::spec::ForkSpec; use serde::Deserialize; use primitive_types::{H160, H256, U256}; -use evm::{Config, ExitSucceed, ExitError}; -use evm::executor::{StackExecutor, MemoryStackState, StackSubstateMetadata, PrecompileOutput}; +use evm::{Config, ExitSucceed, ExitError, Context}; +use evm::executor::{self, StackExecutor, MemoryStackState, StackSubstateMetadata, PrecompileOutput}; use evm::backend::{MemoryAccount, ApplyBackend, MemoryVicinity, MemoryBackend}; use parity_crypto::publickey; +use lazy_static::lazy_static; use crate::utils::*; #[derive(Deserialize, Debug)] @@ -40,41 +42,89 @@ impl Test { } } -fn istanbul_precompile( - address: H160, - input: &[u8], - target_gas: Option, - _context: &evm::Context, -) -> Option> { - use ethcore_builtin::*; - use parity_bytes::BytesRef; - - let builtins: BTreeMap = serde_json::from_str(include_str!("../res/istanbul_builtins.json")).unwrap(); - let builtins = builtins.into_iter().map(|(address, builtin)| { - (address.into(), ethjson::spec::Builtin::from(builtin).try_into().unwrap()) - }).collect::>(); - - if let Some(builtin) = builtins.get(&address) { +lazy_static! { + static ref ISTANBUL_BUILTINS: BTreeMap = + JsonPrecompile::builtins("./res/istanbul_builtins.json"); +} + +lazy_static! { + static ref BERLIN_BUILTINS: BTreeMap = + JsonPrecompile::builtins("./res/berlin_builtins.json"); +} + +macro_rules! precompile_entry { + ($map:expr, $builtins:expr, $index:expr) => { + let x: fn(&[u8], Option, &Context, bool) -> Result = |input: &[u8], gas_limit: Option, _context: &Context, _is_static: bool| { + let builtin = $builtins.get(&H160::from_low_u64_be($index)).unwrap(); + Self::exec_as_precompile(builtin, input, gas_limit) + }; + $map.insert(H160::from_low_u64_be($index), x); + } +} + +pub struct JsonPrecompile; + +impl JsonPrecompile { + pub fn precompile(spec: &ForkSpec) -> Option { + match spec { + ForkSpec::Istanbul => { + let mut map = BTreeMap::new(); + precompile_entry!(map, ISTANBUL_BUILTINS, 1); + precompile_entry!(map, ISTANBUL_BUILTINS, 2); + precompile_entry!(map, ISTANBUL_BUILTINS, 3); + precompile_entry!(map, ISTANBUL_BUILTINS, 4); + precompile_entry!(map, ISTANBUL_BUILTINS, 5); + precompile_entry!(map, ISTANBUL_BUILTINS, 6); + precompile_entry!(map, ISTANBUL_BUILTINS, 7); + precompile_entry!(map, ISTANBUL_BUILTINS, 8); + precompile_entry!(map, ISTANBUL_BUILTINS, 9); + Some(map) + } + ForkSpec::Berlin => { + let mut map = BTreeMap::new(); + precompile_entry!(map, BERLIN_BUILTINS, 1); + precompile_entry!(map, BERLIN_BUILTINS, 2); + precompile_entry!(map, BERLIN_BUILTINS, 3); + precompile_entry!(map, BERLIN_BUILTINS, 4); + precompile_entry!(map, BERLIN_BUILTINS, 5); + precompile_entry!(map, BERLIN_BUILTINS, 6); + precompile_entry!(map, BERLIN_BUILTINS, 7); + precompile_entry!(map, BERLIN_BUILTINS, 8); + precompile_entry!(map, BERLIN_BUILTINS, 9); + Some(map) + } + _ => None, + } + } + + fn builtins(spec_path: &str) -> BTreeMap { + let reader = std::fs::File::open(spec_path).unwrap(); + let builtins: BTreeMap = + serde_json::from_reader(reader).unwrap(); + builtins.into_iter().map(|(address, builtin)| { + (address.into(), ethjson::spec::Builtin::from(builtin).try_into().unwrap()) + }).collect() + } + + fn exec_as_precompile(builtin: ðcore_builtin::Builtin, input: &[u8], gas_limit: Option) -> Result { let cost = builtin.cost(input, 0); - if let Some(target_gas) = target_gas { - if cost > U256::from(u64::max_value()) || target_gas < cost.as_u64() { - return Some(Err(ExitError::OutOfGas)) + if let Some(target_gas) = gas_limit { + if cost > U256::from(u64::MAX) || target_gas < cost.as_u64() { + return Err(ExitError::OutOfGas); } } let mut output = Vec::new(); - match builtin.execute(input, &mut BytesRef::Flexible(&mut output)) { - Ok(()) => Some(Ok(PrecompileOutput { + match builtin.execute(input, &mut parity_bytes::BytesRef::Flexible(&mut output)) { + Ok(()) => Ok(PrecompileOutput { exit_status: ExitSucceed::Stopped, output, cost: cost.as_u64(), logs: Vec::new(), - })), - Err(e) => Some(Err(ExitError::Other(e.into()))), + }), + Err(e) => Err(ExitError::Other(e.into())), } - } else { - None } } @@ -94,10 +144,11 @@ pub fn test(name: &str, test: Test) { child.join().unwrap(); } -pub fn test_run(name: &str, test: Test) { +fn test_run(name: &str, test: Test) { for (spec, states) in &test.0.post_states { let (gasometer_config, delete_empty) = match spec { ethjson::spec::ForkSpec::Istanbul => (Config::istanbul(), true), + ethjson::spec::ForkSpec::Berlin => (Config::berlin(), true), spec => { println!("Skip spec {:?}", spec); continue @@ -119,8 +170,7 @@ pub fn test_run(name: &str, test: Test) { let mut backend = MemoryBackend::new(&vicinity, original_state.clone()); let metadata = StackSubstateMetadata::new(transaction.gas_limit.into(), &gasometer_config); let executor_state = MemoryStackState::new(metadata, &backend); - // TODO: adapt precompile to the fork spec - let precompile = istanbul_precompile; + let precompile = JsonPrecompile::precompile(spec).unwrap(); let mut executor = StackExecutor::new_with_precompile( executor_state, &gasometer_config, @@ -130,6 +180,11 @@ pub fn test_run(name: &str, test: Test) { executor.state_mut().withdraw(caller, total_fee).unwrap(); + let access_list = transaction.access_list + .into_iter() + .map(|(address, keys)| (address.0, keys.into_iter().map(|k| k.0).collect())) + .collect(); + match transaction.to { ethjson::maybe::MaybeEmpty::Some(to) => { let data = data; @@ -137,10 +192,11 @@ pub fn test_run(name: &str, test: Test) { let _reason = executor.transact_call( caller, - to.clone().into(), + to.into(), value, data, - gas_limit + gas_limit, + access_list, ); }, ethjson::maybe::MaybeEmpty::None => { @@ -151,7 +207,8 @@ pub fn test_run(name: &str, test: Test) { caller, value, code, - gas_limit + gas_limit, + access_list, ); }, } diff --git a/jsontests/src/utils.rs b/jsontests/src/utils.rs index c299059..a2bbce6 100644 --- a/jsontests/src/utils.rs +++ b/jsontests/src/utils.rs @@ -128,7 +128,7 @@ pub fn assert_valid_hash(h: &H256, b: &BTreeMap) { let expect = h.clone().into(); if root != expect { - panic!("Hash not equal; calculated: {:?}, expect: {:?}\nState: {:?}", + panic!("Hash not equal; calculated: {:?}, expect: {:?}\nState: {:#x?}", root, expect, b); } } diff --git a/jsontests/src/vm.rs b/jsontests/src/vm.rs index 88ede28..3482017 100644 --- a/jsontests/src/vm.rs +++ b/jsontests/src/vm.rs @@ -68,7 +68,7 @@ pub fn test(name: &str, test: Test) { let mut backend = MemoryBackend::new(&vicinity, original_state); let metadata = StackSubstateMetadata::new(test.unwrap_to_gas_limit(), &config); let state = MemoryStackState::new(metadata, &backend); - let mut executor = StackExecutor::new(state, &config); + let mut executor = StackExecutor::new_with_precompile(state, &config, BTreeMap::new()); let code = test.unwrap_to_code(); let data = test.unwrap_to_data(); diff --git a/jsontests/tests/state.rs b/jsontests/tests/state.rs index 1624400..27da97e 100644 --- a/jsontests/tests/state.rs +++ b/jsontests/tests/state.rs @@ -41,7 +41,6 @@ pub fn run(dir: &str) { #[test] fn st_call_delegate_codes_call_code_homestead() { run("res/ethtests/GeneralStateTests/stCallDelegateCodesCallCodeHomestead") } #[test] fn st_call_delegate_codes_homestead() { run("res/ethtests/GeneralStateTests/stCallDelegateCodesHomestead") } #[test] fn st_chain_id() { run("res/ethtests/GeneralStateTests/stChainId") } -#[test] fn st_changed_eip150() { run("res/ethtests/GeneralStateTests/stChangedEIP150") } #[test] fn st_code_copy() { run("res/ethtests/GeneralStateTests/stCodeCopyTest") } #[test] fn st_code_size_limit() { run("res/ethtests/GeneralStateTests/stCodeSizeLimit") } #[test] #[ignore] fn st_create2() { run("res/ethtests/GeneralStateTests/stCreate2") } diff --git a/jsontests/tests/vm.rs b/jsontests/tests/vm.rs index 9d5ff75..c39e9ff 100644 --- a/jsontests/tests/vm.rs +++ b/jsontests/tests/vm.rs @@ -14,7 +14,7 @@ pub fn run(dir: &str) { let entry = entry.unwrap(); let path = entry.path(); - let file = File::open(path).expect("Open file failed"); + let file = File::open(path).expect("Open file failed"); let reader = BufReader::new(file); let coll = serde_json::from_reader::<_, HashMap>(reader) @@ -26,15 +26,16 @@ pub fn run(dir: &str) { } } -#[test] fn vm_arithmetic() { run("res/ethtests/VMTests/vmArithmeticTest"); } -#[test] fn vm_bitwise_logic() { run("res/ethtests/VMTests/vmBitwiseLogicOperation"); } -#[test] fn vm_block_info() { run("res/ethtests/VMTests/vmBlockInfoTest"); } -#[test] fn vm_environmental_info() { run("res/ethtests/VMTests/vmEnvironmentalInfo"); } -#[test] fn vm_io_and_flow() { run("res/ethtests/VMTests/vmIOandFlowOperations"); } -#[test] fn vm_log() { run("res/ethtests/VMTests/vmLogTest"); } -#[test] #[ignore] fn vm_performance() { run("res/ethtests/VMTests/vmPerformance"); } -#[test] fn vm_push_dup_swap() { run("res/ethtests/VMTests/vmPushDupSwapTest"); } -#[test] fn vm_random() { run("res/ethtests/VMTests/vmRandomTest"); } -#[test] fn vm_sha3() { run("res/ethtests/VMTests/vmSha3Test"); } -#[test] fn vm_system() { run("res/ethtests/VMTests/vmSystemOperations"); } -#[test] fn vm_other() { run("res/ethtests/VMTests/vmTests"); } +// TODO: upgrade to GeneralStateTests/VMTests instead of using LegacyTests version +#[test] fn vm_arithmetic() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmArithmeticTest"); } +#[test] fn vm_bitwise_logic() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmBitwiseLogicOperation"); } +#[test] fn vm_block_info() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmBlockInfoTest"); } +#[test] fn vm_environmental_info() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmEnvironmentalInfo"); } +#[test] fn vm_io_and_flow() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmIOandFlowOperations"); } +#[test] fn vm_log() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmLogTest"); } +#[test] #[ignore] fn vm_performance() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmPerformance"); } +#[test] fn vm_push_dup_swap() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmPushDupSwapTest"); } +#[test] fn vm_random() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmRandomTest"); } +#[test] fn vm_sha3() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmSha3Test"); } +#[test] fn vm_system() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmSystemOperations"); } +#[test] fn vm_other() { run("res/ethtests/LegacyTests/Constantinople/VMTests/vmTests"); }