diff --git a/src/state.rs b/src/state.rs
index 3a4ad1833..648caa20a 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -140,9 +140,9 @@ impl State {
/// This will change the state accordingly.
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
let e = try!(Executive::new(self, env_info, engine).transact(t));
- println!("Executed: {:?}", e);
+ //println!("Executed: {:?}", e);
self.commit();
- Ok(Receipt::new(self.root().clone(), e.gas_used, e.logs))
+ Ok(Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs))
}
pub fn revert(&mut self, backup: State) {
@@ -156,7 +156,7 @@ impl State {
/// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit.
/// `accounts` is mutable because we may need to commit the code or storage and record that.
- pub fn commit_into(db: &mut HashDB, mut root: H256, accounts: &mut HashMap
>) -> H256 {
+ pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap>) {
// first, commit the sub trees.
// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?
for (_, ref mut a) in accounts.iter_mut() {
@@ -170,7 +170,7 @@ impl State {
}
{
- let mut trie = SecTrieDBMut::from_existing(db, &mut root);
+ let mut trie = SecTrieDBMut::from_existing(db, root);
for (address, ref a) in accounts.iter() {
match a {
&&Some(ref account) => trie.insert(address, &account.rlp()),
@@ -178,13 +178,11 @@ impl State {
}
}
}
- root
}
/// Commits our cached account changes into the trie.
pub fn commit(&mut self) {
- let r = self.root.clone(); // would prefer not to do this, really.
- self.root = Self::commit_into(&mut self.db, r, self.cache.borrow_mut().deref_mut());
+ Self::commit_into(&mut self.db, &mut self.root, self.cache.borrow_mut().deref_mut());
}
/// Populate the state from `accounts`.
diff --git a/src/tests/state.rs b/src/tests/state.rs
index 8aeb20560..fdedd7a83 100644
--- a/src/tests/state.rs
+++ b/src/tests/state.rs
@@ -4,54 +4,72 @@ use pod_state::*;
use state_diff::*;
use ethereum;
+fn flush(s: String) {
+ ::std::io::stdout().write(s.as_bytes()).unwrap();
+ ::std::io::stdout().flush().unwrap();
+}
+
fn do_json_test(json_data: &[u8]) -> Vec {
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();
+ flush(format!("\n"));
+
for (name, test) in json.as_object().unwrap() {
- println!("name: {:?}", name);
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 = xjson!(&test["postStateRoot"]);
- let pre = PodState::from_json(&test["pre"]);
- let post = PodState::from_json(&test["post"]);
- let logs: Vec<_> = test["logs"].as_array().unwrap().iter().map(&LogEntry::from_json).collect();
-
- //println!("Transaction: {:?}", t);
- //println!("Env: {:?}", env);
-
{
- let mut s = State::new_temp();
- s.populate_from(post.clone());
- s.commit();
- assert_eq!(&post_state_root, s.root());
- }
+ let mut fail_unless = |cond: bool| if !cond && !fail {
+ failed.push(name.to_string());
+ flush(format!("FAIL\n"));
+ fail = true;
+ true
+ } else {false};
- let mut s = State::new_temp();
- s.populate_from(pre);
- s.commit();
- let res = s.apply(&env, engine.deref(), &t);
+ flush(format!(" - {}...", name));
- if fail_unless(s.root() == &post_state_root) {
- println!("!!! {}: State mismatch (got: {}, expect: {}):", name, s.root(), post_state_root);
- let our_post = s.to_pod();
- println!("Got:\n{}", our_post);
- println!("Expect:\n{}", post);
- println!("Diff ---expect -> +++got:\n{}", StateDiff::diff_pod(&post, &our_post));
- }
+ 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 = xjson!(&test["postStateRoot"]);
+ let pre = PodState::from_json(&test["pre"]);
+ let post = PodState::from_json(&test["post"]);
+ let logs: Vec<_> = test["logs"].as_array().unwrap().iter().map(&LogEntry::from_json).collect();
- if let Ok(r) = res {
- if fail_unless(logs == r.logs) {
- println!("!!! {}: Logs mismatch:", name);
- println!("Got:\n{:?}", r.logs);
- println!("Expect:\n{:?}", logs);
+ //println!("Transaction: {:?}", t);
+ //println!("Env: {:?}", env);
+
+ {
+ let mut s = State::new_temp();
+ s.populate_from(post.clone());
+ s.commit();
+ assert_eq!(&post_state_root, s.root());
}
+
+ let mut s = State::new_temp();
+ s.populate_from(pre);
+ s.commit();
+ let res = s.apply(&env, engine.deref(), &t);
+
+ if fail_unless(s.root() == &post_state_root) {
+ println!("!!! {}: State mismatch (got: {}, expect: {}):", name, s.root(), post_state_root);
+ let our_post = s.to_pod();
+ println!("Got:\n{}", our_post);
+ println!("Expect:\n{}", post);
+ println!("Diff ---expect -> +++got:\n{}", StateDiff::diff_pod(&post, &our_post));
+ }
+
+ if let Ok(r) = res {
+ if fail_unless(logs == r.logs) {
+ println!("!!! {}: Logs mismatch:", name);
+ println!("Got:\n{:?}", r.logs);
+ println!("Expect:\n{:?}", logs);
+ }
+ }
+ }
+ if !fail {
+ flush(format!("ok\n"));
}
// TODO: Add extra APIs for output
//if fail_unless(out == r.)