Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 4f178a3

Browse files
committed
return Result instead of Option
1 parent 86926ea commit 4f178a3

File tree

2 files changed

+74
-37
lines changed

2 files changed

+74
-37
lines changed

runtime/src/accounts_db.rs

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ use {
4242
get_ancient_append_vec_capacity, is_ancient, AccountsToStore, StorageSelector,
4343
},
4444
append_vec::{
45-
aligned_stored_size, AppendVec, StorableAccountsWithHashesAndWriteVersions,
46-
StoredAccountMeta, StoredMetaWriteVersion, APPEND_VEC_MMAPPED_FILES_OPEN,
47-
STORE_META_OVERHEAD,
45+
aligned_stored_size, AppendVec, MatchAccountOwnerError,
46+
StorableAccountsWithHashesAndWriteVersions, StoredAccountMeta, StoredMetaWriteVersion,
47+
APPEND_VEC_MMAPPED_FILES_OPEN, STORE_META_OVERHEAD,
4848
},
4949
cache_hash_data::{CacheHashData, CacheHashDataFile},
5050
contains::Contains,
@@ -816,22 +816,28 @@ impl<'a> LoadedAccountAccessor<'a> {
816816
}
817817
}
818818

819-
fn account_matches_owners(&self, owners: &[&Pubkey]) -> Option<bool> {
819+
fn account_matches_owners(&self, owners: &[&Pubkey]) -> Result<(), MatchAccountOwnerError> {
820820
match self {
821821
LoadedAccountAccessor::Cached(cached_account) => cached_account
822822
.as_ref()
823-
.map(|cached_account| owners.contains(&cached_account.account.owner())),
823+
.and_then(|cached_account| {
824+
owners
825+
.contains(&cached_account.account.owner())
826+
.then_some(())
827+
})
828+
.ok_or(MatchAccountOwnerError::NoMatch),
824829
LoadedAccountAccessor::Stored(maybe_storage_entry) => {
825830
// storage entry may not be present if slot was cleaned up in
826831
// between reading the accounts index and calling this function to
827832
// get account meta from the storage entry here
828833
maybe_storage_entry
829834
.as_ref()
830-
.and_then(|(storage_entry, offset)| {
835+
.map(|(storage_entry, offset)| {
831836
storage_entry
832837
.accounts
833838
.account_matches_owners(*offset, owners)
834839
})
840+
.unwrap_or(Err(MatchAccountOwnerError::UnableToLoad))
835841
}
836842
}
837843
}
@@ -4943,25 +4949,31 @@ impl AccountsDb {
49434949
ancestors: &Ancestors,
49444950
account: &Pubkey,
49454951
owners: &[&Pubkey],
4946-
) -> Option<bool> {
4947-
let (slot, storage_location, _maybe_account_accesor) =
4948-
self.read_index_for_accessor_or_load_slow(ancestors, account, None, false)?;
4952+
) -> Result<(), MatchAccountOwnerError> {
4953+
let (slot, storage_location, _maybe_account_accesor) = self
4954+
.read_index_for_accessor_or_load_slow(ancestors, account, None, false)
4955+
.ok_or(MatchAccountOwnerError::UnableToLoad)?;
49494956

49504957
if !storage_location.is_cached() {
49514958
let result = self.read_only_accounts_cache.load(*account, slot);
49524959
if let Some(account) = result {
4953-
return Some(owners.contains(&account.owner()));
4960+
return owners
4961+
.contains(&account.owner())
4962+
.then_some(())
4963+
.ok_or(MatchAccountOwnerError::NoMatch);
49544964
}
49554965
}
49564966

4957-
let (account_accessor, _slot) = self.retry_to_get_account_accessor(
4958-
slot,
4959-
storage_location,
4960-
ancestors,
4961-
account,
4962-
None,
4963-
LoadHint::Unspecified,
4964-
)?;
4967+
let (account_accessor, _slot) = self
4968+
.retry_to_get_account_accessor(
4969+
slot,
4970+
storage_location,
4971+
ancestors,
4972+
account,
4973+
None,
4974+
LoadHint::Unspecified,
4975+
)
4976+
.ok_or(MatchAccountOwnerError::UnableToLoad)?;
49654977
account_accessor.account_matches_owners(owners)
49664978
}
49674979

@@ -14150,19 +14162,19 @@ pub mod tests {
1415014162

1415114163
assert_eq!(
1415214164
db.account_matches_owners(&Ancestors::default(), &account1_key, &owners_refs),
14153-
Some(true)
14165+
Ok(())
1415414166
);
1415514167
assert_eq!(
1415614168
db.account_matches_owners(&Ancestors::default(), &account2_key, &owners_refs),
14157-
Some(true)
14169+
Ok(())
1415814170
);
1415914171
assert_eq!(
1416014172
db.account_matches_owners(&Ancestors::default(), &account3_key, &owners_refs),
14161-
Some(false)
14173+
Err(MatchAccountOwnerError::NoMatch)
1416214174
);
1416314175
assert_eq!(
1416414176
db.account_matches_owners(&Ancestors::default(), &Pubkey::new_unique(), &owners_refs),
14165-
None
14177+
Err(MatchAccountOwnerError::UnableToLoad)
1416614178
);
1416714179

1416814180
// Flush the cache and load account1 (so that it's in the cache)
@@ -14180,19 +14192,19 @@ pub mod tests {
1418014192

1418114193
assert_eq!(
1418214194
db.account_matches_owners(&Ancestors::default(), &account1_key, &owners_refs),
14183-
Some(true)
14195+
Ok(())
1418414196
);
1418514197
assert_eq!(
1418614198
db.account_matches_owners(&Ancestors::default(), &account2_key, &owners_refs),
14187-
Some(true)
14199+
Ok(())
1418814200
);
1418914201
assert_eq!(
1419014202
db.account_matches_owners(&Ancestors::default(), &account3_key, &owners_refs),
14191-
Some(false)
14203+
Err(MatchAccountOwnerError::NoMatch)
1419214204
);
1419314205
assert_eq!(
1419414206
db.account_matches_owners(&Ancestors::default(), &Pubkey::new_unique(), &owners_refs),
14195-
None
14207+
Err(MatchAccountOwnerError::UnableToLoad)
1419614208
);
1419714209
}
1419814210

runtime/src/append_vec.rs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use {
2828
Mutex,
2929
},
3030
},
31+
thiserror::Error,
3132
};
3233

3334
pub mod test_utils;
@@ -270,6 +271,14 @@ impl<'a> Iterator for AppendVecAccountsIter<'a> {
270271
}
271272
}
272273

274+
#[derive(Error, Debug, PartialEq, Eq)]
275+
pub enum MatchAccountOwnerError {
276+
#[error("The account owner does not match with the provided list")]
277+
NoMatch,
278+
#[error("Unable to load the account")]
279+
UnableToLoad,
280+
}
281+
273282
/// A thread-safe, file-backed block of memory used to store `Account` instances. Append operations
274283
/// are serialized such that only one thread updates the internal `append_lock` at a time. No
275284
/// restrictions are placed on reading. That is, one may read items from one thread while another
@@ -594,17 +603,30 @@ impl AppendVec {
594603
))
595604
}
596605

597-
/// Return Some(true) if the account owner at `offset` is one of the pubkeys in `owners`.
598-
/// Return Some(false) if the account owner is not one of the pubkeys in `owners`.
599-
/// It returns None if the `offset` value causes a data overrun.
600-
pub fn account_matches_owners(&self, offset: usize, owners: &[&Pubkey]) -> Option<bool> {
606+
fn get_account_meta<'a>(&'a self, offset: usize) -> Option<&'a AccountMeta> {
601607
// Skip over StoredMeta data in the account
602608
let offset = offset.checked_add(mem::size_of::<StoredMeta>())?;
603609
// u64_align! does an unchecked add for alignment. Check that it won't cause an overflow.
604610
offset.checked_add(ALIGN_BOUNDARY_OFFSET - 1)?;
605611
let (account_meta, _): (&AccountMeta, _) = self.get_type(u64_align!(offset))?;
612+
Some(account_meta)
613+
}
606614

607-
Some(owners.contains(&&account_meta.owner))
615+
/// Return Some(true) if the account owner at `offset` is one of the pubkeys in `owners`.
616+
/// Return Some(false) if the account owner is not one of the pubkeys in `owners`.
617+
/// It returns None if the `offset` value causes a data overrun.
618+
pub fn account_matches_owners(
619+
&self,
620+
offset: usize,
621+
owners: &[&Pubkey],
622+
) -> Result<(), MatchAccountOwnerError> {
623+
let account_meta = self
624+
.get_account_meta(offset)
625+
.ok_or(MatchAccountOwnerError::UnableToLoad)?;
626+
owners
627+
.contains(&&account_meta.owner)
628+
.then_some(())
629+
.ok_or(MatchAccountOwnerError::NoMatch)
608630
}
609631

610632
#[cfg(test)]
@@ -1070,31 +1092,34 @@ pub mod tests {
10701092
let mut account = create_test_account(5);
10711093
account.1.set_owner(owners[0]);
10721094
let index = av.append_account_test(&account).unwrap();
1073-
assert_eq!(av.account_matches_owners(index, &owners_refs), Some(true));
1095+
assert_eq!(av.account_matches_owners(index, &owners_refs), Ok(()));
10741096

10751097
let mut account1 = create_test_account(6);
10761098
account1.1.set_owner(owners[1]);
10771099
let index1 = av.append_account_test(&account1).unwrap();
1078-
assert_eq!(av.account_matches_owners(index1, &owners_refs), Some(true));
1079-
assert_eq!(av.account_matches_owners(index, &owners_refs), Some(true));
1100+
assert_eq!(av.account_matches_owners(index1, &owners_refs), Ok(()));
1101+
assert_eq!(av.account_matches_owners(index, &owners_refs), Ok(()));
10801102

10811103
let mut account2 = create_test_account(6);
10821104
account2.1.set_owner(Pubkey::new_unique());
10831105
let index2 = av.append_account_test(&account2).unwrap();
1084-
assert_eq!(av.account_matches_owners(index2, &owners_refs), Some(false));
1106+
assert_eq!(
1107+
av.account_matches_owners(index2, &owners_refs),
1108+
Err(MatchAccountOwnerError::NoMatch)
1109+
);
10851110

10861111
// tests for overflow
10871112
assert_eq!(
10881113
av.account_matches_owners(usize::MAX - mem::size_of::<StoredMeta>(), &owners_refs),
1089-
None
1114+
Err(MatchAccountOwnerError::UnableToLoad)
10901115
);
10911116

10921117
assert_eq!(
10931118
av.account_matches_owners(
10941119
usize::MAX - mem::size_of::<StoredMeta>() - mem::size_of::<AccountMeta>() + 1,
10951120
&owners_refs
10961121
),
1097-
None
1122+
Err(MatchAccountOwnerError::UnableToLoad)
10981123
);
10991124
}
11001125

0 commit comments

Comments
 (0)