diff --git a/runtime/src/storable_accounts.rs b/runtime/src/storable_accounts.rs index e3089168c0..8d79c0f78c 100644 --- a/runtime/src/storable_accounts.rs +++ b/runtime/src/storable_accounts.rs @@ -26,6 +26,40 @@ pub trait StorableAccounts<'a, T: ReadableAccount + Sync>: Sync { fn contains_multiple_slots(&self) -> bool; } +/// accounts that are moving from 'old_slot' to 'target_slot' +/// since all accounts are from the same old slot, we don't need to create a slice with per-account slot +/// but, we need slot(_) to return 'old_slot' for all accounts +/// Created a struct instead of a tuple to make the code easier to read. +pub struct StorableAccountsMovingSlots<'a, T: ReadableAccount + Sync> { + pub accounts: &'a [(&'a Pubkey, &'a T)], + /// accounts will be written to this slot + pub target_slot: Slot, + /// slot where accounts are currently stored + pub old_slot: Slot, +} + +impl<'a, T: ReadableAccount + Sync> StorableAccounts<'a, T> for StorableAccountsMovingSlots<'a, T> { + fn pubkey(&self, index: usize) -> &Pubkey { + self.accounts[index].0 + } + fn account(&self, index: usize) -> &T { + self.accounts[index].1 + } + fn slot(&self, _index: usize) -> Slot { + // per-index slot is not unique per slot, but it is different than 'target_slot' + self.old_slot + } + fn target_slot(&self) -> Slot { + self.target_slot + } + fn len(&self) -> usize { + self.accounts.len() + } + fn contains_multiple_slots(&self) -> bool { + false + } +} + impl<'a, T: ReadableAccount + Sync> StorableAccounts<'a, T> for (Slot, &'a [(&'a Pubkey, &'a T)]) { fn pubkey(&self, index: usize) -> &Pubkey { self.1[index].0 @@ -146,15 +180,24 @@ pub mod tests { }); let test2 = (target_slot, &two[..]); let test3 = (target_slot, &three[..]); + let old_slot = starting_slot; + let test_moving_slots = StorableAccountsMovingSlots { + accounts: &two[..], + target_slot, + old_slot, + }; compare(&test2, &test3); + compare(&test2, &test_moving_slots); for (i, raw) in raw.iter().enumerate() { assert_eq!(raw.0, *test3.pubkey(i)); assert_eq!(raw.1, *test3.account(i)); assert_eq!(raw.2, test3.slot(i)); assert_eq!(target_slot, test2.slot(i)); + assert_eq!(old_slot, test_moving_slots.slot(i)); } assert_eq!(target_slot, test3.target_slot()); assert!(!test2.contains_multiple_slots()); + assert!(!test_moving_slots.contains_multiple_slots()); assert_eq!(test3.contains_multiple_slots(), entries > 1); } }