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.
This commit is contained in:
parent
025b4f90de
commit
4c0bc1fd88
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Pubkey>,
|
||||
program_ids: Vec<Pubkey>,
|
||||
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<Pubkey>())
|
||||
+ blockhash_size
|
||||
+ len_size
|
||||
+ (tx.message.program_ids.len() * size_of::<Pubkey>())
|
||||
+ (tx.message.program_ids().len() * size_of::<Pubkey>())
|
||||
+ len_size
|
||||
+ expected_instruction_size;
|
||||
assert_eq!(expected_transaction_size, 214);
|
||||
|
|
Loading…
Reference in New Issue