Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

testnet fixup: only update rent_epoch on load until feature #28543

Merged
merged 3 commits into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions runtime/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ use {
bank::Rewrites,
cache_hash_data::CacheHashData,
contains::Contains,
expected_rent_collection::{ExpectedRentCollection, SlotInfoInEpoch},
pubkey_bins::PubkeyBinCalculator24,
read_only_accounts_cache::ReadOnlyAccountsCache,
rent_collector::RentCollector,
Expand Down Expand Up @@ -1792,22 +1793,26 @@ trait AppendVecScan: Send + Sync + Clone {
/// These would have been captured in a fn from within the scan function.
/// Some of these are constant across all pubkeys, some are constant across a slot.
/// Some could be unique per pubkey.
struct ScanState<'a> {
struct ScanState<'a, T: Fn(Slot) -> Option<Slot> + Sync + Send + Clone> {
/// slot we're currently scanning
current_slot: Slot,
/// accumulated results
accum: BinnedHashData,
/// max slot (inclusive) that we're calculating accounts hash on
max_slot_info: SlotInfoInEpoch,
bin_calculator: &'a PubkeyBinCalculator24,
bin_range: &'a Range<usize>,
config: &'a CalcAccountsHashConfig<'a>,
mismatch_found: Arc<AtomicU64>,
stats: &'a crate::accounts_hash::HashStats,
find_unskipped_slot: &'a T,
filler_account_suffix: Option<&'a Pubkey>,
range: usize,
sort_time: Arc<AtomicU64>,
pubkey_to_bin_index: usize,
}

impl<'a> AppendVecScan for ScanState<'a> {
impl<'a, T: Fn(Slot) -> Option<Slot> + Sync + Send + Clone> AppendVecScan for ScanState<'a, T> {
fn set_slot(&mut self, slot: Slot) {
self.current_slot = slot;
}
Expand Down Expand Up @@ -1836,6 +1841,20 @@ impl<'a> AppendVecScan for ScanState<'a> {
};

let loaded_hash = loaded_account.loaded_hash();
let new_hash = ExpectedRentCollection::maybe_rehash_skipped_rewrite(
loaded_account,
&loaded_hash,
pubkey,
self.current_slot,
self.config.epoch_schedule,
self.config.rent_collector,
self.stats,
&self.max_slot_info,
self.find_unskipped_slot,
self.filler_account_suffix,
);
let loaded_hash = new_hash.unwrap_or(loaded_hash);

let source_item = CalculateHashIntermediate::new(loaded_hash, balance, *pubkey);

if self.config.check_hash
Expand Down Expand Up @@ -6236,6 +6255,8 @@ impl AccountsDb {
let total_lamports = Mutex::<u64>::new(0);
let stats = HashStats::default();

let max_slot_info = SlotInfoInEpoch::new(max_slot, config.epoch_schedule);

let get_hashes = || {
keys.par_chunks(chunks)
.map(|pubkeys| {
Expand Down Expand Up @@ -6268,7 +6289,23 @@ impl AccountsDb {
.get_loaded_account()
.and_then(
|loaded_account| {
let find_unskipped_slot = |slot: Slot| {
self.find_unskipped_slot(slot, config.ancestors)
};
let loaded_hash = loaded_account.loaded_hash();
let new_hash = ExpectedRentCollection::maybe_rehash_skipped_rewrite(
&loaded_account,
&loaded_hash,
pubkey,
*slot,
config.epoch_schedule,
config.rent_collector,
&stats,
&max_slot_info,
find_unskipped_slot,
self.filler_account_suffix.as_ref(),
);
let loaded_hash = new_hash.unwrap_or(loaded_hash);
let balance = loaded_account.lamports();
if config.check_hash && !self.is_filler_account(pubkey) { // this will not be supported anymore
let computed_hash =
Expand Down Expand Up @@ -6853,15 +6890,22 @@ impl AccountsDb {
let range = bin_range.end - bin_range.start;
let sort_time = Arc::new(AtomicU64::new(0));

let find_unskipped_slot = |slot: Slot| self.find_unskipped_slot(slot, config.ancestors);

let max_slot_info =
SlotInfoInEpoch::new(storage.max_slot_inclusive(), config.epoch_schedule);
let scanner = ScanState {
current_slot: Slot::default(),
accum: BinnedHashData::default(),
bin_calculator: &bin_calculator,
config,
mismatch_found: mismatch_found.clone(),
max_slot_info,
find_unskipped_slot: &find_unskipped_slot,
filler_account_suffix,
range,
bin_range,
stats,
sort_time: sort_time.clone(),
pubkey_to_bin_index: 0,
};
Expand Down
29 changes: 28 additions & 1 deletion runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ use {
builtins::{self, BuiltinAction, BuiltinFeatureTransition, Builtins},
cost_tracker::CostTracker,
epoch_stakes::{EpochStakes, NodeVoteAccounts},
expected_rent_collection::{ExpectedRentCollection, SlotInfoInEpoch},
inline_spl_associated_token_account, inline_spl_token,
message_processor::MessageProcessor,
rent_collector::{CollectedInfo, RentCollector},
Expand Down Expand Up @@ -6380,7 +6381,33 @@ impl Bank {
ancestors: &Ancestors,
pubkey: &Pubkey,
) -> Option<(AccountSharedData, Slot)> {
self.rc.accounts.load_with_fixed_root(ancestors, pubkey)
match self.rc.accounts.load_with_fixed_root(ancestors, pubkey) {
Some((mut account, storage_slot)) => {
if !self.feature_set.is_active(
&solana_sdk::feature_set::on_load_preserve_rent_epoch_for_rent_exempt_accounts::id(),
) {
// this was a bug in 1.14+. This code should not have run once this feature was activated:
// preserve rent epoch for rent exempt accounts #26479
// But, it did run. On mnb, this caused bank mismatches.
// On testnet, where ALL validators were running this code incorrectly, the rent_epoch was updated here.
// The network was happy, but the behavior was wrong. So, correctly removing this code disagreed with
// what the network agreed was 'correct'. So, we have to preserve the previous erroneous behavior on testnet
// until we can activate this feature to switch the network's understanding of 'correct'.
ExpectedRentCollection::maybe_update_rent_epoch_on_load(
&mut account,
&SlotInfoInEpoch::new_small(storage_slot),
&SlotInfoInEpoch::new_small(self.slot()),
self.epoch_schedule(),
self.rent_collector(),
pubkey,
&self.rewrites_skipped_this_slot,
);
}

Some((account, storage_slot))
}
None => None,
}
}

pub fn get_program_accounts(
Expand Down
Loading