diff --git a/core/tests/bank_forks.rs b/core/tests/bank_forks.rs index e58a8f4b4..6351f9c13 100644 --- a/core/tests/bank_forks.rs +++ b/core/tests/bank_forks.rs @@ -237,7 +237,7 @@ mod tests { let key1 = Keypair::new().pubkey(); let tx = system_transaction::transfer(&mint_keypair, &key1, 1, genesis_config.hash()); assert_eq!(bank.process_transaction(&tx), Ok(())); - bank.freeze(); + bank.squash(); bank_forks.insert(bank); let package_sender = { diff --git a/ledger/src/snapshot_utils.rs b/ledger/src/snapshot_utils.rs index 4b5d89626..2f5d5993a 100644 --- a/ledger/src/snapshot_utils.rs +++ b/ledger/src/snapshot_utils.rs @@ -74,7 +74,7 @@ pub fn package_snapshot, Q: AsRef>( // Get a reference to all the relevant AccountStorageEntries let account_storage_entries: Vec<_> = bank .rc - .get_storage_entries() + .get_rooted_storage_entries() .into_iter() .filter(|x| x.slot_id() <= bank.slot()) .collect(); diff --git a/runtime/src/accounts_db.rs b/runtime/src/accounts_db.rs index f2d1ec921..a4ae59bc7 100644 --- a/runtime/src/accounts_db.rs +++ b/runtime/src/accounts_db.rs @@ -487,13 +487,21 @@ impl AccountsDB { append_vecs_path.as_ref().join(&append_vec_relative_path); let mut copy_options = CopyOptions::new(); copy_options.overwrite = true; - fs_extra::move_items(&vec![&append_vec_abs_path], &local_dir, ©_options) - .map_err(|e| { - AccountsDB::get_io_error(&format!( - "Unable to move {:?} to {:?}: {}", - append_vec_abs_path, local_dir, e - )) - })?; + let e = fs_extra::move_items( + &vec![&append_vec_abs_path], + &local_dir, + ©_options, + ) + .map_err(|e| { + AccountsDB::get_io_error(&format!( + "Unable to move {:?} to {:?}: {}", + append_vec_abs_path, local_dir, e + )) + }); + if e.is_err() { + info!("{:?}", e); + continue; + } // Notify the AppendVec of the new file location let local_path = local_dir.join(append_vec_relative_path); @@ -508,7 +516,13 @@ impl AccountsDB { .collect(); let new_storage_map = new_storage_map?; - let storage = AccountStorage(new_storage_map); + let mut storage = AccountStorage(new_storage_map); + + // discard any slots with no storage entries + // this can happen if a non-root slot was serialized + // but non-root stores should not be included in the snapshot + storage.0.retain(|_slot_id, stores| !stores.is_empty()); + let version: u64 = deserialize_from(&mut stream) .map_err(|_| AccountsDB::get_io_error("write version deserialize error"))?; @@ -1095,12 +1109,14 @@ impl AccountsDB { self.accounts_index.write().unwrap().add_root(slot) } - pub fn get_storage_entries(&self) -> Vec> { + pub fn get_rooted_storage_entries(&self) -> Vec> { + let accounts_index = self.accounts_index.read().unwrap(); let r_storage = self.storage.read().unwrap(); r_storage .0 .values() .flat_map(|slot_store| slot_store.values().cloned()) + .filter(|store| accounts_index.is_root(store.slot_id)) .collect() } @@ -2094,7 +2110,7 @@ pub mod tests { accounts_db: &AccountsDB, output_dir: P, ) -> IOResult<()> { - let storage_entries = accounts_db.get_storage_entries(); + let storage_entries = accounts_db.get_rooted_storage_entries(); for storage in storage_entries { let storage_path = storage.get_path(); let output_path = output_dir.as_ref().join( diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 7dc6daeca..768e44ddf 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -97,8 +97,8 @@ impl BankRc { Ok(()) } - pub fn get_storage_entries(&self) -> Vec> { - self.accounts.accounts_db.get_storage_entries() + pub fn get_rooted_storage_entries(&self) -> Vec> { + self.accounts.accounts_db.get_rooted_storage_entries() } fn get_io_error(error: &str) -> IOError { @@ -3879,23 +3879,33 @@ mod tests { #[test] fn test_bank_serialize() { + solana_logger::setup(); let (genesis_config, _) = create_genesis_config(500); let bank0 = Arc::new(Bank::new(&genesis_config)); - let bank = new_from_parent(&bank0); + let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), 1); + bank0.squash(); + + // Create an account on a non-root fork + let key1 = Keypair::new(); + bank1.deposit(&key1.pubkey(), 5); + + let bank2 = Bank::new_from_parent(&bank0, &Pubkey::default(), 2); // Test new account - let key = Keypair::new(); - bank.deposit(&key.pubkey(), 10); - assert_eq!(bank.get_balance(&key.pubkey()), 10); - let key2 = Keypair::new(); - bank.deposit(&key2.pubkey(), 0); + bank2.deposit(&key2.pubkey(), 10); + assert_eq!(bank2.get_balance(&key2.pubkey()), 10); - let len = serialized_size(&bank).unwrap() + serialized_size(&bank.rc).unwrap(); + let key3 = Keypair::new(); + bank2.deposit(&key3.pubkey(), 0); + + bank2.squash(); + + let len = serialized_size(&bank2).unwrap() + serialized_size(&bank2.rc).unwrap(); let mut buf = vec![0u8; len as usize]; let mut writer = Cursor::new(&mut buf[..]); - serialize_into(&mut writer, &bank).unwrap(); - serialize_into(&mut writer, &bank.rc).unwrap(); + serialize_into(&mut writer, &bank2).unwrap(); + serialize_into(&mut writer, &bank2.rc).unwrap(); let mut rdr = Cursor::new(&buf[..]); let mut dbank: Bank = deserialize_from(&mut rdr).unwrap(); @@ -3903,20 +3913,20 @@ mod tests { // Create a new set of directories for this bank's accounts let (_accounts_dir, dbank_paths) = get_temp_accounts_paths(4).unwrap(); - dbank.set_bank_rc( - &BankRc::new(dbank_paths.clone(), 0, dbank.slot()), - &StatusCacheRc::default(), - ); + let ref_sc = StatusCacheRc::default(); + ref_sc.status_cache.write().unwrap().add_root(2); + dbank.set_bank_rc(&BankRc::new(dbank_paths.clone(), 0, dbank.slot()), &ref_sc); // Create a directory to simulate AppendVecs unpackaged from a snapshot tar let copied_accounts = TempDir::new().unwrap(); - copy_append_vecs(&bank.rc.accounts.accounts_db, copied_accounts.path()).unwrap(); + copy_append_vecs(&bank2.rc.accounts.accounts_db, copied_accounts.path()).unwrap(); dbank .rc .accounts_from_stream(&mut reader, dbank_paths, copied_accounts.path()) .unwrap(); - assert_eq!(dbank.get_balance(&key.pubkey()), 10); - assert_eq!(dbank.get_balance(&key2.pubkey()), 0); - bank.compare_bank(&dbank); + assert_eq!(dbank.get_balance(&key1.pubkey()), 0); + assert_eq!(dbank.get_balance(&key2.pubkey()), 10); + assert_eq!(dbank.get_balance(&key3.pubkey()), 0); + bank2.compare_bank(&dbank); } #[test]