From 61d91d2d55d01c4552d300c8007244071ab83ea4 Mon Sep 17 00:00:00 2001 From: Jack May Date: Wed, 3 Jun 2020 21:16:15 -0700 Subject: [PATCH] Don't reuse executable accounts between instructions (#10403) automerge --- runtime/src/bank.rs | 38 ++++++++++++++++++++++++++++++++ runtime/src/message_processor.rs | 7 +----- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 3b537d65cd..8959f236ac 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -6993,4 +6993,42 @@ mod tests { bank = Arc::new(new_from_parent(&bank)); } } + + #[test] + fn test_same_program_id_uses_unqiue_executable_accounts() { + fn nested_processor( + _program_id: &Pubkey, + keyed_accounts: &[KeyedAccount], + _data: &[u8], + ) -> result::Result<(), InstructionError> { + assert_eq!(42, keyed_accounts[0].lamports().unwrap()); + let mut account = keyed_accounts[0].try_account_ref_mut()?; + account.lamports += 1; + Ok(()) + } + + let (genesis_config, mint_keypair) = create_genesis_config(50000); + let mut bank = Bank::new(&genesis_config); + + // Add a new program + let program1_pubkey = Pubkey::new_rand(); + bank.add_builtin_program("program", program1_pubkey, nested_processor); + + // Add a new program owned by the first + let program2_pubkey = Pubkey::new_rand(); + let mut program2_account = Account::new(42, 1, &program1_pubkey); + program2_account.executable = true; + bank.store_account(&program2_pubkey, &program2_account); + + let instruction = Instruction::new(program2_pubkey, &10, vec![]); + let tx = Transaction::new_signed_with_payer( + &[instruction.clone(), instruction], + Some(&mint_keypair.pubkey()), + &[&mint_keypair], + bank.last_blockhash(), + ); + assert!(bank.process_transaction(&tx).is_ok()); + assert_eq!(1, bank.get_balance(&program1_pubkey)); + assert_eq!(42, bank.get_balance(&program2_pubkey)); + } } diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 0504de8fc0..3f727df3cf 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -516,15 +516,10 @@ impl MessageProcessor { rent_collector: &RentCollector, ) -> Result<(), TransactionError> { for (instruction_index, instruction) in message.instructions.iter().enumerate() { - let executable_index = message - .program_position(instruction.program_id_index as usize) - .ok_or(TransactionError::InvalidAccountIndex)?; - let executable_accounts = &loaders[executable_index]; - self.execute_instruction( message, instruction, - executable_accounts, + &loaders[instruction_index], accounts, rent_collector, )