Make program owners a const array instead of Vec<_> (#33275)

The program owners pubkeys are constant, no need to reconstruct the
Vec<Pubkey> and Vec<&Pubkey> each time this function runs (every time we
execute transactions).
This commit is contained in:
steviez 2023-09-18 10:59:03 -05:00 committed by GitHub
parent fe598a9273
commit 9e11ae6275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 32 deletions

View File

@ -648,7 +648,7 @@ impl Accounts {
ancestors: &Ancestors, ancestors: &Ancestors,
txs: &[SanitizedTransaction], txs: &[SanitizedTransaction],
lock_results: &mut [TransactionCheckResult], lock_results: &mut [TransactionCheckResult],
program_owners: &[&'a Pubkey], program_owners: &'a [Pubkey],
hash_queue: &BlockhashQueue, hash_queue: &BlockhashQueue,
) -> HashMap<Pubkey, (&'a Pubkey, u64)> { ) -> HashMap<Pubkey, (&'a Pubkey, u64)> {
let mut result: HashMap<Pubkey, (&'a Pubkey, u64)> = HashMap::new(); let mut result: HashMap<Pubkey, (&'a Pubkey, u64)> = HashMap::new();
@ -678,7 +678,7 @@ impl Accounts {
) { ) {
program_owners program_owners
.get(index) .get(index)
.map(|owner| entry.insert((*owner, 1))); .map(|owner| entry.insert((owner, 1)));
} }
} }
}); });
@ -2090,11 +2090,12 @@ mod tests {
let sanitized_tx2 = SanitizedTransaction::from_transaction_for_tests(tx2); let sanitized_tx2 = SanitizedTransaction::from_transaction_for_tests(tx2);
let ancestors = vec![(0, 0)].into_iter().collect(); let ancestors = vec![(0, 0)].into_iter().collect();
let owners = &[program1_pubkey, program2_pubkey];
let programs = accounts.filter_executable_program_accounts( let programs = accounts.filter_executable_program_accounts(
&ancestors, &ancestors,
&[sanitized_tx1, sanitized_tx2], &[sanitized_tx1, sanitized_tx2],
&mut [(Ok(()), None), (Ok(()), None)], &mut [(Ok(()), None), (Ok(()), None)],
&[&program1_pubkey, &program2_pubkey], owners,
&hash_queue, &hash_queue,
); );
@ -2198,12 +2199,13 @@ mod tests {
let sanitized_tx2 = SanitizedTransaction::from_transaction_for_tests(tx2); let sanitized_tx2 = SanitizedTransaction::from_transaction_for_tests(tx2);
let ancestors = vec![(0, 0)].into_iter().collect(); let ancestors = vec![(0, 0)].into_iter().collect();
let owners = &[program1_pubkey, program2_pubkey];
let mut lock_results = vec![(Ok(()), None), (Ok(()), None)]; let mut lock_results = vec![(Ok(()), None), (Ok(()), None)];
let programs = accounts.filter_executable_program_accounts( let programs = accounts.filter_executable_program_accounts(
&ancestors, &ancestors,
&[sanitized_tx1, sanitized_tx2], &[sanitized_tx1, sanitized_tx2],
&mut lock_results, &mut lock_results,
&[&program1_pubkey, &program2_pubkey], owners,
&hash_queue, &hash_queue,
); );

View File

@ -865,7 +865,7 @@ impl<'a> LoadedAccountAccessor<'a> {
} }
} }
fn account_matches_owners(&self, owners: &[&Pubkey]) -> Result<usize, MatchAccountOwnerError> { fn account_matches_owners(&self, owners: &[Pubkey]) -> Result<usize, MatchAccountOwnerError> {
match self { match self {
LoadedAccountAccessor::Cached(cached_account) => cached_account LoadedAccountAccessor::Cached(cached_account) => cached_account
.as_ref() .as_ref()
@ -875,7 +875,7 @@ impl<'a> LoadedAccountAccessor<'a> {
} else { } else {
owners owners
.iter() .iter()
.position(|entry| &cached_account.account.owner() == entry) .position(|entry| cached_account.account.owner() == entry)
} }
}) })
.ok_or(MatchAccountOwnerError::NoMatch), .ok_or(MatchAccountOwnerError::NoMatch),
@ -5074,7 +5074,7 @@ impl AccountsDb {
&self, &self,
ancestors: &Ancestors, ancestors: &Ancestors,
account: &Pubkey, account: &Pubkey,
owners: &[&Pubkey], owners: &[Pubkey],
) -> Result<usize, MatchAccountOwnerError> { ) -> Result<usize, MatchAccountOwnerError> {
let (slot, storage_location, _maybe_account_accesor) = self let (slot, storage_location, _maybe_account_accesor) = self
.read_index_for_accessor_or_load_slow(ancestors, account, None, false) .read_index_for_accessor_or_load_slow(ancestors, account, None, false)
@ -5088,7 +5088,7 @@ impl AccountsDb {
} else { } else {
owners owners
.iter() .iter()
.position(|entry| &account.owner() == entry) .position(|entry| account.owner() == entry)
.ok_or(MatchAccountOwnerError::NoMatch) .ok_or(MatchAccountOwnerError::NoMatch)
}; };
} }
@ -14092,7 +14092,6 @@ pub mod tests {
)); ));
let owners: Vec<Pubkey> = (0..2).map(|_| Pubkey::new_unique()).collect(); let owners: Vec<Pubkey> = (0..2).map(|_| Pubkey::new_unique()).collect();
let owners_refs: Vec<&Pubkey> = owners.iter().collect();
let account1_key = Pubkey::new_unique(); let account1_key = Pubkey::new_unique();
let account1 = AccountSharedData::new(321, 10, &owners[0]); let account1 = AccountSharedData::new(321, 10, &owners[0]);
@ -14122,23 +14121,23 @@ pub mod tests {
db.clean_accounts_for_tests(); db.clean_accounts_for_tests();
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &account1_key, &owners_refs), db.account_matches_owners(&Ancestors::default(), &account1_key, &owners),
Ok(0) Ok(0)
); );
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &account2_key, &owners_refs), db.account_matches_owners(&Ancestors::default(), &account2_key, &owners),
Ok(1) Ok(1)
); );
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &account3_key, &owners_refs), db.account_matches_owners(&Ancestors::default(), &account3_key, &owners),
Err(MatchAccountOwnerError::NoMatch) Err(MatchAccountOwnerError::NoMatch)
); );
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &account4_key, &owners_refs), db.account_matches_owners(&Ancestors::default(), &account4_key, &owners),
Err(MatchAccountOwnerError::NoMatch) Err(MatchAccountOwnerError::NoMatch)
); );
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &Pubkey::new_unique(), &owners_refs), db.account_matches_owners(&Ancestors::default(), &Pubkey::new_unique(), &owners),
Err(MatchAccountOwnerError::UnableToLoad) Err(MatchAccountOwnerError::UnableToLoad)
); );
@ -14156,23 +14155,23 @@ pub mod tests {
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &account1_key, &owners_refs), db.account_matches_owners(&Ancestors::default(), &account1_key, &owners),
Ok(0) Ok(0)
); );
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &account2_key, &owners_refs), db.account_matches_owners(&Ancestors::default(), &account2_key, &owners),
Ok(1) Ok(1)
); );
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &account3_key, &owners_refs), db.account_matches_owners(&Ancestors::default(), &account3_key, &owners),
Err(MatchAccountOwnerError::NoMatch) Err(MatchAccountOwnerError::NoMatch)
); );
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &account4_key, &owners_refs), db.account_matches_owners(&Ancestors::default(), &account4_key, &owners),
Err(MatchAccountOwnerError::NoMatch) Err(MatchAccountOwnerError::NoMatch)
); );
assert_eq!( assert_eq!(
db.account_matches_owners(&Ancestors::default(), &Pubkey::new_unique(), &owners_refs), db.account_matches_owners(&Ancestors::default(), &Pubkey::new_unique(), &owners),
Err(MatchAccountOwnerError::UnableToLoad) Err(MatchAccountOwnerError::UnableToLoad)
); );
} }

View File

@ -116,7 +116,7 @@ impl AccountsFile {
pub fn account_matches_owners( pub fn account_matches_owners(
&self, &self,
offset: usize, offset: usize,
owners: &[&Pubkey], owners: &[Pubkey],
) -> std::result::Result<usize, MatchAccountOwnerError> { ) -> std::result::Result<usize, MatchAccountOwnerError> {
match self { match self {
Self::AppendVec(av) => av.account_matches_owners(offset, owners), Self::AppendVec(av) => av.account_matches_owners(offset, owners),

View File

@ -519,7 +519,7 @@ impl AppendVec {
pub fn account_matches_owners( pub fn account_matches_owners(
&self, &self,
offset: usize, offset: usize,
owners: &[&Pubkey], owners: &[Pubkey],
) -> std::result::Result<usize, MatchAccountOwnerError> { ) -> std::result::Result<usize, MatchAccountOwnerError> {
let account_meta = self let account_meta = self
.get_account_meta(offset) .get_account_meta(offset)
@ -529,7 +529,7 @@ impl AppendVec {
} else { } else {
owners owners
.iter() .iter()
.position(|entry| &&account_meta.owner == entry) .position(|entry| &account_meta.owner == entry)
.ok_or(MatchAccountOwnerError::NoMatch) .ok_or(MatchAccountOwnerError::NoMatch)
} }
} }
@ -1022,37 +1022,36 @@ pub mod tests {
let path = get_append_vec_path("test_append_data"); let path = get_append_vec_path("test_append_data");
let av = AppendVec::new(&path.path, true, 1024 * 1024); let av = AppendVec::new(&path.path, true, 1024 * 1024);
let owners: Vec<Pubkey> = (0..2).map(|_| Pubkey::new_unique()).collect(); let owners: Vec<Pubkey> = (0..2).map(|_| Pubkey::new_unique()).collect();
let owners_refs: Vec<&Pubkey> = owners.iter().collect();
let mut account = create_test_account(5); let mut account = create_test_account(5);
account.1.set_owner(owners[0]); account.1.set_owner(owners[0]);
let index = av.append_account_test(&account).unwrap(); let index = av.append_account_test(&account).unwrap();
assert_eq!(av.account_matches_owners(index, &owners_refs), Ok(0)); assert_eq!(av.account_matches_owners(index, &owners), Ok(0));
let mut account1 = create_test_account(6); let mut account1 = create_test_account(6);
account1.1.set_owner(owners[1]); account1.1.set_owner(owners[1]);
let index1 = av.append_account_test(&account1).unwrap(); let index1 = av.append_account_test(&account1).unwrap();
assert_eq!(av.account_matches_owners(index1, &owners_refs), Ok(1)); assert_eq!(av.account_matches_owners(index1, &owners), Ok(1));
assert_eq!(av.account_matches_owners(index, &owners_refs), Ok(0)); assert_eq!(av.account_matches_owners(index, &owners), Ok(0));
let mut account2 = create_test_account(6); let mut account2 = create_test_account(6);
account2.1.set_owner(Pubkey::new_unique()); account2.1.set_owner(Pubkey::new_unique());
let index2 = av.append_account_test(&account2).unwrap(); let index2 = av.append_account_test(&account2).unwrap();
assert_eq!( assert_eq!(
av.account_matches_owners(index2, &owners_refs), av.account_matches_owners(index2, &owners),
Err(MatchAccountOwnerError::NoMatch) Err(MatchAccountOwnerError::NoMatch)
); );
// tests for overflow // tests for overflow
assert_eq!( assert_eq!(
av.account_matches_owners(usize::MAX - mem::size_of::<StoredMeta>(), &owners_refs), av.account_matches_owners(usize::MAX - mem::size_of::<StoredMeta>(), &owners),
Err(MatchAccountOwnerError::UnableToLoad) Err(MatchAccountOwnerError::UnableToLoad)
); );
assert_eq!( assert_eq!(
av.account_matches_owners( av.account_matches_owners(
usize::MAX - mem::size_of::<StoredMeta>() - mem::size_of::<AccountMeta>() + 1, usize::MAX - mem::size_of::<StoredMeta>() - mem::size_of::<AccountMeta>() + 1,
&owners_refs &owners
), ),
Err(MatchAccountOwnerError::UnableToLoad) Err(MatchAccountOwnerError::UnableToLoad)
); );

View File

@ -5116,18 +5116,17 @@ impl Bank {
); );
check_time.stop(); check_time.stop();
let program_owners: Vec<Pubkey> = vec![ const PROGRAM_OWNERS: &[Pubkey] = &[
bpf_loader_upgradeable::id(), bpf_loader_upgradeable::id(),
bpf_loader::id(), bpf_loader::id(),
bpf_loader_deprecated::id(), bpf_loader_deprecated::id(),
loader_v4::id(), loader_v4::id(),
]; ];
let program_owners_refs: Vec<&Pubkey> = program_owners.iter().collect();
let mut program_accounts_map = self.rc.accounts.filter_executable_program_accounts( let mut program_accounts_map = self.rc.accounts.filter_executable_program_accounts(
&self.ancestors, &self.ancestors,
sanitized_txs, sanitized_txs,
&mut check_results, &mut check_results,
&program_owners_refs, PROGRAM_OWNERS,
&self.blockhash_queue.read().unwrap(), &self.blockhash_queue.read().unwrap(),
); );
let native_loader = native_loader::id(); let native_loader = native_loader::id();