diff --git a/src/account.rs b/src/account.rs index 4a0d6b56b..e342333ec 100644 --- a/src/account.rs +++ b/src/account.rs @@ -10,6 +10,7 @@ use util::uint::*; pub const SHA3_EMPTY: H256 = H256( [0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, 0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70] ); /// Single account in the system. +#[derive(Debug)] pub struct Account { // Balance of the account. balance: U256, diff --git a/src/blockheader.rs b/src/blockheader.rs index 6abbbdff7..566a77f69 100644 --- a/src/blockheader.rs +++ b/src/blockheader.rs @@ -102,6 +102,4 @@ impl Encodable for Header { #[cfg(test)] mod tests { - fn encoding_and_decoding() { - } } diff --git a/src/state.rs b/src/state.rs index 528aaf035..b5b323a1a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -5,7 +5,29 @@ use util::overlaydb::*; use util::trie::*; use util::rlp::*; use util::uint::*; +use std::mem; use account::Account; +/* +enum ValueOrRef<'self, 'db: 'self> { + Value(OverlayDB), + Ref(&'db mut OverlayDB) +} + +impl<'self, 'db> ValueOrRef<'self, 'db: 'self> { + pub fn get_mut(&mut self) -> &mut OverlayDB { + match self { + Value(ref mut x) => x, + Ref(x) => x, + } + } + pub fn get(&self) -> &OverlayDB { + match self { + Value(ref x) => x, + Ref(x) => x, + } + } +} +*/ /// Representation of the entire state of all accounts in the system. pub struct State { @@ -58,12 +80,24 @@ impl State { &self.root } + /// Desttroy the current database and return it. + /// WARNING: the struct should be dropped immediately following this. + pub fn take_db(&mut self) -> OverlayDB { + mem::replace(&mut self.db, OverlayDB::new_temp()) + } + + /// Destroy the current object and return root and database. + pub fn drop(mut self) -> (H256, OverlayDB) { + (mem::replace(&mut self.root, H256::new()), mem::replace(&mut self.db, OverlayDB::new_temp())) + } + /// Expose the underlying database; good to use for calling `state.db().commit()`. pub fn db(&mut self) -> &mut OverlayDB { &mut self.db } /// Get the balance of account `a`. + // TODO: make immutable pub fn balance(&mut self, a: &Address) -> U256 { self.get(a, false).as_ref().map(|account| account.balance().clone()).unwrap_or(U256::from(0u8)) } @@ -79,6 +113,7 @@ impl State { } /// Get the nonce of account `a`. + // TODO: make immutable pub fn nonce(&mut self, a: &Address) -> U256 { self.get(a, false).as_ref().map(|account| account.nonce().clone()).unwrap_or(U256::from(0u8)) } @@ -123,10 +158,12 @@ impl State { /// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too. /// `force_create` creates a new, empty basic account if there is not currently an active account. + // TODO: make immutable. fn get(&mut self, a: &Address, require_code: bool) -> Option<&mut Account> { if self.cache.get(a).is_none() { // load from trie. - self.cache.insert(a.clone(), TrieDB::new(&mut self.db, &mut self.root).at(&a).map(|rlp| Account::from_rlp(rlp))); + let t = TrieDB::new_existing(&mut self.db, &mut self.root); + self.cache.insert(a.clone(), t.at(&a).map(|rlp| { println!("RLP: {:?}", rlp); Account::from_rlp(rlp) })); } let db = &self.db; @@ -171,8 +208,20 @@ use util::uint::*; use std::str::FromStr; #[test] -fn playpen() { +fn revived() { + let a = Address::from_str("0000000000000000000000000000000000000000").unwrap(); + 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.root().clone(), s.take_db()) + }; + let mut s = State::new_existing(db, r, U256::from(0u8)); + assert_eq!(s.balance(&a), U256::from(69u64)); + assert_eq!(s.nonce(&a), U256::from(1u64)); } #[test]