getter functions for StoredAccountMeta (#30447)

This PR makes all the StoredAccountMeta fields pub(crate)
and provides getter functions to access its member fields.

This PR is a preparation step for abstracting out StoredAccountMeta.
This commit is contained in:
Yueh-Hsuan Chiang 2023-02-27 10:03:22 -08:00 committed by GitHub
parent 18c22c7cef
commit 33e179905f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 109 additions and 88 deletions

View File

@ -129,12 +129,12 @@ impl AccountsUpdateNotifierImpl {
) -> Option<ReplicaAccountInfoV3<'a>> {
Some(ReplicaAccountInfoV3 {
pubkey: stored_account_meta.pubkey().as_ref(),
lamports: stored_account_meta.account_meta.lamports,
owner: stored_account_meta.account_meta.owner.as_ref(),
executable: stored_account_meta.account_meta.executable,
rent_epoch: stored_account_meta.account_meta.rent_epoch,
data: stored_account_meta.data,
write_version: stored_account_meta.meta.write_version_obsolete,
lamports: stored_account_meta.lamports(),
owner: stored_account_meta.owner().as_ref(),
executable: stored_account_meta.executable(),
rent_epoch: stored_account_meta.rent_epoch(),
data: stored_account_meta.data(),
write_version: stored_account_meta.write_version(),
txn: None,
})
}

View File

@ -79,7 +79,7 @@ fn append_vec_sequential_read(bencher: &mut Bencher) {
println!("reading pos {sample} {pos}");
let (account, _next) = vec.get_account(pos).unwrap();
let (_meta, test) = create_test_account(sample);
assert_eq!(account.data, test.data());
assert_eq!(account.data(), test.data());
indexes.push((sample, pos));
});
}
@ -94,7 +94,7 @@ fn append_vec_random_read(bencher: &mut Bencher) {
let (sample, pos) = &indexes[random_index];
let (account, _next) = vec.get_account(*pos).unwrap();
let (_meta, test) = create_test_account(*sample);
assert_eq!(account.data, test.data());
assert_eq!(account.data(), test.data());
});
}
@ -123,7 +123,7 @@ fn append_vec_concurrent_append_read(bencher: &mut Bencher) {
let (sample, pos) = *indexes.lock().unwrap().get(random_index).unwrap();
let (account, _next) = vec.get_account(pos).unwrap();
let (_meta, test) = create_test_account(sample);
assert_eq!(account.data, test.data());
assert_eq!(account.data(), test.data());
});
}
@ -143,7 +143,7 @@ fn append_vec_concurrent_read_append(bencher: &mut Bencher) {
let (sample, pos) = *indexes1.lock().unwrap().get(random_index % len).unwrap();
let (account, _next) = vec1.get_account(pos).unwrap();
let (_meta, test) = create_test_account(sample);
assert_eq!(account.data, test.data());
assert_eq!(account.data(), test.data());
});
bencher.iter(|| {
let sample: usize = thread_rng().gen_range(0, 256);

View File

@ -98,13 +98,13 @@ impl<'a: 'b, 'b, T: ReadableAccount + Sync + 'b, U: StorableAccounts<'a, T>, V:
/// (see `StoredAccountMeta::clone_account()`).
#[derive(PartialEq, Eq, Debug)]
pub struct StoredAccountMeta<'a> {
pub meta: &'a StoredMeta,
pub(crate) meta: &'a StoredMeta,
/// account data
pub account_meta: &'a AccountMeta,
pub data: &'a [u8],
pub offset: usize,
pub stored_size: usize,
pub hash: &'a Hash,
pub(crate) account_meta: &'a AccountMeta,
pub(crate) data: &'a [u8],
pub(crate) offset: usize,
pub(crate) stored_size: usize,
pub(crate) hash: &'a Hash,
}
impl<'a> StoredAccountMeta<'a> {
@ -123,6 +123,30 @@ impl<'a> StoredAccountMeta<'a> {
&self.meta.pubkey
}
pub fn hash(&self) -> &Hash {
self.hash
}
pub fn stored_size(&self) -> usize {
self.stored_size
}
pub fn offset(&self) -> usize {
self.offset
}
pub fn data(&self) -> &[u8] {
self.data
}
pub fn data_len(&self) -> u64 {
self.meta.data_len
}
pub fn write_version(&self) -> StoredMetaWriteVersion {
self.meta.write_version_obsolete
}
pub(crate) fn sanitize(&self) -> bool {
self.sanitize_executable() && self.sanitize_lamports()
}
@ -147,6 +171,24 @@ impl<'a> StoredAccountMeta<'a> {
}
}
impl<'a> ReadableAccount for StoredAccountMeta<'a> {
fn lamports(&self) -> u64 {
self.account_meta.lamports
}
fn data(&self) -> &[u8] {
self.data()
}
fn owner(&self) -> &Pubkey {
&self.account_meta.owner
}
fn executable(&self) -> bool {
self.account_meta.executable
}
fn rent_epoch(&self) -> Epoch {
self.account_meta.rent_epoch
}
}
/// Meta contains enough context to recover the index from storage itself
/// This struct will be backed by mmaped and snapshotted data files.
/// So the data layout must be stable and consistent across the entire cluster!

View File

@ -237,7 +237,7 @@ impl<'a> ShrinkCollectRefs<'a> for AliveAccounts<'a> {
}
fn add(&mut self, _ref_count: u64, account: &'a StoredAccountMeta<'a>) {
self.accounts.push(account);
self.bytes = self.bytes.saturating_add(account.stored_size);
self.bytes = self.bytes.saturating_add(account.stored_size());
}
fn len(&self) -> usize {
self.accounts.len()
@ -882,7 +882,7 @@ pub enum LoadedAccount<'a> {
impl<'a> LoadedAccount<'a> {
pub fn loaded_hash(&self) -> Hash {
match self {
LoadedAccount::Stored(stored_account_meta) => *stored_account_meta.hash,
LoadedAccount::Stored(stored_account_meta) => *stored_account_meta.hash(),
LoadedAccount::Cached(cached_account) => cached_account.hash(),
}
}
@ -934,36 +934,32 @@ impl<'a> LoadedAccount<'a> {
impl<'a> ReadableAccount for LoadedAccount<'a> {
fn lamports(&self) -> u64 {
match self {
LoadedAccount::Stored(stored_account_meta) => stored_account_meta.account_meta.lamports,
LoadedAccount::Stored(stored_account_meta) => stored_account_meta.lamports(),
LoadedAccount::Cached(cached_account) => cached_account.account.lamports(),
}
}
fn data(&self) -> &[u8] {
match self {
LoadedAccount::Stored(stored_account_meta) => stored_account_meta.data,
LoadedAccount::Stored(stored_account_meta) => stored_account_meta.data(),
LoadedAccount::Cached(cached_account) => cached_account.account.data(),
}
}
fn owner(&self) -> &Pubkey {
match self {
LoadedAccount::Stored(stored_account_meta) => &stored_account_meta.account_meta.owner,
LoadedAccount::Stored(stored_account_meta) => stored_account_meta.owner(),
LoadedAccount::Cached(cached_account) => cached_account.account.owner(),
}
}
fn executable(&self) -> bool {
match self {
LoadedAccount::Stored(stored_account_meta) => {
stored_account_meta.account_meta.executable
}
LoadedAccount::Stored(stored_account_meta) => stored_account_meta.executable(),
LoadedAccount::Cached(cached_account) => cached_account.account.executable(),
}
}
fn rent_epoch(&self) -> Epoch {
match self {
LoadedAccount::Stored(stored_account_meta) => {
stored_account_meta.account_meta.rent_epoch
}
LoadedAccount::Stored(stored_account_meta) => stored_account_meta.rent_epoch(),
LoadedAccount::Cached(cached_account) => cached_account.account.rent_epoch(),
}
}
@ -2253,24 +2249,6 @@ impl<'a> ZeroLamport for StoredAccountMeta<'a> {
}
}
impl<'a> ReadableAccount for StoredAccountMeta<'a> {
fn lamports(&self) -> u64 {
self.account_meta.lamports
}
fn data(&self) -> &[u8] {
self.data
}
fn owner(&self) -> &Pubkey {
&self.account_meta.owner
}
fn executable(&self) -> bool {
self.account_meta.executable
}
fn rent_epoch(&self) -> Epoch {
self.account_meta.rent_epoch
}
}
struct IndexAccountMapEntry<'a> {
pub write_version: StoredMetaWriteVersion,
pub store_id: AppendVecId,
@ -4330,7 +4308,7 @@ impl AccountsDb {
storage
.accounts
.account_iter()
.map(|account| account.stored_size)
.map(|account| account.stored_size())
.collect()
})
.unwrap_or_default()
@ -8599,7 +8577,7 @@ impl AccountsDb {
let num_accounts = storage.approx_stored_count();
let mut accounts_map = GenerateIndexAccountsMap::with_capacity(num_accounts);
storage.accounts.account_iter().for_each(|stored_account| {
let this_version = stored_account.meta.write_version_obsolete;
let this_version = stored_account.write_version();
let pubkey = stored_account.pubkey();
assert!(!self.is_filler_account(pubkey));
accounts_map.insert(
@ -8681,8 +8659,8 @@ impl AccountsDb {
(
pubkey,
AccountInfo::new(
StorageLocation::AppendVec(store_id, stored_account.offset), // will never be cached
stored_account.account_meta.lamports,
StorageLocation::AppendVec(store_id, stored_account.offset()), // will never be cached
stored_account.lamports(),
),
)
},
@ -8914,9 +8892,9 @@ impl AccountsDb {
let ai = AccountInfo::new(
StorageLocation::AppendVec(
account_info.store_id,
account_info.stored_account.offset,
account_info.stored_account.offset(),
), // will never be cached
account_info.stored_account.account_meta.lamports,
account_info.stored_account.lamports(),
);
assert_eq!(&ai, account_info2);
}
@ -9148,7 +9126,7 @@ impl AccountsDb {
let mut info = storage_info_local
.entry(v.store_id)
.or_insert_with(StorageSizeAndCount::default);
info.stored_size += v.stored_account.stored_size;
info.stored_size += v.stored_account.stored_size();
info.count += 1;
}
storage_size_accounts_map_time.stop();
@ -9631,7 +9609,7 @@ pub mod tests {
hash: &hash,
};
let map = vec![&account];
let alive_total_bytes = account.stored_size;
let alive_total_bytes = account.stored_size();
let to_store = AccountsToStore::new(available_bytes, &map, alive_total_bytes, slot0);
// Done: setup 'to_store'
@ -14591,7 +14569,7 @@ pub mod tests {
let reclaims = vec![account_info];
accounts_db.remove_dead_accounts(reclaims.iter(), None, None, true);
let after_size = storage0.alive_bytes.load(Ordering::Acquire);
assert_eq!(before_size, after_size + account.stored_size);
assert_eq!(before_size, after_size + account.stored_size());
}
}
@ -17592,7 +17570,7 @@ pub mod tests {
if let Some(storage) = db.get_storage_for_slot(slot) {
storage.accounts.account_iter().for_each(|account| {
let info = AccountInfo::new(
StorageLocation::AppendVec(storage.append_vec_id(), account.offset),
StorageLocation::AppendVec(storage.append_vec_id(), account.offset()),
account.lamports(),
);
db.accounts_index.upsert(

View File

@ -97,7 +97,7 @@ impl AccountsDb {
let mut account_len = 0;
accounts.for_each(|account| {
account_len += 1;
if notified_accounts.contains(&account.meta.pubkey) {
if notified_accounts.contains(account.pubkey()) {
notify_stats.skipped_accounts += 1;
return;
}
@ -105,7 +105,7 @@ impl AccountsDb {
// later entries in the same slot are more recent and override earlier accounts for the same pubkey
// We can pass an incrementing number here for write_version in the future, if the storage does not have a write_version.
// As long as all accounts for this slot are in 1 append vec that can be itereated olest to newest.
accounts_to_stream.insert(account.meta.pubkey, account);
accounts_to_stream.insert(*account.pubkey(), account);
});
notify_stats.total_accounts += account_len;
measure_filter.stop();
@ -148,7 +148,7 @@ impl AccountsDb {
notify_stats.total_pure_notify += measure_pure_notify.as_us() as usize;
let mut measure_bookkeep = Measure::start("accountsdb-plugin-notifying-bookeeeping");
notified_accounts.insert(account.meta.pubkey);
notified_accounts.insert(*account.pubkey());
measure_bookkeep.stop();
notify_stats.total_pure_bookeeping += measure_bookkeep.as_us() as usize;
}
@ -213,7 +213,7 @@ pub mod tests {
/// from a snapshot.
fn notify_account_restore_from_snapshot(&self, slot: Slot, account: &StoredAccountMeta) {
self.accounts_notified
.entry(account.meta.pubkey)
.entry(*account.pubkey())
.or_default()
.push((slot, account.clone_account()));
}

View File

@ -706,7 +706,7 @@ impl<'a> AccountsToStore<'a> {
if alive_total_bytes > available_bytes as usize {
// not all the alive bytes fit, so we have to find how many accounts fit within available_bytes
for (i, account) in accounts.iter().enumerate() {
let account_size = account.stored_size as u64;
let account_size = account.stored_size() as u64;
if available_bytes >= account_size {
available_bytes = available_bytes.saturating_sub(account_size);
} else if index_first_item_overflow == num_accounts {

View File

@ -594,7 +594,7 @@ pub mod tests {
}
fn get_executable_byte(&self) -> u8 {
let executable_bool: bool = self.account_meta.executable;
let executable_bool: bool = self.executable();
// UNSAFE: Force to interpret mmap-backed bool as u8 to really read the actual memory content
let executable_byte: u8 = unsafe { std::mem::transmute::<bool, u8>(executable_bool) };
executable_byte
@ -1065,12 +1065,12 @@ pub mod tests {
let accounts = av.accounts(0);
let account = accounts.first().unwrap();
account.set_data_len_unsafe(crafted_data_len);
assert_eq!(account.meta.data_len, crafted_data_len);
assert_eq!(account.data_len(), crafted_data_len);
// Reload accounts and observe crafted_data_len
let accounts = av.accounts(0);
let account = accounts.first().unwrap();
assert_eq!(account.meta.data_len, crafted_data_len);
assert_eq!(account.data_len(), crafted_data_len);
av.flush().unwrap();
let accounts_len = av.len();
@ -1092,7 +1092,7 @@ pub mod tests {
let accounts = av.accounts(0);
let account = accounts.first().unwrap();
account.set_data_len_unsafe(too_large_data_len);
assert_eq!(account.meta.data_len, too_large_data_len);
assert_eq!(account.data_len(), too_large_data_len);
// Reload accounts and observe no account with bad offset
let accounts = av.accounts(0);
@ -1155,7 +1155,7 @@ pub mod tests {
// we can NOT observe crafted value by value
{
let executable_bool: bool = account.account_meta.executable;
let executable_bool: bool = account.executable();
assert!(!executable_bool);
assert_eq!(account.get_executable_byte(), 0); // Wow, not crafted_executable!
}

View File

@ -319,7 +319,7 @@ impl<'a> SnapshotMinimizer<'a> {
let mut purge_pubkeys = Vec::with_capacity(CHUNK_SIZE);
chunk.iter().for_each(|account| {
if self.minimized_account_set.contains(account.pubkey()) {
chunk_bytes += account.stored_size;
chunk_bytes += account.stored_size();
keep_accounts.push(account);
} else if self
.accounts_db()
@ -361,8 +361,8 @@ impl<'a> SnapshotMinimizer<'a> {
for alive_account in keep_accounts {
accounts.push(alive_account);
hashes.push(alive_account.hash);
write_versions.push(alive_account.meta.write_version_obsolete);
hashes.push(alive_account.hash());
write_versions.push(alive_account.write_version());
}
shrink_in_progress = Some(self.accounts_db().get_store_for_shrink(slot, aligned_total));

View File

@ -148,10 +148,10 @@ impl<'a> StorableAccounts<'a, StoredAccountMeta<'a>>
true
}
fn hash(&self, index: usize) -> &Hash {
self.account(index).hash
self.account(index).hash()
}
fn write_version(&self, index: usize) -> u64 {
self.account(index).meta.write_version_obsolete
self.account(index).write_version()
}
}
@ -252,10 +252,10 @@ impl<'a> StorableAccounts<'a, StoredAccountMeta<'a>> for StorableAccountsBySlot<
true
}
fn hash(&self, index: usize) -> &Hash {
self.account(index).hash
self.account(index).hash()
}
fn write_version(&self, index: usize) -> u64 {
self.account(index).meta.write_version_obsolete
self.account(index).write_version()
}
}
@ -292,10 +292,10 @@ impl<'a> StorableAccounts<'a, StoredAccountMeta<'a>>
true
}
fn hash(&self, index: usize) -> &Hash {
self.account(index).hash
self.account(index).hash()
}
fn write_version(&self, index: usize) -> u64 {
self.account(index).meta.write_version_obsolete
self.account(index).write_version()
}
}
@ -556,12 +556,9 @@ pub mod tests {
let index = index as usize;
assert_eq!(storable.account(index), &raw2[index]);
assert_eq!(storable.pubkey(index), raw2[index].pubkey());
assert_eq!(storable.hash(index), raw2[index].hash);
assert_eq!(storable.hash(index), raw2[index].hash());
assert_eq!(storable.slot(index), expected_slots[index]);
assert_eq!(
storable.write_version(index),
raw2[index].meta.write_version_obsolete
);
assert_eq!(storable.write_version(index), raw2[index].write_version());
})
}
}

View File

@ -2,7 +2,11 @@ use {
clap::{crate_description, crate_name, value_t, value_t_or_exit, App, Arg},
log::*,
solana_runtime::{account_storage::meta::StoredAccountMeta, append_vec::AppendVec},
solana_sdk::{account::AccountSharedData, hash::Hash, pubkey::Pubkey},
solana_sdk::{
account::{AccountSharedData, ReadableAccount},
hash::Hash,
pubkey::Pubkey,
},
};
fn main() {
@ -42,13 +46,13 @@ fn main() {
info!(
" account: {:?} version: {} lamports: {} data: {} hash: {:?}",
account.pubkey(),
account.meta.write_version_obsolete,
account.account_meta.lamports,
account.meta.data_len,
account.hash
account.write_version(),
account.lamports(),
account.data_len(),
account.hash()
);
num_accounts = num_accounts.saturating_add(1);
stored_accounts_len = stored_accounts_len.saturating_add(account.stored_size);
stored_accounts_len = stored_accounts_len.saturating_add(account.stored_size());
}
info!(
"num_accounts: {} stored_accounts_len: {}",
@ -57,9 +61,9 @@ fn main() {
}
fn is_account_zeroed(account: &StoredAccountMeta) -> bool {
account.hash == &Hash::default()
&& account.meta.data_len == 0
&& account.meta.write_version_obsolete == 0
account.hash() == &Hash::default()
&& account.data_len() == 0
&& account.write_version() == 0
&& account.pubkey() == &Pubkey::default()
&& account.clone_account() == AccountSharedData::default()
}