Allow passing of program_ids to programs (#8639)
This commit is contained in:
parent
0e3a8fa6d9
commit
97c5fb8141
|
@ -127,17 +127,13 @@ impl Accounts {
|
|||
// If a fee can pay for execution then the program will be scheduled
|
||||
let mut accounts: TransactionAccounts = Vec::with_capacity(message.account_keys.len());
|
||||
let mut tx_rent: TransactionRent = 0;
|
||||
for (i, key) in message
|
||||
.account_keys
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, key)| !message.program_ids().contains(key))
|
||||
{
|
||||
for (i, key) in message.account_keys.iter().enumerate().filter(|(i, key)| {
|
||||
!message.program_ids().contains(key) || message.is_key_passed_to_program(*i)
|
||||
}) {
|
||||
let (account, rent) = AccountsDB::load(storage, ancestors, accounts_index, key)
|
||||
.and_then(|(mut account, _)| {
|
||||
let rent_due: u64;
|
||||
if message.is_writable(i) {
|
||||
rent_due = rent_collector.update(&mut account);
|
||||
if message.is_writable(i) && !account.executable {
|
||||
let rent_due = rent_collector.update(&mut account);
|
||||
Some((account, rent_due))
|
||||
} else {
|
||||
Some((account, 0))
|
||||
|
@ -1125,12 +1121,12 @@ mod tests {
|
|||
|
||||
let loaded_accounts = load_accounts(tx, &accounts, &mut error_counters);
|
||||
|
||||
assert_eq!(error_counters.invalid_account_for_fee, 1);
|
||||
assert_eq!(error_counters.account_not_found, 1);
|
||||
assert_eq!(loaded_accounts.len(), 1);
|
||||
assert_eq!(
|
||||
loaded_accounts[0],
|
||||
(
|
||||
Err(TransactionError::InvalidAccountForFee),
|
||||
Err(TransactionError::AccountNotFound),
|
||||
Some(HashAgeKind::Extant)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -5568,7 +5568,6 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "index out of bounds: the len is 3 but the index is 3")]
|
||||
fn test_transaction_with_program_ids_passed_to_programs() {
|
||||
let (genesis_config, mint_keypair) = create_genesis_config(500);
|
||||
let mut bank = Bank::new(&genesis_config);
|
||||
|
|
|
@ -332,10 +332,6 @@ impl MessageProcessor {
|
|||
.ok_or(TransactionError::InvalidAccountIndex)?;
|
||||
let executable_accounts = &loaders[executable_index];
|
||||
|
||||
// TODO: panics on an index out of bounds if an executable
|
||||
// account is also included as a regular account for an instruction, because the
|
||||
// executable account is not passed in as part of the accounts slice
|
||||
// See test: bank::tests::test_transaction_with_program_ids_passed_to_programs
|
||||
let program_accounts: Vec<_> = instruction
|
||||
.accounts
|
||||
.iter()
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::{
|
|||
short_vec, system_instruction,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
fn position(keys: &[Pubkey], key: &Pubkey) -> u8 {
|
||||
keys.iter().position(|k| k == key).unwrap() as u8
|
||||
|
@ -233,6 +234,17 @@ impl Message {
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub fn is_key_passed_to_program(&self, index: usize) -> bool {
|
||||
if let Ok(index) = u8::try_from(index) {
|
||||
for ix in self.instructions.iter() {
|
||||
if ix.accounts.contains(&index) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn program_position(&self, index: usize) -> Option<usize> {
|
||||
let program_ids = self.program_ids();
|
||||
program_ids
|
||||
|
|
Loading…
Reference in New Issue