speedup sysvar or builtin test (#25047)

* Add a quick lookup table to speed up sysvar/builtin key check

* Fix up the syntax

* Fix syntax

* Fix syntax 2

* Rename the static variable, improve commenting

* Fix merge error

* Fixed two clippy suggestions

* Improved commenting
This commit is contained in:
Jason 2022-05-10 10:37:51 -05:00 committed by GitHub
parent 6cfa19e2e4
commit c80896b58f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 12 deletions

View File

@ -44,6 +44,27 @@ lazy_static! {
};
}
lazy_static! {
// Each element of a key is a u8. We use key[0] as an index into this table of 256 boolean
// elements, to store whether or not the first element of any key is present in the static
// lists of built-in-program keys or system ids. By using this lookup table, we can very
// quickly determine that a key under consideration cannot be in either of these lists (if
// the value is "false"), or might be in one of these lists (if the value is "true")
pub static ref MAYBE_BUILTIN_KEY_OR_SYSVAR: [bool; 256] = {
let mut temp_table: [bool; 256] = [false; 256];
BUILTIN_PROGRAMS_KEYS.iter().for_each(|key| temp_table[key.0[0] as usize] = true);
sysvar::ALL_IDS.iter().for_each(|key| temp_table[key.0[0] as usize] = true);
temp_table
};
}
pub fn is_builtin_key_or_sysvar(key: &Pubkey) -> bool {
if MAYBE_BUILTIN_KEY_OR_SYSVAR[key.0[0] as usize] {
return sysvar::is_sysvar_id(key) || BUILTIN_PROGRAMS_KEYS.contains(key);
}
false
}
fn position(keys: &[Pubkey], key: &Pubkey) -> u8 {
keys.iter().position(|k| k == key).unwrap() as u8
}
@ -530,10 +551,7 @@ impl Message {
|| (i >= self.header.num_required_signatures as usize
&& i < self.account_keys.len()
- self.header.num_readonly_unsigned_accounts as usize))
&& !{
let key = self.account_keys[i];
sysvar::is_sysvar_id(&key) || BUILTIN_PROGRAMS_KEYS.contains(&key)
}
&& !is_builtin_key_or_sysvar(&self.account_keys[i])
&& !self.demote_program_id(i)
}

View File

@ -1,9 +1,8 @@
use {
crate::{
bpf_loader_upgradeable,
message::{legacy::BUILTIN_PROGRAMS_KEYS, v0, AccountKeys},
message::{legacy::is_builtin_key_or_sysvar, v0, AccountKeys},
pubkey::Pubkey,
sysvar,
},
std::{borrow::Cow, collections::HashSet},
};
@ -109,9 +108,7 @@ impl<'a> LoadedMessage<'a> {
pub fn is_writable(&self, key_index: usize) -> bool {
if self.is_writable_index(key_index) {
if let Some(key) = self.account_keys().get(key_index) {
return !(sysvar::is_sysvar_id(key)
|| BUILTIN_PROGRAMS_KEYS.contains(key)
|| self.demote_program_id(key_index));
return !(is_builtin_key_or_sysvar(key) || self.demote_program_id(key_index));
}
}
false

View File

@ -15,12 +15,12 @@ use crate::{
hash::Hash,
instruction::{CompiledInstruction, Instruction},
message::{
compiled_keys::CompileError, legacy::BUILTIN_PROGRAMS_KEYS, AccountKeys, CompiledKeys,
compiled_keys::CompileError, legacy::is_builtin_key_or_sysvar, AccountKeys, CompiledKeys,
MessageHeader, MESSAGE_VERSION_PREFIX,
},
pubkey::Pubkey,
sanitize::SanitizeError,
short_vec, sysvar,
short_vec,
};
pub use loaded::*;
@ -344,7 +344,7 @@ impl Message {
// demote reserved ids
self.account_keys
.get(key_index)
.map(|key| sysvar::is_sysvar_id(key) || BUILTIN_PROGRAMS_KEYS.contains(key))
.map(is_builtin_key_or_sysvar)
.unwrap_or_default()
}
&& !{