Skip to content
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
14 changes: 14 additions & 0 deletions accounts-db/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,20 @@ impl Accounts {
self.load_slow(ancestors, pubkey, LoadHint::FixedMaxRoot)
}

/// same as `load_with_fixed_root` except:
/// if the account is not already in the read cache, it is NOT put in the read cache on successful load
pub fn load_with_fixed_root_do_not_populate_read_cache(
&self,
ancestors: &Ancestors,
pubkey: &Pubkey,
) -> Option<(AccountSharedData, Slot)> {
self.load_slow(
ancestors,
pubkey,
LoadHint::FixedMaxRootDoNotPopulateReadCache,
)
}

pub fn load_without_fixed_root(
&self,
ancestors: &Ancestors,
Expand Down
8 changes: 5 additions & 3 deletions accounts-db/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,8 @@ pub enum LoadHint {
// account loading, while maintaining the determinism of account loading and resultant
// transaction execution thereof.
FixedMaxRoot,
/// same as `FixedMaxRoot`, except do not populate the read cache on load
FixedMaxRootDoNotPopulateReadCache,
// Caller can't hint the above safety assumption. Generally RPC and miscellaneous
// other call-site falls into this category. The likelihood of slower path is slightly
// increased as well.
Expand Down Expand Up @@ -5119,7 +5121,7 @@ impl AccountsDb {
// so retry. This works because in accounts cache flush, an account is written to
// storage *before* it is removed from the cache
match load_hint {
LoadHint::FixedMaxRoot => {
LoadHint::FixedMaxRootDoNotPopulateReadCache | LoadHint::FixedMaxRoot => {
// it's impossible for this to fail for transaction loads from
// replaying/banking more than once.
// This is because:
Expand All @@ -5139,7 +5141,7 @@ impl AccountsDb {
}
LoadedAccountAccessor::Stored(None) => {
match load_hint {
LoadHint::FixedMaxRoot => {
LoadHint::FixedMaxRootDoNotPopulateReadCache | LoadHint::FixedMaxRoot => {
// When running replay on the validator, or banking stage on the leader,
// it should be very rare that the storage entry doesn't exist if the
// entry in the accounts index is the latest version of this account.
Expand Down Expand Up @@ -5348,7 +5350,7 @@ impl AccountsDb {
return None;
}

if !is_cached {
if !is_cached && load_hint != LoadHint::FixedMaxRootDoNotPopulateReadCache {
/*
We show this store into the read-only cache for account 'A' and future loads of 'A' from the read-only cache are
safe/reflect 'A''s latest state on this fork.
Expand Down
7 changes: 6 additions & 1 deletion runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1823,8 +1823,13 @@ impl Bank {
// from Stakes<Delegation> by reading the full account state from
// accounts-db. Note that it is crucial that these accounts are loaded
// at the right slot and match precisely with serialized Delegations.
// Note that we are disabling the read cache while we populate the stakes cache.
// The stakes accounts will not be expected to be loaded again.
// If we populate the read cache with these loads, then we'll just soon have to evict these.
let stakes = Stakes::new(&fields.stakes, |pubkey| {
let (account, _slot) = bank_rc.accounts.load_with_fixed_root(&ancestors, pubkey)?;
let (account, _slot) = bank_rc
.accounts
.load_with_fixed_root_do_not_populate_read_cache(&ancestors, pubkey)?;
Some(account)
})
.expect(
Expand Down