From 4c0bc1fd8834985e305c4007a314c95179f25eda Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Tue, 2 Apr 2019 16:02:57 -0600 Subject: [PATCH] Add program_ids() methods Added CompiledInstruction::program_id() so that we don't need to pass around instruction indexes just for Message::program_id(). Also added Message.program_ids() that returns a slice so that we can move those pubkeys into Message::account_keys. --- core/src/storage_stage.rs | 2 +- runtime/src/accounts.rs | 4 ++-- runtime/src/message_processor.rs | 20 ++++++++++---------- sdk/src/instruction.rs | 4 ++++ sdk/src/message.rs | 7 +++---- sdk/src/transaction.rs | 19 +++++++++++-------- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/core/src/storage_stage.rs b/core/src/storage_stage.rs index f26ae94a8b..11a09eb3ab 100644 --- a/core/src/storage_stage.rs +++ b/core/src/storage_stage.rs @@ -402,7 +402,7 @@ impl StorageStage { // the storage_keys with their signatures for tx in entry.transactions { let message = tx.message(); - for (i, program_id) in message.program_ids.iter().enumerate() { + for (i, program_id) in message.program_ids().iter().enumerate() { if solana_storage_api::check_id(&program_id) { match deserialize(&message.instructions[i].data) { Ok(StorageInstruction::SubmitMiningProof { diff --git a/runtime/src/accounts.rs b/runtime/src/accounts.rs index 24ed8caf32..0820a0dec7 100644 --- a/runtime/src/accounts.rs +++ b/runtime/src/accounts.rs @@ -707,11 +707,11 @@ impl AccountsDB { .instructions .iter() .map(|ix| { - if message.program_ids.len() <= ix.program_ids_index as usize { + if message.program_ids().len() <= ix.program_ids_index as usize { error_counters.account_not_found += 1; return Err(TransactionError::AccountNotFound); } - let program_id = message.program_ids[ix.program_ids_index as usize]; + let program_id = message.program_ids()[ix.program_ids_index as usize]; self.load_executable_accounts(fork, &program_id, error_counters) }) .collect() diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index b9153ab64a..40e7f1f37f 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -1,7 +1,7 @@ use crate::native_loader; use crate::system_instruction_processor; use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount}; -use solana_sdk::instruction::InstructionError; +use solana_sdk::instruction::{CompiledInstruction, InstructionError}; use solana_sdk::message::Message; use solana_sdk::pubkey::Pubkey; use solana_sdk::system_program; @@ -118,15 +118,15 @@ impl MessageProcessor { fn process_instruction( &self, message: &Message, - instruction_index: usize, + instruction: &CompiledInstruction, executable_accounts: &mut [(Pubkey, Account)], program_accounts: &mut [&mut Account], tick_height: u64, ) -> Result<(), InstructionError> { - let program_id = message.program_id(instruction_index); + let program_id = instruction.program_id(message.program_ids()); let mut keyed_accounts = create_keyed_accounts(executable_accounts); - let mut keyed_accounts2: Vec<_> = message.instructions[instruction_index] + let mut keyed_accounts2: Vec<_> = instruction .accounts .iter() .map(|&index| { @@ -144,7 +144,7 @@ impl MessageProcessor { return process_instruction( &program_id, &mut keyed_accounts[1..], - &message.instructions[instruction_index].data, + &instruction.data, tick_height, ); } @@ -153,7 +153,7 @@ impl MessageProcessor { native_loader::entrypoint( &program_id, &mut keyed_accounts, - &message.instructions[instruction_index].data, + &instruction.data, tick_height, ) } @@ -165,12 +165,12 @@ impl MessageProcessor { fn execute_instruction( &self, message: &Message, - instruction_index: usize, + instruction: &CompiledInstruction, executable_accounts: &mut [(Pubkey, Account)], program_accounts: &mut [&mut Account], tick_height: u64, ) -> Result<(), InstructionError> { - let program_id = message.program_id(instruction_index); + let program_id = instruction.program_id(message.program_ids()); // TODO: the runtime should be checking read/write access to memory // we are trusting the hard-coded programs not to clobber or allocate let pre_total: u64 = program_accounts.iter().map(|a| a.lamports).sum(); @@ -181,7 +181,7 @@ impl MessageProcessor { self.process_instruction( message, - instruction_index, + instruction, executable_accounts, program_accounts, tick_height, @@ -224,7 +224,7 @@ impl MessageProcessor { .map_err(|err| TransactionError::InstructionError(instruction_index as u8, err))?; self.execute_instruction( message, - instruction_index, + instruction, executable_accounts, &mut program_accounts, tick_height, diff --git a/sdk/src/instruction.rs b/sdk/src/instruction.rs index c6740082fe..5f956d52c7 100644 --- a/sdk/src/instruction.rs +++ b/sdk/src/instruction.rs @@ -129,4 +129,8 @@ impl CompiledInstruction { accounts, } } + + pub fn program_id<'a>(&self, program_ids: &'a [Pubkey]) -> &'a Pubkey { + &program_ids[self.program_ids_index as usize] + } } diff --git a/sdk/src/message.rs b/sdk/src/message.rs index 71340d0770..654bad71b1 100644 --- a/sdk/src/message.rs +++ b/sdk/src/message.rs @@ -83,7 +83,7 @@ pub struct Message { /// All the program id keys used to execute this transaction's instructions #[serde(with = "short_vec")] - pub program_ids: Vec, + program_ids: Vec, /// Programs that will be executed in sequence and committed in one atomic transaction if all /// succeed. @@ -123,9 +123,8 @@ impl Message { ) } - pub fn program_id(&self, instruction_index: usize) -> &Pubkey { - let program_ids_index = self.instructions[instruction_index].program_ids_index; - &self.program_ids[program_ids_index as usize] + pub fn program_ids(&self) -> &[Pubkey] { + &self.program_ids } } diff --git a/sdk/src/transaction.rs b/sdk/src/transaction.rs index 242103975f..36d98663e6 100644 --- a/sdk/src/transaction.rs +++ b/sdk/src/transaction.rs @@ -145,9 +145,6 @@ impl Transaction { } } } - pub fn program_id(&self, instruction_index: usize) -> &Pubkey { - self.message().program_id(instruction_index) - } /// Return a message containing all data that should be signed. pub fn message(&self) -> &Message { @@ -185,7 +182,7 @@ impl Transaction { pub fn verify_refs(&self) -> bool { let message = self.message(); for instruction in &message.instructions { - if (instruction.program_ids_index as usize) >= message.program_ids.len() { + if (instruction.program_ids_index as usize) >= message.program_ids().len() { return false; } for account_index in &instruction.accounts { @@ -207,6 +204,12 @@ mod tests { use bincode::{deserialize, serialize, serialized_size}; use std::mem::size_of; + fn get_program_id(tx: &Transaction, instruction_index: usize) -> &Pubkey { + let message = tx.message(); + let instruction = &message.instructions[instruction_index]; + instruction.program_id(message.program_ids()) + } + #[test] fn test_refs() { let key = Keypair::new(); @@ -245,8 +248,8 @@ mod tests { assert_eq!(tx.key(0, 2), None); assert_eq!(tx.signer_key(0, 2), None); - assert_eq!(*tx.program_id(0), prog1); - assert_eq!(*tx.program_id(1), prog2); + assert_eq!(*get_program_id(&tx, 0), prog1); + assert_eq!(*get_program_id(&tx, 1), prog2); } #[test] fn test_refs_invalid_program_id() { @@ -272,7 +275,7 @@ mod tests { vec![Pubkey::default()], instructions, ); - assert_eq!(*tx.program_id(0), Pubkey::default()); + assert_eq!(*get_program_id(&tx, 0), Pubkey::default()); assert!(!tx.verify_refs()); } @@ -350,7 +353,7 @@ mod tests { + (tx.message.account_keys.len() * size_of::()) + blockhash_size + len_size - + (tx.message.program_ids.len() * size_of::()) + + (tx.message.program_ids().len() * size_of::()) + len_size + expected_instruction_size; assert_eq!(expected_transaction_size, 214);