From ba170247c1f9c7111e9d6762c799440fc96b225e Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 29 Jan 2016 20:51:17 +0400 Subject: [PATCH 01/15] env_info trivia --- src/env_info.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/env_info.rs b/src/env_info.rs index 76d33cd5a..d1dcfbe02 100644 --- a/src/env_info.rs +++ b/src/env_info.rs @@ -59,3 +59,36 @@ impl FromJson for EnvInfo { } } } + +#[cfg(test)] +mod tests { + extern crate rustc_serialize; + + use super::*; + use rustc_serialize::*; + use util::from_json::FromJson; + + #[test] + fn it_serializes_form_json() { + let env_info = EnvInfo::from_json(&json::Json::from_str( +r#" + { + "currentCoinbase": "0x0000000000000000000000000000000000000000", + "currentNumber": 0, + "currentDifficulty": 0, + "currentGasLimit" : 0, + "currentTimestamp" : 0 + } +"# + ).unwrap()); + + assert_eq!(env_info.number, 0); + } + + #[test] + fn it_can_be_created_as_default() { + let default_env_info = EnvInfo::default(); + + assert_eq!(default_env_info.difficulty, x!(0)); + } +} \ No newline at end of file From 3f492d5ac2079f12b9ea0369ff115009fc256ed8 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sat, 30 Jan 2016 15:53:16 +0400 Subject: [PATCH 02/15] podstate trivia --- src/pod_state.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/pod_state.rs b/src/pod_state.rs index 15ae6a8ae..f37a327f8 100644 --- a/src/pod_state.rs +++ b/src/pod_state.rs @@ -53,3 +53,31 @@ impl fmt::Display for PodState { Ok(()) } } + +#[cfg(test)] +mod tests { + extern crate rustc_serialize; + + use super::*; + use rustc_serialize::*; + use util::from_json::FromJson; + use util::hash::*; + + #[test] + fn it_serializes_form_json() { + let pod_state = PodState::from_json(&json::Json::from_str( +r#" + { + "0000000000000000000000000000000000000000": { + "balance": "1000", + "nonce": "100", + "storage": {}, + "code" : [] + } + } +"# + ).unwrap()); + + assert!(pod_state.get().get(&ZERO_ADDRESS).is_some()); + } +} From 1b48d07a9c7b2e8253e80054afd34f2fc3f1d5b7 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sat, 30 Jan 2016 17:00:36 +0400 Subject: [PATCH 03/15] receipt, service --- src/receipt.rs | 16 ++++++++++++++++ src/service.rs | 14 +++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/receipt.rs b/src/receipt.rs index d320373d6..4c6051314 100644 --- a/src/receipt.rs +++ b/src/receipt.rs @@ -36,3 +36,19 @@ impl Encodable for Receipt { s.append(&self.logs); } } + +#[cfg(test)] +mod tests { + use super::*; + use util::*; + + #[test] + fn it_can_be_encoded() { + let mut rlp_stream = RlpStream::new(); + let receipt = Receipt::new(H256::zero(), U256::zero(), vec![]); + rlp_stream.append(&receipt); + + let out = rlp_stream.out(); + assert_eq!(out.len(), 297); + } +} diff --git a/src/service.rs b/src/service.rs index a56ed7f44..f72d50588 100644 --- a/src/service.rs +++ b/src/service.rs @@ -56,7 +56,6 @@ impl ClientService { /// Get client interface pub fn client(&self) -> Arc { self.client.clone() - } /// Get network service component @@ -98,3 +97,16 @@ impl IoHandler for ClientIoHandler { } } +#[cfg(test)] +mod tests { + use super::*; + use tests::helpers::*; + use util::network::*; + + #[test] + fn it_can_be_started() { + let spec = get_test_spec(); + let service = ClientService::start(spec, NetworkConfiguration::new()); + assert!(service.is_ok()); + } +} \ No newline at end of file From 0402887cbfef98531990e8c079c8ab7ad5d6e518 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sat, 30 Jan 2016 17:15:37 +0400 Subject: [PATCH 04/15] accrue trivia --- src/service.rs | 2 +- src/substate.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/service.rs b/src/service.rs index f72d50588..f24758abb 100644 --- a/src/service.rs +++ b/src/service.rs @@ -102,7 +102,7 @@ mod tests { use super::*; use tests::helpers::*; use util::network::*; - + #[test] fn it_can_be_started() { let spec = get_test_spec(); diff --git a/src/substate.rs b/src/substate.rs index 5c4cde60c..d2aca983e 100644 --- a/src/substate.rs +++ b/src/substate.rs @@ -33,3 +33,15 @@ impl Substate { self.contracts_created.extend(s.contracts_created.into_iter()); } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn accrue() { + let mut sub_state = Substate::new(); + let sub_state_2 = Substate::new(); + sub_state.accrue(sub_state_2); + } +} \ No newline at end of file From 4ae26aed42b8166e39e49aae0f236236cdc59583 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 31 Jan 2016 13:52:07 +0400 Subject: [PATCH 05/15] temp directory refactoring in many cases --- src/block.rs | 73 ++++++++------- src/ethereum/ethash.rs | 16 ++-- src/ethereum/mod.rs | 6 +- src/executive.rs | 46 ++++++---- src/state.rs | 200 +++++++++++++++++++++-------------------- src/substate.rs | 6 +- src/tests/executive.rs | 4 +- src/tests/helpers.rs | 40 ++++++++- src/tests/state.rs | 17 ++-- util/src/journaldb.rs | 11 ++- 10 files changed, 254 insertions(+), 165 deletions(-) diff --git a/src/block.rs b/src/block.rs index 963124be0..f8e8ef16f 100644 --- a/src/block.rs +++ b/src/block.rs @@ -349,38 +349,49 @@ pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, db: JournalDB, parent Ok(try!(try!(enact_bytes(block_bytes, engine, db, parent, last_hashes)).seal(header.seal()))) } -#[test] -fn open_block() { - use spec::*; - let engine = Spec::new_test().to_engine().unwrap(); - let genesis_header = engine.spec().genesis_header(); - let mut db = JournalDB::new_temp(); - engine.spec().ensure_db_good(&mut db); - let last_hashes = vec![genesis_header.hash()]; - let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]); - let b = b.close(); - let _ = b.seal(vec![]); -} +#[cfg(test)] +mod tests { + use tests::helpers::*; + use super::*; + use common::*; + use engine::*; -#[test] -fn enact_block() { - use spec::*; - let engine = Spec::new_test().to_engine().unwrap(); - let genesis_header = engine.spec().genesis_header(); + #[test] + fn open_block() { + use spec::*; + let engine = Spec::new_test().to_engine().unwrap(); + let genesis_header = engine.spec().genesis_header(); + let mut db_result = get_temp_journal_db(); + let db = db_result.reference_mut(); + engine.spec().ensure_db_good(db); + let last_hashes = vec![genesis_header.hash()]; + let b = OpenBlock::new(engine.deref(), db.clone(), &genesis_header, &last_hashes, Address::zero(), vec![]); + let b = b.close(); + let _ = b.seal(vec![]); + } - let mut db = JournalDB::new_temp(); - engine.spec().ensure_db_good(&mut db); - let b = OpenBlock::new(engine.deref(), db, &genesis_header, &vec![genesis_header.hash()], Address::zero(), vec![]).close().seal(vec![]).unwrap(); - let orig_bytes = b.rlp_bytes(); - let orig_db = b.drain(); + #[test] + fn enact_block() { + use spec::*; + let engine = Spec::new_test().to_engine().unwrap(); + let genesis_header = engine.spec().genesis_header(); - let mut db = JournalDB::new_temp(); - engine.spec().ensure_db_good(&mut db); - let e = enact_and_seal(&orig_bytes, engine.deref(), db, &genesis_header, &vec![genesis_header.hash()]).unwrap(); + let mut db_result = get_temp_journal_db(); + let db = db_result.reference_mut(); + engine.spec().ensure_db_good(db); + let b = OpenBlock::new(engine.deref(), db.clone(), &genesis_header, &vec![genesis_header.hash()], Address::zero(), vec![]).close().seal(vec![]).unwrap(); + let orig_bytes = b.rlp_bytes(); + let orig_db = b.drain(); - assert_eq!(e.rlp_bytes(), orig_bytes); - - let db = e.drain(); - assert_eq!(orig_db.keys(), db.keys()); - assert!(orig_db.keys().iter().filter(|k| orig_db.get(k.0) != db.get(k.0)).next() == None); -} + let mut db_result = get_temp_journal_db(); + let db = db_result.reference_mut(); + engine.spec().ensure_db_good(db); + let e = enact_and_seal(&orig_bytes, engine.deref(), db.clone(), &genesis_header, &vec![genesis_header.hash()]).unwrap(); + + assert_eq!(e.rlp_bytes(), orig_bytes); + + let db = e.drain(); + assert_eq!(orig_db.keys(), db.keys()); + assert!(orig_db.keys().iter().filter(|k| orig_db.get(k.0) != db.get(k.0)).next() == None); + } +} \ No newline at end of file diff --git a/src/ethereum/ethash.rs b/src/ethereum/ethash.rs index f28ea31c6..ce40c5f42 100644 --- a/src/ethereum/ethash.rs +++ b/src/ethereum/ethash.rs @@ -7,6 +7,8 @@ use spec::*; use engine::*; use evm::Schedule; use evm::Factory; +#[cfg(test)] +use tests::helpers::*; /// Engine using Ethash proof-of-work consensus algorithm, suitable for Ethereum /// mainnet chains in the Olympic, Frontier and Homestead eras. @@ -227,10 +229,11 @@ fn on_close_block() { use super::*; let engine = new_morden().to_engine().unwrap(); let genesis_header = engine.spec().genesis_header(); - let mut db = JournalDB::new_temp(); - engine.spec().ensure_db_good(&mut db); + let mut db_result = get_temp_journal_db(); + let mut db = db_result.reference_mut(); + engine.spec().ensure_db_good(db); let last_hashes = vec![genesis_header.hash()]; - let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]); + let b = OpenBlock::new(engine.deref(), db.clone(), &genesis_header, &last_hashes, Address::zero(), vec![]); let b = b.close(); assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap()); } @@ -240,10 +243,11 @@ fn on_close_block_with_uncle() { use super::*; let engine = new_morden().to_engine().unwrap(); let genesis_header = engine.spec().genesis_header(); - let mut db = JournalDB::new_temp(); - engine.spec().ensure_db_good(&mut db); + let mut db_result = get_temp_journal_db(); + let mut db = db_result.reference_mut(); + engine.spec().ensure_db_good(db); let last_hashes = vec![genesis_header.hash()]; - let mut b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]); + let mut b = OpenBlock::new(engine.deref(), db.clone(), &genesis_header, &last_hashes, Address::zero(), vec![]); let mut uncle = Header::new(); let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106"); uncle.author = uncle_author.clone(); diff --git a/src/ethereum/mod.rs b/src/ethereum/mod.rs index 66bb7f356..5dd5a8da2 100644 --- a/src/ethereum/mod.rs +++ b/src/ethereum/mod.rs @@ -37,13 +37,15 @@ mod tests { use state::*; use engine::*; use super::*; + use tests::helpers::*; #[test] fn ensure_db_good() { let engine = new_morden().to_engine().unwrap(); let genesis_header = engine.spec().genesis_header(); - let mut db = JournalDB::new_temp(); - engine.spec().ensure_db_good(&mut db); + let mut db_result = get_temp_journal_db(); + let mut db = db_result.reference_mut(); + engine.spec().ensure_db_good(db); let s = State::from_existing(db.clone(), genesis_header.state_root.clone(), engine.account_start_nonce()); assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000001")), U256::from(1u64)); assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000002")), U256::from(1u64)); diff --git a/src/executive.rs b/src/executive.rs index b113363fd..5e1689830 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -341,12 +341,12 @@ impl<'a> Executive<'a> { mod tests { use super::*; use common::*; - use state::*; use ethereum; use engine::*; use spec::*; use evm::{Schedule, Factory, VMType}; use substate::*; + use tests::helpers::*; struct TestEngine { factory: Factory, @@ -395,7 +395,8 @@ mod tests { params.gas = U256::from(100_000); params.code = Some("3331600055".from_hex().unwrap()); params.value = ActionValue::Transfer(U256::from(0x7)); - let mut state = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(0x100u64)); let info = EnvInfo::new(); let engine = TestEngine::new(0, factory); @@ -453,7 +454,8 @@ mod tests { params.gas = U256::from(100_000); params.code = Some(code.clone()); params.value = ActionValue::Transfer(U256::from(100)); - let mut state = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(100)); let info = EnvInfo::new(); let engine = TestEngine::new(0, factory); @@ -506,7 +508,8 @@ mod tests { params.gas = U256::from(100_000); params.code = Some(code.clone()); params.value = ActionValue::Transfer(U256::from(100)); - let mut state = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(100)); let info = EnvInfo::new(); let engine = TestEngine::new(0, factory); @@ -557,7 +560,8 @@ mod tests { params.gas = U256::from(100_000); params.code = Some(code.clone()); params.value = ActionValue::Transfer(U256::from(100)); - let mut state = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(100)); let info = EnvInfo::new(); let engine = TestEngine::new(1024, factory); @@ -613,7 +617,8 @@ mod tests { params.code = Some(code_a.clone()); params.value = ActionValue::Transfer(U256::from(100_000)); - let mut state = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); state.init_code(&address_a, code_a.clone()); state.init_code(&address_b, code_b.clone()); state.add_balance(&sender, &U256::from(100_000)); @@ -659,7 +664,8 @@ mod tests { params.address = address.clone(); params.gas = U256::from(100_000); params.code = Some(code.clone()); - let mut state = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); state.init_code(&address, code.clone()); let info = EnvInfo::new(); let engine = TestEngine::new(0, factory); @@ -684,8 +690,9 @@ mod tests { let sender = t.sender().unwrap(); let contract = contract_address(&sender, &U256::zero()); - let mut state = State::new_temp(); - state.add_balance(&sender, &U256::from(18)); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); + state.add_balance(&sender, &U256::from(18)); let mut info = EnvInfo::new(); info.gas_limit = U256::from(100_000); let engine = TestEngine::new(0, factory); @@ -711,7 +718,8 @@ mod tests { fn test_transact_invalid_sender(factory: Factory) { let t = Transaction::new_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::zero(), U256::zero()); - let mut state = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); let mut info = EnvInfo::new(); info.gas_limit = U256::from(100_000); let engine = TestEngine::new(0, factory); @@ -734,8 +742,9 @@ mod tests { t.sign(&keypair.secret()); let sender = t.sender().unwrap(); - let mut state = State::new_temp(); - state.add_balance(&sender, &U256::from(17)); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); + state.add_balance(&sender, &U256::from(17)); let mut info = EnvInfo::new(); info.gas_limit = U256::from(100_000); let engine = TestEngine::new(0, factory); @@ -759,8 +768,9 @@ mod tests { t.sign(&keypair.secret()); let sender = t.sender().unwrap(); - let mut state = State::new_temp(); - state.add_balance(&sender, &U256::from(17)); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); + state.add_balance(&sender, &U256::from(17)); let mut info = EnvInfo::new(); info.gas_used = U256::from(20_000); info.gas_limit = U256::from(100_000); @@ -785,8 +795,9 @@ mod tests { t.sign(&keypair.secret()); let sender = t.sender().unwrap(); - let mut state = State::new_temp(); - state.add_balance(&sender, &U256::from(100_017)); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); + state.add_balance(&sender, &U256::from(100_017)); let mut info = EnvInfo::new(); info.gas_limit = U256::from(100_000); let engine = TestEngine::new(0, factory); @@ -818,7 +829,8 @@ mod tests { params.gas = U256::from(0x0186a0); params.code = Some(code.clone()); params.value = ActionValue::Transfer(U256::from_str("0de0b6b3a7640000").unwrap()); - let mut state = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap()); let info = EnvInfo::new(); let engine = TestEngine::new(0, factory); diff --git a/src/state.rs b/src/state.rs index 7310f63a7..c1b7e71c6 100644 --- a/src/state.rs +++ b/src/state.rs @@ -50,11 +50,6 @@ impl State { } } - /// Create temporary state object - pub fn new_temp() -> State { - Self::new(JournalDB::new_temp(), U256::from(0u8)) - } - /// Destroy the current object and return root and database. pub fn drop(self) -> (H256, JournalDB) { (self.root, self.db) @@ -285,158 +280,169 @@ use util::trie::*; use util::rlp::*; use util::uint::*; use account::*; +use tests::helpers::*; #[test] fn code_from_database() { let a = Address::zero(); - let (r, db) = { - let mut s = State::new_temp(); - s.require_or_from(&a, false, ||Account::new_contract(U256::from(42u32)), |_|{}); - s.init_code(&a, vec![1, 2, 3]); - assert_eq!(s.code(&a), Some([1u8, 2, 3].to_vec())); - s.commit(); - assert_eq!(s.code(&a), Some([1u8, 2, 3].to_vec())); - s.drop() + let temp = RandomTempPath::new(); + let (root, db) = { + let mut state = get_temp_state_in(temp.as_path()); + state.require_or_from(&a, false, ||Account::new_contract(U256::from(42u32)), |_|{}); + state.init_code(&a, vec![1, 2, 3]); + assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec())); + state.commit(); + assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec())); + state.drop() }; - let s = State::from_existing(db, r, U256::from(0u8)); - assert_eq!(s.code(&a), Some([1u8, 2, 3].to_vec())); + let state = State::from_existing(db, root, U256::from(0u8)); + assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec())); } #[test] fn storage_at_from_database() { let a = Address::zero(); - let (r, db) = { - let mut s = State::new_temp(); - s.set_storage(&a, H256::from(&U256::from(01u64)), H256::from(&U256::from(69u64))); - s.commit(); - s.drop() + let temp = RandomTempPath::new(); + let (root, db) = { + let mut state = get_temp_state_in(temp.as_path()); + state.set_storage(&a, H256::from(&U256::from(01u64)), H256::from(&U256::from(69u64))); + state.commit(); + state.drop() }; - let s = State::from_existing(db, r, U256::from(0u8)); + let s = State::from_existing(db, root, U256::from(0u8)); assert_eq!(s.storage_at(&a, &H256::from(&U256::from(01u64))), H256::from(&U256::from(69u64))); } #[test] fn get_from_database() { let a = Address::zero(); - let (r, db) = { - let mut s = State::new_temp(); - s.inc_nonce(&a); - s.add_balance(&a, &U256::from(69u64)); - s.commit(); - assert_eq!(s.balance(&a), U256::from(69u64)); - s.drop() + let temp = RandomTempPath::new(); + let (root, db) = { + let mut state = get_temp_state_in(temp.as_path()); + state.inc_nonce(&a); + state.add_balance(&a, &U256::from(69u64)); + state.commit(); + assert_eq!(state.balance(&a), U256::from(69u64)); + state.drop() }; - let s = State::from_existing(db, r, U256::from(0u8)); - assert_eq!(s.balance(&a), U256::from(69u64)); - assert_eq!(s.nonce(&a), U256::from(1u64)); + let state = State::from_existing(db, root, U256::from(0u8)); + assert_eq!(state.balance(&a), U256::from(69u64)); + assert_eq!(state.nonce(&a), U256::from(1u64)); } #[test] fn remove() { let a = Address::zero(); - let mut s = State::new_temp(); - assert_eq!(s.exists(&a), false); - s.inc_nonce(&a); - assert_eq!(s.exists(&a), true); - assert_eq!(s.nonce(&a), U256::from(1u64)); - s.kill_account(&a); - assert_eq!(s.exists(&a), false); - assert_eq!(s.nonce(&a), U256::from(0u64)); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); + assert_eq!(state.exists(&a), false); + state.inc_nonce(&a); + assert_eq!(state.exists(&a), true); + assert_eq!(state.nonce(&a), U256::from(1u64)); + state.kill_account(&a); + assert_eq!(state.exists(&a), false); + assert_eq!(state.nonce(&a), U256::from(0u64)); } #[test] fn remove_from_database() { let a = Address::zero(); - let (r, db) = { - let mut s = State::new_temp(); - s.inc_nonce(&a); - s.commit(); - assert_eq!(s.exists(&a), true); - assert_eq!(s.nonce(&a), U256::from(1u64)); - s.drop() + let temp = RandomTempPath::new(); + { + let mut state = get_temp_state_in(temp.as_path()); + state.inc_nonce(&a); + state.commit(); + assert_eq!(state.exists(&a), true); + assert_eq!(state.nonce(&a), U256::from(1u64)); + state.drop() }; - let (r, db) = { - let mut s = State::from_existing(db, r, U256::from(0u8)); - assert_eq!(s.exists(&a), true); - assert_eq!(s.nonce(&a), U256::from(1u64)); - s.kill_account(&a); - s.commit(); - assert_eq!(s.exists(&a), false); - assert_eq!(s.nonce(&a), U256::from(0u64)); - s.drop() + let (root, db) = { + let mut state = get_temp_state_in(temp.as_path()); + assert_eq!(state.exists(&a), true); + assert_eq!(state.nonce(&a), U256::from(1u64)); + state.kill_account(&a); + state.commit(); + assert_eq!(state.exists(&a), false); + assert_eq!(state.nonce(&a), U256::from(0u64)); + state.drop() }; - let s = State::from_existing(db, r, U256::from(0u8)); - assert_eq!(s.exists(&a), false); - assert_eq!(s.nonce(&a), U256::from(0u64)); + let state = State::from_existing(db, root, U256::from(0u8)); + assert_eq!(state.exists(&a), false); + assert_eq!(state.nonce(&a), U256::from(0u64)); } #[test] fn alter_balance() { - let mut s = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); let a = Address::zero(); let b = address_from_u64(1u64); - s.add_balance(&a, &U256::from(69u64)); - assert_eq!(s.balance(&a), U256::from(69u64)); - s.commit(); - assert_eq!(s.balance(&a), U256::from(69u64)); - s.sub_balance(&a, &U256::from(42u64)); - assert_eq!(s.balance(&a), U256::from(27u64)); - s.commit(); - assert_eq!(s.balance(&a), U256::from(27u64)); - s.transfer_balance(&a, &b, &U256::from(18u64)); - assert_eq!(s.balance(&a), U256::from(9u64)); - assert_eq!(s.balance(&b), U256::from(18u64)); - s.commit(); - assert_eq!(s.balance(&a), U256::from(9u64)); - assert_eq!(s.balance(&b), U256::from(18u64)); + state.add_balance(&a, &U256::from(69u64)); + assert_eq!(state.balance(&a), U256::from(69u64)); + state.commit(); + assert_eq!(state.balance(&a), U256::from(69u64)); + state.sub_balance(&a, &U256::from(42u64)); + assert_eq!(state.balance(&a), U256::from(27u64)); + state.commit(); + assert_eq!(state.balance(&a), U256::from(27u64)); + state.transfer_balance(&a, &b, &U256::from(18u64)); + assert_eq!(state.balance(&a), U256::from(9u64)); + assert_eq!(state.balance(&b), U256::from(18u64)); + state.commit(); + assert_eq!(state.balance(&a), U256::from(9u64)); + assert_eq!(state.balance(&b), U256::from(18u64)); } #[test] fn alter_nonce() { - let mut s = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); let a = Address::zero(); - s.inc_nonce(&a); - assert_eq!(s.nonce(&a), U256::from(1u64)); - s.inc_nonce(&a); - assert_eq!(s.nonce(&a), U256::from(2u64)); - s.commit(); - assert_eq!(s.nonce(&a), U256::from(2u64)); - s.inc_nonce(&a); - assert_eq!(s.nonce(&a), U256::from(3u64)); - s.commit(); - assert_eq!(s.nonce(&a), U256::from(3u64)); + state.inc_nonce(&a); + assert_eq!(state.nonce(&a), U256::from(1u64)); + state.inc_nonce(&a); + assert_eq!(state.nonce(&a), U256::from(2u64)); + state.commit(); + assert_eq!(state.nonce(&a), U256::from(2u64)); + state.inc_nonce(&a); + assert_eq!(state.nonce(&a), U256::from(3u64)); + state.commit(); + assert_eq!(state.nonce(&a), U256::from(3u64)); } #[test] fn balance_nonce() { - let mut s = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); let a = Address::zero(); - assert_eq!(s.balance(&a), U256::from(0u64)); - assert_eq!(s.nonce(&a), U256::from(0u64)); - s.commit(); - assert_eq!(s.balance(&a), U256::from(0u64)); - assert_eq!(s.nonce(&a), U256::from(0u64)); + assert_eq!(state.balance(&a), U256::from(0u64)); + assert_eq!(state.nonce(&a), U256::from(0u64)); + state.commit(); + assert_eq!(state.balance(&a), U256::from(0u64)); + assert_eq!(state.nonce(&a), U256::from(0u64)); } #[test] fn ensure_cached() { - let mut s = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); let a = Address::zero(); - s.require(&a, false); - s.commit(); - assert_eq!(s.root().hex(), "0ce23f3c809de377b008a4a3ee94a0834aac8bec1f86e28ffe4fdb5a15b0c785"); + state.require(&a, false); + state.commit(); + assert_eq!(state.root().hex(), "0ce23f3c809de377b008a4a3ee94a0834aac8bec1f86e28ffe4fdb5a15b0c785"); } #[test] fn create_empty() { - let mut s = State::new_temp(); - s.commit(); - assert_eq!(s.root().hex(), "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); + state.commit(); + assert_eq!(state.root().hex(), "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); } } diff --git a/src/substate.rs b/src/substate.rs index d2aca983e..e14ac4d20 100644 --- a/src/substate.rs +++ b/src/substate.rs @@ -37,11 +37,15 @@ impl Substate { #[cfg(test)] mod tests { use super::*; + use util::hash::*; #[test] fn accrue() { let mut sub_state = Substate::new(); - let sub_state_2 = Substate::new(); + sub_state.contracts_created.push(address_from_u64(1u64)); + let mut sub_state_2 = Substate::new(); + sub_state_2.contracts_created.push(address_from_u64(2u64)); sub_state.accrue(sub_state_2); + assert_eq!(sub_state.contracts_created.len(), 2); } } \ No newline at end of file diff --git a/src/tests/executive.rs b/src/tests/executive.rs index 1df1b7eec..f097a17ad 100644 --- a/src/tests/executive.rs +++ b/src/tests/executive.rs @@ -8,6 +8,7 @@ use evm::{Schedule, Ext, Factory, VMType, ContractCreateResult, MessageCallResul use ethereum; use externalities::*; use substate::*; +use tests::helpers::*; struct TestEngine { vm_factory: Factory, @@ -174,7 +175,8 @@ fn do_json_test_for(vm: &VMType, json_data: &[u8]) -> Vec { }; // test env - let mut state = State::new_temp(); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); test.find("pre").map(|pre| for (addr, s) in pre.as_object().unwrap() { let address = Address::from(addr.as_ref()); diff --git a/src/tests/helpers.rs b/src/tests/helpers.rs index de73224fd..d2423f95c 100644 --- a/src/tests/helpers.rs +++ b/src/tests/helpers.rs @@ -5,7 +5,8 @@ use std::path::PathBuf; use spec::*; use std::fs::{remove_dir_all}; use blockchain::{BlockChain}; - +use state::*; +use rocksdb::*; pub struct RandomTempPath { path: PathBuf @@ -23,6 +24,10 @@ impl RandomTempPath { pub fn as_path(&self) -> &PathBuf { &self.path } + + pub fn as_str(&self) -> &str { + self.path.to_str().unwrap() + } } impl Drop for RandomTempPath { @@ -43,6 +48,10 @@ impl GuardedTempResult { pub fn reference(&self) -> &T { &self.result } + + pub fn reference_mut(&mut self) -> &mut T { + &mut self.result + } } pub fn get_test_spec() -> Spec { @@ -189,6 +198,35 @@ pub fn generate_dummy_empty_blockchain() -> GuardedTempResult { } } +pub fn get_temp_journal_db() -> GuardedTempResult { + let temp = RandomTempPath::new(); + let db = DB::open_default(temp.as_str()).unwrap(); + let journal_db = JournalDB::new(db); + GuardedTempResult { + temp: temp, + result: journal_db + } +} + +pub fn get_temp_state() -> GuardedTempResult { + let temp = RandomTempPath::new(); + let journal_db = get_temp_journal_db_in(temp.as_path()); + GuardedTempResult { + temp: temp, + result: State::new(journal_db, U256::from(0u8)) + } +} + +pub fn get_temp_journal_db_in(path: &Path) -> JournalDB { + let db = DB::open_default(path.to_str().unwrap()).unwrap(); + JournalDB::new(db) +} + +pub fn get_temp_state_in(path: &Path) -> State { + let journal_db = get_temp_journal_db_in(path); + State::new(journal_db, U256::from(0u8)) +} + pub fn get_good_dummy_block() -> Bytes { let mut block_header = Header::new(); let test_spec = get_test_spec(); diff --git a/src/tests/state.rs b/src/tests/state.rs index 325a8b646..1dbe27c9c 100644 --- a/src/tests/state.rs +++ b/src/tests/state.rs @@ -1,8 +1,8 @@ use super::test_common::*; -use state::*; use pod_state::*; use state_diff::*; use ethereum; +use tests::helpers::*; fn do_json_test(json_data: &[u8]) -> Vec { let json = Json::from_str(::std::str::from_utf8(json_data).unwrap()).expect("Json is invalid"); @@ -39,14 +39,15 @@ fn do_json_test(json_data: &[u8]) -> Vec { println!("!!! {}: Trie root mismatch (got: {}, expect: {}):", name, calc_post, post_state_root); println!("!!! Post:\n{}", post); } else { - let mut s = State::new_temp(); - s.populate_from(pre); - s.commit(); - let res = s.apply(&env, engine.deref(), &t); + let mut state_result = get_temp_state(); + let mut state = state_result.reference_mut(); + state.populate_from(pre); + state.commit(); + let res = state.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(); + if fail_unless(state.root() == &post_state_root) { + println!("!!! {}: State mismatch (got: {}, expect: {}):", name, state.root(), post_state_root); + let our_post = state.to_pod(); println!("Got:\n{}", our_post); println!("Expect:\n{}", post); println!("Diff ---expect -> +++got:\n{}", StateDiff::diff_pod(&post, &our_post)); diff --git a/util/src/journaldb.rs b/util/src/journaldb.rs index ba31efafb..858455072 100644 --- a/util/src/journaldb.rs +++ b/util/src/journaldb.rs @@ -19,7 +19,7 @@ pub struct JournalDB { forward: OverlayDB, backing: Arc, inserts: Vec, - removes: Vec, + removes: Vec } impl JournalDB { @@ -45,6 +45,7 @@ impl JournalDB { } /// Create a new instance with an anonymous temporary database. + #[cfg(test)] pub fn new_temp() -> JournalDB { let mut dir = env::temp_dir(); dir.push(H32::random().hex()); @@ -137,6 +138,7 @@ mod tests { use common::*; use super::*; use hashdb::*; + use tests::helpers::*; #[test] fn long_history() { @@ -221,4 +223,11 @@ mod tests { assert!(!jdb.exists(&baz)); assert!(!jdb.exists(&bar)); } + + #[test] + fn old_commits_applied() { + let mut dir = env::temp_dir(); + dir.push(H32::random().hex()); + + } } From 7132d5f7cb8812848b600c1c68a9f8dc8204f0a6 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 31 Jan 2016 13:57:56 +0400 Subject: [PATCH 06/15] removed duplicates --- src/tests/state.rs | 1 - util/src/journaldb.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/tests/state.rs b/src/tests/state.rs index 7bce1d41e..34b24de3b 100644 --- a/src/tests/state.rs +++ b/src/tests/state.rs @@ -3,7 +3,6 @@ use super::helpers::*; use pod_state::*; use state_diff::*; use ethereum; -use tests::helpers::*; fn do_json_test(json_data: &[u8]) -> Vec { json_chain_test(json_data, ChainEra::Frontier) diff --git a/util/src/journaldb.rs b/util/src/journaldb.rs index 858455072..ab332d714 100644 --- a/util/src/journaldb.rs +++ b/util/src/journaldb.rs @@ -1,6 +1,5 @@ //! Disk-backed HashDB implementation. -use std::env; use common::*; use rlp::*; use hashdb::*; From 0a66d297157b965846fe0cf5f02caa1a36a3d7dc Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 31 Jan 2016 14:07:22 +0400 Subject: [PATCH 07/15] fixed mistake of not taking previous database --- src/state.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/state.rs b/src/state.rs index 8d9f35750..58cdf85a2 100644 --- a/src/state.rs +++ b/src/state.rs @@ -351,7 +351,7 @@ fn remove() { fn remove_from_database() { let a = Address::zero(); let temp = RandomTempPath::new(); - { + let (root, db) = { let mut state = get_temp_state_in(temp.as_path()); state.inc_nonce(&a); state.commit(); @@ -361,7 +361,7 @@ fn remove_from_database() { }; let (root, db) = { - let mut state = get_temp_state_in(temp.as_path()); + let mut state = State::from_existing(db, root, U256::from(0u8)); assert_eq!(state.exists(&a), true); assert_eq!(state.nonce(&a), U256::from(1u64)); state.kill_account(&a); From 56511920764d7757365daac6ffeaae475a933e47 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 31 Jan 2016 14:24:45 +0400 Subject: [PATCH 08/15] removed unused stub --- util/src/journaldb.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/util/src/journaldb.rs b/util/src/journaldb.rs index ab332d714..793cb3640 100644 --- a/util/src/journaldb.rs +++ b/util/src/journaldb.rs @@ -222,11 +222,4 @@ mod tests { assert!(!jdb.exists(&baz)); assert!(!jdb.exists(&bar)); } - - #[test] - fn old_commits_applied() { - let mut dir = env::temp_dir(); - dir.push(H32::random().hex()); - - } } From b83dd9fe52cabfc279d561cf19de86de5814bd8b Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 31 Jan 2016 19:01:43 +0400 Subject: [PATCH 09/15] fix merge bug --- .gitmodules | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitmodules b/.gitmodules index e69de29bb..0105f1024 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "ethcore/res/ethereum/tests"] + path = ethcore/res/ethereum/tests + url = git@github.com:ethereum/tests + branch = develop \ No newline at end of file From efc70e9f09b594b3bcb6afa49f7bfd5dc33e36e7 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 31 Jan 2016 19:04:47 +0400 Subject: [PATCH 10/15] merge fix --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 0105f1024..95ac098ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "ethcore/res/ethereum/tests"] path = ethcore/res/ethereum/tests url = git@github.com:ethereum/tests - branch = develop \ No newline at end of file + branch = develop \ No newline at end of file From f2a109684e1c38b8d000576bcd88ce5bf15956df Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 31 Jan 2016 19:35:17 +0400 Subject: [PATCH 11/15] remove directory --- {res => ethcore/res}/ethereum/tests | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {res => ethcore/res}/ethereum/tests (100%) diff --git a/res/ethereum/tests b/ethcore/res/ethereum/tests similarity index 100% rename from res/ethereum/tests rename to ethcore/res/ethereum/tests From 1778393a518ac9fd65b6a97af41dc9db6e3f7d47 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 31 Jan 2016 20:01:36 +0400 Subject: [PATCH 12/15] fix util compilation --- util/src/journaldb.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/src/journaldb.rs b/util/src/journaldb.rs index 793cb3640..68725c213 100644 --- a/util/src/journaldb.rs +++ b/util/src/journaldb.rs @@ -5,6 +5,8 @@ use rlp::*; use hashdb::*; use overlaydb::*; use rocksdb::{DB, Writable}; +#[cfg(test)] +use std::env; #[derive(Clone)] /// Implementation of the HashDB trait for a disk-backed database with a memory overlay @@ -137,7 +139,6 @@ mod tests { use common::*; use super::*; use hashdb::*; - use tests::helpers::*; #[test] fn long_history() { From cf963b1957e4e567bb14fff2960ca27006707ee2 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 1 Feb 2016 15:35:13 +0400 Subject: [PATCH 13/15] more of env_info --- ethcore/src/env_info.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ethcore/src/env_info.rs b/ethcore/src/env_info.rs index d1dcfbe02..8b037036e 100644 --- a/ethcore/src/env_info.rs +++ b/ethcore/src/env_info.rs @@ -67,22 +67,28 @@ mod tests { use super::*; use rustc_serialize::*; use util::from_json::FromJson; + use util::hash::*; + use std::str::FromStr; #[test] fn it_serializes_form_json() { let env_info = EnvInfo::from_json(&json::Json::from_str( r#" { - "currentCoinbase": "0x0000000000000000000000000000000000000000", - "currentNumber": 0, - "currentDifficulty": 0, - "currentGasLimit" : 0, - "currentTimestamp" : 0 + "currentCoinbase": "0x000000f00000000f000000000000f00000000f00", + "currentNumber": 1112339, + "currentDifficulty": 50000, + "currentGasLimit" : 40000, + "currentTimestamp" : 1100 } "# ).unwrap()); - assert_eq!(env_info.number, 0); + assert_eq!(env_info.number, 1112339); + assert_eq!(env_info.author, Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()); + assert_eq!(env_info.gas_limit, x!(40000)); + assert_eq!(env_info.difficulty, x!(50000)); + assert_eq!(env_info.gas_used, x!(0)); } #[test] From e0e8ba01edd334952c1e475820f4528b0db7a30f Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 1 Feb 2016 16:29:12 +0400 Subject: [PATCH 14/15] accrue expanded --- ethcore/src/substate.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ethcore/src/substate.rs b/ethcore/src/substate.rs index e14ac4d20..73ba267cd 100644 --- a/ethcore/src/substate.rs +++ b/ethcore/src/substate.rs @@ -37,15 +37,24 @@ impl Substate { #[cfg(test)] mod tests { use super::*; - use util::hash::*; + use common::*; #[test] fn accrue() { let mut sub_state = Substate::new(); sub_state.contracts_created.push(address_from_u64(1u64)); + sub_state.logs.push(LogEntry::new(address_from_u64(1u64), vec![], vec![])); + sub_state.sstore_clears_count = x!(5); + sub_state.suicides.insert(address_from_u64(10u64)); + let mut sub_state_2 = Substate::new(); sub_state_2.contracts_created.push(address_from_u64(2u64)); + sub_state_2.logs.push(LogEntry::new(address_from_u64(1u64), vec![], vec![])); + sub_state_2.sstore_clears_count = x!(7); + sub_state.accrue(sub_state_2); assert_eq!(sub_state.contracts_created.len(), 2); + assert_eq!(sub_state.sstore_clears_count, x!(12)); + assert_eq!(sub_state.suicides.len(), 1); } } \ No newline at end of file From 79258a99120b5a57027b09bf5e67700c0f0c5983 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 1 Feb 2016 15:07:11 +0100 Subject: [PATCH 15/15] Update journaldb.rs --- util/src/journaldb.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/src/journaldb.rs b/util/src/journaldb.rs index 68725c213..e30b8947c 100644 --- a/util/src/journaldb.rs +++ b/util/src/journaldb.rs @@ -20,7 +20,7 @@ pub struct JournalDB { forward: OverlayDB, backing: Arc, inserts: Vec, - removes: Vec + removes: Vec, } impl JournalDB {