diff --git a/accounts-db/src/stake_rewards.rs b/accounts-db/src/stake_rewards.rs index 3c4e10db0..1e81f5253 100644 --- a/accounts-db/src/stake_rewards.rs +++ b/accounts-db/src/stake_rewards.rs @@ -31,7 +31,7 @@ impl<'a> StorableAccounts<'a> for (Slot, &'a [StakeReward]) { mut callback: impl FnMut(AccountForStorage<'a>) -> Ret, ) -> Ret { let entry = &self.1[index]; - callback((&entry.stake_account).into()) + callback((&self.1[index].stake_pubkey, &entry.stake_account).into()) } fn slot(&self, _index: usize) -> Slot { // per-index slot is not unique per slot when per-account slot is not included in the source data diff --git a/accounts-db/src/storable_accounts.rs b/accounts-db/src/storable_accounts.rs index 103e333f7..2755f636f 100644 --- a/accounts-db/src/storable_accounts.rs +++ b/accounts-db/src/storable_accounts.rs @@ -14,13 +14,13 @@ use { /// hold a ref to an account to store. The account could be represented in memory a few different ways #[derive(Debug, Copy, Clone)] pub enum AccountForStorage<'a> { - AccountSharedData(&'a AccountSharedData), + AddressAndAccount((&'a Pubkey, &'a AccountSharedData)), StoredAccountMeta(&'a StoredAccountMeta<'a>), } -impl<'a> From<&'a AccountSharedData> for AccountForStorage<'a> { - fn from(source: &'a AccountSharedData) -> Self { - Self::AccountSharedData(source) +impl<'a> From<(&'a Pubkey, &'a AccountSharedData)> for AccountForStorage<'a> { + fn from(source: (&'a Pubkey, &'a AccountSharedData)) -> Self { + Self::AddressAndAccount(source) } } @@ -36,40 +36,51 @@ impl<'a> ZeroLamport for AccountForStorage<'a> { } } +impl<'a> AccountForStorage<'a> { + pub(crate) fn pubkey(&self) -> &'a Pubkey { + match self { + AccountForStorage::AddressAndAccount((pubkey, _account)) => pubkey, + AccountForStorage::StoredAccountMeta(account) => account.pubkey(), + } + } +} + impl<'a> ReadableAccount for AccountForStorage<'a> { fn lamports(&self) -> u64 { match self { - AccountForStorage::AccountSharedData(account) => account.lamports(), + AccountForStorage::AddressAndAccount((_pubkey, account)) => account.lamports(), AccountForStorage::StoredAccountMeta(account) => account.lamports(), } } fn data(&self) -> &[u8] { match self { - AccountForStorage::AccountSharedData(account) => account.data(), + AccountForStorage::AddressAndAccount((_pubkey, account)) => account.data(), AccountForStorage::StoredAccountMeta(account) => account.data(), } } fn owner(&self) -> &Pubkey { match self { - AccountForStorage::AccountSharedData(account) => account.owner(), + AccountForStorage::AddressAndAccount((_pubkey, account)) => account.owner(), AccountForStorage::StoredAccountMeta(account) => account.owner(), } } fn executable(&self) -> bool { match self { - AccountForStorage::AccountSharedData(account) => account.executable(), + AccountForStorage::AddressAndAccount((_pubkey, account)) => account.executable(), AccountForStorage::StoredAccountMeta(account) => account.executable(), } } fn rent_epoch(&self) -> Epoch { match self { - AccountForStorage::AccountSharedData(account) => account.rent_epoch(), + AccountForStorage::AddressAndAccount((_pubkey, account)) => account.rent_epoch(), AccountForStorage::StoredAccountMeta(account) => account.rent_epoch(), } } fn to_account_shared_data(&self) -> AccountSharedData { match self { - AccountForStorage::AccountSharedData(account) => account.to_account_shared_data(), + AccountForStorage::AddressAndAccount((_pubkey, account)) => { + account.to_account_shared_data() + } AccountForStorage::StoredAccountMeta(account) => account.to_account_shared_data(), } } @@ -77,8 +88,6 @@ impl<'a> ReadableAccount for AccountForStorage<'a> { lazy_static! { static ref DEFAULT_ACCOUNT_SHARED_DATA: AccountSharedData = AccountSharedData::default(); - pub static ref DEFAULT_ACCOUNT: AccountForStorage<'static> = - AccountForStorage::AccountSharedData(&DEFAULT_ACCOUNT_SHARED_DATA); } /// abstract access to pubkey, account, slot, target_slot of either: @@ -102,7 +111,11 @@ pub trait StorableAccounts<'a>: Sync { callback(if account.lamports() != 0 { account } else { - *DEFAULT_ACCOUNT + // preserve the pubkey, but use a default value for the account + AccountForStorage::AddressAndAccount(( + account.pubkey(), + &DEFAULT_ACCOUNT_SHARED_DATA, + )) }) }) } @@ -150,7 +163,7 @@ pub struct StorableAccountsMovingSlots<'a, T: ReadableAccount + Sync> { impl<'a, T: ReadableAccount + Sync> StorableAccounts<'a> for StorableAccountsMovingSlots<'a, T> where - AccountForStorage<'a>: From<&'a T>, + AccountForStorage<'a>: From<(&'a Pubkey, &'a T)>, { fn pubkey(&self, index: usize) -> &Pubkey { self.accounts[index].0 @@ -160,7 +173,7 @@ where index: usize, mut callback: impl FnMut(AccountForStorage<'a>) -> Ret, ) -> Ret { - callback(self.accounts[index].1.into()) + callback((self.accounts[index].0, self.accounts[index].1).into()) } fn slot(&self, _index: usize) -> Slot { // per-index slot is not unique per slot, but it is different than 'target_slot' @@ -177,7 +190,7 @@ where impl<'a: 'b, 'b, T: ReadableAccount + Sync + 'a> StorableAccounts<'a> for (Slot, &'b [(&'a Pubkey, &'a T)]) where - AccountForStorage<'a>: From<&'a T>, + AccountForStorage<'a>: From<(&'a Pubkey, &'a T)>, { fn pubkey(&self, index: usize) -> &Pubkey { self.1[index].0 @@ -187,7 +200,7 @@ where index: usize, mut callback: impl FnMut(AccountForStorage<'a>) -> Ret, ) -> Ret { - callback(self.1[index].1.into()) + callback((self.1[index].0, self.1[index].1).into()) } fn slot(&self, _index: usize) -> Slot { // per-index slot is not unique per slot when per-account slot is not included in the source data @@ -202,7 +215,7 @@ where } impl<'a, T: ReadableAccount + Sync> StorableAccounts<'a> for (Slot, &'a [&'a (Pubkey, T)]) where - AccountForStorage<'a>: From<&'a T>, + AccountForStorage<'a>: From<(&'a Pubkey, &'a T)>, { fn pubkey(&self, index: usize) -> &Pubkey { &self.1[index].0 @@ -212,7 +225,7 @@ where index: usize, mut callback: impl FnMut(AccountForStorage<'a>) -> Ret, ) -> Ret { - callback((&self.1[index].1).into()) + callback((&self.1[index].0, &self.1[index].1).into()) } fn slot(&self, _index: usize) -> Slot { // per-index slot is not unique per slot when per-account slot is not included in the source data diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 25240aacd..a4bfbc893 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -5035,7 +5035,7 @@ impl Bank { pubkey: &'a Pubkey, account: &'a T, ) where - AccountForStorage<'a>: From<&'a T>, + AccountForStorage<'a>: From<(&'a Pubkey, &'a T)>, { self.store_accounts((self.slot(), &[(pubkey, account)][..])) }