diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index 6e7b9e33e7..bb01626149 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -290,7 +290,7 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs { 'outer: for key in &message.account_keys { for account_info in account_infos { if account_info.unsigned_key() == key { - accounts.push(Rc::new(RefCell::new(ai_to_a(account_info)))); + accounts.push((*key, Rc::new(RefCell::new(ai_to_a(account_info))))); continue 'outer; } } @@ -336,14 +336,12 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs { .map_err(|err| ProgramError::try_from(err).unwrap_or_else(|err| panic!("{}", err)))?; // Copy writeable account modifications back into the caller's AccountInfos - for (i, account_pubkey) in message.account_keys.iter().enumerate() { + for (i, (pubkey, account)) in accounts.iter().enumerate().take(message.account_keys.len()) { if !message.is_writable(i, true) { continue; } - for account_info in account_infos { - if account_info.unsigned_key() == account_pubkey { - let account = &accounts[i]; + if account_info.unsigned_key() == pubkey { **account_info.try_borrow_mut_lamports().unwrap() = account.borrow().lamports(); let mut data = account_info.try_borrow_mut_data()?; diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 1b900e9b10..9ad7f9e259 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -1417,7 +1417,7 @@ type TranslatedAccount<'a> = ( Option>, ); type TranslatedAccounts<'a> = ( - Vec>>, + Vec<(Pubkey, Rc>)>, Vec>>, ); @@ -2062,7 +2062,7 @@ where if i == program_account_index || account.borrow().executable() { // Use the known account - accounts.push(account); + accounts.push((**account_key, account)); refs.push(None); } else if let Some(account_info) = account_info_keys @@ -2077,7 +2077,7 @@ where }) { let (account, account_ref) = do_translate(account_info, invoke_context)?; - accounts.push(account); + accounts.push((**account_key, account)); refs.push(account_ref); } else { ic_msg!( @@ -2266,6 +2266,7 @@ fn call<'a>( ic_msg!(invoke_context, "Unknown program {}", callee_program_id,); SyscallError::InstructionError(InstructionError::MissingAccount) })? + .1 .clone(); let programdata_executable = get_upgradeable_executable(&callee_program_id, &program_account, &invoke_context)?; @@ -2307,7 +2308,7 @@ fn call<'a>( // Copy results back to caller { let invoke_context = syscall.get_context()?; - for (i, (account, account_ref)) in accounts.iter().zip(account_refs).enumerate() { + for (i, ((_key, account), account_ref)) in accounts.iter().zip(account_refs).enumerate() { let account = account.borrow(); if let Some(mut account_ref) = account_ref { if message.is_writable(i, demote_sysvar_write_locks) && !account.executable() { diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index 0f4e4512ab..13d9917f3b 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -3096,15 +3096,21 @@ pub mod rpc_full { accounts.push(if result.is_err() { None } else { - transaction - .message - .account_keys - .iter() - .position(|pubkey| *pubkey == address) - .map(|i| post_simulation_accounts.get(i)) - .flatten() - .map(|account| { - UiAccount::encode(&address, account, accounts_encoding, None, None) + (0..transaction.message.account_keys.len()) + .position(|i| { + post_simulation_accounts + .get(i) + .map(|(key, _account)| *key == address) + .unwrap_or(false) + }) + .map(|i| { + UiAccount::encode( + &address, + &post_simulation_accounts[i].1, + accounts_encoding, + None, + None, + ) }) }); } diff --git a/runtime/src/accounts.rs b/runtime/src/accounts.rs index 651d249ec7..b521c81b9f 100644 --- a/runtime/src/accounts.rs +++ b/runtime/src/accounts.rs @@ -97,14 +97,12 @@ pub struct Accounts { } // for the load instructions -pub type TransactionAccounts = Vec; -pub type TransactionAccountDeps = Vec<(Pubkey, AccountSharedData)>; +pub type TransactionAccounts = Vec<(Pubkey, AccountSharedData)>; pub type TransactionRent = u64; pub type TransactionLoaders = Vec>; #[derive(PartialEq, Debug, Clone)] pub struct LoadedTransaction { pub accounts: TransactionAccounts, - pub account_deps: TransactionAccountDeps, pub loaders: TransactionLoaders, pub rent: TransactionRent, pub rent_debits: RentDebits, @@ -277,36 +275,43 @@ impl Accounts { // Fill in an empty account for the program slots. AccountSharedData::default() }; - accounts.push(account); + accounts.push((*key, account)); } debug_assert_eq!(accounts.len(), message.account_keys.len()); + // Appends the account_deps at the end of the accounts, + // this way they can be accessed in a uniform way. + // At places where only the accounts are needed, + // the account_deps are truncated using e.g: + // accounts.iter().take(message.account_keys.len()) + accounts.append(&mut account_deps); if let Some(payer_index) = payer_index { if payer_index != 0 { warn!("Payer index should be 0! {:?}", tx); } - if accounts[payer_index].lamports() == 0 { + let payer_account = &mut accounts[payer_index].1; + if payer_account.lamports() == 0 { error_counters.account_not_found += 1; Err(TransactionError::AccountNotFound) } else { - let min_balance = match get_system_account_kind(&accounts[payer_index]) - .ok_or_else(|| { + let min_balance = + match get_system_account_kind(payer_account).ok_or_else(|| { error_counters.invalid_account_for_fee += 1; TransactionError::InvalidAccountForFee })? { - SystemAccountKind::System => 0, - SystemAccountKind::Nonce => { - // Should we ever allow a fees charge to zero a nonce account's - // balance. The state MUST be set to uninitialized in that case - rent_collector.rent.minimum_balance(nonce::State::size()) - } - }; + SystemAccountKind::System => 0, + SystemAccountKind::Nonce => { + // Should we ever allow a fees charge to zero a nonce account's + // balance. The state MUST be set to uninitialized in that case + rent_collector.rent.minimum_balance(nonce::State::size()) + } + }; - if accounts[payer_index].lamports() < fee + min_balance { + if payer_account.lamports() < fee + min_balance { error_counters.insufficient_funds += 1; Err(TransactionError::InsufficientFundsForFee) } else { - accounts[payer_index] + payer_account .checked_sub_lamports(fee) .map_err(|_| TransactionError::InsufficientFundsForFee)?; @@ -329,7 +334,6 @@ impl Accounts { .collect::>()?; Ok(LoadedTransaction { accounts, - account_deps, loaders, rent: tx_rent, rent_debits, @@ -992,12 +996,9 @@ impl Accounts { let message = &tx.message(); let loaded_transaction = raccs.as_mut().unwrap(); let mut fee_payer_index = None; - for ((i, key), account) in message - .account_keys - .iter() - .enumerate() + for (i, (key, account)) in (0..message.account_keys.len()) .zip(loaded_transaction.accounts.iter_mut()) - .filter(|((i, key), _account)| message.is_non_loader_key(key, *i)) + .filter(|(i, (key, _account))| message.is_non_loader_key(key, *i)) { let is_nonce_account = prepare_if_nonce_account( account, @@ -1035,7 +1036,7 @@ impl Accounts { .rent_debits .push(key, rent, account.lamports()); } - accounts.push((key, &*account)); + accounts.push((&*key, &*account)); } } } @@ -1377,7 +1378,7 @@ mod tests { assert_eq!(loaded_accounts.len(), 1); let (load_res, _nonce_rollback) = &loaded_accounts[0]; let loaded_transaction = load_res.as_ref().unwrap(); - assert_eq!(loaded_transaction.accounts[0].lamports(), min_balance); + assert_eq!(loaded_transaction.accounts[0].1.lamports(), min_balance); // Fee leaves zero balance fails accounts[0].1.set_lamports(min_balance); @@ -1439,7 +1440,7 @@ mod tests { match &loaded_accounts[0] { (Ok(loaded_transaction), _nonce_rollback) => { assert_eq!(loaded_transaction.accounts.len(), 3); - assert_eq!(loaded_transaction.accounts[0], accounts[0].1); + assert_eq!(loaded_transaction.accounts[0].1, accounts[0].1); assert_eq!(loaded_transaction.loaders.len(), 1); assert_eq!(loaded_transaction.loaders[0].len(), 0); } @@ -1662,7 +1663,7 @@ mod tests { match &loaded_accounts[0] { (Ok(loaded_transaction), _nonce_rollback) => { assert_eq!(loaded_transaction.accounts.len(), 3); - assert_eq!(loaded_transaction.accounts[0], accounts[0].1); + assert_eq!(loaded_transaction.accounts[0].1, accounts[0].1); assert_eq!(loaded_transaction.loaders.len(), 2); assert_eq!(loaded_transaction.loaders[0].len(), 1); assert_eq!(loaded_transaction.loaders[1].len(), 2); @@ -1970,6 +1971,9 @@ mod tests { let keypair0 = Keypair::new(); let keypair1 = Keypair::new(); let pubkey = solana_sdk::pubkey::new_rand(); + let account0 = AccountSharedData::new(1, 0, &Pubkey::default()); + let account1 = AccountSharedData::new(2, 0, &Pubkey::default()); + let account2 = AccountSharedData::new(3, 0, &Pubkey::default()); let rent_collector = RentCollector::default(); @@ -1982,6 +1986,10 @@ mod tests { Hash::default(), instructions, ); + let transaction_accounts0 = vec![ + (message.account_keys[0], account0), + (message.account_keys[1], account2.clone()), + ]; let tx0 = Transaction::new(&[&keypair0], message, Hash::default()); let instructions = vec![CompiledInstruction::new(2, &(), vec![0, 1])]; @@ -1993,22 +2001,19 @@ mod tests { Hash::default(), instructions, ); + let transaction_accounts1 = vec![ + (message.account_keys[0], account1), + (message.account_keys[1], account2), + ]; let tx1 = Transaction::new(&[&keypair1], message, Hash::default()); - let txs = vec![tx0, tx1]; let loaders = vec![(Ok(()), None), (Ok(()), None)]; - let account0 = AccountSharedData::new(1, 0, &Pubkey::default()); - let account1 = AccountSharedData::new(2, 0, &Pubkey::default()); - let account2 = AccountSharedData::new(3, 0, &Pubkey::default()); - - let transaction_accounts0 = vec![account0, account2.clone()]; let transaction_loaders0 = vec![]; let transaction_rent0 = 0; let loaded0 = ( Ok(LoadedTransaction { accounts: transaction_accounts0, - account_deps: vec![], loaders: transaction_loaders0, rent: transaction_rent0, rent_debits: RentDebits::default(), @@ -2016,13 +2021,11 @@ mod tests { None, ); - let transaction_accounts1 = vec![account1, account2]; let transaction_loaders1 = vec![]; let transaction_rent1 = 0; let loaded1 = ( Ok(LoadedTransaction { accounts: transaction_accounts1, - account_deps: vec![], loaders: transaction_loaders1, rent: transaction_rent1, rent_debits: RentDebits::default(), @@ -2046,6 +2049,7 @@ mod tests { .unwrap() .insert_new_readonly(&pubkey); } + let txs = &[tx0, tx1]; let collected_accounts = accounts.collect_accounts_to_store( txs.iter(), &loaders, @@ -2349,16 +2353,34 @@ mod tests { let from = keypair_from_seed(&[1; 32]).unwrap(); let from_address = from.pubkey(); let to_address = Pubkey::new_unique(); + let nonce_state = + nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { + authority: nonce_authority.pubkey(), + blockhash: Hash::new_unique(), + fee_calculator: FeeCalculator::default(), + })); + let nonce_account_post = + AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap(); + let from_account_post = AccountSharedData::new(4199, 0, &Pubkey::default()); + let to_account = AccountSharedData::new(2, 0, &Pubkey::default()); + let nonce_authority_account = AccountSharedData::new(3, 0, &Pubkey::default()); + let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default()); + let instructions = vec![ system_instruction::advance_nonce_account(&nonce_address, &nonce_authority.pubkey()), system_instruction::transfer(&from_address, &to_address, 42), ]; let message = Message::new(&instructions, Some(&from_address)); let blockhash = Hash::new_unique(); + let transaction_accounts = vec![ + (message.account_keys[0], from_account_post), + (message.account_keys[1], nonce_authority_account), + (message.account_keys[2], nonce_account_post), + (message.account_keys[3], to_account), + (message.account_keys[4], recent_blockhashes_sysvar_account), + ]; let tx = Transaction::new(&[&nonce_authority, &from], message, blockhash); - let txs = vec![tx]; - let nonce_state = nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { authority: nonce_authority.pubkey(), @@ -2382,33 +2404,11 @@ mod tests { nonce_rollback.clone(), )]; - let nonce_state = - nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { - authority: nonce_authority.pubkey(), - blockhash: Hash::new_unique(), - fee_calculator: FeeCalculator::default(), - })); - let nonce_account_post = - AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap(); - - let from_account_post = AccountSharedData::new(4199, 0, &Pubkey::default()); - let to_account = AccountSharedData::new(2, 0, &Pubkey::default()); - let nonce_authority_account = AccountSharedData::new(3, 0, &Pubkey::default()); - let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default()); - - let transaction_accounts = vec![ - from_account_post, - nonce_authority_account, - nonce_account_post, - to_account, - recent_blockhashes_sysvar_account, - ]; let transaction_loaders = vec![]; let transaction_rent = 0; let loaded = ( Ok(LoadedTransaction { accounts: transaction_accounts, - account_deps: vec![], loaders: transaction_loaders, rent: transaction_rent, rent_debits: RentDebits::default(), @@ -2426,6 +2426,7 @@ mod tests { false, AccountShrinkThreshold::default(), ); + let txs = &[tx]; let collected_accounts = accounts.collect_accounts_to_store( txs.iter(), &loaders, @@ -2470,16 +2471,34 @@ mod tests { let from = keypair_from_seed(&[1; 32]).unwrap(); let from_address = from.pubkey(); let to_address = Pubkey::new_unique(); + let nonce_state = + nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { + authority: nonce_authority.pubkey(), + blockhash: Hash::new_unique(), + fee_calculator: FeeCalculator::default(), + })); + let nonce_account_post = + AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap(); + let from_account_post = AccountSharedData::new(4200, 0, &Pubkey::default()); + let to_account = AccountSharedData::new(2, 0, &Pubkey::default()); + let nonce_authority_account = AccountSharedData::new(3, 0, &Pubkey::default()); + let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default()); + let instructions = vec![ system_instruction::advance_nonce_account(&nonce_address, &nonce_authority.pubkey()), system_instruction::transfer(&from_address, &to_address, 42), ]; let message = Message::new(&instructions, Some(&nonce_address)); let blockhash = Hash::new_unique(); + let transaction_accounts = vec![ + (message.account_keys[0], from_account_post), + (message.account_keys[1], nonce_authority_account), + (message.account_keys[2], nonce_account_post), + (message.account_keys[3], to_account), + (message.account_keys[4], recent_blockhashes_sysvar_account), + ]; let tx = Transaction::new(&[&nonce_authority, &from], message, blockhash); - let txs = vec![tx]; - let nonce_state = nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { authority: nonce_authority.pubkey(), @@ -2502,33 +2521,11 @@ mod tests { nonce_rollback.clone(), )]; - let nonce_state = - nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { - authority: nonce_authority.pubkey(), - blockhash: Hash::new_unique(), - fee_calculator: FeeCalculator::default(), - })); - let nonce_account_post = - AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap(); - - let from_account_post = AccountSharedData::new(4200, 0, &Pubkey::default()); - let to_account = AccountSharedData::new(2, 0, &Pubkey::default()); - let nonce_authority_account = AccountSharedData::new(3, 0, &Pubkey::default()); - let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default()); - - let transaction_accounts = vec![ - from_account_post, - nonce_authority_account, - nonce_account_post, - to_account, - recent_blockhashes_sysvar_account, - ]; let transaction_loaders = vec![]; let transaction_rent = 0; let loaded = ( Ok(LoadedTransaction { accounts: transaction_accounts, - account_deps: vec![], loaders: transaction_loaders, rent: transaction_rent, rent_debits: RentDebits::default(), @@ -2546,6 +2543,7 @@ mod tests { false, AccountShrinkThreshold::default(), ); + let txs = &[tx]; let collected_accounts = accounts.collect_accounts_to_store( txs.iter(), &loaders, diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index a562890833..dc7f5e1813 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -35,8 +35,8 @@ //! already been signed and verified. use crate::{ accounts::{ - AccountAddressFilter, Accounts, TransactionAccountDeps, TransactionAccounts, - TransactionLoadResult, TransactionLoaders, + AccountAddressFilter, Accounts, TransactionAccounts, TransactionLoadResult, + TransactionLoaders, }, accounts_db::{AccountShrinkThreshold, ErrorCounters, SnapshotStorages}, accounts_index::{AccountSecondaryIndexes, IndexKey, ScanResult}, @@ -177,8 +177,7 @@ impl ExecuteTimings { type BankStatusCache = StatusCache>; #[frozen_abi(digest = "HhY4tMP5KZU9fw9VLpMMUikfvNVCLksocZBUKjt8ZjYH")] pub type BankSlotDelta = SlotDelta>; -type TransactionAccountRefCells = Vec>>; -type TransactionAccountDepRefCells = Vec<(Pubkey, Rc>)>; +type TransactionAccountRefCells = Vec<(Pubkey, Rc>)>; type TransactionLoaderRefCells = Vec>)>>; // Eager rent collection repeats in cyclic manner. @@ -625,30 +624,32 @@ impl NonceRollbackFull { pub fn from_partial( partial: NonceRollbackPartial, message: &Message, - accounts: &[AccountSharedData], + accounts: &[(Pubkey, AccountSharedData)], ) -> Result { let NonceRollbackPartial { nonce_address, nonce_account, } = partial; - let fee_payer = message - .account_keys - .iter() - .enumerate() - .find(|(i, k)| message.is_non_loader_key(k, *i)) - .and_then(|(i, k)| accounts.get(i).cloned().map(|a| (*k, a))); + let fee_payer = (0..message.account_keys.len()).find_map(|i| { + if let Some((k, a)) = &accounts.get(i) { + if message.is_non_loader_key(k, i) { + return Some((k, a)); + } + } + None + }); if let Some((fee_pubkey, fee_account)) = fee_payer { - if fee_pubkey == nonce_address { + if *fee_pubkey == nonce_address { Ok(Self { nonce_address, - nonce_account: fee_account, + nonce_account: fee_account.clone(), fee_account: None, }) } else { Ok(Self { nonce_address, nonce_account, - fee_account: Some(fee_account), + fee_account: Some(fee_account.clone()), }) } } else { @@ -2643,7 +2644,11 @@ impl Bank { pub fn simulate_transaction( &self, transaction: &Transaction, - ) -> (Result<()>, TransactionLogMessages, Vec) { + ) -> ( + Result<()>, + TransactionLogMessages, + Vec<(Pubkey, AccountSharedData)>, + ) { assert!(self.is_frozen(), "simulation bank must be frozen"); let batch = self.prepare_simulation_batch(transaction); @@ -2651,7 +2656,7 @@ impl Bank { let mut timings = ExecuteTimings::default(); let ( - loaded_accounts, + loaded_txs, executed, _inner_instructions, log_messages, @@ -2673,7 +2678,7 @@ impl Bank { let log_messages = log_messages .get(0) .map_or(vec![], |messages| messages.to_vec()); - let post_transaction_accounts = loaded_accounts + let post_transaction_accounts = loaded_txs .into_iter() .next() .unwrap() @@ -2940,20 +2945,11 @@ impl Bank { /// ownership by draining the source fn accounts_to_refcells( accounts: &mut TransactionAccounts, - account_deps: &mut TransactionAccountDeps, loaders: &mut TransactionLoaders, - ) -> ( - TransactionAccountRefCells, - TransactionAccountDepRefCells, - TransactionLoaderRefCells, - ) { + ) -> (TransactionAccountRefCells, TransactionLoaderRefCells) { let account_refcells: Vec<_> = accounts .drain(..) - .map(|account| Rc::new(RefCell::new(account))) - .collect(); - let account_dep_refcells: Vec<_> = account_deps - .drain(..) - .map(|(pubkey, account_dep)| (pubkey, Rc::new(RefCell::new(account_dep)))) + .map(|(pubkey, account)| (pubkey, Rc::new(RefCell::new(account)))) .collect(); let loader_refcells: Vec> = loaders .iter_mut() @@ -2963,7 +2959,7 @@ impl Bank { .collect() }) .collect(); - (account_refcells, account_dep_refcells, loader_refcells) + (account_refcells, loader_refcells) } /// Converts back from RefCell to AccountSharedData, this involves moving @@ -2974,12 +2970,13 @@ impl Bank { mut account_refcells: TransactionAccountRefCells, loader_refcells: TransactionLoaderRefCells, ) -> std::result::Result<(), TransactionError> { - for account_refcell in account_refcells.drain(..) { - accounts.push( + for (pubkey, account_refcell) in account_refcells.drain(..) { + accounts.push(( + pubkey, Rc::try_unwrap(account_refcell) .map_err(|_| TransactionError::AccountBorrowOutstanding)? .into_inner(), - ) + )) } for (ls, mut lrcs) in loaders.iter_mut().zip(loader_refcells) { for (pubkey, lrc) in lrcs.drain(..) { @@ -3106,7 +3103,7 @@ impl Bank { check_time.stop(); let mut load_time = Measure::start("accounts_load"); - let mut loaded_accounts = self.rc.accounts.load_accounts( + let mut loaded_txs = self.rc.accounts.load_accounts( &self.ancestors, hashed_txs.as_transactions_iter(), check_results, @@ -3126,7 +3123,7 @@ impl Bank { .bpf_compute_budget .unwrap_or_else(BpfComputeBudget::new); - let executed: Vec = loaded_accounts + let executed: Vec = loaded_txs .iter_mut() .zip(hashed_txs.as_transactions_iter()) .map(|(accs, tx)| match accs { @@ -3135,12 +3132,10 @@ impl Bank { signature_count += u64::from(tx.message().header.num_required_signatures); let executors = self.get_executors(&tx.message, &loaded_transaction.loaders); - let (account_refcells, account_dep_refcells, loader_refcells) = - Self::accounts_to_refcells( - &mut loaded_transaction.accounts, - &mut loaded_transaction.account_deps, - &mut loaded_transaction.loaders, - ); + let (account_refcells, loader_refcells) = Self::accounts_to_refcells( + &mut loaded_transaction.accounts, + &mut loaded_transaction.loaders, + ); let instruction_recorders = if enable_cpi_recording { let ix_count = tx.message.instructions.len(); @@ -3161,7 +3156,6 @@ impl Bank { tx.message(), &loader_refcells, &account_refcells, - &account_dep_refcells, &self.rent_collector, log_collector.clone(), executors.clone(), @@ -3308,7 +3302,7 @@ impl Bank { } Self::update_error_counters(&error_counters); ( - loaded_accounts, + loaded_txs, executed, inner_instructions, transaction_log_messages, @@ -3380,7 +3374,7 @@ impl Bank { pub fn commit_transactions( &self, hashed_txs: &[HashedTransaction], - loaded_accounts: &mut [TransactionLoadResult], + loaded_txs: &mut [TransactionLoadResult], executed: &[TransactionExecutionResult], tx_count: u64, signature_count: u64, @@ -3419,19 +3413,16 @@ impl Bank { self.slot(), hashed_txs.as_transactions_iter(), executed, - loaded_accounts, + loaded_txs, &self.rent_collector, &self.last_blockhash_with_fee_calculator(), self.fix_recent_blockhashes_sysvar_delay(), self.demote_sysvar_write_locks(), ); - let rent_debits = self.collect_rent(executed, loaded_accounts); + let rent_debits = self.collect_rent(executed, loaded_txs); - let overwritten_vote_accounts = self.update_cached_accounts( - hashed_txs.as_transactions_iter(), - executed, - loaded_accounts, - ); + let overwritten_vote_accounts = + self.update_cached_accounts(hashed_txs.as_transactions_iter(), executed, loaded_txs); // once committed there is no way to unroll write_time.stop(); @@ -3611,11 +3602,11 @@ impl Bank { fn collect_rent( &self, res: &[TransactionExecutionResult], - loaded_accounts: &mut [TransactionLoadResult], + loaded_txs: &mut [TransactionLoadResult], ) -> Vec { let mut collected_rent: u64 = 0; - let mut rent_debits: Vec = Vec::with_capacity(loaded_accounts.len()); - for (i, (raccs, _nonce_rollback)) in loaded_accounts.iter_mut().enumerate() { + let mut rent_debits: Vec = Vec::with_capacity(loaded_txs.len()); + for (i, (raccs, _nonce_rollback)) in loaded_txs.iter_mut().enumerate() { let (res, _nonce_rollback) = &res[i]; if res.is_err() || raccs.is_err() { rent_debits.push(RentDebits::default()); @@ -4054,7 +4045,7 @@ impl Bank { }; let ( - mut loaded_accounts, + mut loaded_txs, executed, inner_instructions, transaction_logs, @@ -4071,7 +4062,7 @@ impl Bank { let results = self.commit_transactions( batch.hashed_transactions(), - &mut loaded_accounts, + &mut loaded_txs, &executed, tx_count, signature_count, @@ -4793,10 +4784,10 @@ impl Bank { &self, txs: impl Iterator, res: &[TransactionExecutionResult], - loaded: &[TransactionLoadResult], + loaded_txs: &[TransactionLoadResult], ) -> Vec { let mut overwritten_vote_accounts = vec![]; - for (i, ((raccs, _load_nonce_rollback), tx)) in loaded.iter().zip(txs).enumerate() { + for (i, ((raccs, _load_nonce_rollback), tx)) in loaded_txs.iter().zip(txs).enumerate() { let (res, _res_nonce_rollback) = &res[i]; if res.is_err() || raccs.is_err() { continue; @@ -4805,11 +4796,9 @@ impl Bank { let message = &tx.message(); let loaded_transaction = raccs.as_ref().unwrap(); - for (pubkey, account) in message - .account_keys - .iter() + for (_i, (pubkey, account)) in (0..message.account_keys.len()) .zip(loaded_transaction.accounts.iter()) - .filter(|(_key, account)| (Stakes::is_stake(account))) + .filter(|(_i, (_pubkey, account))| (Stakes::is_stake(account))) { if Stakes::is_stake(account) { if let Some(old_vote_account) = self.stakes.write().unwrap().store( @@ -5433,10 +5422,13 @@ pub(crate) mod tests { let to_account = AccountSharedData::new(45, 0, &Pubkey::default()); let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default()); let accounts = [ - from_account.clone(), - nonce_account.clone(), - to_account.clone(), - recent_blockhashes_sysvar_account.clone(), + (message.account_keys[0], from_account.clone()), + (message.account_keys[1], nonce_account.clone()), + (message.account_keys[2], to_account.clone()), + ( + message.account_keys[3], + recent_blockhashes_sysvar_account.clone(), + ), ]; // NonceRollbackFull create + NonceRollbackInfo impl @@ -5448,10 +5440,10 @@ pub(crate) mod tests { let message = Message::new(&instructions, Some(&nonce_address)); let accounts = [ - nonce_account, - from_account, - to_account, - recent_blockhashes_sysvar_account, + (message.account_keys[0], nonce_account), + (message.account_keys[1], from_account), + (message.account_keys[2], to_account), + (message.account_keys[3], recent_blockhashes_sysvar_account), ]; // Nonce account is fee-payer diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 1a76e9a763..039a008e79 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -260,9 +260,8 @@ impl ComputeMeter for ThisComputeMeter { pub struct ThisInvokeContext<'a> { invoke_stack: Vec>, rent: Rent, - message: &'a Message, pre_accounts: Vec, - account_deps: &'a [(Pubkey, Rc>)], + accounts: &'a [(Pubkey, Rc>)], programs: &'a [(Pubkey, ProcessInstructionWithContext)], logger: Rc>, bpf_compute_budget: BpfComputeBudget, @@ -284,8 +283,7 @@ impl<'a> ThisInvokeContext<'a> { message: &'a Message, instruction: &'a CompiledInstruction, executable_accounts: &'a [(Pubkey, Rc>)], - accounts: &'a [Rc>], - account_deps: &'a [(Pubkey, Rc>)], + accounts: &'a [(Pubkey, Rc>)], programs: &'a [(Pubkey, ProcessInstructionWithContext)], log_collector: Option>, bpf_compute_budget: BpfComputeBudget, @@ -306,9 +304,8 @@ impl<'a> ThisInvokeContext<'a> { let mut invoke_context = Self { invoke_stack: Vec::with_capacity(bpf_compute_budget.max_invoke_depth), rent, - message, pre_accounts, - account_deps, + accounts, programs, logger: Rc::new(RefCell::new(ThisLogger { log_collector })), bpf_compute_budget, @@ -361,25 +358,21 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { let keyed_accounts = keyed_accounts .iter() .map(|(is_signer, is_writable, search_key, account)| { - self.account_deps + self.accounts .iter() - .map(|(key, _account)| key) - .chain(self.message.account_keys.iter()) - .position(|key| key == *search_key) - .map(|mut index| { + .position(|(key, _account)| key == *search_key) + .map(|index| { // TODO // Currently we are constructing new accounts on the stack // before calling MessageProcessor::process_cross_program_instruction // Ideally we would recycle the existing accounts here. - let key = if index < self.account_deps.len() { - &self.account_deps[index].0 - // &self.account_deps[index].1 as &RefCell, - } else { - index = index.saturating_sub(self.account_deps.len()); - &self.message.account_keys[index] - // &self.accounts[index] as &RefCell, - }; - (*is_signer, *is_writable, key, transmute_lifetime(*account)) + ( + *is_signer, + *is_writable, + &self.accounts[index].0, + // &self.accounts[index] as &RefCell + transmute_lifetime(*account), + ) }) }) .collect::>>() @@ -400,7 +393,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { &mut self, message: &Message, instruction: &CompiledInstruction, - accounts: &[Rc>], + accounts: &[(Pubkey, Rc>)], caller_write_privileges: Option<&[bool]>, ) -> Result<(), InstructionError> { let stack_frame = self @@ -469,16 +462,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { self.feature_set.is_active(feature_id) } fn get_account(&self, pubkey: &Pubkey) -> Option>> { - if let Some(account) = self.pre_accounts.iter().find_map(|pre| { - if pre.key == *pubkey { - Some(pre.account.clone()) - } else { - None - } - }) { - return Some(account); - } - self.account_deps.iter().find_map(|(key, account)| { + self.accounts.iter().find_map(|(key, account)| { if key == pubkey { Some(account.clone()) } else { @@ -628,7 +612,7 @@ impl MessageProcessor { message: &'a Message, instruction: &'a CompiledInstruction, executable_accounts: &'a [(Pubkey, Rc>)], - accounts: &'a [Rc>], + accounts: &'a [(Pubkey, Rc>)], demote_sysvar_write_locks: bool, ) -> Vec<(bool, bool, &'a Pubkey, &'a RefCell)> { executable_accounts @@ -639,8 +623,8 @@ impl MessageProcessor { ( message.is_signer(index), message.is_writable(index, demote_sysvar_write_locks), - &message.account_keys[index], - &accounts[index] as &RefCell, + &accounts[index].0, + &accounts[index].1 as &RefCell, ) })) .collect::>() @@ -800,7 +784,7 @@ impl MessageProcessor { for keyed_account_index in keyed_account_indices { let keyed_account = &keyed_accounts[*keyed_account_index]; if account_key == keyed_account.unsigned_key() { - accounts.push(Rc::new(keyed_account.account.clone())); + accounts.push((*account_key, Rc::new(keyed_account.account.clone()))); keyed_account_indices_reordered.push(*keyed_account_index); continue 'root; } @@ -886,7 +870,7 @@ impl MessageProcessor { { let invoke_context = invoke_context.borrow(); let keyed_accounts = invoke_context.get_keyed_accounts()?; - for (src_keyed_account_index, (account, dst_keyed_account_index)) in accounts + for (src_keyed_account_index, ((_key, account), dst_keyed_account_index)) in accounts .iter() .zip(keyed_account_indices_reordered) .enumerate() @@ -928,7 +912,7 @@ impl MessageProcessor { pub fn process_cross_program_instruction( message: &Message, executable_accounts: &[(Pubkey, Rc>)], - accounts: &[Rc>], + accounts: &[(Pubkey, Rc>)], caller_write_privileges: &[bool], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { @@ -984,15 +968,17 @@ impl MessageProcessor { pub fn create_pre_accounts( message: &Message, instruction: &CompiledInstruction, - accounts: &[Rc>], + accounts: &[(Pubkey, Rc>)], ) -> Vec { let mut pre_accounts = Vec::with_capacity(instruction.accounts.len()); { let mut work = |_unique_index: usize, account_index: usize| { - let key = &message.account_keys[account_index]; - let account = accounts[account_index].borrow(); - pre_accounts.push(PreAccount::new(key, &account)); - Ok(()) + if account_index < message.account_keys.len() && account_index < accounts.len() { + let account = accounts[account_index].1.borrow(); + pre_accounts.push(PreAccount::new(&accounts[account_index].0, &account)); + return Ok(()); + } + Err(InstructionError::MissingAccount) }; let _ = instruction.visit_each_account(&mut work); } @@ -1017,7 +1003,7 @@ impl MessageProcessor { instruction: &CompiledInstruction, pre_accounts: &[PreAccount], executable_accounts: &[(Pubkey, Rc>)], - accounts: &[Rc>], + accounts: &[(Pubkey, Rc>)], rent: &Rent, timings: &mut ExecuteDetailsTimings, demote_sysvar_write_locks: bool, @@ -1034,10 +1020,11 @@ impl MessageProcessor { { // Verify account has no outstanding references let _ = accounts[account_index] + .1 .try_borrow_mut() .map_err(|_| InstructionError::AccountBorrowOutstanding)?; } - let account = accounts[account_index].borrow(); + let account = accounts[account_index].1.borrow(); pre_accounts[unique_index] .verify( program_id, @@ -1076,7 +1063,7 @@ impl MessageProcessor { message: &Message, instruction: &CompiledInstruction, pre_accounts: &mut [PreAccount], - accounts: &[Rc>], + accounts: &[(Pubkey, Rc>)], program_id: &Pubkey, rent: &Rent, caller_write_privileges: Option<&[bool]>, @@ -1088,8 +1075,7 @@ impl MessageProcessor { let (mut pre_sum, mut post_sum) = (0_u128, 0_u128); let mut work = |_unique_index: usize, account_index: usize| { if account_index < message.account_keys.len() && account_index < accounts.len() { - let key = &message.account_keys[account_index]; - let account = &accounts[account_index]; + let (key, account) = &accounts[account_index]; let is_writable = if let Some(caller_write_privileges) = caller_write_privileges { caller_write_privileges[account_index] } else { @@ -1142,8 +1128,7 @@ impl MessageProcessor { message: &Message, instruction: &CompiledInstruction, executable_accounts: &[(Pubkey, Rc>)], - accounts: &[Rc>], - account_deps: &[(Pubkey, Rc>)], + accounts: &[(Pubkey, Rc>)], rent_collector: &RentCollector, log_collector: Option>, executors: Rc>, @@ -1159,9 +1144,9 @@ impl MessageProcessor { // Fixup the special instructions key if present // before the account pre-values are taken care of if feature_set.is_active(&instructions_sysvar_enabled::id()) { - for (i, key) in message.account_keys.iter().enumerate() { - if instructions::check_id(key) { - let mut mut_account_ref = accounts[i].borrow_mut(); + for (pubkey, accont) in accounts.iter().take(message.account_keys.len()) { + if instructions::check_id(pubkey) { + let mut mut_account_ref = accont.borrow_mut(); instructions::store_current_index( mut_account_ref.data_as_mut_slice(), instruction_index as u16, @@ -1179,7 +1164,6 @@ impl MessageProcessor { instruction, executable_accounts, accounts, - account_deps, &self.programs, log_collector, bpf_compute_budget, @@ -1216,8 +1200,7 @@ impl MessageProcessor { &self, message: &Message, loaders: &[Vec<(Pubkey, Rc>)>], - accounts: &[Rc>], - account_deps: &[(Pubkey, Rc>)], + accounts: &[(Pubkey, Rc>)], rent_collector: &RentCollector, log_collector: Option>, executors: Rc>, @@ -1240,7 +1223,6 @@ impl MessageProcessor { instruction, &loaders[instruction_index], accounts, - account_deps, rent_collector, log_collector.clone(), executors.clone(), @@ -1281,25 +1263,29 @@ mod tests { fn test_invoke_context() { const MAX_DEPTH: usize = 10; let mut invoke_stack = vec![]; - let mut keys = vec![]; let mut accounts = vec![]; let mut metas = vec![]; for i in 0..MAX_DEPTH { invoke_stack.push(solana_sdk::pubkey::new_rand()); - keys.push(solana_sdk::pubkey::new_rand()); - accounts.push(Rc::new(RefCell::new(AccountSharedData::new( - i as u64, - 1, - &invoke_stack[i], - )))); - metas.push(AccountMeta::new(keys[i], false)); + accounts.push(( + solana_sdk::pubkey::new_rand(), + Rc::new(RefCell::new(AccountSharedData::new( + i as u64, + 1, + &invoke_stack[i], + ))), + )); + metas.push(AccountMeta::new(accounts[i].0, false)); } for program_id in invoke_stack.iter() { - accounts.push(Rc::new(RefCell::new(AccountSharedData::new( - 1, - 1, - &solana_sdk::pubkey::Pubkey::default(), - )))); + accounts.push(( + *program_id, + Rc::new(RefCell::new(AccountSharedData::new( + 1, + 1, + &solana_sdk::pubkey::Pubkey::default(), + ))), + )); metas.push(AccountMeta::new(*program_id, false)); } @@ -1316,7 +1302,6 @@ mod tests { &[], &accounts, &[], - &[], None, BpfComputeBudget::default(), Rc::new(RefCell::new(Executors::default())), @@ -1341,8 +1326,8 @@ mod tests { for owned_index in (1..depth_reached).rev() { let not_owned_index = owned_index - 1; let metas = vec![ - AccountMeta::new(keys[not_owned_index], false), - AccountMeta::new(keys[owned_index], false), + AccountMeta::new(accounts[not_owned_index].0, false), + AccountMeta::new(accounts[owned_index].0, false), ]; let message = Message::new( &[Instruction::new_with_bytes( @@ -1354,14 +1339,17 @@ mod tests { ); // modify account owned by the program - accounts[owned_index].borrow_mut().data_as_mut_slice()[0] = + accounts[owned_index].1.borrow_mut().data_as_mut_slice()[0] = (MAX_DEPTH + owned_index) as u8; let mut these_accounts = accounts[not_owned_index..owned_index + 1].to_vec(); - these_accounts.push(Rc::new(RefCell::new(AccountSharedData::new( - 1, - 1, - &solana_sdk::pubkey::Pubkey::default(), - )))); + these_accounts.push(( + message.account_keys[2], + Rc::new(RefCell::new(AccountSharedData::new( + 1, + 1, + &solana_sdk::pubkey::Pubkey::default(), + ))), + )); invoke_context .verify_and_update(&message, &message.instructions[0], &these_accounts, None) .unwrap(); @@ -1374,8 +1362,8 @@ mod tests { ); // modify account not owned by the program - let data = accounts[not_owned_index].borrow_mut().data()[0]; - accounts[not_owned_index].borrow_mut().data_as_mut_slice()[0] = + let data = accounts[not_owned_index].1.borrow_mut().data()[0]; + accounts[not_owned_index].1.borrow_mut().data_as_mut_slice()[0] = (MAX_DEPTH + not_owned_index) as u8; assert_eq!( invoke_context.verify_and_update( @@ -1393,7 +1381,7 @@ mod tests { .data()[0], data ); - accounts[not_owned_index].borrow_mut().data_as_mut_slice()[0] = data; + accounts[not_owned_index].1.borrow_mut().data_as_mut_slice()[0] = data; invoke_context.pop(); } @@ -1869,26 +1857,28 @@ mod tests { let mut message_processor = MessageProcessor::default(); message_processor.add_program(mock_system_program_id, mock_system_process_instruction); - let mut accounts: Vec>> = Vec::new(); - let account = AccountSharedData::new_ref(100, 1, &mock_system_program_id); - accounts.push(account); - let account = AccountSharedData::new_ref(0, 1, &mock_system_program_id); - accounts.push(account); + let accounts = vec![ + ( + solana_sdk::pubkey::new_rand(), + AccountSharedData::new_ref(100, 1, &mock_system_program_id), + ), + ( + solana_sdk::pubkey::new_rand(), + AccountSharedData::new_ref(0, 1, &mock_system_program_id), + ), + ]; - let mut loaders: Vec>)>> = Vec::new(); let account = Rc::new(RefCell::new(create_loadable_account_for_test( "mock_system_program", ))); - loaders.push(vec![(mock_system_program_id, account)]); + let loaders = vec![vec![(mock_system_program_id, account)]]; let executors = Rc::new(RefCell::new(Executors::default())); let ancestors = Ancestors::default(); - let from_pubkey = solana_sdk::pubkey::new_rand(); - let to_pubkey = solana_sdk::pubkey::new_rand(); let account_metas = vec![ - AccountMeta::new(from_pubkey, true), - AccountMeta::new_readonly(to_pubkey, false), + AccountMeta::new(accounts[0].0, true), + AccountMeta::new_readonly(accounts[1].0, false), ]; let message = Message::new( &[Instruction::new_with_bincode( @@ -1896,14 +1886,13 @@ mod tests { &MockSystemInstruction::Correct, account_metas.clone(), )], - Some(&from_pubkey), + Some(&accounts[0].0), ); let result = message_processor.process_message( &message, &loaders, &accounts, - &[], &rent_collector, None, executors.clone(), @@ -1915,8 +1904,8 @@ mod tests { &ancestors, ); assert_eq!(result, Ok(())); - assert_eq!(accounts[0].borrow().lamports(), 100); - assert_eq!(accounts[1].borrow().lamports(), 0); + assert_eq!(accounts[0].1.borrow().lamports(), 100); + assert_eq!(accounts[1].1.borrow().lamports(), 0); let message = Message::new( &[Instruction::new_with_bincode( @@ -1924,14 +1913,13 @@ mod tests { &MockSystemInstruction::AttemptCredit { lamports: 50 }, account_metas.clone(), )], - Some(&from_pubkey), + Some(&accounts[0].0), ); let result = message_processor.process_message( &message, &loaders, &accounts, - &[], &rent_collector, None, executors.clone(), @@ -1956,14 +1944,13 @@ mod tests { &MockSystemInstruction::AttemptDataChange { data: 50 }, account_metas, )], - Some(&from_pubkey), + Some(&accounts[0].0), ); let result = message_processor.process_message( &message, &loaders, &accounts, - &[], &rent_collector, None, executors, @@ -2049,28 +2036,29 @@ mod tests { let mut message_processor = MessageProcessor::default(); message_processor.add_program(mock_program_id, mock_system_process_instruction); - let mut accounts: Vec>> = Vec::new(); - let account = AccountSharedData::new_ref(100, 1, &mock_program_id); - accounts.push(account); - let account = AccountSharedData::new_ref(0, 1, &mock_program_id); - accounts.push(account); + let accounts = vec![ + ( + solana_sdk::pubkey::new_rand(), + AccountSharedData::new_ref(100, 1, &mock_program_id), + ), + ( + solana_sdk::pubkey::new_rand(), + AccountSharedData::new_ref(0, 1, &mock_program_id), + ), + ]; - let mut loaders: Vec>)>> = Vec::new(); let account = Rc::new(RefCell::new(create_loadable_account_for_test( "mock_system_program", ))); - loaders.push(vec![(mock_program_id, account)]); + let loaders = vec![vec![(mock_program_id, account)]]; let executors = Rc::new(RefCell::new(Executors::default())); let ancestors = Ancestors::default(); - let from_pubkey = solana_sdk::pubkey::new_rand(); - let to_pubkey = solana_sdk::pubkey::new_rand(); - let dup_pubkey = from_pubkey; let account_metas = vec![ - AccountMeta::new(from_pubkey, true), - AccountMeta::new(to_pubkey, false), - AccountMeta::new(dup_pubkey, false), + AccountMeta::new(accounts[0].0, true), + AccountMeta::new(accounts[1].0, false), + AccountMeta::new(accounts[0].0, false), ]; // Try to borrow mut the same account @@ -2080,13 +2068,12 @@ mod tests { &MockSystemInstruction::BorrowFail, account_metas.clone(), )], - Some(&from_pubkey), + Some(&accounts[0].0), ); let result = message_processor.process_message( &message, &loaders, &accounts, - &[], &rent_collector, None, executors.clone(), @@ -2112,13 +2099,12 @@ mod tests { &MockSystemInstruction::MultiBorrowMut, account_metas.clone(), )], - Some(&from_pubkey), + Some(&accounts[0].0), ); let result = message_processor.process_message( &message, &loaders, &accounts, - &[], &rent_collector, None, executors.clone(), @@ -2141,14 +2127,13 @@ mod tests { }, account_metas, )], - Some(&from_pubkey), + Some(&accounts[0].0), ); let ancestors = Ancestors::default(); let result = message_processor.process_message( &message, &loaders, &accounts, - &[], &rent_collector, None, executors, @@ -2160,9 +2145,9 @@ mod tests { &ancestors, ); assert_eq!(result, Ok(())); - assert_eq!(accounts[0].borrow().lamports(), 80); - assert_eq!(accounts[1].borrow().lamports(), 20); - assert_eq!(accounts[0].borrow().data(), &vec![42]); + assert_eq!(accounts[0].1.borrow().lamports(), 80); + assert_eq!(accounts[1].1.borrow().lamports(), 20); + assert_eq!(accounts[0].1.borrow().data(), &vec![42]); } #[test] @@ -2214,25 +2199,28 @@ mod tests { Rc::new(RefCell::new(program_account.clone())), )]; - let owned_key = solana_sdk::pubkey::new_rand(); let owned_account = AccountSharedData::new(42, 1, &callee_program_id); - - let not_owned_key = solana_sdk::pubkey::new_rand(); let not_owned_account = AccountSharedData::new(84, 1, &solana_sdk::pubkey::new_rand()); #[allow(unused_mut)] - let mut accounts = vec![ - Rc::new(RefCell::new(owned_account)), - Rc::new(RefCell::new(not_owned_account)), - Rc::new(RefCell::new(program_account)), + let accounts = vec![ + ( + solana_sdk::pubkey::new_rand(), + Rc::new(RefCell::new(owned_account)), + ), + ( + solana_sdk::pubkey::new_rand(), + Rc::new(RefCell::new(not_owned_account)), + ), + (callee_program_id, Rc::new(RefCell::new(program_account))), ]; let compiled_instruction = CompiledInstruction::new(2, &(), vec![0, 1, 2]); let programs: Vec<(_, ProcessInstructionWithContext)> = vec![(callee_program_id, mock_process_instruction)]; let metas = vec![ - AccountMeta::new(owned_key, false), - AccountMeta::new(not_owned_key, false), + AccountMeta::new(accounts[0].0, false), + AccountMeta::new(accounts[1].0, false), ]; let instruction = Instruction::new_with_bincode( @@ -2250,7 +2238,6 @@ mod tests { &compiled_instruction, &executable_accounts, &accounts, - &[], programs.as_slice(), None, BpfComputeBudget::default(), @@ -2270,7 +2257,7 @@ mod tests { .enumerate() .map(|(i, _)| message.is_writable(i, demote_sysvar_write_locks)) .collect::>(); - accounts[0].borrow_mut().data_as_mut_slice()[0] = 1; + accounts[0].1.borrow_mut().data_as_mut_slice()[0] = 1; assert_eq!( MessageProcessor::process_cross_program_instruction( &message, @@ -2281,7 +2268,7 @@ mod tests { ), Err(InstructionError::ExternalAccountDataModified) ); - accounts[0].borrow_mut().data_as_mut_slice()[0] = 0; + accounts[0].1.borrow_mut().data_as_mut_slice()[0] = 0; let cases = vec![ (MockInstruction::NoopSuccess, Ok(())), @@ -2309,7 +2296,6 @@ mod tests { &compiled_instruction, &executable_accounts, &accounts, - &[], programs.as_slice(), None, BpfComputeBudget::default(), diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 5a43398711..ff47bda3d5 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -64,7 +64,7 @@ pub trait InvokeContext { &mut self, message: &Message, instruction: &CompiledInstruction, - accounts: &[Rc>], + accounts: &[(Pubkey, Rc>)], caller_pivileges: Option<&[bool]>, ) -> Result<(), InstructionError>; /// Get the program ID of the currently executing program @@ -90,7 +90,7 @@ pub trait InvokeContext { fn record_instruction(&self, instruction: &Instruction); /// Get the bank's active feature set fn is_feature_active(&self, feature_id: &Pubkey) -> bool; - /// Get an account from a pre-account + /// Get an account by its key fn get_account(&self, pubkey: &Pubkey) -> Option>>; /// Update timing fn update_timing( @@ -395,7 +395,7 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { &mut self, _message: &Message, _instruction: &CompiledInstruction, - _accounts: &[Rc>], + _accounts: &[(Pubkey, Rc>)], _caller_pivileges: Option<&[bool]>, ) -> Result<(), InstructionError> { Ok(())