write Option<AccountSharedData> (#16874)
* write Option<&AccountSharedData> * add comment
This commit is contained in:
committed by
GitHub
parent
25054bfd35
commit
1864bc2080
@ -3323,7 +3323,7 @@ impl AccountsDb {
|
|||||||
slot: Slot,
|
slot: Slot,
|
||||||
hashes: &[impl Borrow<Hash>],
|
hashes: &[impl Borrow<Hash>],
|
||||||
mut storage_finder: F,
|
mut storage_finder: F,
|
||||||
accounts_and_meta_to_store: &[(StoredMeta, &AccountSharedData)],
|
accounts_and_meta_to_store: &[(StoredMeta, Option<&AccountSharedData>)],
|
||||||
) -> Vec<AccountInfo> {
|
) -> Vec<AccountInfo> {
|
||||||
assert_eq!(hashes.len(), accounts_and_meta_to_store.len());
|
assert_eq!(hashes.len(), accounts_and_meta_to_store.len());
|
||||||
let mut infos: Vec<AccountInfo> = Vec::with_capacity(accounts_and_meta_to_store.len());
|
let mut infos: Vec<AccountInfo> = Vec::with_capacity(accounts_and_meta_to_store.len());
|
||||||
@ -3331,7 +3331,10 @@ impl AccountsDb {
|
|||||||
let mut total_storage_find_us = 0;
|
let mut total_storage_find_us = 0;
|
||||||
while infos.len() < accounts_and_meta_to_store.len() {
|
while infos.len() < accounts_and_meta_to_store.len() {
|
||||||
let mut storage_find = Measure::start("storage_finder");
|
let mut storage_find = Measure::start("storage_finder");
|
||||||
let data_len = accounts_and_meta_to_store[infos.len()].1.data().len();
|
let data_len = accounts_and_meta_to_store[infos.len()]
|
||||||
|
.1
|
||||||
|
.map(|account| account.data().len())
|
||||||
|
.unwrap_or_default();
|
||||||
let storage = storage_finder(slot, data_len + STORE_META_OVERHEAD);
|
let storage = storage_finder(slot, data_len + STORE_META_OVERHEAD);
|
||||||
storage_find.stop();
|
storage_find.stop();
|
||||||
total_storage_find_us += storage_find.as_us();
|
total_storage_find_us += storage_find.as_us();
|
||||||
@ -3377,7 +3380,9 @@ impl AccountsDb {
|
|||||||
store_id: storage.append_vec_id(),
|
store_id: storage.append_vec_id(),
|
||||||
offset: offsets[0],
|
offset: offsets[0],
|
||||||
stored_size,
|
stored_size,
|
||||||
lamports: account.lamports(),
|
lamports: account
|
||||||
|
.map(|account| account.lamports())
|
||||||
|
.unwrap_or_default(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// restore the state to available
|
// restore the state to available
|
||||||
@ -3705,7 +3710,7 @@ impl AccountsDb {
|
|||||||
&self,
|
&self,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
hashes: Option<&[impl Borrow<Hash>]>,
|
hashes: Option<&[impl Borrow<Hash>]>,
|
||||||
accounts_and_meta_to_store: &[(StoredMeta, &AccountSharedData)],
|
accounts_and_meta_to_store: &[(StoredMeta, Option<&AccountSharedData>)],
|
||||||
) -> Vec<AccountInfo> {
|
) -> Vec<AccountInfo> {
|
||||||
let len = accounts_and_meta_to_store.len();
|
let len = accounts_and_meta_to_store.len();
|
||||||
let hashes = hashes.map(|hashes| {
|
let hashes = hashes.map(|hashes| {
|
||||||
@ -3718,9 +3723,17 @@ impl AccountsDb {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, (meta, account))| {
|
.map(|(i, (meta, account))| {
|
||||||
let hash = hashes.map(|hashes| hashes[i].borrow());
|
let hash = hashes.map(|hashes| hashes[i].borrow());
|
||||||
let cached_account =
|
|
||||||
self.accounts_cache
|
let account = account.cloned().unwrap_or_default();
|
||||||
.store(slot, &meta.pubkey, (*account).clone(), hash);
|
|
||||||
|
let account_info = AccountInfo {
|
||||||
|
store_id: CACHE_VIRTUAL_STORAGE_ID,
|
||||||
|
offset: CACHE_VIRTUAL_OFFSET,
|
||||||
|
stored_size: CACHE_VIRTUAL_STORED_SIZE,
|
||||||
|
lamports: account.lamports(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let cached_account = self.accounts_cache.store(slot, &meta.pubkey, account, hash);
|
||||||
// hash this account in the bg
|
// hash this account in the bg
|
||||||
match &self.sender_bg_hasher {
|
match &self.sender_bg_hasher {
|
||||||
Some(ref sender) => {
|
Some(ref sender) => {
|
||||||
@ -3728,13 +3741,7 @@ impl AccountsDb {
|
|||||||
}
|
}
|
||||||
None => (),
|
None => (),
|
||||||
};
|
};
|
||||||
|
account_info
|
||||||
AccountInfo {
|
|
||||||
store_id: CACHE_VIRTUAL_STORAGE_ID,
|
|
||||||
offset: CACHE_VIRTUAL_OFFSET,
|
|
||||||
stored_size: CACHE_VIRTUAL_STORED_SIZE,
|
|
||||||
lamports: account.lamports(),
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@ -3751,17 +3758,18 @@ impl AccountsDb {
|
|||||||
mut write_version_producer: P,
|
mut write_version_producer: P,
|
||||||
is_cached_store: bool,
|
is_cached_store: bool,
|
||||||
) -> Vec<AccountInfo> {
|
) -> Vec<AccountInfo> {
|
||||||
let default_account = AccountSharedData::default();
|
let accounts_and_meta_to_store: Vec<(StoredMeta, Option<&AccountSharedData>)> = accounts
|
||||||
let accounts_and_meta_to_store: Vec<(StoredMeta, &AccountSharedData)> = accounts
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(pubkey, account)| {
|
.map(|(pubkey, account)| {
|
||||||
self.read_only_accounts_cache.remove(pubkey, slot);
|
self.read_only_accounts_cache.remove(pubkey, slot);
|
||||||
let account = if account.lamports() == 0 {
|
// this is the source of Some(Account) or None.
|
||||||
&default_account
|
// Some(Account) = store 'Account'
|
||||||
|
// None = store a default/empty account with 0 lamports
|
||||||
|
let (account, data_len) = if account.lamports() == 0 {
|
||||||
|
(None, 0)
|
||||||
} else {
|
} else {
|
||||||
*account
|
(Some(*account), account.data().len() as u64)
|
||||||
};
|
};
|
||||||
let data_len = account.data().len() as u64;
|
|
||||||
let meta = StoredMeta {
|
let meta = StoredMeta {
|
||||||
write_version: write_version_producer.next().unwrap(),
|
write_version: write_version_producer.next().unwrap(),
|
||||||
pubkey: **pubkey,
|
pubkey: **pubkey,
|
||||||
@ -5822,7 +5830,7 @@ pub mod tests {
|
|||||||
};
|
};
|
||||||
storages[0][0]
|
storages[0][0]
|
||||||
.accounts
|
.accounts
|
||||||
.append_accounts(&[(sm, &acc)], &[&Hash::default()]);
|
.append_accounts(&[(sm, Some(&acc))], &[&Hash::default()]);
|
||||||
|
|
||||||
let calls = AtomicU64::new(0);
|
let calls = AtomicU64::new(0);
|
||||||
let result = AccountsDb::scan_account_storage_no_bank(
|
let result = AccountsDb::scan_account_storage_no_bank(
|
||||||
|
@ -69,6 +69,15 @@ impl<'a, T: ReadableAccount> From<&'a T> for AccountMeta {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// References to account data stored elsewhere. Getting an `Account` requires cloning
|
/// References to account data stored elsewhere. Getting an `Account` requires cloning
|
||||||
/// (see `StoredAccountMeta::clone_account()`).
|
/// (see `StoredAccountMeta::clone_account()`).
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
@ -453,7 +462,7 @@ impl AppendVec {
|
|||||||
/// and will be available to other threads.
|
/// and will be available to other threads.
|
||||||
pub fn append_accounts(
|
pub fn append_accounts(
|
||||||
&self,
|
&self,
|
||||||
accounts: &[(StoredMeta, &AccountSharedData)],
|
accounts: &[(StoredMeta, Option<&AccountSharedData>)],
|
||||||
hashes: &[impl Borrow<Hash>],
|
hashes: &[impl Borrow<Hash>],
|
||||||
) -> Vec<usize> {
|
) -> Vec<usize> {
|
||||||
let _lock = self.append_lock.lock().unwrap();
|
let _lock = self.append_lock.lock().unwrap();
|
||||||
@ -464,7 +473,10 @@ impl AppendVec {
|
|||||||
let account_meta = AccountMeta::from(*account);
|
let account_meta = AccountMeta::from(*account);
|
||||||
let account_meta_ptr = &account_meta as *const AccountMeta;
|
let account_meta_ptr = &account_meta as *const AccountMeta;
|
||||||
let data_len = stored_meta.data_len as usize;
|
let data_len = stored_meta.data_len as usize;
|
||||||
let data_ptr = account.data().as_ptr();
|
let data_ptr = account
|
||||||
|
.map(|account| account.data())
|
||||||
|
.unwrap_or_default()
|
||||||
|
.as_ptr();
|
||||||
let hash_ptr = hash.borrow().as_ref().as_ptr();
|
let hash_ptr = hash.borrow().as_ref().as_ptr();
|
||||||
let ptrs = [
|
let ptrs = [
|
||||||
(meta_ptr as *const u8, mem::size_of::<StoredMeta>()),
|
(meta_ptr as *const u8, mem::size_of::<StoredMeta>()),
|
||||||
@ -495,7 +507,7 @@ impl AppendVec {
|
|||||||
account: &AccountSharedData,
|
account: &AccountSharedData,
|
||||||
hash: Hash,
|
hash: Hash,
|
||||||
) -> Option<usize> {
|
) -> Option<usize> {
|
||||||
let res = self.append_accounts(&[(storage_meta, account)], &[&hash]);
|
let res = self.append_accounts(&[(storage_meta, Some(account))], &[&hash]);
|
||||||
if res.len() == 1 {
|
if res.len() == 1 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@ -592,6 +604,43 @@ pub mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_account_meta_default() {
|
||||||
|
let def1 = AccountMeta::default();
|
||||||
|
let def2 = AccountMeta::from(&Account::default());
|
||||||
|
assert_eq!(&def1, &def2);
|
||||||
|
let def2 = AccountMeta::from(&AccountSharedData::default());
|
||||||
|
assert_eq!(&def1, &def2);
|
||||||
|
let def2 = AccountMeta::from(Some(&AccountSharedData::default()));
|
||||||
|
assert_eq!(&def1, &def2);
|
||||||
|
let none: Option<&AccountSharedData> = None;
|
||||||
|
let def2 = AccountMeta::from(none);
|
||||||
|
assert_eq!(&def1, &def2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_account_meta_non_default() {
|
||||||
|
let def1 = AccountMeta {
|
||||||
|
lamports: 1,
|
||||||
|
owner: Pubkey::new_unique(),
|
||||||
|
executable: true,
|
||||||
|
rent_epoch: 3,
|
||||||
|
};
|
||||||
|
let def2_account = Account {
|
||||||
|
lamports: def1.lamports,
|
||||||
|
owner: def1.owner,
|
||||||
|
executable: def1.executable,
|
||||||
|
rent_epoch: def1.rent_epoch,
|
||||||
|
data: Vec::new(),
|
||||||
|
};
|
||||||
|
let def2 = AccountMeta::from(&def2_account);
|
||||||
|
assert_eq!(&def1, &def2);
|
||||||
|
let def2 = AccountMeta::from(&AccountSharedData::from(def2_account.clone()));
|
||||||
|
assert_eq!(&def1, &def2);
|
||||||
|
let def2 = AccountMeta::from(Some(&AccountSharedData::from(def2_account)));
|
||||||
|
assert_eq!(&def1, &def2);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "too small file size 0 for AppendVec")]
|
#[should_panic(expected = "too small file size 0 for AppendVec")]
|
||||||
fn test_append_vec_new_bad_size() {
|
fn test_append_vec_new_bad_size() {
|
||||||
|
Reference in New Issue
Block a user