solana_accounts_db/account_storage/
meta.rsuse {
crate::{
accounts_hash::AccountHash,
append_vec::AppendVecStoredAccountMeta,
storable_accounts::StorableAccounts,
tiered_storage::{hot::HotAccountMeta, readable::TieredReadableAccount},
},
solana_sdk::{account::ReadableAccount, hash::Hash, pubkey::Pubkey, stake_history::Epoch},
std::{borrow::Borrow, marker::PhantomData},
};
pub type StoredMetaWriteVersion = u64;
#[derive(Debug, Clone)]
pub struct StoredAccountInfo {
pub offset: usize,
pub size: usize,
}
lazy_static! {
static ref DEFAULT_ACCOUNT_HASH: AccountHash = AccountHash(Hash::default());
}
pub struct StorableAccountsWithHashesAndWriteVersions<
'a: 'b,
'b,
T: ReadableAccount + Sync + 'b,
U: StorableAccounts<'a, T>,
V: Borrow<AccountHash>,
> {
pub(crate) accounts: &'b U,
hashes_and_write_versions: Option<(Vec<V>, Vec<StoredMetaWriteVersion>)>,
_phantom: PhantomData<&'a T>,
}
impl<
'a: 'b,
'b,
T: ReadableAccount + Sync + 'b,
U: StorableAccounts<'a, T>,
V: Borrow<AccountHash>,
> StorableAccountsWithHashesAndWriteVersions<'a, 'b, T, U, V>
{
pub fn new(accounts: &'b U) -> Self {
assert!(accounts.has_hash_and_write_version());
Self {
accounts,
hashes_and_write_versions: None,
_phantom: PhantomData,
}
}
pub fn new_with_hashes_and_write_versions(
accounts: &'b U,
hashes: Vec<V>,
write_versions: Vec<StoredMetaWriteVersion>,
) -> Self {
assert!(!accounts.has_hash_and_write_version());
assert_eq!(accounts.len(), hashes.len());
assert_eq!(write_versions.len(), hashes.len());
Self {
accounts,
hashes_and_write_versions: Some((hashes, write_versions)),
_phantom: PhantomData,
}
}
pub fn get(&self, index: usize) -> (Option<&T>, &Pubkey, &AccountHash, StoredMetaWriteVersion) {
let account = self.accounts.account_default_if_zero_lamport(index);
let pubkey = self.accounts.pubkey(index);
let (hash, write_version) = if self.accounts.has_hash_and_write_version() {
(
self.accounts.hash(index),
self.accounts.write_version(index),
)
} else {
let item = self.hashes_and_write_versions.as_ref().unwrap();
(item.0[index].borrow(), item.1[index])
};
(account, pubkey, hash, write_version)
}
pub fn account(&self, index: usize) -> Option<&T> {
self.accounts.account_default_if_zero_lamport(index)
}
pub fn len(&self) -> usize {
self.accounts.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
#[derive(PartialEq, Eq, Debug)]
pub enum StoredAccountMeta<'storage> {
AppendVec(AppendVecStoredAccountMeta<'storage>),
Hot(TieredReadableAccount<'storage, HotAccountMeta>),
}
impl<'storage> StoredAccountMeta<'storage> {
pub fn pubkey(&self) -> &'storage Pubkey {
match self {
Self::AppendVec(av) => av.pubkey(),
Self::Hot(hot) => hot.address(),
}
}
pub fn hash(&self) -> &'storage AccountHash {
match self {
Self::AppendVec(av) => av.hash(),
Self::Hot(hot) => hot.hash().unwrap_or(&DEFAULT_ACCOUNT_HASH),
}
}
pub fn stored_size(&self) -> usize {
match self {
Self::AppendVec(av) => av.stored_size(),
Self::Hot(_) => unimplemented!(),
}
}
pub fn offset(&self) -> usize {
match self {
Self::AppendVec(av) => av.offset(),
Self::Hot(hot) => hot.index(),
}
}
pub fn data(&self) -> &'storage [u8] {
match self {
Self::AppendVec(av) => av.data(),
Self::Hot(hot) => hot.data(),
}
}
pub fn data_len(&self) -> u64 {
match self {
Self::AppendVec(av) => av.data_len(),
Self::Hot(hot) => hot.data().len() as u64,
}
}
pub fn write_version(&self) -> StoredMetaWriteVersion {
match self {
Self::AppendVec(av) => av.write_version(),
Self::Hot(_) => StoredMetaWriteVersion::default(),
}
}
pub fn meta(&self) -> &StoredMeta {
match self {
Self::AppendVec(av) => av.meta(),
Self::Hot(_) => unreachable!(),
}
}
pub fn set_meta(&mut self, meta: &'storage StoredMeta) {
match self {
Self::AppendVec(av) => av.set_meta(meta),
Self::Hot(_) => unreachable!(),
}
}
pub(crate) fn sanitize(&self) -> bool {
match self {
Self::AppendVec(av) => av.sanitize(),
Self::Hot(_) => unimplemented!(),
}
}
}
impl<'storage> ReadableAccount for StoredAccountMeta<'storage> {
fn lamports(&self) -> u64 {
match self {
Self::AppendVec(av) => av.lamports(),
Self::Hot(hot) => hot.lamports(),
}
}
fn data(&self) -> &[u8] {
match self {
Self::AppendVec(av) => av.data(),
Self::Hot(hot) => hot.data(),
}
}
fn owner(&self) -> &Pubkey {
match self {
Self::AppendVec(av) => av.owner(),
Self::Hot(hot) => hot.owner(),
}
}
fn executable(&self) -> bool {
match self {
Self::AppendVec(av) => av.executable(),
Self::Hot(hot) => hot.executable(),
}
}
fn rent_epoch(&self) -> Epoch {
match self {
Self::AppendVec(av) => av.rent_epoch(),
Self::Hot(hot) => hot.rent_epoch(),
}
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
#[repr(C)]
pub struct StoredMeta {
pub write_version_obsolete: StoredMetaWriteVersion,
pub data_len: u64,
pub pubkey: Pubkey,
}
#[derive(Serialize, Deserialize, Clone, Debug, Default, Eq, PartialEq)]
#[repr(C)]
pub struct AccountMeta {
pub lamports: u64,
pub rent_epoch: Epoch,
pub owner: Pubkey,
pub executable: bool,
}
impl<'a, T: ReadableAccount> From<&'a T> for AccountMeta {
fn from(account: &'a T) -> Self {
Self {
lamports: account.lamports(),
owner: *account.owner(),
executable: account.executable(),
rent_epoch: account.rent_epoch(),
}
}
}
impl<'a, T: ReadableAccount> From<Option<&'a T>> for AccountMeta {
fn from(account: Option<&'a T>) -> Self {
match account {
Some(account) => AccountMeta::from(account),
None => AccountMeta::default(),
}
}
}