add test_stake_account_consistency_with_rent_epoch_max_feature (#29915)
* add test_stake_account_consistency_with_rent_epoch_max_feature * create_stake_account takes id * use test_case * reformat panic message
This commit is contained in:
parent
6f4fe37bd2
commit
5e35823b66
|
@ -423,6 +423,7 @@ pub const ACCOUNTS_DB_CONFIG_FOR_TESTING: AccountsDbConfig = AccountsDbConfig {
|
|||
ancient_append_vec_offset: None,
|
||||
skip_initial_hash_calc: false,
|
||||
exhaustively_verify_refcounts: false,
|
||||
assert_stakes_cache_consistency: true,
|
||||
};
|
||||
pub const ACCOUNTS_DB_CONFIG_FOR_BENCHMARKS: AccountsDbConfig = AccountsDbConfig {
|
||||
index: Some(ACCOUNTS_INDEX_CONFIG_FOR_BENCHMARKS),
|
||||
|
@ -432,6 +433,7 @@ pub const ACCOUNTS_DB_CONFIG_FOR_BENCHMARKS: AccountsDbConfig = AccountsDbConfig
|
|||
ancient_append_vec_offset: None,
|
||||
skip_initial_hash_calc: false,
|
||||
exhaustively_verify_refcounts: false,
|
||||
assert_stakes_cache_consistency: false,
|
||||
};
|
||||
|
||||
pub type BinnedHashData = Vec<Vec<CalculateHashIntermediate>>;
|
||||
|
@ -489,6 +491,8 @@ pub struct AccountsDbConfig {
|
|||
pub ancient_append_vec_offset: Option<i64>,
|
||||
pub skip_initial_hash_calc: bool,
|
||||
pub exhaustively_verify_refcounts: bool,
|
||||
/// when stakes cache consistency check occurs, assert that cached accounts match accounts db
|
||||
pub assert_stakes_cache_consistency: bool,
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
|
@ -1275,6 +1279,8 @@ pub struct AccountsDb {
|
|||
|
||||
pub(crate) storage: AccountStorage,
|
||||
|
||||
pub(crate) assert_stakes_cache_consistency: bool,
|
||||
|
||||
pub accounts_cache: AccountsCache,
|
||||
|
||||
write_cache_limit_bytes: Option<u64>,
|
||||
|
@ -2291,6 +2297,7 @@ impl AccountsDb {
|
|||
const ACCOUNTS_STACK_SIZE: usize = 8 * 1024 * 1024;
|
||||
|
||||
AccountsDb {
|
||||
assert_stakes_cache_consistency: false,
|
||||
verify_accounts_hash_in_bg: VerifyAccountsHashInBackground::default(),
|
||||
filler_accounts_per_slot: AtomicU64::default(),
|
||||
filler_account_slots_remaining: AtomicU64::default(),
|
||||
|
@ -2409,6 +2416,11 @@ impl AccountsDb {
|
|||
.map(|config| config.exhaustively_verify_refcounts)
|
||||
.unwrap_or_default();
|
||||
|
||||
let assert_stakes_cache_consistency = accounts_db_config
|
||||
.as_ref()
|
||||
.map(|config| config.assert_stakes_cache_consistency)
|
||||
.unwrap_or_default();
|
||||
|
||||
let filler_account_suffix = if filler_accounts_config.count > 0 {
|
||||
Some(solana_sdk::pubkey::new_rand())
|
||||
} else {
|
||||
|
@ -2425,6 +2437,7 @@ impl AccountsDb {
|
|||
accounts_update_notifier,
|
||||
filler_accounts_config,
|
||||
filler_account_suffix,
|
||||
assert_stakes_cache_consistency,
|
||||
write_cache_limit_bytes: accounts_db_config
|
||||
.as_ref()
|
||||
.and_then(|x| x.write_cache_limit_bytes),
|
||||
|
|
|
@ -2494,6 +2494,11 @@ impl Bank {
|
|||
}
|
||||
};
|
||||
if cached_stake_account.account() != &stake_account {
|
||||
if self.rc.accounts.accounts_db.assert_stakes_cache_consistency {
|
||||
panic!(
|
||||
"stakes cache accounts mismatch {cached_stake_account:?} {stake_account:?}"
|
||||
);
|
||||
}
|
||||
invalid_cached_stake_accounts.fetch_add(1, Relaxed);
|
||||
let cached_stake_account = cached_stake_account.account();
|
||||
if cached_stake_account.lamports() == stake_account.lamports()
|
||||
|
@ -7916,6 +7921,7 @@ pub(crate) mod tests {
|
|||
genesis_sysvar_and_builtin_program_lamports, GenesisConfigInfo,
|
||||
ValidatorVoteKeypairs,
|
||||
},
|
||||
rent_collector::RENT_EXEMPT_RENT_EPOCH,
|
||||
rent_paying_accounts_by_partition::RentPayingAccountsByPartition,
|
||||
status_cache::MAX_CACHE_ENTRIES,
|
||||
},
|
||||
|
@ -7969,6 +7975,7 @@ pub(crate) mod tests {
|
|||
fs::File, io::Read, result, str::FromStr, sync::atomic::Ordering::Release,
|
||||
thread::Builder, time::Duration,
|
||||
},
|
||||
test_case::test_case,
|
||||
test_utils::goto_end_of_slot,
|
||||
};
|
||||
|
||||
|
@ -10236,8 +10243,10 @@ pub(crate) mod tests {
|
|||
let vote_id = solana_sdk::pubkey::new_rand();
|
||||
let mut vote_account =
|
||||
vote_state::create_account(&vote_id, &solana_sdk::pubkey::new_rand(), 0, 100);
|
||||
let (stake_id1, stake_account1) = crate::stakes::tests::create_stake_account(123, &vote_id);
|
||||
let (stake_id2, stake_account2) = crate::stakes::tests::create_stake_account(456, &vote_id);
|
||||
let stake_id1 = solana_sdk::pubkey::new_rand();
|
||||
let stake_account1 = crate::stakes::tests::create_stake_account(123, &vote_id, &stake_id1);
|
||||
let stake_id2 = solana_sdk::pubkey::new_rand();
|
||||
let stake_account2 = crate::stakes::tests::create_stake_account(456, &vote_id, &stake_id2);
|
||||
|
||||
// set up accounts
|
||||
bank.store_account_and_update_capitalization(&stake_id1, &stake_account1);
|
||||
|
@ -17423,7 +17432,23 @@ pub(crate) mod tests {
|
|||
&validator_keypairs,
|
||||
vec![LAMPORTS_PER_SOL; 2],
|
||||
);
|
||||
let bank = Arc::new(Bank::new_for_tests(&genesis_config));
|
||||
let bank = Arc::new(Bank::new_with_paths(
|
||||
&genesis_config,
|
||||
Arc::<RuntimeConfig>::default(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
AccountSecondaryIndexes::default(),
|
||||
AccountShrinkThreshold::default(),
|
||||
false,
|
||||
Some(AccountsDbConfig {
|
||||
// at least one tests hit this assert, so disable it
|
||||
assert_stakes_cache_consistency: false,
|
||||
..ACCOUNTS_DB_CONFIG_FOR_TESTING
|
||||
}),
|
||||
None,
|
||||
&Arc::default(),
|
||||
));
|
||||
let vote_and_stake_accounts =
|
||||
load_vote_and_stake_accounts(&bank).vote_with_stake_delegations_map;
|
||||
assert_eq!(vote_and_stake_accounts.len(), 2);
|
||||
|
@ -20151,4 +20176,87 @@ pub(crate) mod tests {
|
|||
bank.apply_feature_activations(ApplyFeatureActivationsCaller::NewFromParent, false);
|
||||
assert_eq!(bank.hashes_per_tick, Some(DEFAULT_HASHES_PER_TICK));
|
||||
}
|
||||
|
||||
#[test_case(true)]
|
||||
#[test_case(false)]
|
||||
fn test_stake_account_consistency_with_rent_epoch_max_feature(
|
||||
rent_epoch_max_enabled_initially: bool,
|
||||
) {
|
||||
// this test can be removed once set_exempt_rent_epoch_max gets activated
|
||||
solana_logger::setup();
|
||||
let (mut genesis_config, _mint_keypair) = create_genesis_config(100 * LAMPORTS_PER_SOL);
|
||||
genesis_config.rent = Rent::default();
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
let expected_initial_rent_epoch = if rent_epoch_max_enabled_initially {
|
||||
bank.activate_feature(&solana_sdk::feature_set::set_exempt_rent_epoch_max::id());
|
||||
RENT_EXEMPT_RENT_EPOCH
|
||||
} else {
|
||||
Epoch::default()
|
||||
};
|
||||
|
||||
assert!(bank.rc.accounts.accounts_db.assert_stakes_cache_consistency);
|
||||
let mut pubkey_bytes_early = [0u8; 32];
|
||||
pubkey_bytes_early[31] = 2;
|
||||
let stake_id1 = Pubkey::from(pubkey_bytes_early);
|
||||
let vote_id = solana_sdk::pubkey::new_rand();
|
||||
let stake_account1 =
|
||||
crate::stakes::tests::create_stake_account(12300000, &vote_id, &stake_id1);
|
||||
|
||||
// set up accounts
|
||||
bank.store_account_and_update_capitalization(&stake_id1, &stake_account1);
|
||||
|
||||
// create banks at a few slots
|
||||
assert_eq!(
|
||||
bank.load_slow(&bank.ancestors, &stake_id1)
|
||||
.unwrap()
|
||||
.0
|
||||
.rent_epoch(),
|
||||
0 // manually created, so default is 0
|
||||
);
|
||||
let slot = 1;
|
||||
let slots_per_epoch = bank.epoch_schedule().get_slots_in_epoch(0);
|
||||
let mut bank = Bank::new_from_parent(&Arc::new(bank), &Pubkey::default(), slot);
|
||||
if !rent_epoch_max_enabled_initially {
|
||||
bank.activate_feature(&solana_sdk::feature_set::set_exempt_rent_epoch_max::id());
|
||||
}
|
||||
let bank = Arc::new(bank);
|
||||
|
||||
let slot = slots_per_epoch - 1;
|
||||
assert_eq!(
|
||||
bank.load_slow(&bank.ancestors, &stake_id1)
|
||||
.unwrap()
|
||||
.0
|
||||
.rent_epoch(),
|
||||
// rent has been collected, so if rent epoch is max is activated, this will be max by now
|
||||
expected_initial_rent_epoch
|
||||
);
|
||||
let mut bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), slot));
|
||||
|
||||
let last_slot_in_epoch = bank.epoch_schedule().get_last_slot_in_epoch(1);
|
||||
let slot = last_slot_in_epoch - 2;
|
||||
assert_eq!(
|
||||
bank.load_slow(&bank.ancestors, &stake_id1)
|
||||
.unwrap()
|
||||
.0
|
||||
.rent_epoch(),
|
||||
expected_initial_rent_epoch
|
||||
);
|
||||
bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), slot));
|
||||
assert_eq!(
|
||||
bank.load_slow(&bank.ancestors, &stake_id1)
|
||||
.unwrap()
|
||||
.0
|
||||
.rent_epoch(),
|
||||
expected_initial_rent_epoch
|
||||
);
|
||||
let slot = last_slot_in_epoch - 1;
|
||||
bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), slot));
|
||||
assert_eq!(
|
||||
bank.load_slow(&bank.ancestors, &stake_id1)
|
||||
.unwrap()
|
||||
.0
|
||||
.rent_epoch(),
|
||||
RENT_EXEMPT_RENT_EPOCH
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -521,9 +521,13 @@ pub(crate) mod tests {
|
|||
let vote_pubkey = solana_sdk::pubkey::new_rand();
|
||||
let vote_account =
|
||||
vote_state::create_account(&vote_pubkey, &solana_sdk::pubkey::new_rand(), 0, 1);
|
||||
let stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||
(
|
||||
(vote_pubkey, vote_account),
|
||||
create_stake_account(stake, &vote_pubkey),
|
||||
(
|
||||
stake_pubkey,
|
||||
create_stake_account(stake, &vote_pubkey, &stake_pubkey),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -531,17 +535,14 @@ pub(crate) mod tests {
|
|||
pub(crate) fn create_stake_account(
|
||||
stake: u64,
|
||||
vote_pubkey: &Pubkey,
|
||||
) -> (Pubkey, AccountSharedData) {
|
||||
let stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||
(
|
||||
stake_pubkey: &Pubkey,
|
||||
) -> AccountSharedData {
|
||||
stake_state::create_account(
|
||||
stake_pubkey,
|
||||
stake_state::create_account(
|
||||
&stake_pubkey,
|
||||
vote_pubkey,
|
||||
&vote_state::create_account(vote_pubkey, &solana_sdk::pubkey::new_rand(), 0, 1),
|
||||
&Rent::free(),
|
||||
stake,
|
||||
),
|
||||
vote_pubkey,
|
||||
&vote_state::create_account(vote_pubkey, &solana_sdk::pubkey::new_rand(), 0, 1),
|
||||
&Rent::free(),
|
||||
stake,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -615,7 +616,8 @@ pub(crate) mod tests {
|
|||
}
|
||||
|
||||
// activate more
|
||||
let (_stake_pubkey, mut stake_account) = create_stake_account(42, &vote_pubkey);
|
||||
let mut stake_account =
|
||||
create_stake_account(42, &vote_pubkey, &solana_sdk::pubkey::new_rand());
|
||||
stakes_cache.check_and_store(&stake_pubkey, &stake_account);
|
||||
let stake = stake_state::stake_from(&stake_account).unwrap();
|
||||
{
|
||||
|
@ -799,7 +801,8 @@ pub(crate) mod tests {
|
|||
let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) =
|
||||
create_staked_node_accounts(10);
|
||||
|
||||
let (stake_pubkey2, stake_account2) = create_stake_account(10, &vote_pubkey);
|
||||
let stake_pubkey2 = solana_sdk::pubkey::new_rand();
|
||||
let stake_account2 = create_stake_account(10, &vote_pubkey, &stake_pubkey2);
|
||||
|
||||
stakes_cache.check_and_store(&vote_pubkey, &vote_account);
|
||||
|
||||
|
|
Loading…
Reference in New Issue