Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cli/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ use {
system_instruction::{self, SystemError},
system_program,
transaction::{Transaction, TransactionError},
transaction_context::TransactionContext,
},
std::{
fs::File,
Expand Down Expand Up @@ -1990,7 +1991,8 @@ fn read_and_verify_elf(program_location: &str) -> Result<Vec<u8>, Box<dyn std::e
let mut program_data = Vec::new();
file.read_to_end(&mut program_data)
.map_err(|err| format!("Unable to read program file: {}", err))?;
let mut invoke_context = InvokeContext::new_mock(&[], &[]);
let transaction_context = TransactionContext::new(Vec::new(), 1);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);

// Verify the program
Executable::<BpfError, ThisInstructionMeter>::from_elf(
Expand Down
314 changes: 163 additions & 151 deletions program-runtime/src/invoke_context.rs

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions program-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,17 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
// Convert AccountInfos into Accounts
let mut accounts = Vec::with_capacity(instruction_accounts.len());
for instruction_account in instruction_accounts.iter() {
let account_key = invoke_context.get_account_key_at_index(instruction_account.index);
let account_key = invoke_context
.transaction_context
.get_key_of_account_at_index(instruction_account.index);
let account_info = account_infos
.iter()
.find(|account_info| account_info.unsigned_key() == account_key)
.ok_or(InstructionError::MissingAccount)
.unwrap();
{
let mut account = invoke_context
.transaction_context
.get_account_at_index(instruction_account.index)
.borrow_mut();
account.copy_into_owner_from_slice(account_info.owner.as_ref());
Expand All @@ -284,7 +287,9 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {

// Copy writeable account modifications back into the caller's AccountInfos
for (account_index, account_info) in accounts.into_iter() {
let account = invoke_context.get_account_at_index(account_index);
let account = invoke_context
.transaction_context
.get_account_at_index(account_index);
let account_borrow = account.borrow();
**account_info.try_borrow_mut_lamports().unwrap() = account_borrow.lamports();
let mut data = account_info.try_borrow_mut_data()?;
Expand Down
4 changes: 3 additions & 1 deletion programs/bpf_loader/src/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ mod tests {
bpf_loader,
entrypoint::deserialize,
instruction::AccountMeta,
transaction_context::TransactionContext,
},
std::{
cell::RefCell,
Expand Down Expand Up @@ -452,7 +453,8 @@ mod tests {
let program_indices = [0];
let preparation =
prepare_mock_invoke_context(transaction_accounts.clone(), instruction_accounts);
let mut invoke_context = InvokeContext::new_mock(&preparation.transaction_accounts, &[]);
let transaction_context = TransactionContext::new(preparation.transaction_accounts, 1);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
invoke_context
.push(&preparation.instruction_accounts, &program_indices)
.unwrap();
Expand Down
174 changes: 94 additions & 80 deletions programs/bpf_loader/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use {
alloc::Alloc,
solana_program_runtime::{
ic_logger_msg, ic_msg,
invoke_context::{ComputeMeter, InstructionAccount, InvokeContext},
invoke_context::{ComputeMeter, InvokeContext},
stable_log,
},
solana_rbpf::{
Expand Down Expand Up @@ -41,6 +41,7 @@ use {
Secp256k1RecoverError, SECP256K1_PUBLIC_KEY_LENGTH, SECP256K1_SIGNATURE_LENGTH,
},
sysvar::{self, Sysvar, SysvarId},
transaction_context::InstructionAccount,
},
std::{
alloc::Layout,
Expand Down Expand Up @@ -2214,8 +2215,12 @@ where
accounts.push((*program_account_index, None));

for instruction_account in instruction_accounts.iter() {
let account = invoke_context.get_account_at_index(instruction_account.index);
let account_key = invoke_context.get_account_key_at_index(instruction_account.index);
let account = invoke_context
.transaction_context
.get_account_at_index(instruction_account.index);
let account_key = invoke_context
.transaction_context
.get_key_of_account_at_index(instruction_account.index);
if account.borrow().executable() {
// Use the known account
accounts.push((instruction_account.index, None));
Expand Down Expand Up @@ -2396,6 +2401,7 @@ fn call<'a, 'b: 'a>(
for (callee_account_index, caller_account) in accounts.iter_mut() {
if let Some(caller_account) = caller_account {
let callee_account = invoke_context
.transaction_context
.get_account_at_index(*callee_account_index)
.borrow();
*caller_account.lamports = callee_account.lamports();
Expand Down Expand Up @@ -2669,6 +2675,7 @@ mod tests {
},
solana_sdk::{
account::AccountSharedData, bpf_loader, fee_calculator::FeeCalculator, hash::hashv,
transaction_context::TransactionContext,
},
std::str::FromStr,
};
Expand Down Expand Up @@ -2979,9 +2986,11 @@ mod tests {
#[should_panic(expected = "UserError(SyscallError(Panic(\"Gaggablaghblagh!\", 42, 84)))")]
fn test_syscall_sol_panic() {
let program_id = Pubkey::new_unique();
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
let accounts = [(program_id, program_account)];
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let transaction_context = TransactionContext::new(
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
1,
);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
invoke_context.push(&[], &[0]).unwrap();
let mut syscall_panic = SyscallPanic {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
Expand Down Expand Up @@ -3050,9 +3059,11 @@ mod tests {
#[test]
fn test_syscall_sol_log() {
let program_id = Pubkey::new_unique();
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
let accounts = [(program_id, program_account)];
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let transaction_context = TransactionContext::new(
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
1,
);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
invoke_context.push(&[], &[0]).unwrap();
let mut syscall_sol_log = SyscallLog {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
Expand Down Expand Up @@ -3148,9 +3159,11 @@ mod tests {
#[test]
fn test_syscall_sol_log_u64() {
let program_id = Pubkey::new_unique();
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
let accounts = [(program_id, program_account)];
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let transaction_context = TransactionContext::new(
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
1,
);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
invoke_context.push(&[], &[0]).unwrap();
let cost = invoke_context.get_compute_budget().log_64_units;
let mut syscall_sol_log_u64 = SyscallLogU64 {
Expand Down Expand Up @@ -3184,9 +3197,11 @@ mod tests {
#[test]
fn test_syscall_sol_pubkey() {
let program_id = Pubkey::new_unique();
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
let accounts = [(program_id, program_account)];
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let transaction_context = TransactionContext::new(
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
1,
);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
invoke_context.push(&[], &[0]).unwrap();
let cost = invoke_context.get_compute_budget().log_pubkey_units;
let mut syscall_sol_pubkey = SyscallLogPubkey {
Expand Down Expand Up @@ -3390,10 +3405,14 @@ mod tests {
fn test_syscall_sha256() {
let config = Config::default();
let program_id = Pubkey::new_unique();
let program_account =
RefCell::new(AccountSharedData::new(0, 0, &bpf_loader_deprecated::id()));
let accounts = [(program_id, program_account)];
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let transaction_context = TransactionContext::new(
vec![(
program_id,
AccountSharedData::new(0, 0, &bpf_loader_deprecated::id()),
)],
1,
);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
invoke_context.push(&[], &[0]).unwrap();

let bytes1 = "Gaggablaghblagh!";
Expand Down Expand Up @@ -3511,11 +3530,55 @@ mod tests {
}

#[test]
#[allow(deprecated)]
fn test_syscall_get_sysvar() {
let config = Config::default();
let src_clock = Clock {
slot: 1,
epoch_start_timestamp: 2,
epoch: 3,
leader_schedule_epoch: 4,
unix_timestamp: 5,
};
let mut data_clock = vec![];
bincode::serialize_into(&mut data_clock, &src_clock).unwrap();
let src_epochschedule = EpochSchedule {
slots_per_epoch: 1,
leader_schedule_slot_offset: 2,
warmup: false,
first_normal_epoch: 3,
first_normal_slot: 4,
};
let mut data_epochschedule = vec![];
bincode::serialize_into(&mut data_epochschedule, &src_epochschedule).unwrap();
let src_fees = Fees {
fee_calculator: FeeCalculator {
lamports_per_signature: 1,
},
};
let mut data_fees = vec![];
bincode::serialize_into(&mut data_fees, &src_fees).unwrap();
let src_rent = Rent {
lamports_per_byte_year: 1,
exemption_threshold: 2.0,
burn_percent: 3,
};
let mut data_rent = vec![];
bincode::serialize_into(&mut data_rent, &src_rent).unwrap();
let sysvars = [
(sysvar::clock::id(), data_clock),
(sysvar::epoch_schedule::id(), data_epochschedule),
(sysvar::fees::id(), data_fees),
(sysvar::rent::id(), data_rent),
];
let program_id = Pubkey::new_unique();
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
let accounts = [(program_id, program_account)];
let transaction_context = TransactionContext::new(
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
1,
);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
invoke_context.sysvars = &sysvars;
invoke_context.push(&[], &[0]).unwrap();

// Test clock sysvar
{
Expand All @@ -3536,20 +3599,6 @@ mod tests {
&config,
)
.unwrap();

let src_clock = Clock {
slot: 1,
epoch_start_timestamp: 2,
epoch: 3,
leader_schedule_epoch: 4,
unix_timestamp: 5,
};
let mut data = vec![];
bincode::serialize_into(&mut data, &src_clock).unwrap();
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let sysvars = [(sysvar::clock::id(), data)];
invoke_context.sysvars = &sysvars;
invoke_context.push(&[], &[0]).unwrap();
let mut syscall = SyscallGetClockSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
};
Expand Down Expand Up @@ -3579,20 +3628,6 @@ mod tests {
&config,
)
.unwrap();

let src_epochschedule = EpochSchedule {
slots_per_epoch: 1,
leader_schedule_slot_offset: 2,
warmup: false,
first_normal_epoch: 3,
first_normal_slot: 4,
};
let mut data = vec![];
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let sysvars = [(sysvar::epoch_schedule::id(), data)];
invoke_context.sysvars = &sysvars;
invoke_context.push(&[], &[0]).unwrap();
let mut syscall = SyscallGetEpochScheduleSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
};
Expand All @@ -3612,7 +3647,6 @@ mod tests {
}

// Test fees sysvar
#[allow(deprecated)]
{
let got_fees = Fees::default();
let got_fees_va = 0x100000000;
Expand All @@ -3631,18 +3665,6 @@ mod tests {
&config,
)
.unwrap();

let src_fees = Fees {
fee_calculator: FeeCalculator {
lamports_per_signature: 1,
},
};
let mut data = vec![];
bincode::serialize_into(&mut data, &src_fees).unwrap();
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let sysvars = [(sysvar::fees::id(), data)];
invoke_context.sysvars = &sysvars;
invoke_context.push(&[], &[0]).unwrap();
let mut syscall = SyscallGetFeesSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
};
Expand Down Expand Up @@ -3672,18 +3694,6 @@ mod tests {
&config,
)
.unwrap();

let src_rent = Rent {
lamports_per_byte_year: 1,
exemption_threshold: 2.0,
burn_percent: 3,
};
let mut data = vec![];
bincode::serialize_into(&mut data, &src_rent).unwrap();
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let sysvars = [(sysvar::rent::id(), data)];
invoke_context.sysvars = &sysvars;
invoke_context.push(&[], &[0]).unwrap();
let mut syscall = SyscallGetRentSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
};
Expand Down Expand Up @@ -3812,9 +3822,11 @@ mod tests {
// These tests duplicate the direct tests in solana_program::pubkey

let program_id = Pubkey::new_unique();
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
let accounts = [(program_id, program_account)];
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let transaction_context = TransactionContext::new(
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
1,
);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
invoke_context.push(&[], &[0]).unwrap();
let address = bpf_loader_upgradeable::id();

Expand Down Expand Up @@ -3922,9 +3934,11 @@ mod tests {
#[test]
fn test_find_program_address() {
let program_id = Pubkey::new_unique();
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
let accounts = [(program_id, program_account)];
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let transaction_context = TransactionContext::new(
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
1,
);
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
invoke_context.push(&[], &[0]).unwrap();
let cost = invoke_context
.get_compute_budget()
Expand Down
Loading