reuse work in is_non_loader_key (#16521)

This commit is contained in:
Jeff Washington (jwash) 2021-05-21 10:07:04 -05:00 committed by GitHub
parent 8143ee5502
commit 44831c18d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 4 deletions

View File

@ -26,7 +26,7 @@ use solana_sdk::{
fee_calculator::{FeeCalculator, FeeConfig},
genesis_config::ClusterType,
hash::Hash,
message::Message,
message::{Message, MessageProgramIdsCache},
native_loader, nonce,
pubkey::Pubkey,
transaction::Result,
@ -205,9 +205,9 @@ impl Accounts {
let mut account_deps = Vec::with_capacity(message.account_keys.len());
let demote_sysvar_write_locks =
feature_set.is_active(&feature_set::demote_sysvar_write_locks::id());
let mut key_check = MessageProgramIdsCache::new(&message);
for (i, key) in message.account_keys.iter().enumerate() {
let account = if message.is_non_loader_key(key, i) {
let account = if key_check.is_non_loader_key(key, i) {
if payer_index.is_none() {
payer_index = Some(i);
}

View File

@ -240,6 +240,26 @@ impl Sanitize for Message {
Ok(())
}
}
pub struct MessageProgramIdsCache<'a> {
program_ids: Option<Vec<&'a Pubkey>>,
message: &'a Message,
}
impl<'a> MessageProgramIdsCache<'a> {
pub fn new(message: &'a Message) -> Self {
Self {
program_ids: None,
message,
}
}
pub fn is_non_loader_key(&mut self, key: &Pubkey, key_index: usize) -> bool {
if self.program_ids.is_none() {
self.program_ids = Some(self.message.program_ids());
}
self.message
.is_non_loader_key_internal(self.program_ids.as_ref().unwrap(), key, key_index)
}
}
impl Message {
pub fn new_with_compiled_instructions(
@ -349,8 +369,17 @@ impl Message {
false
}
pub(crate) fn is_non_loader_key_internal(
&self,
program_ids: &[&Pubkey],
key: &Pubkey,
key_index: usize,
) -> bool {
!program_ids.contains(&key) || self.is_key_passed_to_program(key_index)
}
pub fn is_non_loader_key(&self, key: &Pubkey, key_index: usize) -> bool {
!self.program_ids().contains(&key) || self.is_key_passed_to_program(key_index)
self.is_non_loader_key_internal(&self.program_ids(), key, key_index)
}
pub fn program_position(&self, index: usize) -> Option<usize> {
@ -1013,10 +1042,14 @@ mod tests {
Hash::default(),
instructions,
);
let mut helper = MessageProgramIdsCache::new(&message);
assert!(message.is_non_loader_key(&key0, 0));
assert!(message.is_non_loader_key(&key1, 1));
assert!(!message.is_non_loader_key(&loader2, 2));
assert!(helper.is_non_loader_key(&key0, 0));
assert!(helper.is_non_loader_key(&key1, 1));
assert!(!helper.is_non_loader_key(&loader2, 2));
}
#[test]