feature: don't do rewrites in rent collection (#26491)

* feature: don't do rewrites in rent collection

* modify test to specifically test this feature
This commit is contained in:
Jeff Washington (jwash) 2023-01-09 10:14:17 -06:00 committed by GitHub
parent d41da2178c
commit a703019caa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 21 deletions

View File

@ -7612,7 +7612,10 @@ impl AccountsDb {
/// 1. pubkey, hash pairs for the slot
/// 2. us spent scanning
/// 3. Measure started when we began accumulating
fn get_pubkey_hash_for_slot(&self, slot: Slot) -> (Vec<(Pubkey, Hash)>, u64, Measure) {
pub(crate) fn get_pubkey_hash_for_slot(
&self,
slot: Slot,
) -> (Vec<(Pubkey, Hash)>, u64, Measure) {
let mut scan = Measure::start("scan");
let scan_result: ScanStorageResult<(Pubkey, Hash), DashMapVersionHash> = self

View File

@ -5342,6 +5342,15 @@ impl Bank {
}
}
/// true if rent collection does NOT rewrite accounts whose pubkey indicates
/// it is time for rent collection, but the account is rent exempt.
/// false if rent collection DOES rewrite accounts if the account is rent exempt
/// This is the default behavior historically.
fn bank_hash_skips_rent_rewrites(&self) -> bool {
self.feature_set
.is_active(&feature_set::skip_rent_rewrites::id())
}
/// Collect rent from `accounts`
///
/// This fn is called inside a parallel loop from `collect_rent_in_partition()`. Avoid adding
@ -5363,7 +5372,7 @@ impl Bank {
Vec::<(&Pubkey, &AccountSharedData)>::with_capacity(accounts.len());
let mut time_collecting_rent_us = 0;
let mut time_storing_accounts_us = 0;
let can_skip_rewrites = false; // this will be goverened by a feature soon
let can_skip_rewrites = self.bank_hash_skips_rent_rewrites();
let set_exempt_rent_epoch_max: bool = self
.feature_set
.is_active(&solana_sdk::feature_set::set_exempt_rent_epoch_max::id());
@ -10046,28 +10055,48 @@ pub(crate) mod tests {
fn test_collect_rent_from_accounts() {
solana_logger::setup();
let zero_lamport_pubkey = Pubkey::new(&[0; 32]);
for skip_rewrites in [false, true] {
let zero_lamport_pubkey = Pubkey::new(&[0; 32]);
let genesis_bank = create_simple_test_arc_bank(100000);
let first_bank = Arc::new(new_from_parent(&genesis_bank));
let first_slot = 1;
assert_eq!(first_slot, first_bank.slot());
let epoch_delta = 4;
let later_bank = Arc::new(new_from_parent_next_epoch(&first_bank, epoch_delta)); // a bank a few epochs in the future
let later_slot = later_bank.slot();
assert!(later_bank.epoch() == genesis_bank.epoch() + epoch_delta);
let genesis_bank = create_simple_test_arc_bank(100000);
let mut first_bank = new_from_parent(&genesis_bank);
if skip_rewrites {
first_bank.activate_feature(&feature_set::skip_rent_rewrites::id());
}
let first_bank = Arc::new(first_bank);
let data_size = 0; // make sure we're rent exempt
let lamports = later_bank.get_minimum_balance_for_rent_exemption(data_size); // cannot be 0 or we zero out rent_epoch in rent collection and we need to be rent exempt
let mut account = AccountSharedData::new(lamports, data_size, &Pubkey::default());
account.set_rent_epoch(later_bank.epoch() - 1); // non-zero, but less than later_bank's epoch
let first_slot = 1;
assert_eq!(first_slot, first_bank.slot());
let epoch_delta = 4;
let later_bank = Arc::new(new_from_parent_next_epoch(&first_bank, epoch_delta)); // a bank a few epochs in the future
let later_slot = later_bank.slot();
assert!(later_bank.epoch() == genesis_bank.epoch() + epoch_delta);
// loaded from previous slot, so we skip rent collection on it
let _result = later_bank.collect_rent_from_accounts(
vec![(zero_lamport_pubkey, account, later_slot - 1)],
None,
PartitionIndex::default(),
);
let data_size = 0; // make sure we're rent exempt
let lamports = later_bank.get_minimum_balance_for_rent_exemption(data_size); // cannot be 0 or we zero out rent_epoch in rent collection and we need to be rent exempt
let mut account = AccountSharedData::new(lamports, data_size, &Pubkey::default());
account.set_rent_epoch(later_bank.epoch() - 1); // non-zero, but less than later_bank's epoch
// loaded from previous slot, so we skip rent collection on it
let _result = later_bank.collect_rent_from_accounts(
vec![(zero_lamport_pubkey, account, later_slot - 1)],
None,
PartitionIndex::default(),
);
let deltas = later_bank
.rc
.accounts
.accounts_db
.get_pubkey_hash_for_slot(later_slot)
.0;
assert_eq!(
!deltas
.iter()
.any(|(pubkey, _)| pubkey == &zero_lamport_pubkey),
skip_rewrites
);
}
}
#[test]

View File

@ -462,6 +462,10 @@ pub mod enable_early_verification_of_account_modifications {
solana_sdk::declare_id!("7Vced912WrRnfjaiKRiNBcbuFw7RrnLv3E3z95Y4GTNc");
}
pub mod skip_rent_rewrites {
solana_sdk::declare_id!("CGB2jM8pwZkeeiXQ66kBMyBR6Np61mggL7XUsmLjVcrw");
}
pub mod prevent_crediting_accounts_that_end_rent_paying {
solana_sdk::declare_id!("812kqX67odAp5NFwM8D2N24cku7WTm9CHUTFUXaDkWPn");
}
@ -679,6 +683,7 @@ lazy_static! {
(stake_redelegate_instruction::id(), "enable the redelegate stake instruction #26294"),
(preserve_rent_epoch_for_rent_exempt_accounts::id(), "preserve rent epoch for rent exempt accounts #26479"),
(enable_bpf_loader_extend_program_ix::id(), "enable bpf upgradeable loader ExtendProgram instruction #25234"),
(skip_rent_rewrites::id(), "skip rewriting rent exempt accounts during rent collection #26491"),
(enable_early_verification_of_account_modifications::id(), "enable early verification of account modifications #25899"),
(disable_rehash_for_rent_epoch::id(), "on accounts hash calculation, do not try to rehash accounts #28934"),
(account_hash_ignore_slot::id(), "ignore slot when calculating an account hash #28420"),