account_default_if_zero_lamport always returns a value (#822)

This commit is contained in:
Jeff Washington (jwash) 2024-04-16 08:11:46 -05:00 committed by GitHub
parent 14135e110f
commit c75fe56354
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 43 additions and 71 deletions

View File

@ -64,7 +64,7 @@ impl<'a: 'b, 'b, U: StorableAccounts<'a>, V: Borrow<AccountHash>>
pub fn get<Ret>(
&self,
index: usize,
mut callback: impl FnMut((Option<AccountForStorage>, &Pubkey, &AccountHash)) -> Ret,
mut callback: impl FnMut((AccountForStorage, &Pubkey, &AccountHash)) -> Ret,
) -> Ret {
let pubkey = self.accounts.pubkey(index);
let hash = if self.accounts.has_hash() {
@ -83,7 +83,7 @@ impl<'a: 'b, 'b, U: StorableAccounts<'a>, V: Borrow<AccountHash>>
pub fn account<Ret>(
&self,
index: usize,
callback: impl FnMut(Option<AccountForStorage<'a>>) -> Ret,
callback: impl FnMut(AccountForStorage<'a>) -> Ret,
) -> Ret {
self.accounts
.account_default_if_zero_lamport(index, callback)

View File

@ -5989,9 +5989,7 @@ impl AccountsDb {
// See if an account overflows the append vecs in the slot.
accounts_and_meta_to_store.account(infos.len(), |account| {
let data_len = account
.map(|account| account.data().len())
.unwrap_or_default();
let data_len = account.data().len();
let data_len = (data_len + STORE_META_OVERHEAD) as u64;
if !self.has_space_available(slot, data_len) {
info!(
@ -6015,11 +6013,7 @@ impl AccountsDb {
infos.push(AccountInfo::new(
StorageLocation::AppendVec(store_id, stored_account_info.offset),
accounts_and_meta_to_store.account(i, |account| {
account
.map(|account| account.lamports())
.unwrap_or_default()
}),
accounts_and_meta_to_store.account(i, |account| account.lamports()),
));
}
// restore the state to available
@ -6399,9 +6393,7 @@ impl AccountsDb {
.map(|(i, txn)| {
let mut account_info = AccountInfo::default();
accounts_and_meta_to_store.account_default_if_zero_lamport(i, |account| {
let account = account
.map(|account| account.to_account_shared_data())
.unwrap_or_default();
let account = account.to_account_shared_data();
let pubkey = accounts_and_meta_to_store.pubkey(i);
account_info = AccountInfo::new(StorageLocation::Cached, account.lamports());

View File

@ -753,30 +753,22 @@ impl AppendVec {
break;
}
accounts.get(i, |(account, pubkey, hash)| {
let account_meta = account
.map(|account| AccountMeta {
lamports: account.lamports(),
owner: *account.owner(),
rent_epoch: account.rent_epoch(),
executable: account.executable(),
})
.unwrap_or_default();
let account_meta = AccountMeta {
lamports: account.lamports(),
owner: *account.owner(),
rent_epoch: account.rent_epoch(),
executable: account.executable(),
};
let stored_meta = StoredMeta {
pubkey: *pubkey,
data_len: account
.map(|account| account.data().len())
.unwrap_or_default() as u64,
data_len: account.data().len() as u64,
write_version_obsolete: 0,
};
let meta_ptr = &stored_meta as *const StoredMeta;
let account_meta_ptr = &account_meta as *const AccountMeta;
let data_len = stored_meta.data_len as usize;
let data_ptr = account
.as_ref()
.map(|account| account.data())
.unwrap_or_default()
.as_ptr();
let data_ptr = account.data().as_ptr();
let hash_ptr = bytemuck::bytes_of(hash).as_ptr();
let ptrs = [
(meta_ptr as *const u8, mem::size_of::<StoredMeta>()),
@ -983,7 +975,7 @@ pub mod tests {
let accounts2 = (slot, &accounts[..]);
let storable = StorableAccountsWithHashes::new_with_hashes(&accounts2, hashes.clone());
storable.account(0, |get_account| {
assert!(get_account.is_none());
assert!(accounts_equal(&get_account, &AccountSharedData::default()));
});
// non-zero lamports, data should be correct
@ -998,7 +990,7 @@ pub mod tests {
let accounts2 = (slot, &accounts[..]);
let storable = StorableAccountsWithHashes::new_with_hashes(&accounts2, hashes);
storable.account(0, |get_account| {
assert!(accounts_equal(&account, &get_account.unwrap()));
assert!(accounts_equal(&account, &get_account));
});
}

View File

@ -75,6 +75,12 @@ 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:
/// a. (slot, &[&Pubkey, &ReadableAccount])
/// b. (slot, &[&Pubkey, &ReadableAccount, Slot]) (we will use this later)
@ -90,10 +96,14 @@ pub trait StorableAccounts<'a>: Sync {
fn account_default_if_zero_lamport<Ret>(
&self,
index: usize,
mut callback: impl FnMut(Option<AccountForStorage<'a>>) -> Ret,
mut callback: impl FnMut(AccountForStorage<'a>) -> Ret,
) -> Ret {
self.account(index, |account| {
callback((!account.is_zero_lamport()).then_some(account))
callback(if account.lamports() != 0 {
account
} else {
*DEFAULT_ACCOUNT
})
})
}
// current slot for account at 'index'

View File

@ -356,12 +356,7 @@ mod tests {
let mut expected_accounts_map = HashMap::new();
for i in 0..num_accounts {
storable_accounts.get(i, |(account, address, _account_hash)| {
expected_accounts_map.insert(
*address,
account
.map(|account| account.to_account_shared_data())
.unwrap_or_default(),
);
expected_accounts_map.insert(*address, account.to_account_shared_data());
});
}

View File

@ -16,7 +16,7 @@ use {
AccountAddressRange, AccountMetaFlags, AccountMetaOptionalFields, TieredAccountMeta,
},
mmap_utils::{get_pod, get_slice},
owners::{OwnerOffset, OwnersBlockFormat, OwnersTable, OWNER_NO_OWNER},
owners::{OwnerOffset, OwnersBlockFormat, OwnersTable},
StorableAccounts, StorableAccountsWithHashes, TieredStorageError, TieredStorageFormat,
TieredStorageResult,
},
@ -756,20 +756,17 @@ impl HotStorageWriter {
// Obtain necessary fields from the account, or default fields
// for a zero-lamport account in the None case.
let (lamports, owner, data, executable, rent_epoch) = account
.as_ref()
.map(|acc| {
(
acc.lamports(),
acc.owner(),
acc.data(),
acc.executable(),
// only persist rent_epoch for those rent-paying accounts
(acc.rent_epoch() != RENT_EXEMPT_RENT_EPOCH)
.then_some(acc.rent_epoch()),
)
})
.unwrap_or((0, &OWNER_NO_OWNER, &[], false, None));
let (lamports, owner, data, executable, rent_epoch) = {
(
account.lamports(),
account.owner(),
account.data(),
account.executable(),
// only persist rent_epoch for those rent-paying accounts
(account.rent_epoch() != RENT_EXEMPT_RENT_EPOCH)
.then_some(account.rent_epoch()),
)
};
let owner_offset = owners_table.insert(owner);
let stored_size =
self.write_account(lamports, owner_offset, data, executable, rent_epoch)?;
@ -1565,9 +1562,7 @@ mod tests {
storable_accounts.get(i, |(account, address, _account_hash)| {
verify_test_account(
&stored_account_meta,
&account
.map(|account| account.to_account_shared_data())
.unwrap_or_default(),
&account.to_account_shared_data(),
address,
);
});
@ -1590,9 +1585,7 @@ mod tests {
storable_accounts.get(stored_info.offset, |(account, address, _account_hash)| {
verify_test_account(
&stored_account_meta,
&account
.map(|account| account.to_account_shared_data())
.unwrap_or_default(),
&account.to_account_shared_data(),
address,
);
});
@ -1604,13 +1597,7 @@ mod tests {
// first, we verify everything
for (i, stored_meta) in accounts.iter().enumerate() {
storable_accounts.get(i, |(account, address, _account_hash)| {
verify_test_account(
stored_meta,
&account
.map(|account| account.to_account_shared_data())
.unwrap_or_default(),
address,
);
verify_test_account(stored_meta, &account.to_account_shared_data(), address);
});
}

View File

@ -16,10 +16,6 @@ use {
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)]
pub struct OwnerOffset(pub u32);
lazy_static! {
pub static ref OWNER_NO_OWNER: Pubkey = Pubkey::default();
}
/// Owner block holds a set of unique addresses of account owners,
/// and an account meta has a owner_offset field for accessing
/// it's owner address.