2016-01-13 01:19:05 +01:00
|
|
|
use super::test_common::*;
|
|
|
|
use state::*;
|
2016-01-14 00:27:36 +01:00
|
|
|
use executive::*;
|
2016-01-13 01:19:05 +01:00
|
|
|
use ethereum;
|
|
|
|
|
2016-01-13 12:14:11 +01:00
|
|
|
pub fn map_h256_h256_from_json(json: &Json) -> BTreeMap<H256, H256> {
|
|
|
|
json.as_object().unwrap().iter().fold(BTreeMap::new(), |mut m, (key, value)| {
|
2016-01-13 17:45:06 +01:00
|
|
|
m.insert(H256::from(&u256_from_str(key)), H256::from(&u256_from_json(value)));
|
2016-01-13 12:14:11 +01:00
|
|
|
m
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-01-13 01:19:05 +01:00
|
|
|
/// Translate the JSON object into a hash map of account information ready for insertion into State.
|
2016-01-13 12:14:11 +01:00
|
|
|
pub fn pod_map_from_json(json: &Json) -> BTreeMap<Address, PodAccount> {
|
|
|
|
json.as_object().unwrap().iter().fold(BTreeMap::new(), |mut state, (address, acc)| {
|
2016-01-13 01:19:05 +01:00
|
|
|
let balance = acc.find("balance").map(&u256_from_json);
|
|
|
|
let nonce = acc.find("nonce").map(&u256_from_json);
|
2016-01-13 12:14:11 +01:00
|
|
|
let storage = acc.find("storage").map(&map_h256_h256_from_json);;
|
2016-01-13 01:19:05 +01:00
|
|
|
let code = acc.find("code").map(&bytes_from_json);
|
2016-01-13 12:14:11 +01:00
|
|
|
if balance.is_some() || nonce.is_some() || storage.is_some() || code.is_some() {
|
2016-01-13 01:19:05 +01:00
|
|
|
state.insert(address_from_hex(address), PodAccount{
|
|
|
|
balance: balance.unwrap_or(U256::zero()),
|
|
|
|
nonce: nonce.unwrap_or(U256::zero()),
|
2016-01-13 12:14:11 +01:00
|
|
|
storage: storage.unwrap_or(BTreeMap::new()),
|
2016-01-13 01:19:05 +01:00
|
|
|
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"]);
|
2016-01-13 18:40:18 +01:00
|
|
|
let _out = bytes_from_json(&test["out"]);
|
2016-01-13 01:19:05 +01:00
|
|
|
let post_state_root = h256_from_json(&test["postStateRoot"]);
|
2016-01-13 12:14:11 +01:00
|
|
|
let pre = pod_map_from_json(&test["pre"]);
|
|
|
|
let post = pod_map_from_json(&test["post"]);
|
2016-01-13 01:19:05 +01:00
|
|
|
// TODO: read test["logs"]
|
|
|
|
|
2016-01-14 00:27:36 +01:00
|
|
|
//println!("Transaction: {:?}", t);
|
|
|
|
//println!("Env: {:?}", env);
|
2016-01-13 15:54:17 +01:00
|
|
|
|
2016-01-14 02:09:43 +01:00
|
|
|
{
|
|
|
|
let mut s = State::new_temp();
|
|
|
|
s.populate_from(post.clone());
|
|
|
|
s.commit();
|
|
|
|
assert_eq!(&post_state_root, s.root());
|
|
|
|
}
|
|
|
|
|
2016-01-13 01:19:05 +01:00
|
|
|
let mut s = State::new_temp();
|
|
|
|
s.populate_from(pre);
|
2016-01-13 15:54:17 +01:00
|
|
|
|
2016-01-14 02:09:43 +01:00
|
|
|
s.apply(&env, engine.deref(), &t).unwrap();
|
2016-01-13 12:14:11 +01:00
|
|
|
let our_post = s.to_pod_map();
|
2016-01-13 01:19:05 +01:00
|
|
|
|
|
|
|
if fail_unless(s.root() == &post_state_root) {
|
2016-01-14 00:27:36 +01:00
|
|
|
println!("FAILED {}. Diff:\n{}", name, pod_map_diff(&post, &our_post));
|
2016-01-13 01:19:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Compare logs.
|
|
|
|
}
|
|
|
|
for f in failed.iter() {
|
|
|
|
println!("FAILED: {:?}", f);
|
|
|
|
}
|
|
|
|
failed
|
|
|
|
}
|
|
|
|
|
|
|
|
declare_test!{StateTests_stExample, "StateTests/stExample"}
|