diff --git a/runtime/src/accounts.rs b/runtime/src/accounts.rs index cc22940566..01ebddb426 100644 --- a/runtime/src/accounts.rs +++ b/runtime/src/accounts.rs @@ -1203,11 +1203,11 @@ impl Accounts { leave_nonce_on_success, ); self.accounts_db - .store_cached(slot, &accounts_to_store, Some(&txn_signatures)); + .store_cached((slot, &accounts_to_store[..]), Some(&txn_signatures)); } pub fn store_accounts_cached(&self, slot: Slot, accounts: &[(&Pubkey, &AccountSharedData)]) { - self.accounts_db.store_cached(slot, accounts, None) + self.accounts_db.store_cached((slot, accounts), None) } /// Add a slot to root. Root slots cannot be purged diff --git a/runtime/src/accounts_db.rs b/runtime/src/accounts_db.rs index ae7e2ab939..7095e03d80 100644 --- a/runtime/src/accounts_db.rs +++ b/runtime/src/accounts_db.rs @@ -7374,13 +7374,12 @@ impl AccountsDb { .fetch_add(measure.as_us(), Ordering::Relaxed); } - pub fn store_cached( + pub fn store_cached<'a, T: ReadableAccount + Sync + ZeroLamport>( &self, - slot: Slot, - accounts: &[(&Pubkey, &AccountSharedData)], - txn_signatures: Option<&[Option<&Signature>]>, + accounts: impl StorableAccounts<'a, T>, + txn_signatures: Option<&'a [Option<&'a Signature>]>, ) { - self.store((slot, accounts), self.caching_enabled, txn_signatures); + self.store(accounts, self.caching_enabled, txn_signatures); } /// Store the account update. @@ -9755,7 +9754,7 @@ pub mod tests { let account0 = AccountSharedData::new(1, 0, &key); let ancestors = vec![(unrooted_slot, 1)].into_iter().collect(); if is_cached { - db.store_cached(unrooted_slot, &[(&key, &account0)], None); + db.store_cached((unrooted_slot, &[(&key, &account0)][..]), None); } else { db.store_uncached(unrooted_slot, &[(&key, &account0)]); } @@ -12724,13 +12723,13 @@ pub mod tests { let account = AccountSharedData::new(1, 16 * 4096, &Pubkey::default()); let pubkey1 = solana_sdk::pubkey::new_rand(); - accounts.store_cached(0, &[(&pubkey1, &account)], None); + accounts.store_cached((0, &[(&pubkey1, &account)][..]), None); let pubkey2 = solana_sdk::pubkey::new_rand(); - accounts.store_cached(0, &[(&pubkey2, &account)], None); + accounts.store_cached((0, &[(&pubkey2, &account)][..]), None); let zero_account = AccountSharedData::new(0, 1, &Pubkey::default()); - accounts.store_cached(1, &[(&pubkey1, &zero_account)], None); + accounts.store_cached((1, &[(&pubkey1, &zero_account)][..]), None); // Add root 0 and flush separately accounts.get_accounts_delta_hash(0); @@ -12902,7 +12901,7 @@ pub mod tests { let key = Pubkey::default(); let account0 = AccountSharedData::new(1, 0, &key); let slot = 0; - db.store_cached(slot, &[(&key, &account0)], None); + db.store_cached((slot, &[(&key, &account0)][..]), None); // Load with no ancestors and no root will return nothing assert!(db @@ -12935,7 +12934,7 @@ pub mod tests { let key = Pubkey::default(); let account0 = AccountSharedData::new(1, 0, &key); let slot = 0; - db.store_cached(slot, &[(&key, &account0)], None); + db.store_cached((slot, &[(&key, &account0)][..]), None); db.mark_slot_frozen(slot); // No root was added yet, requires an ancestor to find @@ -12968,9 +12967,9 @@ pub mod tests { let unrooted_key = solana_sdk::pubkey::new_rand(); let key5 = solana_sdk::pubkey::new_rand(); let key6 = solana_sdk::pubkey::new_rand(); - db.store_cached(unrooted_slot, &[(&unrooted_key, &account0)], None); - db.store_cached(root5, &[(&key5, &account0)], None); - db.store_cached(root6, &[(&key6, &account0)], None); + db.store_cached((unrooted_slot, &[(&unrooted_key, &account0)][..]), None); + db.store_cached((root5, &[(&key5, &account0)][..]), None); + db.store_cached((root6, &[(&key6, &account0)][..]), None); for slot in &[unrooted_slot, root5, root6] { db.mark_slot_frozen(*slot); } @@ -13033,7 +13032,7 @@ pub mod tests { let num_slots = 2 * max_cache_slots(); for i in 0..num_roots + num_unrooted { let key = Pubkey::new_unique(); - db.store_cached(i as Slot, &[(&key, &account0)], None); + db.store_cached((i as Slot, &[(&key, &account0)][..]), None); keys.push(key); db.mark_slot_frozen(i as Slot); if i < num_roots { @@ -13102,8 +13101,8 @@ pub mod tests { let zero_lamport_account = AccountSharedData::new(0, 0, AccountSharedData::default().owner()); let slot1_account = AccountSharedData::new(1, 1, AccountSharedData::default().owner()); - db.store_cached(0, &[(&account_key, &zero_lamport_account)], None); - db.store_cached(1, &[(&account_key, &slot1_account)], None); + db.store_cached((0, &[(&account_key, &zero_lamport_account)][..]), None); + db.store_cached((1, &[(&account_key, &slot1_account)][..]), None); db.add_root(0); db.add_root(1); @@ -13125,7 +13124,7 @@ pub mod tests { .unwrap(); assert_eq!(account.lamports(), 1); assert_eq!(db.read_only_accounts_cache.cache_len(), 1); - db.store_cached(2, &[(&account_key, &zero_lamport_account)], None); + db.store_cached((2, &[(&account_key, &zero_lamport_account)][..]), None); assert_eq!(db.read_only_accounts_cache.cache_len(), 1); let account = db .load_with_fixed_root(&Ancestors::default(), &account_key) @@ -13150,8 +13149,8 @@ pub mod tests { let zero_lamport_account = AccountSharedData::new(0, 0, AccountSharedData::default().owner()); let slot1_account = AccountSharedData::new(1, 1, AccountSharedData::default().owner()); - db.store_cached(0, &[(&account_key, &zero_lamport_account)], None); - db.store_cached(1, &[(&account_key, &slot1_account)], None); + db.store_cached((0, &[(&account_key, &zero_lamport_account)][..]), None); + db.store_cached((1, &[(&account_key, &slot1_account)][..]), None); db.add_root(0); db.add_root(1); @@ -13205,18 +13204,20 @@ pub mod tests { AccountSharedData::new(0, 0, AccountSharedData::default().owner()); // Store into slot 0, and then flush the slot to storage - db.store_cached(0, &[(&zero_lamport_account_key, &slot0_account)], None); + db.store_cached( + (0, &[(&zero_lamport_account_key, &slot0_account)][..]), + None, + ); // Second key keeps other lamport account entry for slot 0 alive, // preventing clean of the zero_lamport_account in slot 1. - db.store_cached(0, &[(&other_account_key, &slot0_account)], None); + db.store_cached((0, &[(&other_account_key, &slot0_account)][..]), None); db.add_root(0); db.flush_accounts_cache(true, None); assert!(!db.storage.get_slot_storage_entries(0).unwrap().is_empty()); // Store into slot 1, a dummy slot that will be dead and purged before flush db.store_cached( - 1, - &[(&zero_lamport_account_key, &zero_lamport_account)], + (1, &[(&zero_lamport_account_key, &zero_lamport_account)][..]), None, ); @@ -13227,8 +13228,7 @@ pub mod tests { // the refcount in the index. This means clean should *not* remove // `zero_lamport_account_key` from slot 2 db.store_cached( - 2, - &[(&zero_lamport_account_key, &zero_lamport_account)], + (2, &[(&zero_lamport_account_key, &zero_lamport_account)][..]), None, ); db.add_root(1); @@ -13352,11 +13352,11 @@ pub mod tests { / \ 1 2 (root) */ - db.store_cached(0, &[(&account_key, &zero_lamport_account)], None); - db.store_cached(1, &[(&account_key, &slot1_account)], None); + db.store_cached((0, &[(&account_key, &zero_lamport_account)][..]), None); + db.store_cached((1, &[(&account_key, &slot1_account)][..]), None); // Fodder for the scan so that the lock on `account_key` is not held - db.store_cached(1, &[(&account_key2, &slot1_account)], None); - db.store_cached(2, &[(&account_key, &slot2_account)], None); + db.store_cached((1, &[(&account_key2, &slot1_account)][..]), None); + db.store_cached((2, &[(&account_key, &slot2_account)][..]), None); db.get_accounts_delta_hash(0); let max_scan_root = 0; @@ -13450,7 +13450,7 @@ pub mod tests { for data_size in 0..num_keys { let account = AccountSharedData::new(1, data_size, &Pubkey::default()); - accounts_db.store_cached(slot, &[(&Pubkey::new_unique(), &account)], None); + accounts_db.store_cached((slot, &[(&Pubkey::new_unique(), &account)][..]), None); } accounts_db.add_root(slot); @@ -13513,11 +13513,13 @@ pub mod tests { if scan_slot.is_some() { accounts_db.store_cached( // Store it in a slot that isn't returned in `slots` - stall_slot, - &[( - &scan_stall_key, - &AccountSharedData::new(1, 0, &Pubkey::default()), - )], + ( + stall_slot, + &[( + &scan_stall_key, + &AccountSharedData::new(1, 0, &Pubkey::default()), + )][..], + ), None, ); } @@ -13528,8 +13530,10 @@ pub mod tests { for key in &keys[*slot as usize..] { let space = 1; // 1 byte allows us to track by size accounts_db.store_cached( - *slot, - &[(key, &AccountSharedData::new(1, space, &Pubkey::default()))], + ( + *slot, + &[(key, &AccountSharedData::new(1, space, &Pubkey::default()))][..], + ), None, ); } @@ -13573,8 +13577,10 @@ pub mod tests { for key in &keys { // Store a slot that overwrites all previous keys, rendering all previous keys dead accounts_db.store_cached( - alive_slot, - &[(key, &AccountSharedData::new(1, 0, &Pubkey::default()))], + ( + alive_slot, + &[(key, &AccountSharedData::new(1, 0, &Pubkey::default()))][..], + ), None, ); accounts_db.add_root(alive_slot); @@ -13913,8 +13919,8 @@ pub mod tests { let account1 = AccountSharedData::new(1, 0, AccountSharedData::default().owner()); // Store into slot 0 - db.store_cached(0, &[(&account_key1, &account1)], None); - db.store_cached(0, &[(&account_key2, &account1)], None); + db.store_cached((0, &[(&account_key1, &account1)][..]), None); + db.store_cached((0, &[(&account_key2, &account1)][..]), None); db.add_root(0); if !do_intra_cache_clean { // If we don't want the cache doing purges before flush, @@ -13928,7 +13934,7 @@ pub mod tests { } // Make account_key1 in slot 0 outdated by updating in rooted slot 1 - db.store_cached(1, &[(&account_key1, &account1)], None); + db.store_cached((1, &[(&account_key1, &account1)][..]), None); db.add_root(1); // Flushes all roots db.flush_accounts_cache(true, None); @@ -13952,7 +13958,7 @@ pub mod tests { db.shrink_candidate_slots(); // Make slot 0 dead by updating the remaining key - db.store_cached(2, &[(&account_key2, &account1)], None); + db.store_cached((2, &[(&account_key2, &account1)][..]), None); db.add_root(2); // Flushes all roots @@ -14176,11 +14182,13 @@ pub mod tests { let pubkey = Arc::new(Pubkey::new_unique()); let exit = Arc::new(AtomicBool::new(false)); db.store_cached( - 0, - &[( - &pubkey, - &AccountSharedData::new(1, 0, AccountSharedData::default().owner()), - )], + ( + 0, + &[( + pubkey.as_ref(), + &AccountSharedData::new(1, 0, AccountSharedData::default().owner()), + )][..], + ), None, ); db.add_root(0); @@ -14194,13 +14202,13 @@ pub mod tests { std::thread::Builder::new() .name("account-cache-flush".to_string()) .spawn(move || { - let mut slot = 1; + let mut slot: Slot = 1; loop { if exit.load(Ordering::Relaxed) { return; } account.set_lamports(slot + 1); - db.store_cached(slot, &[(&pubkey, &account)], None); + db.store_cached((slot, &[(pubkey.as_ref(), &account)][..]), None); db.add_root(slot); sleep(Duration::from_millis(RACY_SLEEP_MS)); db.flush_accounts_cache(true, None); @@ -14368,7 +14376,7 @@ pub mod tests { let num_trials = 10; for _ in 0..num_trials { let pubkey = Pubkey::new_unique(); - db.store_cached(slot, &[(&pubkey, &account)], None); + db.store_cached((slot, &[(&pubkey, &account)][..]), None); // Wait for both threads to finish flush_trial_start_sender.send(()).unwrap(); remove_trial_start_sender.send(()).unwrap(); @@ -14459,7 +14467,7 @@ pub mod tests { let slot_to_pubkey_map: HashMap = (0..num_cached_slots) .map(|slot| { let pubkey = Pubkey::new_unique(); - db.store_cached(slot, &[(&pubkey, &account)], None); + db.store_cached((slot, &[(&pubkey, &account)][..]), None); (slot, pubkey) }) .collect(); @@ -14888,21 +14896,21 @@ pub mod tests { let owner = solana_sdk::pubkey::new_rand(); let space = 0; - let slot1 = 1; + let slot1: Slot = 1; let account = AccountSharedData::new(111, space, &owner); - accounts_db.store_cached(slot1, &[(&pubkey, &account)], None); + accounts_db.store_cached((slot1, &[(&pubkey, &account)][..]), None); accounts_db.get_accounts_delta_hash(slot1); accounts_db.add_root(slot1); - let slot2 = 2; + let slot2: Slot = 2; let account = AccountSharedData::new(222, space, &owner); - accounts_db.store_cached(slot2, &[(&pubkey, &account)], None); + accounts_db.store_cached((slot2, &[(&pubkey, &account)][..]), None); accounts_db.get_accounts_delta_hash(slot2); accounts_db.add_root(slot2); - let slot3 = 3; + let slot3: Slot = 3; let account = AccountSharedData::new(0, space, &owner); - accounts_db.store_cached(slot3, &[(&pubkey, &account)], None); + accounts_db.store_cached((slot3, &[(&pubkey, &account)][..]), None); accounts_db.get_accounts_delta_hash(slot3); accounts_db.add_root(slot3); diff --git a/runtime/src/accounts_db/geyser_plugin_utils.rs b/runtime/src/accounts_db/geyser_plugin_utils.rs index a4252036a0..3371472b68 100644 --- a/runtime/src/accounts_db/geyser_plugin_utils.rs +++ b/runtime/src/accounts_db/geyser_plugin_utils.rs @@ -340,24 +340,24 @@ pub mod tests { let account1 = AccountSharedData::new(account1_lamports1, 1, AccountSharedData::default().owner()); let slot0 = 0; - accounts.store_cached(slot0, &[(&key1, &account1)], None); + accounts.store_cached((slot0, &[(&key1, &account1)][..]), None); let key2 = solana_sdk::pubkey::new_rand(); let account2_lamports: u64 = 200; let account2 = AccountSharedData::new(account2_lamports, 1, AccountSharedData::default().owner()); - accounts.store_cached(slot0, &[(&key2, &account2)], None); + accounts.store_cached((slot0, &[(&key2, &account2)][..]), None); let account1_lamports2 = 2; let slot1 = 1; let account1 = AccountSharedData::new(account1_lamports2, 1, account1.owner()); - accounts.store_cached(slot1, &[(&key1, &account1)], None); + accounts.store_cached((slot1, &[(&key1, &account1)][..]), None); let key3 = solana_sdk::pubkey::new_rand(); let account3_lamports: u64 = 300; let account3 = AccountSharedData::new(account3_lamports, 1, AccountSharedData::default().owner()); - accounts.store_cached(slot1, &[(&key3, &account3)], None); + accounts.store_cached((slot1, &[(&key3, &account3)][..]), None); let notifier = notifier.write().unwrap(); assert_eq!(notifier.accounts_notified.get(&key1).unwrap().len(), 2);