diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index 4db023017..327979ce3 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -225,7 +225,7 @@ mod tests { use util::{Address, FixedHash, H256, HashDB, DBValue}; use rlp::{UntrustedRlp, View}; - use std::collections::{HashSet, HashMap}; + use std::collections::HashSet; use super::{ACC_EMPTY, Account}; diff --git a/ethcore/src/snapshot/tests/state.rs b/ethcore/src/snapshot/tests/state.rs index e1d4df5f9..5257903d5 100644 --- a/ethcore/src/snapshot/tests/state.rs +++ b/ethcore/src/snapshot/tests/state.rs @@ -17,6 +17,7 @@ //! State snapshotting tests. use snapshot::{chunk_state, Progress, StateRebuilder}; +use snapshot::account::Account; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use super::helpers::{compare_dbs, StateProducer}; @@ -28,6 +29,8 @@ use util::memorydb::MemoryDB; use util::Mutex; use devtools::RandomTempPath; +use util::sha3::SHA3_NULL_RLP; + use std::sync::Arc; #[test] @@ -82,3 +85,54 @@ fn snap_and_restore() { compare_dbs(&old_db, new_db.as_hashdb()); } + +#[test] +fn get_code_from_prev_chunk() { + use std::collections::HashSet; + use rlp::{RlpStream, Stream}; + use util::{HashDB, H256, FixedHash, U256, Hashable}; + + use account_db::{AccountDBMut, AccountDB}; + + let code = b"this is definitely code"; + let mut used_code = HashSet::new(); + let mut acc_stream = RlpStream::new_list(4); + acc_stream.append(&U256::default()) + .append(&U256::default()) + .append(&SHA3_NULL_RLP) + .append(&code.sha3()); + + let (h1, h2) = (H256::random(), H256::random()); + + // two accounts with the same code, one per chunk. + // first one will have code inlined, + // second will just have its hash. + let thin_rlp = acc_stream.out(); + let acc1 = Account::from_thin_rlp(&thin_rlp); + let acc2 = Account::from_thin_rlp(&thin_rlp); + + let mut make_chunk = |acc: Account, hash| { + let mut db = MemoryDB::new(); + AccountDBMut::from_hash(&mut db, hash).insert(&code[..]); + + let fat_rlp = acc.to_fat_rlp(&AccountDB::from_hash(&db, hash), &mut used_code).unwrap(); + + let mut stream = RlpStream::new_list(1); + stream.begin_list(2).append(&hash).append_raw(&fat_rlp, 1); + stream.out() + }; + + let chunk1 = make_chunk(acc1, h1); + let chunk2 = make_chunk(acc2, h2); + + let db_path = RandomTempPath::create_dir(); + let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS); + let new_db = Arc::new(Database::open(&db_cfg, &db_path.to_string_lossy()).unwrap()); + + let mut rebuilder = StateRebuilder::new(new_db, Algorithm::Archive); + + rebuilder.feed(&chunk1).unwrap(); + rebuilder.feed(&chunk2).unwrap(); + + rebuilder.check_missing().unwrap(); +} \ No newline at end of file