Optimize Message::is_non_loader_key method (#18579)
This commit is contained in:
parent
12aa238eb1
commit
e806d31224
@ -201,7 +201,7 @@ pub fn write_transaction<W: io::Write>(
|
|||||||
}
|
}
|
||||||
let mut fee_payer_index = None;
|
let mut fee_payer_index = None;
|
||||||
for (account_index, account) in message.account_keys.iter().enumerate() {
|
for (account_index, account) in message.account_keys.iter().enumerate() {
|
||||||
if fee_payer_index.is_none() && message.is_non_loader_key(account, account_index) {
|
if fee_payer_index.is_none() && message.is_non_loader_key(account_index) {
|
||||||
fee_payer_index = Some(account_index)
|
fee_payer_index = Some(account_index)
|
||||||
}
|
}
|
||||||
writeln!(
|
writeln!(
|
||||||
|
@ -28,7 +28,7 @@ use solana_sdk::{
|
|||||||
fee_calculator::FeeCalculator,
|
fee_calculator::FeeCalculator,
|
||||||
genesis_config::ClusterType,
|
genesis_config::ClusterType,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
message::{Message, MessageProgramIdsCache},
|
message::Message,
|
||||||
native_loader, nonce,
|
native_loader, nonce,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
transaction::Result,
|
transaction::Result,
|
||||||
@ -208,12 +208,11 @@ impl Accounts {
|
|||||||
let mut tx_rent: TransactionRent = 0;
|
let mut tx_rent: TransactionRent = 0;
|
||||||
let mut accounts = Vec::with_capacity(message.account_keys.len());
|
let mut accounts = Vec::with_capacity(message.account_keys.len());
|
||||||
let mut account_deps = Vec::with_capacity(message.account_keys.len());
|
let mut account_deps = Vec::with_capacity(message.account_keys.len());
|
||||||
let mut key_check = MessageProgramIdsCache::new(message);
|
|
||||||
let mut rent_debits = RentDebits::default();
|
let mut rent_debits = RentDebits::default();
|
||||||
let rent_for_sysvars = feature_set.is_active(&feature_set::rent_for_sysvars::id());
|
let rent_for_sysvars = feature_set.is_active(&feature_set::rent_for_sysvars::id());
|
||||||
|
|
||||||
for (i, key) in message.account_keys.iter().enumerate() {
|
for (i, key) in message.account_keys.iter().enumerate() {
|
||||||
let account = if key_check.is_non_loader_key(key, i) {
|
let account = if message.is_non_loader_key(i) {
|
||||||
if payer_index.is_none() {
|
if payer_index.is_none() {
|
||||||
payer_index = Some(i);
|
payer_index = Some(i);
|
||||||
}
|
}
|
||||||
@ -981,7 +980,7 @@ impl Accounts {
|
|||||||
let mut fee_payer_index = None;
|
let mut fee_payer_index = None;
|
||||||
for (i, (key, account)) in (0..message.account_keys.len())
|
for (i, (key, account)) in (0..message.account_keys.len())
|
||||||
.zip(loaded_transaction.accounts.iter_mut())
|
.zip(loaded_transaction.accounts.iter_mut())
|
||||||
.filter(|(i, (key, _account))| message.is_non_loader_key(key, *i))
|
.filter(|(i, _account)| message.is_non_loader_key(*i))
|
||||||
{
|
{
|
||||||
let is_nonce_account = prepare_if_nonce_account(
|
let is_nonce_account = prepare_if_nonce_account(
|
||||||
account,
|
account,
|
||||||
|
@ -632,7 +632,7 @@ impl NonceRollbackFull {
|
|||||||
} = partial;
|
} = partial;
|
||||||
let fee_payer = (0..message.account_keys.len()).find_map(|i| {
|
let fee_payer = (0..message.account_keys.len()).find_map(|i| {
|
||||||
if let Some((k, a)) = &accounts.get(i) {
|
if let Some((k, a)) = &accounts.get(i) {
|
||||||
if message.is_non_loader_key(k, i) {
|
if message.is_non_loader_key(i) {
|
||||||
return Some((k, a));
|
return Some((k, a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,26 +240,6 @@ impl Sanitize for Message {
|
|||||||
Ok(())
|
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 {
|
impl Message {
|
||||||
pub fn new_with_compiled_instructions(
|
pub fn new_with_compiled_instructions(
|
||||||
@ -356,28 +336,28 @@ impl Message {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_key_passed_to_program(&self, index: usize) -> bool {
|
pub fn is_key_passed_to_program(&self, key_index: usize) -> bool {
|
||||||
if let Ok(index) = u8::try_from(index) {
|
if let Ok(key_index) = u8::try_from(key_index) {
|
||||||
for ix in self.instructions.iter() {
|
self.instructions
|
||||||
if ix.accounts.contains(&index) {
|
.iter()
|
||||||
return true;
|
.any(|ix| ix.accounts.contains(&key_index))
|
||||||
}
|
} else {
|
||||||
}
|
false
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_non_loader_key_internal(
|
pub fn is_key_called_as_program(&self, key_index: usize) -> bool {
|
||||||
&self,
|
if let Ok(key_index) = u8::try_from(key_index) {
|
||||||
program_ids: &[&Pubkey],
|
self.instructions
|
||||||
key: &Pubkey,
|
.iter()
|
||||||
key_index: usize,
|
.any(|ix| ix.program_id_index == key_index)
|
||||||
) -> bool {
|
} else {
|
||||||
!program_ids.contains(&key) || self.is_key_passed_to_program(key_index)
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_non_loader_key(&self, key: &Pubkey, key_index: usize) -> bool {
|
pub fn is_non_loader_key(&self, key_index: usize) -> bool {
|
||||||
self.is_non_loader_key_internal(&self.program_ids(), key, key_index)
|
!self.is_key_called_as_program(key_index) || self.is_key_passed_to_program(key_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn program_position(&self, index: usize) -> Option<usize> {
|
pub fn program_position(&self, index: usize) -> Option<usize> {
|
||||||
@ -1029,14 +1009,9 @@ mod tests {
|
|||||||
Hash::default(),
|
Hash::default(),
|
||||||
instructions,
|
instructions,
|
||||||
);
|
);
|
||||||
let mut helper = MessageProgramIdsCache::new(&message);
|
assert!(message.is_non_loader_key(0));
|
||||||
|
assert!(message.is_non_loader_key(1));
|
||||||
assert!(message.is_non_loader_key(&key0, 0));
|
assert!(!message.is_non_loader_key(2));
|
||||||
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]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user