2020-05-22 10:54:24 -07:00
|
|
|
#[cfg(test)]
|
|
|
|
use {
|
|
|
|
super::*,
|
|
|
|
crate::{
|
|
|
|
accounts::{create_test_accounts, Accounts},
|
|
|
|
accounts_db::get_temp_accounts_paths,
|
|
|
|
bank::{Bank, StatusCacheRc},
|
2021-03-10 09:49:10 -08:00
|
|
|
hardened_unpack::UnpackedAppendVecMap,
|
2020-05-22 10:54:24 -07:00
|
|
|
},
|
2020-08-03 16:27:17 -07:00
|
|
|
bincode::serialize_into,
|
2020-05-22 10:54:24 -07:00
|
|
|
rand::{thread_rng, Rng},
|
|
|
|
solana_sdk::{
|
2021-04-23 07:35:09 -07:00
|
|
|
account::{AccountSharedData, ReadableAccount},
|
2020-05-22 10:54:24 -07:00
|
|
|
clock::Slot,
|
2020-09-08 07:55:09 -07:00
|
|
|
genesis_config::{create_genesis_config, ClusterType},
|
2020-05-22 10:54:24 -07:00
|
|
|
pubkey::Pubkey,
|
|
|
|
signature::{Keypair, Signer},
|
|
|
|
},
|
2021-03-10 09:49:10 -08:00
|
|
|
std::{
|
|
|
|
io::{BufReader, Cursor},
|
|
|
|
path::Path,
|
|
|
|
},
|
2020-05-22 10:54:24 -07:00
|
|
|
tempfile::TempDir,
|
|
|
|
};
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
fn copy_append_vecs<P: AsRef<Path>>(
|
2021-02-18 23:42:09 -08:00
|
|
|
accounts_db: &AccountsDb,
|
2020-05-22 10:54:24 -07:00
|
|
|
output_dir: P,
|
2021-03-10 09:49:10 -08:00
|
|
|
) -> std::io::Result<UnpackedAppendVecMap> {
|
2020-05-22 10:54:24 -07:00
|
|
|
let storage_entries = accounts_db.get_snapshot_storages(Slot::max_value());
|
2021-03-10 09:49:10 -08:00
|
|
|
let mut unpacked_append_vec_map = UnpackedAppendVecMap::new();
|
2020-05-22 10:54:24 -07:00
|
|
|
for storage in storage_entries.iter().flatten() {
|
|
|
|
let storage_path = storage.get_path();
|
2021-03-10 09:49:10 -08:00
|
|
|
let file_name = AppendVec::file_name(storage.slot(), storage.append_vec_id());
|
|
|
|
let output_path = output_dir.as_ref().join(&file_name);
|
|
|
|
std::fs::copy(&storage_path, &output_path)?;
|
|
|
|
unpacked_append_vec_map.insert(file_name, output_path);
|
2020-05-22 10:54:24 -07:00
|
|
|
}
|
|
|
|
|
2021-03-10 09:49:10 -08:00
|
|
|
Ok(unpacked_append_vec_map)
|
2020-05-22 10:54:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
fn check_accounts(accounts: &Accounts, pubkeys: &[Pubkey], num: usize) {
|
|
|
|
for _ in 1..num {
|
|
|
|
let idx = thread_rng().gen_range(0, num - 1);
|
|
|
|
let ancestors = vec![(0, 0)].into_iter().collect();
|
2021-04-16 08:23:32 -07:00
|
|
|
let account = accounts.load_without_fixed_root(&ancestors, &pubkeys[idx]);
|
2020-05-22 10:54:24 -07:00
|
|
|
let account1 = Some((
|
2021-04-23 07:35:09 -07:00
|
|
|
AccountSharedData::new((idx + 1) as u64, 0, AccountSharedData::default().owner()),
|
2020-05-22 10:54:24 -07:00
|
|
|
0,
|
|
|
|
));
|
|
|
|
assert_eq!(account, account1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
2021-03-10 09:49:10 -08:00
|
|
|
fn context_accountsdb_from_stream<'a, C, R>(
|
2020-05-22 10:54:24 -07:00
|
|
|
stream: &mut BufReader<R>,
|
|
|
|
account_paths: &[PathBuf],
|
2021-03-10 09:49:10 -08:00
|
|
|
unpacked_append_vec_map: UnpackedAppendVecMap,
|
2021-02-18 23:42:09 -08:00
|
|
|
) -> Result<AccountsDb, Error>
|
2020-05-22 10:54:24 -07:00
|
|
|
where
|
|
|
|
C: TypeContext<'a>,
|
|
|
|
R: Read,
|
|
|
|
{
|
|
|
|
// read and deserialise the accounts database directly from the stream
|
2020-07-13 07:00:59 -07:00
|
|
|
reconstruct_accountsdb_from_fields(
|
2020-05-22 10:54:24 -07:00
|
|
|
C::deserialize_accounts_db_fields(stream)?,
|
|
|
|
account_paths,
|
2021-03-10 09:49:10 -08:00
|
|
|
unpacked_append_vec_map,
|
2020-09-08 07:55:09 -07:00
|
|
|
&ClusterType::Development,
|
2020-12-31 18:06:03 -08:00
|
|
|
HashSet::new(),
|
2021-01-11 17:00:23 -08:00
|
|
|
false,
|
2020-05-22 10:54:24 -07:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
2021-03-10 09:49:10 -08:00
|
|
|
fn accountsdb_from_stream<R>(
|
2020-05-22 10:54:24 -07:00
|
|
|
serde_style: SerdeStyle,
|
|
|
|
stream: &mut BufReader<R>,
|
|
|
|
account_paths: &[PathBuf],
|
2021-03-10 09:49:10 -08:00
|
|
|
unpacked_append_vec_map: UnpackedAppendVecMap,
|
2021-02-18 23:42:09 -08:00
|
|
|
) -> Result<AccountsDb, Error>
|
2020-05-22 10:54:24 -07:00
|
|
|
where
|
|
|
|
R: Read,
|
|
|
|
{
|
|
|
|
match serde_style {
|
2021-03-10 09:49:10 -08:00
|
|
|
SerdeStyle::Newer => context_accountsdb_from_stream::<TypeContextFuture, R>(
|
2020-05-22 10:54:24 -07:00
|
|
|
stream,
|
|
|
|
account_paths,
|
2021-03-10 09:49:10 -08:00
|
|
|
unpacked_append_vec_map,
|
2020-05-22 10:54:24 -07:00
|
|
|
),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
fn accountsdb_to_stream<W>(
|
|
|
|
serde_style: SerdeStyle,
|
|
|
|
stream: &mut W,
|
2021-02-18 23:42:09 -08:00
|
|
|
accounts_db: &AccountsDb,
|
2020-05-22 10:54:24 -07:00
|
|
|
slot: Slot,
|
|
|
|
account_storage_entries: &[SnapshotStorage],
|
2020-06-17 01:56:29 -07:00
|
|
|
) -> Result<(), Error>
|
2020-05-22 10:54:24 -07:00
|
|
|
where
|
|
|
|
W: Write,
|
|
|
|
{
|
|
|
|
match serde_style {
|
2021-02-18 23:42:09 -08:00
|
|
|
SerdeStyle::Newer => serialize_into(
|
2020-05-22 10:54:24 -07:00
|
|
|
stream,
|
2021-02-18 23:42:09 -08:00
|
|
|
&SerializableAccountsDb::<TypeContextFuture> {
|
2020-05-22 10:54:24 -07:00
|
|
|
accounts_db,
|
|
|
|
slot,
|
|
|
|
account_storage_entries,
|
|
|
|
phantom: std::marker::PhantomData::default(),
|
|
|
|
},
|
2020-06-17 01:56:29 -07:00
|
|
|
),
|
2020-05-22 10:54:24 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
fn test_accounts_serialize_style(serde_style: SerdeStyle) {
|
|
|
|
solana_logger::setup();
|
|
|
|
let (_accounts_dir, paths) = get_temp_accounts_paths(4).unwrap();
|
2021-01-11 17:00:23 -08:00
|
|
|
let accounts =
|
|
|
|
Accounts::new_with_config(paths, &ClusterType::Development, HashSet::new(), false);
|
2020-05-22 10:54:24 -07:00
|
|
|
|
|
|
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
|
|
|
create_test_accounts(&accounts, &mut pubkeys, 100, 0);
|
|
|
|
check_accounts(&accounts, &pubkeys, 100);
|
|
|
|
accounts.add_root(0);
|
|
|
|
|
|
|
|
let mut writer = Cursor::new(vec![]);
|
|
|
|
accountsdb_to_stream(
|
|
|
|
serde_style,
|
|
|
|
&mut writer,
|
|
|
|
&*accounts.accounts_db,
|
|
|
|
0,
|
|
|
|
&accounts.accounts_db.get_snapshot_storages(0),
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let copied_accounts = TempDir::new().unwrap();
|
|
|
|
|
|
|
|
// Simulate obtaining a copy of the AppendVecs from a tarball
|
2021-03-10 09:49:10 -08:00
|
|
|
let unpacked_append_vec_map =
|
|
|
|
copy_append_vecs(&accounts.accounts_db, copied_accounts.path()).unwrap();
|
2020-05-22 10:54:24 -07:00
|
|
|
|
|
|
|
let buf = writer.into_inner();
|
|
|
|
let mut reader = BufReader::new(&buf[..]);
|
|
|
|
let (_accounts_dir, daccounts_paths) = get_temp_accounts_paths(2).unwrap();
|
|
|
|
let daccounts = Accounts::new_empty(
|
|
|
|
accountsdb_from_stream(
|
|
|
|
serde_style,
|
|
|
|
&mut reader,
|
|
|
|
&daccounts_paths,
|
2021-03-10 09:49:10 -08:00
|
|
|
unpacked_append_vec_map,
|
2020-05-22 10:54:24 -07:00
|
|
|
)
|
|
|
|
.unwrap(),
|
|
|
|
);
|
|
|
|
check_accounts(&daccounts, &pubkeys, 100);
|
|
|
|
assert_eq!(accounts.bank_hash_at(0), daccounts.bank_hash_at(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
fn test_bank_serialize_style(serde_style: SerdeStyle) {
|
|
|
|
solana_logger::setup();
|
|
|
|
let (genesis_config, _) = create_genesis_config(500);
|
|
|
|
let bank0 = Arc::new(Bank::new(&genesis_config));
|
|
|
|
let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
|
|
|
|
bank0.squash();
|
|
|
|
|
|
|
|
// Create an account on a non-root fork
|
|
|
|
let key1 = Keypair::new();
|
2021-04-30 14:22:17 -07:00
|
|
|
bank1.deposit(&key1.pubkey(), 5).unwrap();
|
2020-05-22 10:54:24 -07:00
|
|
|
|
|
|
|
let bank2 = Bank::new_from_parent(&bank0, &Pubkey::default(), 2);
|
|
|
|
|
|
|
|
// Test new account
|
|
|
|
let key2 = Keypair::new();
|
2021-04-30 14:22:17 -07:00
|
|
|
bank2.deposit(&key2.pubkey(), 10).unwrap();
|
2020-05-22 10:54:24 -07:00
|
|
|
assert_eq!(bank2.get_balance(&key2.pubkey()), 10);
|
|
|
|
|
|
|
|
let key3 = Keypair::new();
|
2021-04-30 14:22:17 -07:00
|
|
|
bank2.deposit(&key3.pubkey(), 0).unwrap();
|
2020-05-22 10:54:24 -07:00
|
|
|
|
2021-01-11 17:00:23 -08:00
|
|
|
bank2.freeze();
|
2020-05-22 10:54:24 -07:00
|
|
|
bank2.squash();
|
2021-01-11 17:00:23 -08:00
|
|
|
bank2.force_flush_accounts_cache();
|
2020-05-22 10:54:24 -07:00
|
|
|
|
|
|
|
let snapshot_storages = bank2.get_snapshot_storages();
|
|
|
|
let mut buf = vec![];
|
|
|
|
let mut writer = Cursor::new(&mut buf);
|
2020-07-13 07:00:59 -07:00
|
|
|
crate::serde_snapshot::bank_to_stream(
|
2020-05-22 10:54:24 -07:00
|
|
|
serde_style,
|
|
|
|
&mut std::io::BufWriter::new(&mut writer),
|
2020-07-13 07:00:59 -07:00
|
|
|
&bank2,
|
2020-05-22 10:54:24 -07:00
|
|
|
&snapshot_storages,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2020-07-13 07:00:59 -07:00
|
|
|
let rdr = Cursor::new(&buf[..]);
|
2020-05-22 10:54:24 -07:00
|
|
|
let mut reader = std::io::BufReader::new(&buf[rdr.position() as usize..]);
|
|
|
|
|
|
|
|
// Create a new set of directories for this bank's accounts
|
|
|
|
let (_accounts_dir, dbank_paths) = get_temp_accounts_paths(4).unwrap();
|
|
|
|
let ref_sc = StatusCacheRc::default();
|
|
|
|
ref_sc.status_cache.write().unwrap().add_root(2);
|
|
|
|
// Create a directory to simulate AppendVecs unpackaged from a snapshot tar
|
|
|
|
let copied_accounts = TempDir::new().unwrap();
|
2021-03-10 09:49:10 -08:00
|
|
|
let unpacked_append_vec_map =
|
|
|
|
copy_append_vecs(&bank2.rc.accounts.accounts_db, copied_accounts.path()).unwrap();
|
2020-07-13 07:00:59 -07:00
|
|
|
let mut dbank = crate::serde_snapshot::bank_from_stream(
|
|
|
|
serde_style,
|
|
|
|
&mut reader,
|
|
|
|
&dbank_paths,
|
2021-03-10 09:49:10 -08:00
|
|
|
unpacked_append_vec_map,
|
2020-07-13 07:00:59 -07:00
|
|
|
&genesis_config,
|
|
|
|
&[],
|
2020-09-23 18:46:42 -07:00
|
|
|
None,
|
2020-09-24 12:23:09 -07:00
|
|
|
None,
|
2020-12-31 18:06:03 -08:00
|
|
|
HashSet::new(),
|
2021-01-11 17:00:23 -08:00
|
|
|
false,
|
2020-07-13 07:00:59 -07:00
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
dbank.src = ref_sc;
|
2020-05-22 10:54:24 -07:00
|
|
|
assert_eq!(dbank.get_balance(&key1.pubkey()), 0);
|
|
|
|
assert_eq!(dbank.get_balance(&key2.pubkey()), 10);
|
|
|
|
assert_eq!(dbank.get_balance(&key3.pubkey()), 0);
|
2020-10-08 23:44:41 -07:00
|
|
|
assert!(bank2 == dbank);
|
2020-05-22 10:54:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
pub(crate) fn reconstruct_accounts_db_via_serialization(
|
2021-02-18 23:42:09 -08:00
|
|
|
accounts: &AccountsDb,
|
2020-05-22 10:54:24 -07:00
|
|
|
slot: Slot,
|
2021-02-18 23:42:09 -08:00
|
|
|
) -> AccountsDb {
|
2020-05-22 10:54:24 -07:00
|
|
|
let mut writer = Cursor::new(vec![]);
|
|
|
|
let snapshot_storages = accounts.get_snapshot_storages(slot);
|
|
|
|
accountsdb_to_stream(
|
2021-02-18 23:42:09 -08:00
|
|
|
SerdeStyle::Newer,
|
2020-05-22 10:54:24 -07:00
|
|
|
&mut writer,
|
|
|
|
&accounts,
|
|
|
|
slot,
|
|
|
|
&snapshot_storages,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let buf = writer.into_inner();
|
|
|
|
let mut reader = BufReader::new(&buf[..]);
|
|
|
|
let copied_accounts = TempDir::new().unwrap();
|
2021-03-10 09:49:10 -08:00
|
|
|
|
2020-05-22 10:54:24 -07:00
|
|
|
// Simulate obtaining a copy of the AppendVecs from a tarball
|
2021-03-10 09:49:10 -08:00
|
|
|
let unpacked_append_vec_map = copy_append_vecs(&accounts, copied_accounts.path()).unwrap();
|
|
|
|
let mut accounts_db =
|
|
|
|
accountsdb_from_stream(SerdeStyle::Newer, &mut reader, &[], unpacked_append_vec_map)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// The append vecs will be used from `copied_accounts` directly by the new AccountsDb so keep
|
|
|
|
// its TempDir alive
|
|
|
|
accounts_db
|
|
|
|
.temp_paths
|
|
|
|
.as_mut()
|
|
|
|
.unwrap()
|
|
|
|
.push(copied_accounts);
|
|
|
|
|
|
|
|
accounts_db
|
2020-05-22 10:54:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_accounts_serialize_newer() {
|
2021-02-18 23:42:09 -08:00
|
|
|
test_accounts_serialize_style(SerdeStyle::Newer)
|
2020-05-22 10:54:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_bank_serialize_newer() {
|
2021-02-18 23:42:09 -08:00
|
|
|
test_bank_serialize_style(SerdeStyle::Newer)
|
2020-05-22 10:54:24 -07:00
|
|
|
}
|
|
|
|
|
2020-07-06 04:22:23 -07:00
|
|
|
#[cfg(all(test, RUSTC_WITH_SPECIALIZATION))]
|
2020-07-13 07:00:59 -07:00
|
|
|
mod test_bank_serialize {
|
2020-07-06 04:22:23 -07:00
|
|
|
use super::*;
|
|
|
|
|
|
|
|
// These some what long test harness is required to freeze the ABI of
|
2020-07-13 07:00:59 -07:00
|
|
|
// Bank's serialization due to versioned nature
|
2021-02-18 23:42:09 -08:00
|
|
|
#[frozen_abi(digest = "DuRGntVwLGNAv5KooafUSpxk67BPAx2yC7Z8A9c8wr2G")]
|
2020-07-13 08:58:34 -07:00
|
|
|
#[derive(Serialize, AbiExample)]
|
2020-07-13 07:00:59 -07:00
|
|
|
pub struct BankAbiTestWrapperFuture {
|
2020-07-06 04:22:23 -07:00
|
|
|
#[serde(serialize_with = "wrapper_future")]
|
2020-07-13 07:00:59 -07:00
|
|
|
bank: Bank,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn wrapper_future<S>(bank: &Bank, s: S) -> std::result::Result<S::Ok, S::Error>
|
2020-07-06 04:22:23 -07:00
|
|
|
where
|
|
|
|
S: serde::Serializer,
|
|
|
|
{
|
2020-07-13 07:00:59 -07:00
|
|
|
let snapshot_storages = bank.rc.accounts.accounts_db.get_snapshot_storages(0);
|
2020-07-13 08:58:34 -07:00
|
|
|
// ensure there is a single snapshot storage example for ABI digesting
|
|
|
|
assert_eq!(snapshot_storages.len(), 1);
|
|
|
|
|
2020-07-13 07:00:59 -07:00
|
|
|
(SerializableBankAndStorage::<future::Context> {
|
|
|
|
bank,
|
2020-07-06 04:22:23 -07:00
|
|
|
snapshot_storages: &snapshot_storages,
|
|
|
|
phantom: std::marker::PhantomData::default(),
|
|
|
|
})
|
|
|
|
.serialize(s)
|
|
|
|
}
|
|
|
|
}
|