Account data hashing used to use different ways of hashing on different clusters. That is no longer the case, but the old code still existed. This commit removes that old, now used code. **NOTE** The golden hash values in bank.rs needed to be updated. Since the original code that selected the hash algorithm used `if >` instead of `if >=`, this meant that the genesis block's hash _always_ used the old hashing method, which is no longer valid. Validated by running `cargo test` successfully.
122 lines
4.0 KiB
Rust
122 lines
4.0 KiB
Rust
use log::*;
|
|
use rand::{thread_rng, Rng};
|
|
use rayon::prelude::*;
|
|
use solana_runtime::{accounts_db::AccountsDb, accounts_index::Ancestors};
|
|
use solana_sdk::genesis_config::ClusterType;
|
|
use solana_sdk::{account::AccountSharedData, clock::Slot, pubkey::Pubkey};
|
|
use std::collections::HashSet;
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
use std::sync::Arc;
|
|
use std::time::Instant;
|
|
|
|
#[test]
|
|
fn test_shrink_and_clean() {
|
|
solana_logger::setup();
|
|
|
|
// repeat the whole test scenario
|
|
for _ in 0..5 {
|
|
let accounts = Arc::new(AccountsDb::new_single());
|
|
let accounts_for_shrink = accounts.clone();
|
|
|
|
// spawn the slot shrinking background thread
|
|
let exit = Arc::new(AtomicBool::default());
|
|
let exit_for_shrink = exit.clone();
|
|
let shrink_thread = std::thread::spawn(move || loop {
|
|
if exit_for_shrink.load(Ordering::Relaxed) {
|
|
break;
|
|
}
|
|
accounts_for_shrink.process_stale_slot_v1();
|
|
});
|
|
|
|
let mut alive_accounts = vec![];
|
|
let owner = Pubkey::default();
|
|
|
|
// populate the AccountsDb with plenty of food for slot shrinking
|
|
// also this simulates realistic some heavy spike account updates in the wild
|
|
for current_slot in 0..100 {
|
|
while alive_accounts.len() <= 10 {
|
|
alive_accounts.push((
|
|
solana_sdk::pubkey::new_rand(),
|
|
AccountSharedData::new(thread_rng().gen_range(0, 50), 0, &owner),
|
|
));
|
|
}
|
|
|
|
alive_accounts.retain(|(_pubkey, account)| account.lamports >= 1);
|
|
|
|
for (pubkey, account) in alive_accounts.iter_mut() {
|
|
account.lamports -= 1;
|
|
accounts.store_uncached(current_slot, &[(&pubkey, &account)]);
|
|
}
|
|
accounts.add_root(current_slot);
|
|
}
|
|
|
|
// let's dance.
|
|
for _ in 0..10 {
|
|
accounts.clean_accounts(None);
|
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
|
}
|
|
|
|
// cleanup
|
|
exit.store(true, Ordering::Relaxed);
|
|
shrink_thread.join().unwrap();
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_bad_bank_hash() {
|
|
solana_logger::setup();
|
|
use solana_sdk::signature::{Keypair, Signer};
|
|
let db = AccountsDb::new(Vec::new(), &ClusterType::Development);
|
|
|
|
let some_slot: Slot = 0;
|
|
let ancestors: Ancestors = [(some_slot, 0)].iter().copied().collect();
|
|
|
|
let max_accounts = 200;
|
|
let mut accounts_keys: Vec<_> = (0..max_accounts)
|
|
.into_par_iter()
|
|
.map(|_| {
|
|
let key = Keypair::new().pubkey();
|
|
let lamports = thread_rng().gen_range(0, 100);
|
|
let some_data_len = thread_rng().gen_range(0, 1000);
|
|
let account = AccountSharedData::new(lamports, some_data_len, &key);
|
|
(key, account)
|
|
})
|
|
.collect();
|
|
|
|
let mut existing = HashSet::new();
|
|
let mut last_print = Instant::now();
|
|
for i in 0..5_000 {
|
|
if last_print.elapsed().as_millis() > 5000 {
|
|
info!("i: {}", i);
|
|
last_print = Instant::now();
|
|
}
|
|
let num_accounts = thread_rng().gen_range(0, 100);
|
|
(0..num_accounts).into_iter().for_each(|_| {
|
|
let mut idx;
|
|
loop {
|
|
idx = thread_rng().gen_range(0, max_accounts);
|
|
if existing.contains(&idx) {
|
|
continue;
|
|
}
|
|
existing.insert(idx);
|
|
break;
|
|
}
|
|
accounts_keys[idx].1.lamports = thread_rng().gen_range(0, 1000);
|
|
});
|
|
|
|
let account_refs: Vec<_> = existing
|
|
.iter()
|
|
.map(|idx| (&accounts_keys[*idx].0, &accounts_keys[*idx].1))
|
|
.collect();
|
|
db.store_uncached(some_slot, &account_refs);
|
|
|
|
for (key, account) in &account_refs {
|
|
assert_eq!(
|
|
db.load_account_hash(&ancestors, &key),
|
|
AccountsDb::hash_account(some_slot, &account, &key)
|
|
);
|
|
}
|
|
existing.clear();
|
|
}
|
|
}
|