Cleanup: get_program_key() and get_loader_key() in TransactionContext (#23191)

* Moves TransactionContext::get_program_key() to InstructionContext::get_program_key().

* Removes TransactionContext::get_loader_key().

* Test full program and loader executable account chain in BPF loader.
This commit is contained in:
Alexander Meißner 2022-02-17 10:16:28 +01:00 committed by GitHub
parent 619335df1a
commit da00b39f4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 247 additions and 361 deletions

View File

@ -443,9 +443,12 @@ impl<'a> InvokeContext<'a> {
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let do_support_realloc = self.feature_set.is_active(&do_support_realloc::id()); let do_support_realloc = self.feature_set.is_active(&do_support_realloc::id());
let cap_accounts_data_len = self.feature_set.is_active(&cap_accounts_data_len::id()); let cap_accounts_data_len = self.feature_set.is_active(&cap_accounts_data_len::id());
let program_id = self let instruction_context = self
.transaction_context .transaction_context
.get_program_key() .get_current_instruction_context()
.map_err(|_| InstructionError::CallDepth)?;
let program_id = instruction_context
.get_program_key(self.transaction_context)
.map_err(|_| InstructionError::CallDepth)?; .map_err(|_| InstructionError::CallDepth)?;
// Verify all executable accounts have zero outstanding refs // Verify all executable accounts have zero outstanding refs
@ -530,8 +533,8 @@ impl<'a> InvokeContext<'a> {
let cap_accounts_data_len = self.feature_set.is_active(&cap_accounts_data_len::id()); let cap_accounts_data_len = self.feature_set.is_active(&cap_accounts_data_len::id());
let transaction_context = &self.transaction_context; let transaction_context = &self.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?; let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = transaction_context let program_id = instruction_context
.get_program_key() .get_program_key(transaction_context)
.map_err(|_| InstructionError::CallDepth)?; .map_err(|_| InstructionError::CallDepth)?;
// Verify the per-account instruction results // Verify the per-account instruction results
@ -1268,7 +1271,7 @@ mod tests {
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let transaction_context = &invoke_context.transaction_context; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?; let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = transaction_context.get_program_key()?; let program_id = instruction_context.get_program_key(transaction_context)?;
assert_eq!( assert_eq!(
program_id, program_id,
instruction_context instruction_context

View File

@ -170,7 +170,9 @@ impl NativeLoader {
invoke_context: &mut InvokeContext, invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let (program_id, name_vec) = { let (program_id, name_vec) = {
let program_id = invoke_context.transaction_context.get_program_key()?; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = instruction_context.get_program_key(transaction_context)?;
let keyed_accounts = invoke_context.get_keyed_accounts()?; let keyed_accounts = invoke_context.get_keyed_accounts()?;
let program = keyed_account_at_index(keyed_accounts, first_instruction_account)?; let program = keyed_account_at_index(keyed_accounts, first_instruction_account)?;
if native_loader::id() != *program_id { if native_loader::id() != *program_id {

View File

@ -105,7 +105,7 @@ pub fn builtin_process_instruction(
..instruction_context.get_number_of_accounts(); ..instruction_context.get_number_of_accounts();
let log_collector = invoke_context.get_log_collector(); let log_collector = invoke_context.get_log_collector();
let program_id = transaction_context.get_program_key()?; let program_id = instruction_context.get_program_key(transaction_context)?;
stable_log::program_invoke( stable_log::program_invoke(
&log_collector, &log_collector,
program_id, program_id,
@ -250,10 +250,12 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
) -> ProgramResult { ) -> ProgramResult {
let invoke_context = get_invoke_context(); let invoke_context = get_invoke_context();
let log_collector = invoke_context.get_log_collector(); let log_collector = invoke_context.get_log_collector();
let transaction_context = &invoke_context.transaction_context;
let caller = *invoke_context let instruction_context = transaction_context
.transaction_context .get_current_instruction_context()
.get_program_key() .unwrap();
let caller = instruction_context
.get_program_key(transaction_context)
.unwrap(); .unwrap();
stable_log::program_invoke( stable_log::program_invoke(
@ -264,7 +266,7 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
let signers = signers_seeds let signers = signers_seeds
.iter() .iter()
.map(|seeds| Pubkey::create_program_address(seeds, &caller).unwrap()) .map(|seeds| Pubkey::create_program_address(seeds, caller).unwrap())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let (instruction_accounts, program_indices) = invoke_context let (instruction_accounts, program_indices) = invoke_context
.prepare_instruction(instruction, &signers) .prepare_instruction(instruction, &signers)
@ -374,12 +376,14 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
fn sol_set_return_data(&self, data: &[u8]) { fn sol_set_return_data(&self, data: &[u8]) {
let invoke_context = get_invoke_context(); let invoke_context = get_invoke_context();
let caller = *invoke_context let transaction_context = &mut invoke_context.transaction_context;
.transaction_context let instruction_context = transaction_context
.get_program_key() .get_current_instruction_context()
.unwrap(); .unwrap();
invoke_context let caller = *instruction_context
.transaction_context .get_program_key(transaction_context)
.unwrap();
transaction_context
.set_return_data(caller, data.to_vec()) .set_return_data(caller, data.to_vec())
.unwrap(); .unwrap();
} }

View File

@ -229,13 +229,12 @@ fn run_program(name: &str) -> u64 {
let mut instruction_count = 0; let mut instruction_count = 0;
let mut tracer = None; let mut tracer = None;
for i in 0..2 { for i in 0..2 {
invoke_context let transaction_context = &mut invoke_context.transaction_context;
.transaction_context let instruction_context = transaction_context.get_current_instruction_context().unwrap();
let caller = *instruction_context.get_program_key(transaction_context).unwrap();
transaction_context
.set_return_data( .set_return_data(
*invoke_context caller,
.transaction_context
.get_program_key()
.unwrap(),
Vec::new(), Vec::new(),
) )
.unwrap(); .unwrap();

View File

@ -273,7 +273,9 @@ fn process_instruction_common(
use_jit: bool, use_jit: bool,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let log_collector = invoke_context.get_log_collector(); let log_collector = invoke_context.get_log_collector();
let program_id = invoke_context.transaction_context.get_program_key()?; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = instruction_context.get_program_key(transaction_context)?;
let keyed_accounts = invoke_context.get_keyed_accounts()?; let keyed_accounts = invoke_context.get_keyed_accounts()?;
let first_account = keyed_account_at_index(keyed_accounts, first_instruction_account)?; let first_account = keyed_account_at_index(keyed_accounts, first_instruction_account)?;
@ -350,7 +352,9 @@ fn process_instruction_common(
use_jit, use_jit,
false, false,
)?; )?;
let program_id = invoke_context.transaction_context.get_program_key()?; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = instruction_context.get_program_key(transaction_context)?;
invoke_context.add_executor(program_id, executor.clone()); invoke_context.add_executor(program_id, executor.clone());
executor executor
} }
@ -397,7 +401,9 @@ fn process_loader_upgradeable_instruction(
use_jit: bool, use_jit: bool,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let log_collector = invoke_context.get_log_collector(); let log_collector = invoke_context.get_log_collector();
let program_id = invoke_context.transaction_context.get_program_key()?; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = instruction_context.get_program_key(transaction_context)?;
let keyed_accounts = invoke_context.get_keyed_accounts()?; let keyed_accounts = invoke_context.get_keyed_accounts()?;
match limited_deserialize(instruction_data)? { match limited_deserialize(instruction_data)? {
@ -550,7 +556,9 @@ fn process_loader_upgradeable_instruction(
.accounts .accounts
.push(AccountMeta::new(*buffer.unsigned_key(), false)); .push(AccountMeta::new(*buffer.unsigned_key(), false));
let caller_program_id = invoke_context.transaction_context.get_program_key()?; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let caller_program_id = instruction_context.get_program_key(transaction_context)?;
let signers = [&[new_program_id.as_ref(), &[bump_seed]]] let signers = [&[new_program_id.as_ref(), &[bump_seed]]]
.iter() .iter()
.map(|seeds| Pubkey::create_program_address(*seeds, caller_program_id)) .map(|seeds| Pubkey::create_program_address(*seeds, caller_program_id))
@ -947,7 +955,9 @@ fn process_loader_instruction(
invoke_context: &mut InvokeContext, invoke_context: &mut InvokeContext,
use_jit: bool, use_jit: bool,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let program_id = invoke_context.transaction_context.get_program_key()?; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = instruction_context.get_program_key(transaction_context)?;
let keyed_accounts = invoke_context.get_keyed_accounts()?; let keyed_accounts = invoke_context.get_keyed_accounts()?;
let program = keyed_account_at_index(keyed_accounts, first_instruction_account)?; let program = keyed_account_at_index(keyed_accounts, first_instruction_account)?;
if program.owner()? != *program_id { if program.owner()? != *program_id {
@ -1036,15 +1046,13 @@ impl Executor for BpfExecutor {
let log_collector = invoke_context.get_log_collector(); let log_collector = invoke_context.get_log_collector();
let compute_meter = invoke_context.get_compute_meter(); let compute_meter = invoke_context.get_compute_meter();
let stack_height = invoke_context.get_stack_height(); let stack_height = invoke_context.get_stack_height();
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = *instruction_context.get_program_key(transaction_context)?;
let mut serialize_time = Measure::start("serialize"); let mut serialize_time = Measure::start("serialize");
let program_id = *invoke_context.transaction_context.get_program_key()?; let (mut parameter_bytes, account_lengths) =
let (mut parameter_bytes, account_lengths) = serialize_parameters( serialize_parameters(invoke_context.transaction_context, instruction_context)?;
invoke_context.transaction_context,
invoke_context
.transaction_context
.get_current_instruction_context()?,
)?;
serialize_time.stop(); serialize_time.stop();
let mut create_vm_time = Measure::start("create_vm"); let mut create_vm_time = Measure::start("create_vm");
let mut execute_time; let mut execute_time;

View File

@ -289,7 +289,11 @@ pub fn bind_syscall_context_objects<'a, 'b>(
let loader_id = invoke_context let loader_id = invoke_context
.transaction_context .transaction_context
.get_loader_key() .get_current_instruction_context()
.and_then(|instruction_context| {
instruction_context.try_borrow_program_account(invoke_context.transaction_context)
})
.map(|program_account| *program_account.get_owner())
.map_err(SyscallError::InstructionError)?; .map_err(SyscallError::InstructionError)?;
let invoke_context = Rc::new(RefCell::new(invoke_context)); let invoke_context = Rc::new(RefCell::new(invoke_context));
@ -617,6 +621,18 @@ fn translate_string_and_do(
} }
} }
/// Returns the owner of the program account in the current InstructionContext
fn get_current_loader_key(invoke_context: &InvokeContext) -> Result<Pubkey, SyscallError> {
invoke_context
.transaction_context
.get_current_instruction_context()
.and_then(|instruction_context| {
instruction_context.try_borrow_program_account(invoke_context.transaction_context)
})
.map(|program_account| *program_account.get_owner())
.map_err(SyscallError::InstructionError)
}
/// Abort syscall functions, called when the BPF program calls `abort()` /// Abort syscall functions, called when the BPF program calls `abort()`
/// LLVM will insert calls to `abort()` if it detects an untenable situation, /// LLVM will insert calls to `abort()` if it detects an untenable situation,
/// `abort()` is not intended to be called explicitly by the program. /// `abort()` is not intended to be called explicitly by the program.
@ -666,20 +682,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallPanic<'a, 'b> {
{ {
question_mark!(invoke_context.get_compute_meter().consume(len), result); question_mark!(invoke_context.get_compute_meter().consume(len), result);
} }
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context *result =
.transaction_context translate_string_and_do(memory_mapping, file, len, loader_id, &mut |string: &str| {
.get_loader_key() Err(SyscallError::Panic(string.to_string(), line, column).into())
.map_err(SyscallError::InstructionError), });
result
);
*result = translate_string_and_do(
memory_mapping,
file,
len,
&loader_id,
&mut |string: &str| Err(SyscallError::Panic(string.to_string(), line, column).into()),
);
} }
} }
@ -717,24 +724,12 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLog<'a, 'b> {
}; };
question_mark!(invoke_context.get_compute_meter().consume(cost), result); question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
question_mark!( question_mark!(
translate_string_and_do( translate_string_and_do(memory_mapping, addr, len, loader_id, &mut |string: &str| {
memory_mapping, stable_log::program_log(&invoke_context.get_log_collector(), string);
addr, Ok(0)
len, }),
&loader_id,
&mut |string: &str| {
stable_log::program_log(&invoke_context.get_log_collector(), string);
Ok(0)
},
),
result result
); );
*result = Ok(0); *result = Ok(0);
@ -840,15 +835,9 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLogPubkey<'a, 'b> {
let cost = invoke_context.get_compute_budget().log_pubkey_units; let cost = invoke_context.get_compute_budget().log_pubkey_units;
question_mark!(invoke_context.get_compute_meter().consume(cost), result); question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let pubkey = question_mark!( let pubkey = question_mark!(
translate_type::<Pubkey>(memory_mapping, pubkey_addr, &loader_id), translate_type::<Pubkey>(memory_mapping, pubkey_addr, loader_id),
result result
); );
stable_log::program_log(&invoke_context.get_log_collector(), &pubkey.to_string()); stable_log::program_log(&invoke_context.get_log_collector(), &pubkey.to_string());
@ -957,20 +946,14 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a, 'b> {
.create_program_address_units; .create_program_address_units;
question_mark!(invoke_context.get_compute_meter().consume(cost), result); question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let (seeds, program_id) = question_mark!( let (seeds, program_id) = question_mark!(
translate_and_check_program_address_inputs( translate_and_check_program_address_inputs(
seeds_addr, seeds_addr,
seeds_len, seeds_len,
program_id_addr, program_id_addr,
memory_mapping, memory_mapping,
&loader_id, loader_id,
), ),
result result
); );
@ -983,7 +966,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a, 'b> {
} }
}; };
let address = question_mark!( let address = question_mark!(
translate_slice_mut::<u8>(memory_mapping, address_addr, 32, &loader_id), translate_slice_mut::<u8>(memory_mapping, address_addr, 32, loader_id),
result result
); );
address.copy_from_slice(new_address.as_ref()); address.copy_from_slice(new_address.as_ref());
@ -1017,20 +1000,14 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a, 'b> {
.create_program_address_units; .create_program_address_units;
question_mark!(invoke_context.get_compute_meter().consume(cost), result); question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let (seeds, program_id) = question_mark!( let (seeds, program_id) = question_mark!(
translate_and_check_program_address_inputs( translate_and_check_program_address_inputs(
seeds_addr, seeds_addr,
seeds_len, seeds_len,
program_id_addr, program_id_addr,
memory_mapping, memory_mapping,
&loader_id, loader_id,
), ),
result result
); );
@ -1045,11 +1022,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a, 'b> {
Pubkey::create_program_address(&seeds_with_bump, program_id) Pubkey::create_program_address(&seeds_with_bump, program_id)
{ {
let bump_seed_ref = question_mark!( let bump_seed_ref = question_mark!(
translate_type_mut::<u8>(memory_mapping, bump_seed_addr, &loader_id), translate_type_mut::<u8>(memory_mapping, bump_seed_addr, loader_id),
result result
); );
let address = question_mark!( let address = question_mark!(
translate_slice_mut::<u8>(memory_mapping, address_addr, 32, &loader_id), translate_slice_mut::<u8>(memory_mapping, address_addr, 32, loader_id),
result result
); );
*bump_seed_ref = bump_seed[0]; *bump_seed_ref = bump_seed[0];
@ -1094,21 +1071,15 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSha256<'a, 'b> {
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let hash_result = question_mark!( let hash_result = question_mark!(
translate_slice_mut::<u8>(memory_mapping, result_addr, HASH_BYTES as u64, &loader_id), translate_slice_mut::<u8>(memory_mapping, result_addr, HASH_BYTES as u64, loader_id),
result result
); );
let mut hasher = Hasher::default(); let mut hasher = Hasher::default();
if vals_len > 0 { if vals_len > 0 {
let vals = question_mark!( let vals = question_mark!(
translate_slice::<&[u8]>(memory_mapping, vals_addr, vals_len, &loader_id), translate_slice::<&[u8]>(memory_mapping, vals_addr, vals_len, loader_id),
result result
); );
for val in vals.iter() { for val in vals.iter() {
@ -1117,7 +1088,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSha256<'a, 'b> {
memory_mapping, memory_mapping,
val.as_ptr() as u64, val.as_ptr() as u64,
val.len() as u64, val.len() as u64,
&loader_id, loader_id,
), ),
result result
); );
@ -1170,17 +1141,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetClockSysvar<'a, 'b> {
.map_err(|_| SyscallError::InvokeContextBorrowFailed), .map_err(|_| SyscallError::InvokeContextBorrowFailed),
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
*result = get_sysvar( *result = get_sysvar(
invoke_context.get_sysvar_cache().get_clock(), invoke_context.get_sysvar_cache().get_clock(),
var_addr, var_addr,
&loader_id, loader_id,
memory_mapping, memory_mapping,
&mut invoke_context, &mut invoke_context,
); );
@ -1207,17 +1172,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a, 'b> {
.map_err(|_| SyscallError::InvokeContextBorrowFailed), .map_err(|_| SyscallError::InvokeContextBorrowFailed),
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
*result = get_sysvar( *result = get_sysvar(
invoke_context.get_sysvar_cache().get_epoch_schedule(), invoke_context.get_sysvar_cache().get_epoch_schedule(),
var_addr, var_addr,
&loader_id, loader_id,
memory_mapping, memory_mapping,
&mut invoke_context, &mut invoke_context,
); );
@ -1245,17 +1204,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a, 'b> {
.map_err(|_| SyscallError::InvokeContextBorrowFailed), .map_err(|_| SyscallError::InvokeContextBorrowFailed),
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
*result = get_sysvar( *result = get_sysvar(
invoke_context.get_sysvar_cache().get_fees(), invoke_context.get_sysvar_cache().get_fees(),
var_addr, var_addr,
&loader_id, loader_id,
memory_mapping, memory_mapping,
&mut invoke_context, &mut invoke_context,
); );
@ -1282,17 +1235,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetRentSysvar<'a, 'b> {
.map_err(|_| SyscallError::InvokeContextBorrowFailed), .map_err(|_| SyscallError::InvokeContextBorrowFailed),
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
*result = get_sysvar( *result = get_sysvar(
invoke_context.get_sysvar_cache().get_rent(), invoke_context.get_sysvar_cache().get_rent(),
var_addr, var_addr,
&loader_id, loader_id,
memory_mapping, memory_mapping,
&mut invoke_context, &mut invoke_context,
); );
@ -1328,26 +1275,20 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallKeccak256<'a, 'b> {
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let hash_result = question_mark!( let hash_result = question_mark!(
translate_slice_mut::<u8>( translate_slice_mut::<u8>(
memory_mapping, memory_mapping,
result_addr, result_addr,
keccak::HASH_BYTES as u64, keccak::HASH_BYTES as u64,
&loader_id, loader_id,
), ),
result result
); );
let mut hasher = keccak::Hasher::default(); let mut hasher = keccak::Hasher::default();
if vals_len > 0 { if vals_len > 0 {
let vals = question_mark!( let vals = question_mark!(
translate_slice::<&[u8]>(memory_mapping, vals_addr, vals_len, &loader_id), translate_slice::<&[u8]>(memory_mapping, vals_addr, vals_len, loader_id),
result result
); );
for val in vals.iter() { for val in vals.iter() {
@ -1356,7 +1297,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallKeccak256<'a, 'b> {
memory_mapping, memory_mapping,
val.as_ptr() as u64, val.as_ptr() as u64,
val.len() as u64, val.len() as u64,
&loader_id, loader_id,
), ),
result result
); );
@ -1451,19 +1392,13 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcpy<'a, 'b> {
question_mark!(invoke_context.get_compute_meter().consume(cost), result); question_mark!(invoke_context.get_compute_meter().consume(cost), result);
}; };
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let dst = question_mark!( let dst = question_mark!(
translate_slice_mut::<u8>(memory_mapping, dst_addr, n, &loader_id), translate_slice_mut::<u8>(memory_mapping, dst_addr, n, loader_id),
result result
); );
let src = question_mark!( let src = question_mark!(
translate_slice::<u8>(memory_mapping, src_addr, n, &loader_id), translate_slice::<u8>(memory_mapping, src_addr, n, loader_id),
result result
); );
unsafe { unsafe {
@ -1495,19 +1430,13 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemmove<'a, 'b> {
); );
question_mark!(mem_op_consume(&invoke_context, n), result); question_mark!(mem_op_consume(&invoke_context, n), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let dst = question_mark!( let dst = question_mark!(
translate_slice_mut::<u8>(memory_mapping, dst_addr, n, &loader_id), translate_slice_mut::<u8>(memory_mapping, dst_addr, n, loader_id),
result result
); );
let src = question_mark!( let src = question_mark!(
translate_slice::<u8>(memory_mapping, src_addr, n, &loader_id), translate_slice::<u8>(memory_mapping, src_addr, n, loader_id),
result result
); );
unsafe { unsafe {
@ -1539,23 +1468,17 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcmp<'a, 'b> {
); );
question_mark!(mem_op_consume(&invoke_context, n), result); question_mark!(mem_op_consume(&invoke_context, n), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let s1 = question_mark!( let s1 = question_mark!(
translate_slice::<u8>(memory_mapping, s1_addr, n, &loader_id), translate_slice::<u8>(memory_mapping, s1_addr, n, loader_id),
result result
); );
let s2 = question_mark!( let s2 = question_mark!(
translate_slice::<u8>(memory_mapping, s2_addr, n, &loader_id), translate_slice::<u8>(memory_mapping, s2_addr, n, loader_id),
result result
); );
let cmp_result = question_mark!( let cmp_result = question_mark!(
translate_type_mut::<i32>(memory_mapping, cmp_result_addr, &loader_id), translate_type_mut::<i32>(memory_mapping, cmp_result_addr, loader_id),
result result
); );
let mut i = 0; let mut i = 0;
@ -1596,15 +1519,9 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemset<'a, 'b> {
); );
question_mark!(mem_op_consume(&invoke_context, n), result); question_mark!(mem_op_consume(&invoke_context, n), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let s = question_mark!( let s = question_mark!(
translate_slice_mut::<u8>(memory_mapping, s_addr, n, &loader_id), translate_slice_mut::<u8>(memory_mapping, s_addr, n, loader_id),
result result
); );
for val in s.iter_mut().take(n as usize) { for val in s.iter_mut().take(n as usize) {
@ -1639,19 +1556,13 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a, 'b> {
let cost = invoke_context.get_compute_budget().secp256k1_recover_cost; let cost = invoke_context.get_compute_budget().secp256k1_recover_cost;
question_mark!(invoke_context.get_compute_meter().consume(cost), result); question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let hash = question_mark!( let hash = question_mark!(
translate_slice::<u8>( translate_slice::<u8>(
memory_mapping, memory_mapping,
hash_addr, hash_addr,
keccak::HASH_BYTES as u64, keccak::HASH_BYTES as u64,
&loader_id, loader_id,
), ),
result result
); );
@ -1660,7 +1571,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a, 'b> {
memory_mapping, memory_mapping,
signature_addr, signature_addr,
SECP256K1_SIGNATURE_LENGTH as u64, SECP256K1_SIGNATURE_LENGTH as u64,
&loader_id, loader_id,
), ),
result result
); );
@ -1669,7 +1580,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a, 'b> {
memory_mapping, memory_mapping,
result_addr, result_addr,
SECP256K1_PUBLIC_KEY_LENGTH as u64, SECP256K1_PUBLIC_KEY_LENGTH as u64,
&loader_id, loader_id,
), ),
result result
); );
@ -1744,20 +1655,13 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallZkTokenElgamalOp<'a, 'b> {
let cost = invoke_context.get_compute_budget().zk_token_elgamal_op_cost; let cost = invoke_context.get_compute_budget().zk_token_elgamal_op_cost;
question_mark!(invoke_context.get_compute_meter().consume(cost), result); question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let ct_0 = question_mark!( let ct_0 = question_mark!(
translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_0_addr, &loader_id), translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_0_addr, loader_id),
result result
); );
let ct_1 = question_mark!( let ct_1 = question_mark!(
translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_1_addr, &loader_id), translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_1_addr, loader_id),
result result
); );
@ -1770,7 +1674,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallZkTokenElgamalOp<'a, 'b> {
translate_type_mut::<pod::ElGamalCiphertext>( translate_type_mut::<pod::ElGamalCiphertext>(
memory_mapping, memory_mapping,
ct_result_addr, ct_result_addr,
&loader_id, loader_id,
), ),
result result
) = ct_result; ) = ct_result;
@ -1807,24 +1711,17 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallZkTokenElgamalOpWithLoHi<'a, 'b>
let cost = invoke_context.get_compute_budget().zk_token_elgamal_op_cost; let cost = invoke_context.get_compute_budget().zk_token_elgamal_op_cost;
question_mark!(invoke_context.get_compute_meter().consume(cost), result); question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let ct_0 = question_mark!( let ct_0 = question_mark!(
translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_0_addr, &loader_id), translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_0_addr, loader_id),
result result
); );
let ct_1_lo = question_mark!( let ct_1_lo = question_mark!(
translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_1_lo_addr, &loader_id), translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_1_lo_addr, loader_id),
result result
); );
let ct_1_hi = question_mark!( let ct_1_hi = question_mark!(
translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_1_hi_addr, &loader_id), translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_1_hi_addr, loader_id),
result result
); );
@ -1837,7 +1734,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallZkTokenElgamalOpWithLoHi<'a, 'b>
translate_type_mut::<pod::ElGamalCiphertext>( translate_type_mut::<pod::ElGamalCiphertext>(
memory_mapping, memory_mapping,
ct_result_addr, ct_result_addr,
&loader_id, loader_id,
), ),
result result
) = ct_result; ) = ct_result;
@ -1874,16 +1771,9 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallZkTokenElgamalOpWithScalar<'a, '
let cost = invoke_context.get_compute_budget().zk_token_elgamal_op_cost; let cost = invoke_context.get_compute_budget().zk_token_elgamal_op_cost;
question_mark!(invoke_context.get_compute_meter().consume(cost), result); question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let ct = question_mark!( let ct = question_mark!(
translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_addr, &loader_id), translate_type::<pod::ElGamalCiphertext>(memory_mapping, ct_addr, loader_id),
result result
); );
@ -1896,7 +1786,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallZkTokenElgamalOpWithScalar<'a, '
translate_type_mut::<pod::ElGamalCiphertext>( translate_type_mut::<pod::ElGamalCiphertext>(
memory_mapping, memory_mapping,
ct_result_addr, ct_result_addr,
&loader_id, loader_id,
), ),
result result
) = ct_result; ) = ct_result;
@ -1936,26 +1826,20 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallBlake3<'a, 'b> {
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let hash_result = question_mark!( let hash_result = question_mark!(
translate_slice_mut::<u8>( translate_slice_mut::<u8>(
memory_mapping, memory_mapping,
result_addr, result_addr,
blake3::HASH_BYTES as u64, blake3::HASH_BYTES as u64,
&loader_id, loader_id,
), ),
result result
); );
let mut hasher = blake3::Hasher::default(); let mut hasher = blake3::Hasher::default();
if vals_len > 0 { if vals_len > 0 {
let vals = question_mark!( let vals = question_mark!(
translate_slice::<&[u8]>(memory_mapping, vals_addr, vals_len, &loader_id), translate_slice::<&[u8]>(memory_mapping, vals_addr, vals_len, loader_id),
result result
); );
for val in vals.iter() { for val in vals.iter() {
@ -1964,7 +1848,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallBlake3<'a, 'b> {
memory_mapping, memory_mapping,
val.as_ptr() as u64, val.as_ptr() as u64,
val.len() as u64, val.len() as u64,
&loader_id, loader_id,
), ),
result result
); );
@ -2676,7 +2560,11 @@ fn call<'a, 'b: 'a>(
// Translate and verify caller's data // Translate and verify caller's data
let loader_id = invoke_context let loader_id = invoke_context
.transaction_context .transaction_context
.get_loader_key() .get_current_instruction_context()
.and_then(|instruction_context| {
instruction_context.try_borrow_program_account(invoke_context.transaction_context)
})
.map(|program_account| *program_account.get_owner())
.map_err(SyscallError::InstructionError)?; .map_err(SyscallError::InstructionError)?;
let instruction = syscall.translate_instruction( let instruction = syscall.translate_instruction(
&loader_id, &loader_id,
@ -2684,9 +2572,12 @@ fn call<'a, 'b: 'a>(
memory_mapping, memory_mapping,
*invoke_context, *invoke_context,
)?; )?;
let caller_program_id = invoke_context let transaction_context = &invoke_context.transaction_context;
.transaction_context let instruction_context = transaction_context
.get_program_key() .get_current_instruction_context()
.map_err(SyscallError::InstructionError)?;
let caller_program_id = instruction_context
.get_program_key(transaction_context)
.map_err(SyscallError::InstructionError)?; .map_err(SyscallError::InstructionError)?;
let signers = syscall.translate_signers( let signers = syscall.translate_signers(
&loader_id, &loader_id,
@ -2801,14 +2692,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSetReturnData<'a, 'b> {
.map_err(|_| SyscallError::InvokeContextBorrowFailed), .map_err(|_| SyscallError::InvokeContextBorrowFailed),
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let budget = invoke_context.get_compute_budget(); let budget = invoke_context.get_compute_budget();
question_mark!( question_mark!(
@ -2827,21 +2711,23 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSetReturnData<'a, 'b> {
Vec::new() Vec::new()
} else { } else {
question_mark!( question_mark!(
translate_slice::<u8>(memory_mapping, addr, len, &loader_id), translate_slice::<u8>(memory_mapping, addr, len, loader_id),
result result
) )
.to_vec() .to_vec()
}; };
let transaction_context = &mut invoke_context.transaction_context;
let program_id = *question_mark!( let program_id = *question_mark!(
invoke_context transaction_context
.transaction_context .get_current_instruction_context()
.get_program_key() .and_then(
|instruction_context| instruction_context.get_program_key(transaction_context)
)
.map_err(SyscallError::InstructionError), .map_err(SyscallError::InstructionError),
result result
); );
question_mark!( question_mark!(
invoke_context transaction_context
.transaction_context
.set_return_data(program_id, return_data) .set_return_data(program_id, return_data)
.map_err(SyscallError::InstructionError), .map_err(SyscallError::InstructionError),
result result
@ -2871,14 +2757,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetReturnData<'a, 'b> {
.map_err(|_| SyscallError::InvokeContextBorrowFailed), .map_err(|_| SyscallError::InvokeContextBorrowFailed),
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let budget = invoke_context.get_compute_budget(); let budget = invoke_context.get_compute_budget();
question_mark!( question_mark!(
@ -2899,14 +2778,14 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetReturnData<'a, 'b> {
); );
let return_data_result = question_mark!( let return_data_result = question_mark!(
translate_slice_mut::<u8>(memory_mapping, return_data_addr, length, &loader_id), translate_slice_mut::<u8>(memory_mapping, return_data_addr, length, loader_id),
result result
); );
return_data_result.copy_from_slice(&return_data[..length as usize]); return_data_result.copy_from_slice(&return_data[..length as usize]);
let program_id_result = question_mark!( let program_id_result = question_mark!(
translate_slice_mut::<Pubkey>(memory_mapping, program_id_addr, 1, &loader_id), translate_slice_mut::<Pubkey>(memory_mapping, program_id_addr, 1, loader_id),
result result
); );
@ -2939,14 +2818,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLogData<'a, 'b> {
.map_err(|_| SyscallError::InvokeContextBorrowFailed), .map_err(|_| SyscallError::InvokeContextBorrowFailed),
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let budget = invoke_context.get_compute_budget(); let budget = invoke_context.get_compute_budget();
question_mark!( question_mark!(
@ -2957,7 +2829,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLogData<'a, 'b> {
); );
let untranslated_fields = question_mark!( let untranslated_fields = question_mark!(
translate_slice::<&[u8]>(memory_mapping, addr, len, &loader_id), translate_slice::<&[u8]>(memory_mapping, addr, len, loader_id),
result result
); );
@ -2986,7 +2858,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLogData<'a, 'b> {
memory_mapping, memory_mapping,
untranslated_field.as_ptr() as *const _ as u64, untranslated_field.as_ptr() as *const _ as u64,
untranslated_field.len() as u64, untranslated_field.len() as u64,
&loader_id, loader_id,
), ),
result result
)); ));
@ -3020,14 +2892,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetProcessedSiblingInstruction<'
.map_err(|_| SyscallError::InvokeContextBorrowFailed), .map_err(|_| SyscallError::InvokeContextBorrowFailed),
result result
); );
let loader_id = question_mark!( let loader_id = &question_mark!(get_current_loader_key(&invoke_context), result);
invoke_context
.transaction_context
.get_loader_key()
.map_err(SyscallError::InstructionError),
result
);
let budget = invoke_context.get_compute_budget(); let budget = invoke_context.get_compute_budget();
question_mark!( question_mark!(
invoke_context invoke_context
@ -3071,7 +2936,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetProcessedSiblingInstruction<'
translate_type_mut::<ProcessedSiblingInstruction>( translate_type_mut::<ProcessedSiblingInstruction>(
memory_mapping, memory_mapping,
meta_addr, meta_addr,
&loader_id loader_id,
), ),
result result
); );
@ -3080,7 +2945,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetProcessedSiblingInstruction<'
&& *accounts_len == instruction_context.get_number_of_instruction_accounts() && *accounts_len == instruction_context.get_number_of_instruction_accounts()
{ {
let program_id = question_mark!( let program_id = question_mark!(
translate_type_mut::<Pubkey>(memory_mapping, program_id_addr, &loader_id), translate_type_mut::<Pubkey>(memory_mapping, program_id_addr, loader_id),
result result
); );
let data = question_mark!( let data = question_mark!(
@ -3088,7 +2953,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetProcessedSiblingInstruction<'
memory_mapping, memory_mapping,
data_addr, data_addr,
*data_len as u64, *data_len as u64,
&loader_id, loader_id,
), ),
result result
); );
@ -3097,7 +2962,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetProcessedSiblingInstruction<'
memory_mapping, memory_mapping,
accounts_addr, accounts_addr,
*accounts_len as u64, *accounts_len as u64,
&loader_id, loader_id,
), ),
result result
); );
@ -3196,6 +3061,28 @@ mod tests {
}; };
} }
macro_rules! prepare_mockup {
($invoke_context:ident,
$transaction_context:ident,
$program_key:ident,
$loader_key:expr $(,)?) => {
let $program_key = Pubkey::new_unique();
let mut $transaction_context = TransactionContext::new(
vec![
(
$loader_key,
AccountSharedData::new(0, 0, &native_loader::id()),
),
($program_key, AccountSharedData::new(0, 0, &$loader_key)),
],
1,
1,
);
let mut $invoke_context = InvokeContext::new_mock(&mut $transaction_context, &[]);
$invoke_context.push(&[], &[0, 1], &[]).unwrap();
};
}
#[allow(dead_code)] #[allow(dead_code)]
struct MockSlice { struct MockSlice {
pub vm_addr: u64, pub vm_addr: u64,
@ -3490,14 +3377,12 @@ mod tests {
#[test] #[test]
#[should_panic(expected = "UserError(SyscallError(Panic(\"Gaggablaghblagh!\", 42, 84)))")] #[should_panic(expected = "UserError(SyscallError(Panic(\"Gaggablaghblagh!\", 42, 84)))")]
fn test_syscall_sol_panic() { fn test_syscall_sol_panic() {
let program_id = Pubkey::new_unique(); prepare_mockup!(
let mut transaction_context = TransactionContext::new( invoke_context,
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))], transaction_context,
1, program_id,
1, bpf_loader::id(),
); );
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context.push(&[], &[0], &[]).unwrap();
let mut syscall_panic = SyscallPanic { let mut syscall_panic = SyscallPanic {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)), invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
}; };
@ -3564,14 +3449,12 @@ mod tests {
#[test] #[test]
fn test_syscall_sol_log() { fn test_syscall_sol_log() {
let program_id = Pubkey::new_unique(); prepare_mockup!(
let mut transaction_context = TransactionContext::new( invoke_context,
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))], transaction_context,
1, program_id,
1, bpf_loader::id(),
); );
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context.push(&[], &[0], &[]).unwrap();
let mut syscall_sol_log = SyscallLog { let mut syscall_sol_log = SyscallLog {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)), invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
}; };
@ -3665,14 +3548,12 @@ mod tests {
#[test] #[test]
fn test_syscall_sol_log_u64() { fn test_syscall_sol_log_u64() {
let program_id = Pubkey::new_unique(); prepare_mockup!(
let mut transaction_context = TransactionContext::new( invoke_context,
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))], transaction_context,
1, program_id,
1, bpf_loader::id(),
); );
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context.push(&[], &[0], &[]).unwrap();
let cost = invoke_context.get_compute_budget().log_64_units; let cost = invoke_context.get_compute_budget().log_64_units;
let mut syscall_sol_log_u64 = SyscallLogU64 { let mut syscall_sol_log_u64 = SyscallLogU64 {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)), invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
@ -3704,14 +3585,12 @@ mod tests {
#[test] #[test]
fn test_syscall_sol_pubkey() { fn test_syscall_sol_pubkey() {
let program_id = Pubkey::new_unique(); prepare_mockup!(
let mut transaction_context = TransactionContext::new( invoke_context,
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))], transaction_context,
1, program_id,
1, bpf_loader::id(),
); );
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context.push(&[], &[0], &[]).unwrap();
let cost = invoke_context.get_compute_budget().log_pubkey_units; let cost = invoke_context.get_compute_budget().log_pubkey_units;
let mut syscall_sol_pubkey = SyscallLogPubkey { let mut syscall_sol_pubkey = SyscallLogPubkey {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)), invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
@ -3913,17 +3792,12 @@ mod tests {
#[test] #[test]
fn test_syscall_sha256() { fn test_syscall_sha256() {
let config = Config::default(); let config = Config::default();
let program_id = Pubkey::new_unique(); prepare_mockup!(
let mut transaction_context = TransactionContext::new( invoke_context,
vec![( transaction_context,
program_id, program_id,
AccountSharedData::new(0, 0, &bpf_loader_deprecated::id()), bpf_loader_deprecated::id(),
)],
1,
1,
); );
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context.push(&[], &[0], &[]).unwrap();
let bytes1 = "Gaggablaghblagh!"; let bytes1 = "Gaggablaghblagh!";
let bytes2 = "flurbos"; let bytes2 = "flurbos";
@ -4074,15 +3948,13 @@ mod tests {
sysvar_cache.set_fees(src_fees.clone()); sysvar_cache.set_fees(src_fees.clone());
sysvar_cache.set_rent(src_rent); sysvar_cache.set_rent(src_rent);
let program_id = Pubkey::new_unique(); prepare_mockup!(
let mut transaction_context = TransactionContext::new( invoke_context,
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))], transaction_context,
1, program_id,
1, bpf_loader::id(),
); );
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context.sysvar_cache = Cow::Owned(sysvar_cache); invoke_context.sysvar_cache = Cow::Owned(sysvar_cache);
invoke_context.push(&[], &[0], &[]).unwrap();
// Test clock sysvar // Test clock sysvar
{ {
@ -4325,14 +4197,12 @@ mod tests {
fn test_create_program_address() { fn test_create_program_address() {
// These tests duplicate the direct tests in solana_program::pubkey // These tests duplicate the direct tests in solana_program::pubkey
let program_id = Pubkey::new_unique(); prepare_mockup!(
let mut transaction_context = TransactionContext::new( invoke_context,
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))], transaction_context,
1, program_id,
1, bpf_loader::id(),
); );
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context.push(&[], &[0], &[]).unwrap();
let address = bpf_loader_upgradeable::id(); let address = bpf_loader_upgradeable::id();
let exceeded_seed = &[127; MAX_SEED_LEN + 1]; let exceeded_seed = &[127; MAX_SEED_LEN + 1];
@ -4438,14 +4308,12 @@ mod tests {
#[test] #[test]
fn test_find_program_address() { fn test_find_program_address() {
let program_id = Pubkey::new_unique(); prepare_mockup!(
let mut transaction_context = TransactionContext::new( invoke_context,
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))], transaction_context,
1, program_id,
1, bpf_loader::id(),
); );
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context.push(&[], &[0], &[]).unwrap();
let cost = invoke_context let cost = invoke_context
.get_compute_budget() .get_compute_budget()
.create_program_address_units; .create_program_address_units;

View File

@ -11212,7 +11212,9 @@ pub(crate) mod tests {
_instruction_data: &[u8], _instruction_data: &[u8],
invoke_context: &mut InvokeContext, invoke_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> { ) -> std::result::Result<(), InstructionError> {
let program_id = invoke_context.transaction_context.get_program_key()?; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = instruction_context.get_program_key(transaction_context)?;
if mock_vote_program_id() != *program_id { if mock_vote_program_id() != *program_id {
return Err(InstructionError::IncorrectProgramId); return Err(InstructionError::IncorrectProgramId);
} }

View File

@ -19,12 +19,16 @@ fn process_instruction_with_program_logging(
invoke_context: &mut InvokeContext, invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let logger = invoke_context.get_log_collector(); let logger = invoke_context.get_log_collector();
let program_id = invoke_context.transaction_context.get_program_key()?; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = instruction_context.get_program_key(transaction_context)?;
stable_log::program_invoke(&logger, program_id, invoke_context.get_stack_height()); stable_log::program_invoke(&logger, program_id, invoke_context.get_stack_height());
let result = process_instruction(first_instruction_account, instruction_data, invoke_context); let result = process_instruction(first_instruction_account, instruction_data, invoke_context);
let program_id = invoke_context.transaction_context.get_program_key()?; let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = instruction_context.get_program_key(transaction_context)?;
match &result { match &result {
Ok(()) => stable_log::program_success(&logger, program_id), Ok(()) => stable_log::program_success(&logger, program_id),
Err(err) => stable_log::program_failure(&logger, program_id, err), Err(err) => stable_log::program_failure(&logger, program_id, err),

View File

@ -228,20 +228,6 @@ impl TransactionContext {
Ok(()) Ok(())
} }
/// Returns the key of the current InstructionContexts program account
pub fn get_program_key(&self) -> Result<&Pubkey, InstructionError> {
let instruction_context = self.get_current_instruction_context()?;
let program_account = instruction_context.try_borrow_program_account(self)?;
Ok(&self.account_keys[program_account.index_in_transaction])
}
/// Returns the owner of the current InstructionContexts program account
pub fn get_loader_key(&self) -> Result<Pubkey, InstructionError> {
let instruction_context = self.get_current_instruction_context()?;
let program_account = instruction_context.try_borrow_program_account(self)?;
Ok(*program_account.get_owner())
}
/// Gets the return data of the current InstructionContext or any above /// Gets the return data of the current InstructionContext or any above
pub fn get_return_data(&self) -> (&Pubkey, &[u8]) { pub fn get_return_data(&self) -> (&Pubkey, &[u8]) {
(&self.return_data.0, &self.return_data.1) (&self.return_data.0, &self.return_data.1)
@ -408,6 +394,16 @@ impl InstructionContext {
}) })
} }
/// Gets the key of the last program account of this Instruction
pub fn get_program_key<'a, 'b: 'a>(
&'a self,
transaction_context: &'b TransactionContext,
) -> Result<&'b Pubkey, InstructionError> {
let index_in_transaction =
self.get_index_in_transaction(self.program_accounts.len().saturating_sub(1))?;
transaction_context.get_key_of_account_at_index(index_in_transaction)
}
/// Gets the last program account of this Instruction /// Gets the last program account of this Instruction
pub fn try_borrow_program_account<'a, 'b: 'a>( pub fn try_borrow_program_account<'a, 'b: 'a>(
&'a self, &'a self,