temp directory refactoring in many cases

This commit is contained in:
Nikolay Volf 2016-01-31 13:52:07 +04:00
parent 0402887cbf
commit 4ae26aed42
10 changed files with 254 additions and 165 deletions

View File

@ -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()))) Ok(try!(try!(enact_bytes(block_bytes, engine, db, parent, last_hashes)).seal(header.seal())))
} }
#[test] #[cfg(test)]
fn open_block() { mod tests {
use spec::*; use tests::helpers::*;
let engine = Spec::new_test().to_engine().unwrap(); use super::*;
let genesis_header = engine.spec().genesis_header(); use common::*;
let mut db = JournalDB::new_temp(); use engine::*;
engine.spec().ensure_db_good(&mut db);
let last_hashes = vec![genesis_header.hash()]; #[test]
let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]); fn open_block() {
let b = b.close(); use spec::*;
let _ = b.seal(vec![]); let engine = Spec::new_test().to_engine().unwrap();
} let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
#[test] let db = db_result.reference_mut();
fn enact_block() { engine.spec().ensure_db_good(db);
use spec::*; let last_hashes = vec![genesis_header.hash()];
let engine = Spec::new_test().to_engine().unwrap(); let b = OpenBlock::new(engine.deref(), db.clone(), &genesis_header, &last_hashes, Address::zero(), vec![]);
let genesis_header = engine.spec().genesis_header(); 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(); #[test]
let orig_bytes = b.rlp_bytes(); fn enact_block() {
let orig_db = b.drain(); use spec::*;
let engine = Spec::new_test().to_engine().unwrap();
let mut db = JournalDB::new_temp(); let genesis_header = engine.spec().genesis_header();
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();
assert_eq!(e.rlp_bytes(), orig_bytes); 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 db = e.drain(); let orig_bytes = b.rlp_bytes();
assert_eq!(orig_db.keys(), db.keys()); let orig_db = b.drain();
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);
}
} }

View File

@ -7,6 +7,8 @@ use spec::*;
use engine::*; use engine::*;
use evm::Schedule; use evm::Schedule;
use evm::Factory; use evm::Factory;
#[cfg(test)]
use tests::helpers::*;
/// Engine using Ethash proof-of-work consensus algorithm, suitable for Ethereum /// Engine using Ethash proof-of-work consensus algorithm, suitable for Ethereum
/// mainnet chains in the Olympic, Frontier and Homestead eras. /// mainnet chains in the Olympic, Frontier and Homestead eras.
@ -227,10 +229,11 @@ fn on_close_block() {
use super::*; use super::*;
let engine = new_morden().to_engine().unwrap(); let engine = new_morden().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header(); let genesis_header = engine.spec().genesis_header();
let mut db = JournalDB::new_temp(); let mut db_result = get_temp_journal_db();
engine.spec().ensure_db_good(&mut db); let mut db = db_result.reference_mut();
engine.spec().ensure_db_good(db);
let last_hashes = vec![genesis_header.hash()]; 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(); let b = b.close();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap()); assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
} }
@ -240,10 +243,11 @@ fn on_close_block_with_uncle() {
use super::*; use super::*;
let engine = new_morden().to_engine().unwrap(); let engine = new_morden().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header(); let genesis_header = engine.spec().genesis_header();
let mut db = JournalDB::new_temp(); let mut db_result = get_temp_journal_db();
engine.spec().ensure_db_good(&mut db); let mut db = db_result.reference_mut();
engine.spec().ensure_db_good(db);
let last_hashes = vec![genesis_header.hash()]; 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 mut uncle = Header::new();
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106"); let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
uncle.author = uncle_author.clone(); uncle.author = uncle_author.clone();

View File

@ -37,13 +37,15 @@ mod tests {
use state::*; use state::*;
use engine::*; use engine::*;
use super::*; use super::*;
use tests::helpers::*;
#[test] #[test]
fn ensure_db_good() { fn ensure_db_good() {
let engine = new_morden().to_engine().unwrap(); let engine = new_morden().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header(); let genesis_header = engine.spec().genesis_header();
let mut db = JournalDB::new_temp(); let mut db_result = get_temp_journal_db();
engine.spec().ensure_db_good(&mut 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()); 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("0000000000000000000000000000000000000001")), U256::from(1u64));
assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000002")), U256::from(1u64)); assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000002")), U256::from(1u64));

View File

@ -341,12 +341,12 @@ impl<'a> Executive<'a> {
mod tests { mod tests {
use super::*; use super::*;
use common::*; use common::*;
use state::*;
use ethereum; use ethereum;
use engine::*; use engine::*;
use spec::*; use spec::*;
use evm::{Schedule, Factory, VMType}; use evm::{Schedule, Factory, VMType};
use substate::*; use substate::*;
use tests::helpers::*;
struct TestEngine { struct TestEngine {
factory: Factory, factory: Factory,
@ -395,7 +395,8 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some("3331600055".from_hex().unwrap()); params.code = Some("3331600055".from_hex().unwrap());
params.value = ActionValue::Transfer(U256::from(0x7)); 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)); state.add_balance(&sender, &U256::from(0x100u64));
let info = EnvInfo::new(); let info = EnvInfo::new();
let engine = TestEngine::new(0, factory); let engine = TestEngine::new(0, factory);
@ -453,7 +454,8 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(code.clone()); params.code = Some(code.clone());
params.value = ActionValue::Transfer(U256::from(100)); 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)); state.add_balance(&sender, &U256::from(100));
let info = EnvInfo::new(); let info = EnvInfo::new();
let engine = TestEngine::new(0, factory); let engine = TestEngine::new(0, factory);
@ -506,7 +508,8 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(code.clone()); params.code = Some(code.clone());
params.value = ActionValue::Transfer(U256::from(100)); 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)); state.add_balance(&sender, &U256::from(100));
let info = EnvInfo::new(); let info = EnvInfo::new();
let engine = TestEngine::new(0, factory); let engine = TestEngine::new(0, factory);
@ -557,7 +560,8 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(code.clone()); params.code = Some(code.clone());
params.value = ActionValue::Transfer(U256::from(100)); 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)); state.add_balance(&sender, &U256::from(100));
let info = EnvInfo::new(); let info = EnvInfo::new();
let engine = TestEngine::new(1024, factory); let engine = TestEngine::new(1024, factory);
@ -613,7 +617,8 @@ mod tests {
params.code = Some(code_a.clone()); params.code = Some(code_a.clone());
params.value = ActionValue::Transfer(U256::from(100_000)); 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_a, code_a.clone());
state.init_code(&address_b, code_b.clone()); state.init_code(&address_b, code_b.clone());
state.add_balance(&sender, &U256::from(100_000)); state.add_balance(&sender, &U256::from(100_000));
@ -659,7 +664,8 @@ mod tests {
params.address = address.clone(); params.address = address.clone();
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(code.clone()); 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()); state.init_code(&address, code.clone());
let info = EnvInfo::new(); let info = EnvInfo::new();
let engine = TestEngine::new(0, factory); let engine = TestEngine::new(0, factory);
@ -684,7 +690,8 @@ mod tests {
let sender = t.sender().unwrap(); let sender = t.sender().unwrap();
let contract = contract_address(&sender, &U256::zero()); let contract = contract_address(&sender, &U256::zero());
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(18)); state.add_balance(&sender, &U256::from(18));
let mut info = EnvInfo::new(); let mut info = EnvInfo::new();
info.gas_limit = U256::from(100_000); info.gas_limit = U256::from(100_000);
@ -711,7 +718,8 @@ mod tests {
fn test_transact_invalid_sender(factory: Factory) { 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 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(); let mut info = EnvInfo::new();
info.gas_limit = U256::from(100_000); info.gas_limit = U256::from(100_000);
let engine = TestEngine::new(0, factory); let engine = TestEngine::new(0, factory);
@ -734,7 +742,8 @@ mod tests {
t.sign(&keypair.secret()); t.sign(&keypair.secret());
let sender = t.sender().unwrap(); let sender = t.sender().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(17)); state.add_balance(&sender, &U256::from(17));
let mut info = EnvInfo::new(); let mut info = EnvInfo::new();
info.gas_limit = U256::from(100_000); info.gas_limit = U256::from(100_000);
@ -759,7 +768,8 @@ mod tests {
t.sign(&keypair.secret()); t.sign(&keypair.secret());
let sender = t.sender().unwrap(); let sender = t.sender().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(17)); state.add_balance(&sender, &U256::from(17));
let mut info = EnvInfo::new(); let mut info = EnvInfo::new();
info.gas_used = U256::from(20_000); info.gas_used = U256::from(20_000);
@ -785,7 +795,8 @@ mod tests {
t.sign(&keypair.secret()); t.sign(&keypair.secret());
let sender = t.sender().unwrap(); let sender = t.sender().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(100_017)); state.add_balance(&sender, &U256::from(100_017));
let mut info = EnvInfo::new(); let mut info = EnvInfo::new();
info.gas_limit = U256::from(100_000); info.gas_limit = U256::from(100_000);
@ -818,7 +829,8 @@ mod tests {
params.gas = U256::from(0x0186a0); params.gas = U256::from(0x0186a0);
params.code = Some(code.clone()); params.code = Some(code.clone());
params.value = ActionValue::Transfer(U256::from_str("0de0b6b3a7640000").unwrap()); 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()); state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap());
let info = EnvInfo::new(); let info = EnvInfo::new();
let engine = TestEngine::new(0, factory); let engine = TestEngine::new(0, factory);

View File

@ -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. /// Destroy the current object and return root and database.
pub fn drop(self) -> (H256, JournalDB) { pub fn drop(self) -> (H256, JournalDB) {
(self.root, self.db) (self.root, self.db)
@ -285,158 +280,169 @@ use util::trie::*;
use util::rlp::*; use util::rlp::*;
use util::uint::*; use util::uint::*;
use account::*; use account::*;
use tests::helpers::*;
#[test] #[test]
fn code_from_database() { fn code_from_database() {
let a = Address::zero(); let a = Address::zero();
let (r, db) = { let temp = RandomTempPath::new();
let mut s = State::new_temp(); let (root, db) = {
s.require_or_from(&a, false, ||Account::new_contract(U256::from(42u32)), |_|{}); let mut state = get_temp_state_in(temp.as_path());
s.init_code(&a, vec![1, 2, 3]); state.require_or_from(&a, false, ||Account::new_contract(U256::from(42u32)), |_|{});
assert_eq!(s.code(&a), Some([1u8, 2, 3].to_vec())); state.init_code(&a, vec![1, 2, 3]);
s.commit(); assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
assert_eq!(s.code(&a), Some([1u8, 2, 3].to_vec())); state.commit();
s.drop() assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
state.drop()
}; };
let s = State::from_existing(db, r, U256::from(0u8)); let state = State::from_existing(db, root, U256::from(0u8));
assert_eq!(s.code(&a), Some([1u8, 2, 3].to_vec())); assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
} }
#[test] #[test]
fn storage_at_from_database() { fn storage_at_from_database() {
let a = Address::zero(); let a = Address::zero();
let (r, db) = { let temp = RandomTempPath::new();
let mut s = State::new_temp(); let (root, db) = {
s.set_storage(&a, H256::from(&U256::from(01u64)), H256::from(&U256::from(69u64))); let mut state = get_temp_state_in(temp.as_path());
s.commit(); state.set_storage(&a, H256::from(&U256::from(01u64)), H256::from(&U256::from(69u64)));
s.drop() 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))); assert_eq!(s.storage_at(&a, &H256::from(&U256::from(01u64))), H256::from(&U256::from(69u64)));
} }
#[test] #[test]
fn get_from_database() { fn get_from_database() {
let a = Address::zero(); let a = Address::zero();
let (r, db) = { let temp = RandomTempPath::new();
let mut s = State::new_temp(); let (root, db) = {
s.inc_nonce(&a); let mut state = get_temp_state_in(temp.as_path());
s.add_balance(&a, &U256::from(69u64)); state.inc_nonce(&a);
s.commit(); state.add_balance(&a, &U256::from(69u64));
assert_eq!(s.balance(&a), U256::from(69u64)); state.commit();
s.drop() assert_eq!(state.balance(&a), U256::from(69u64));
state.drop()
}; };
let s = State::from_existing(db, r, U256::from(0u8)); let state = State::from_existing(db, root, U256::from(0u8));
assert_eq!(s.balance(&a), U256::from(69u64)); assert_eq!(state.balance(&a), U256::from(69u64));
assert_eq!(s.nonce(&a), U256::from(1u64)); assert_eq!(state.nonce(&a), U256::from(1u64));
} }
#[test] #[test]
fn remove() { fn remove() {
let a = Address::zero(); let a = Address::zero();
let mut s = State::new_temp(); let mut state_result = get_temp_state();
assert_eq!(s.exists(&a), false); let mut state = state_result.reference_mut();
s.inc_nonce(&a); assert_eq!(state.exists(&a), false);
assert_eq!(s.exists(&a), true); state.inc_nonce(&a);
assert_eq!(s.nonce(&a), U256::from(1u64)); assert_eq!(state.exists(&a), true);
s.kill_account(&a); assert_eq!(state.nonce(&a), U256::from(1u64));
assert_eq!(s.exists(&a), false); state.kill_account(&a);
assert_eq!(s.nonce(&a), U256::from(0u64)); assert_eq!(state.exists(&a), false);
assert_eq!(state.nonce(&a), U256::from(0u64));
} }
#[test] #[test]
fn remove_from_database() { fn remove_from_database() {
let a = Address::zero(); let a = Address::zero();
let (r, db) = { let temp = RandomTempPath::new();
let mut s = State::new_temp(); {
s.inc_nonce(&a); let mut state = get_temp_state_in(temp.as_path());
s.commit(); state.inc_nonce(&a);
assert_eq!(s.exists(&a), true); state.commit();
assert_eq!(s.nonce(&a), U256::from(1u64)); assert_eq!(state.exists(&a), true);
s.drop() assert_eq!(state.nonce(&a), U256::from(1u64));
state.drop()
}; };
let (r, db) = { let (root, db) = {
let mut s = State::from_existing(db, r, U256::from(0u8)); let mut state = get_temp_state_in(temp.as_path());
assert_eq!(s.exists(&a), true); assert_eq!(state.exists(&a), true);
assert_eq!(s.nonce(&a), U256::from(1u64)); assert_eq!(state.nonce(&a), U256::from(1u64));
s.kill_account(&a); state.kill_account(&a);
s.commit(); state.commit();
assert_eq!(s.exists(&a), false); assert_eq!(state.exists(&a), false);
assert_eq!(s.nonce(&a), U256::from(0u64)); assert_eq!(state.nonce(&a), U256::from(0u64));
s.drop() state.drop()
}; };
let s = State::from_existing(db, r, U256::from(0u8)); let state = State::from_existing(db, root, U256::from(0u8));
assert_eq!(s.exists(&a), false); assert_eq!(state.exists(&a), false);
assert_eq!(s.nonce(&a), U256::from(0u64)); assert_eq!(state.nonce(&a), U256::from(0u64));
} }
#[test] #[test]
fn alter_balance() { 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 a = Address::zero();
let b = address_from_u64(1u64); let b = address_from_u64(1u64);
s.add_balance(&a, &U256::from(69u64)); state.add_balance(&a, &U256::from(69u64));
assert_eq!(s.balance(&a), U256::from(69u64)); assert_eq!(state.balance(&a), U256::from(69u64));
s.commit(); state.commit();
assert_eq!(s.balance(&a), U256::from(69u64)); assert_eq!(state.balance(&a), U256::from(69u64));
s.sub_balance(&a, &U256::from(42u64)); state.sub_balance(&a, &U256::from(42u64));
assert_eq!(s.balance(&a), U256::from(27u64)); assert_eq!(state.balance(&a), U256::from(27u64));
s.commit(); state.commit();
assert_eq!(s.balance(&a), U256::from(27u64)); assert_eq!(state.balance(&a), U256::from(27u64));
s.transfer_balance(&a, &b, &U256::from(18u64)); state.transfer_balance(&a, &b, &U256::from(18u64));
assert_eq!(s.balance(&a), U256::from(9u64)); assert_eq!(state.balance(&a), U256::from(9u64));
assert_eq!(s.balance(&b), U256::from(18u64)); assert_eq!(state.balance(&b), U256::from(18u64));
s.commit(); state.commit();
assert_eq!(s.balance(&a), U256::from(9u64)); assert_eq!(state.balance(&a), U256::from(9u64));
assert_eq!(s.balance(&b), U256::from(18u64)); assert_eq!(state.balance(&b), U256::from(18u64));
} }
#[test] #[test]
fn alter_nonce() { 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(); let a = Address::zero();
s.inc_nonce(&a); state.inc_nonce(&a);
assert_eq!(s.nonce(&a), U256::from(1u64)); assert_eq!(state.nonce(&a), U256::from(1u64));
s.inc_nonce(&a); state.inc_nonce(&a);
assert_eq!(s.nonce(&a), U256::from(2u64)); assert_eq!(state.nonce(&a), U256::from(2u64));
s.commit(); state.commit();
assert_eq!(s.nonce(&a), U256::from(2u64)); assert_eq!(state.nonce(&a), U256::from(2u64));
s.inc_nonce(&a); state.inc_nonce(&a);
assert_eq!(s.nonce(&a), U256::from(3u64)); assert_eq!(state.nonce(&a), U256::from(3u64));
s.commit(); state.commit();
assert_eq!(s.nonce(&a), U256::from(3u64)); assert_eq!(state.nonce(&a), U256::from(3u64));
} }
#[test] #[test]
fn balance_nonce() { 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(); let a = Address::zero();
assert_eq!(s.balance(&a), U256::from(0u64)); assert_eq!(state.balance(&a), U256::from(0u64));
assert_eq!(s.nonce(&a), U256::from(0u64)); assert_eq!(state.nonce(&a), U256::from(0u64));
s.commit(); state.commit();
assert_eq!(s.balance(&a), U256::from(0u64)); assert_eq!(state.balance(&a), U256::from(0u64));
assert_eq!(s.nonce(&a), U256::from(0u64)); assert_eq!(state.nonce(&a), U256::from(0u64));
} }
#[test] #[test]
fn ensure_cached() { 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(); let a = Address::zero();
s.require(&a, false); state.require(&a, false);
s.commit(); state.commit();
assert_eq!(s.root().hex(), "0ce23f3c809de377b008a4a3ee94a0834aac8bec1f86e28ffe4fdb5a15b0c785"); assert_eq!(state.root().hex(), "0ce23f3c809de377b008a4a3ee94a0834aac8bec1f86e28ffe4fdb5a15b0c785");
} }
#[test] #[test]
fn create_empty() { fn create_empty() {
let mut s = State::new_temp(); let mut state_result = get_temp_state();
s.commit(); let mut state = state_result.reference_mut();
assert_eq!(s.root().hex(), "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); state.commit();
assert_eq!(state.root().hex(), "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
} }
} }

View File

@ -37,11 +37,15 @@ impl Substate {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use util::hash::*;
#[test] #[test]
fn accrue() { fn accrue() {
let mut sub_state = Substate::new(); 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); sub_state.accrue(sub_state_2);
assert_eq!(sub_state.contracts_created.len(), 2);
} }
} }

View File

@ -8,6 +8,7 @@ use evm::{Schedule, Ext, Factory, VMType, ContractCreateResult, MessageCallResul
use ethereum; use ethereum;
use externalities::*; use externalities::*;
use substate::*; use substate::*;
use tests::helpers::*;
struct TestEngine { struct TestEngine {
vm_factory: Factory, vm_factory: Factory,
@ -174,7 +175,8 @@ fn do_json_test_for(vm: &VMType, json_data: &[u8]) -> Vec<String> {
}; };
// test env // 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() { test.find("pre").map(|pre| for (addr, s) in pre.as_object().unwrap() {
let address = Address::from(addr.as_ref()); let address = Address::from(addr.as_ref());

View File

@ -5,7 +5,8 @@ use std::path::PathBuf;
use spec::*; use spec::*;
use std::fs::{remove_dir_all}; use std::fs::{remove_dir_all};
use blockchain::{BlockChain}; use blockchain::{BlockChain};
use state::*;
use rocksdb::*;
pub struct RandomTempPath { pub struct RandomTempPath {
path: PathBuf path: PathBuf
@ -23,6 +24,10 @@ impl RandomTempPath {
pub fn as_path(&self) -> &PathBuf { pub fn as_path(&self) -> &PathBuf {
&self.path &self.path
} }
pub fn as_str(&self) -> &str {
self.path.to_str().unwrap()
}
} }
impl Drop for RandomTempPath { impl Drop for RandomTempPath {
@ -43,6 +48,10 @@ impl<T> GuardedTempResult<T> {
pub fn reference(&self) -> &T { pub fn reference(&self) -> &T {
&self.result &self.result
} }
pub fn reference_mut(&mut self) -> &mut T {
&mut self.result
}
} }
pub fn get_test_spec() -> Spec { pub fn get_test_spec() -> Spec {
@ -189,6 +198,35 @@ pub fn generate_dummy_empty_blockchain() -> GuardedTempResult<BlockChain> {
} }
} }
pub fn get_temp_journal_db() -> GuardedTempResult<JournalDB> {
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<State> {
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 { pub fn get_good_dummy_block() -> Bytes {
let mut block_header = Header::new(); let mut block_header = Header::new();
let test_spec = get_test_spec(); let test_spec = get_test_spec();

View File

@ -1,8 +1,8 @@
use super::test_common::*; use super::test_common::*;
use state::*;
use pod_state::*; use pod_state::*;
use state_diff::*; use state_diff::*;
use ethereum; use ethereum;
use tests::helpers::*;
fn do_json_test(json_data: &[u8]) -> Vec<String> { 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 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<String> {
println!("!!! {}: Trie root mismatch (got: {}, expect: {}):", name, calc_post, post_state_root); println!("!!! {}: Trie root mismatch (got: {}, expect: {}):", name, calc_post, post_state_root);
println!("!!! Post:\n{}", post); println!("!!! Post:\n{}", post);
} else { } else {
let mut s = State::new_temp(); let mut state_result = get_temp_state();
s.populate_from(pre); let mut state = state_result.reference_mut();
s.commit(); state.populate_from(pre);
let res = s.apply(&env, engine.deref(), &t); state.commit();
let res = state.apply(&env, engine.deref(), &t);
if fail_unless(s.root() == &post_state_root) { if fail_unless(state.root() == &post_state_root) {
println!("!!! {}: State mismatch (got: {}, expect: {}):", name, s.root(), post_state_root); println!("!!! {}: State mismatch (got: {}, expect: {}):", name, state.root(), post_state_root);
let our_post = s.to_pod(); let our_post = state.to_pod();
println!("Got:\n{}", our_post); println!("Got:\n{}", our_post);
println!("Expect:\n{}", post); println!("Expect:\n{}", post);
println!("Diff ---expect -> +++got:\n{}", StateDiff::diff_pod(&post, &our_post)); println!("Diff ---expect -> +++got:\n{}", StateDiff::diff_pod(&post, &our_post));

View File

@ -19,7 +19,7 @@ pub struct JournalDB {
forward: OverlayDB, forward: OverlayDB,
backing: Arc<DB>, backing: Arc<DB>,
inserts: Vec<H256>, inserts: Vec<H256>,
removes: Vec<H256>, removes: Vec<H256>
} }
impl JournalDB { impl JournalDB {
@ -45,6 +45,7 @@ impl JournalDB {
} }
/// Create a new instance with an anonymous temporary database. /// Create a new instance with an anonymous temporary database.
#[cfg(test)]
pub fn new_temp() -> JournalDB { pub fn new_temp() -> JournalDB {
let mut dir = env::temp_dir(); let mut dir = env::temp_dir();
dir.push(H32::random().hex()); dir.push(H32::random().hex());
@ -137,6 +138,7 @@ mod tests {
use common::*; use common::*;
use super::*; use super::*;
use hashdb::*; use hashdb::*;
use tests::helpers::*;
#[test] #[test]
fn long_history() { fn long_history() {
@ -221,4 +223,11 @@ mod tests {
assert!(!jdb.exists(&baz)); assert!(!jdb.exists(&baz));
assert!(!jdb.exists(&bar)); assert!(!jdb.exists(&bar));
} }
#[test]
fn old_commits_applied() {
let mut dir = env::temp_dir();
dir.push(H32::random().hex());
}
} }