Merge branch 'master' of https://github.com/gavofyork/ethcore into executive_tests
This commit is contained in:
@@ -3,3 +3,4 @@ mod test_common;
|
||||
|
||||
mod transaction;
|
||||
mod executive;
|
||||
mod state;
|
||||
|
||||
80
src/tests/state.rs
Normal file
80
src/tests/state.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use super::test_common::*;
|
||||
use state::*;
|
||||
use ethereum;
|
||||
|
||||
pub fn hashmap_h256_h256_from_json(json: &Json) -> HashMap<H256, H256> {
|
||||
json.as_object().unwrap().iter().fold(HashMap::new(), |mut m, (key, value)| {
|
||||
m.insert(H256::from(&u256_from_hex(key)), H256::from(&u256_from_json(value)));
|
||||
m
|
||||
})
|
||||
}
|
||||
|
||||
pub fn map_h256_h256_from_json(json: &Json) -> BTreeMap<H256, H256> {
|
||||
json.as_object().unwrap().iter().fold(BTreeMap::new(), |mut m, (key, value)| {
|
||||
m.insert(H256::from(&u256_from_hex(key)), H256::from(&u256_from_json(value)));
|
||||
m
|
||||
})
|
||||
}
|
||||
|
||||
/// Translate the JSON object into a hash map of account information ready for insertion into State.
|
||||
pub fn pod_map_from_json(json: &Json) -> BTreeMap<Address, PodAccount> {
|
||||
json.as_object().unwrap().iter().fold(BTreeMap::new(), |mut state, (address, acc)| {
|
||||
let balance = acc.find("balance").map(&u256_from_json);
|
||||
let nonce = acc.find("nonce").map(&u256_from_json);
|
||||
let storage = acc.find("storage").map(&map_h256_h256_from_json);;
|
||||
let code = acc.find("code").map(&bytes_from_json);
|
||||
if balance.is_some() || nonce.is_some() || storage.is_some() || code.is_some() {
|
||||
state.insert(address_from_hex(address), PodAccount{
|
||||
balance: balance.unwrap_or(U256::zero()),
|
||||
nonce: nonce.unwrap_or(U256::zero()),
|
||||
storage: storage.unwrap_or(BTreeMap::new()),
|
||||
code: code.unwrap_or(Vec::new())
|
||||
});
|
||||
}
|
||||
state
|
||||
})
|
||||
}
|
||||
|
||||
fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
let json = Json::from_str(::std::str::from_utf8(json_data).unwrap()).expect("Json is invalid");
|
||||
let mut failed = Vec::new();
|
||||
|
||||
let engine = ethereum::new_frontier_test().to_engine().unwrap();
|
||||
|
||||
for (name, test) in json.as_object().unwrap() {
|
||||
let mut fail = false;
|
||||
let mut fail_unless = |cond: bool| if !cond && !fail { failed.push(name.to_string()); fail = true; true } else {false};
|
||||
|
||||
let t = Transaction::from_json(&test["transaction"]);
|
||||
let env = EnvInfo::from_json(&test["env"]);
|
||||
let out = bytes_from_json(&test["out"]);
|
||||
let post_state_root = h256_from_json(&test["postStateRoot"]);
|
||||
let pre = pod_map_from_json(&test["pre"]);
|
||||
let post = pod_map_from_json(&test["post"]);
|
||||
// TODO: read test["logs"]
|
||||
|
||||
println!("Transaction: {:?}", t);
|
||||
println!("Env: {:?}", env);
|
||||
println!("Out: {:?}", out);
|
||||
println!("Pre: {:?}", pre);
|
||||
println!("Post: {:?}", post);
|
||||
|
||||
let mut s = State::new_temp();
|
||||
s.populate_from(pre);
|
||||
s.apply(&env, engine.deref(), &t).unwrap();
|
||||
let our_post = s.to_pod_map();
|
||||
|
||||
if fail_unless(s.root() == &post_state_root) {
|
||||
println!("EXPECTED:\n{:?}", post);
|
||||
println!("GOT:\n{:?}", our_post);
|
||||
}
|
||||
|
||||
// TODO: Compare logs.
|
||||
}
|
||||
for f in failed.iter() {
|
||||
println!("FAILED: {:?}", f);
|
||||
}
|
||||
failed
|
||||
}
|
||||
|
||||
declare_test!{StateTests_stExample, "StateTests/stExample"}
|
||||
@@ -1,26 +1,5 @@
|
||||
pub use common::*;
|
||||
|
||||
pub fn clean(s: &str) -> &str {
|
||||
if s.len() >= 2 && &s[0..2] == "0x" {
|
||||
&s[2..]
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bytes_from_json(json: &Json) -> Bytes {
|
||||
let s = json.as_string().unwrap();
|
||||
if s.len() % 2 == 1 {
|
||||
FromHex::from_hex(&("0".to_string() + &(clean(s).to_string()))[..]).unwrap_or(vec![])
|
||||
} else {
|
||||
FromHex::from_hex(clean(s)).unwrap_or(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn address_from_json(json: &Json) -> Address {
|
||||
address_from_str(json.as_string().unwrap())
|
||||
}
|
||||
|
||||
pub fn address_from_str<'a>(s: &'a str) -> Address {
|
||||
if s.len() % 2 == 1 {
|
||||
address_from_hex(&("0".to_string() + &(clean(s).to_string()))[..])
|
||||
@@ -29,10 +8,6 @@ pub fn address_from_str<'a>(s: &'a str) -> Address {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn u256_from_json(json: &Json) -> U256 {
|
||||
u256_from_str(json.as_string().unwrap())
|
||||
}
|
||||
|
||||
pub fn u256_from_str<'a>(s: &'a str) -> U256 {
|
||||
if s.len() >= 2 && &s[0..2] == "0x" {
|
||||
// hex
|
||||
|
||||
@@ -6,15 +6,16 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
let mut failed = Vec::new();
|
||||
let old_schedule = evm::Schedule::new_frontier();
|
||||
let new_schedule = evm::Schedule::new_homestead();
|
||||
let ot = RefCell::new(Transaction::new());
|
||||
for (name, test) in json.as_object().unwrap() {
|
||||
let mut fail = false;
|
||||
let mut fail_unless = |cond: bool| if !cond && !fail { failed.push(name.to_string()); fail = true };
|
||||
let mut fail_unless = |cond: bool| if !cond && !fail { failed.push(name.to_string()); println!("Transaction: {:?}", ot.borrow()); fail = true };
|
||||
let schedule = match test.find("blocknumber")
|
||||
.and_then(|j| j.as_string())
|
||||
.and_then(|s| BlockNumber::from_str(s).ok())
|
||||
.unwrap_or(0) { x if x < 900000 => &old_schedule, _ => &new_schedule };
|
||||
let rlp = bytes_from_json(&test["rlp"]);
|
||||
let res = UntrustedRlp::new(&rlp).as_val().map_err(|e| From::from(e)).and_then(|t: Transaction| t.validate(schedule));
|
||||
let res = UntrustedRlp::new(&rlp).as_val().map_err(|e| From::from(e)).and_then(|t: Transaction| t.validate(schedule, schedule.have_delegate_call));
|
||||
fail_unless(test.find("transaction").is_none() == res.is_err());
|
||||
if let (Some(&Json::Object(ref tx)), Some(&Json::String(ref expect_sender))) = (test.find("transaction"), test.find("sender")) {
|
||||
let t = res.unwrap();
|
||||
@@ -25,8 +26,10 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
fail_unless(t.nonce == u256_from_json(&tx["nonce"]));
|
||||
fail_unless(t.value == u256_from_json(&tx["value"]));
|
||||
if let Action::Call(ref to) = t.action {
|
||||
*ot.borrow_mut() = t.clone();
|
||||
fail_unless(to == &address_from_json(&tx["to"]));
|
||||
} else {
|
||||
*ot.borrow_mut() = t.clone();
|
||||
fail_unless(bytes_from_json(&tx["to"]).len() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user