Refactor: Remove KeyedAccount
from program runtime (#22226)
* Makes error handling in BorrowedAccount optional. Adds BorrowedAccount ::get_rent_epoch(). Exposes InstructionContext::get_index_in_transaction(). Turns accounts and account_keys into pinned boxed slices. * Introduces "unsafe" to InvokeContext::push(). * Turns &TransactionContext into &mut TransactionContext in InvokeContext. * Push and pop InstructionContext in InvokeContext. Makes test_process_cross_program and test_native_invoke symmetric. Removes the borrow check from test_invoke_context_verify. * Removes keyed_accounts from prepare_instruction() * Removes usage of invoke_stack. * Removes keyed_accounts from program-test. * Removes caller_write_privileges. * Removes keyed_accounts from BPF parameter (de-)serialization.
This commit is contained in:
committed by
GitHub
parent
672fed04cb
commit
73e6038986
@@ -246,7 +246,8 @@ pub fn bind_syscall_context_objects<'a, 'b>(
|
||||
.is_active(&sol_log_data_syscall_enabled::id());
|
||||
|
||||
let loader_id = invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError)?;
|
||||
let invoke_context = Rc::new(RefCell::new(invoke_context));
|
||||
|
||||
@@ -581,7 +582,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallPanic<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -620,7 +622,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLog<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -734,7 +737,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLogPubkey<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -850,7 +854,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -909,7 +914,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -983,7 +989,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSha256<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1064,7 +1071,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetClockSysvar<'a, 'b> {
|
||||
);
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1100,7 +1108,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a, 'b> {
|
||||
);
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1137,7 +1146,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a, 'b> {
|
||||
);
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1173,7 +1183,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetRentSysvar<'a, 'b> {
|
||||
);
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1216,7 +1227,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallKeccak256<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1316,7 +1328,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcpy<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1360,7 +1373,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemmove<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1404,7 +1418,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcmp<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1461,7 +1476,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemset<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1503,7 +1519,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -1608,7 +1625,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallBlake3<'a, 'b> {
|
||||
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -2202,14 +2220,10 @@ fn get_translated_accounts<'a, T, F>(
|
||||
where
|
||||
F: Fn(&T, &InvokeContext) -> Result<CallerAccount<'a>, EbpfError<BpfError>>,
|
||||
{
|
||||
let keyed_accounts = invoke_context
|
||||
.get_keyed_accounts()
|
||||
let instruction_context = invoke_context
|
||||
.transaction_context
|
||||
.get_current_instruction_context()
|
||||
.map_err(SyscallError::InstructionError)?;
|
||||
let number_of_program_accounts = keyed_accounts.len()
|
||||
- invoke_context
|
||||
.get_instruction_keyed_accounts()
|
||||
.map_err(SyscallError::InstructionError)?
|
||||
.len();
|
||||
let mut accounts = Vec::with_capacity(instruction_accounts.len().saturating_add(1));
|
||||
|
||||
let program_account_index = program_indices
|
||||
@@ -2245,10 +2259,8 @@ where
|
||||
let caller_account = if instruction_account.is_writable {
|
||||
let orig_data_len_index = instruction_account
|
||||
.index_in_caller
|
||||
.saturating_sub(number_of_program_accounts);
|
||||
if keyed_accounts[instruction_account.index_in_caller].unsigned_key() == account_key
|
||||
&& orig_data_len_index < orig_data_lens.len()
|
||||
{
|
||||
.saturating_sub(instruction_context.get_number_of_program_accounts());
|
||||
if orig_data_len_index < orig_data_lens.len() {
|
||||
caller_account.original_data_len = orig_data_lens[orig_data_len_index];
|
||||
} else {
|
||||
ic_msg!(
|
||||
@@ -2351,7 +2363,8 @@ fn call<'a, 'b: 'a>(
|
||||
|
||||
// Translate and verify caller's data
|
||||
let loader_id = invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError)?;
|
||||
let instruction = syscall.translate_instruction(
|
||||
&loader_id,
|
||||
@@ -2360,7 +2373,8 @@ fn call<'a, 'b: 'a>(
|
||||
*invoke_context,
|
||||
)?;
|
||||
let caller_program_id = invoke_context
|
||||
.get_caller()
|
||||
.transaction_context
|
||||
.get_program_key()
|
||||
.map_err(SyscallError::InstructionError)?;
|
||||
let signers = syscall.translate_signers(
|
||||
&loader_id,
|
||||
@@ -2369,7 +2383,7 @@ fn call<'a, 'b: 'a>(
|
||||
signers_seeds_len,
|
||||
memory_mapping,
|
||||
)?;
|
||||
let (instruction_accounts, caller_write_privileges, program_indices) = invoke_context
|
||||
let (instruction_accounts, program_indices) = invoke_context
|
||||
.prepare_instruction(&instruction, &signers)
|
||||
.map_err(SyscallError::InstructionError)?;
|
||||
check_authorized_program(&instruction.program_id, &instruction.data, *invoke_context)?;
|
||||
@@ -2389,7 +2403,6 @@ fn call<'a, 'b: 'a>(
|
||||
.process_instruction(
|
||||
&instruction.data,
|
||||
&instruction_accounts,
|
||||
Some(&caller_write_privileges),
|
||||
&program_indices,
|
||||
&mut compute_units_consumed,
|
||||
)
|
||||
@@ -2476,7 +2489,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSetReturnData<'a, 'b> {
|
||||
);
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -2506,7 +2520,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSetReturnData<'a, 'b> {
|
||||
};
|
||||
let program_id = question_mark!(
|
||||
invoke_context
|
||||
.get_caller()
|
||||
.transaction_context
|
||||
.get_program_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -2538,7 +2553,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetReturnData<'a, 'b> {
|
||||
);
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -2605,7 +2621,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLogData<'a, 'b> {
|
||||
);
|
||||
let loader_id = question_mark!(
|
||||
invoke_context
|
||||
.get_loader()
|
||||
.transaction_context
|
||||
.get_loader_key()
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
@@ -2984,12 +3001,12 @@ mod tests {
|
||||
#[should_panic(expected = "UserError(SyscallError(Panic(\"Gaggablaghblagh!\", 42, 84)))")]
|
||||
fn test_syscall_sol_panic() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let transaction_context = TransactionContext::new(
|
||||
let mut 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 invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
let mut syscall_panic = SyscallPanic {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
};
|
||||
@@ -3057,12 +3074,12 @@ mod tests {
|
||||
#[test]
|
||||
fn test_syscall_sol_log() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let transaction_context = TransactionContext::new(
|
||||
let mut 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 invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
let mut syscall_sol_log = SyscallLog {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
};
|
||||
@@ -3157,12 +3174,12 @@ mod tests {
|
||||
#[test]
|
||||
fn test_syscall_sol_log_u64() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let transaction_context = TransactionContext::new(
|
||||
let mut 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 invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
let cost = invoke_context.get_compute_budget().log_64_units;
|
||||
let mut syscall_sol_log_u64 = SyscallLogU64 {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
@@ -3195,12 +3212,12 @@ mod tests {
|
||||
#[test]
|
||||
fn test_syscall_sol_pubkey() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let transaction_context = TransactionContext::new(
|
||||
let mut 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 invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
let cost = invoke_context.get_compute_budget().log_pubkey_units;
|
||||
let mut syscall_sol_pubkey = SyscallLogPubkey {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
@@ -3403,15 +3420,15 @@ mod tests {
|
||||
fn test_syscall_sha256() {
|
||||
let config = Config::default();
|
||||
let program_id = Pubkey::new_unique();
|
||||
let transaction_context = TransactionContext::new(
|
||||
let mut 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 mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
|
||||
let bytes1 = "Gaggablaghblagh!";
|
||||
let bytes2 = "flurbos";
|
||||
@@ -3570,13 +3587,13 @@ mod tests {
|
||||
(sysvar::rent::id(), data_rent),
|
||||
];
|
||||
let program_id = Pubkey::new_unique();
|
||||
let transaction_context = TransactionContext::new(
|
||||
let mut transaction_context = TransactionContext::new(
|
||||
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
|
||||
1,
|
||||
);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.sysvars = &sysvars;
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
|
||||
// Test clock sysvar
|
||||
{
|
||||
@@ -3820,12 +3837,12 @@ mod tests {
|
||||
// These tests duplicate the direct tests in solana_program::pubkey
|
||||
|
||||
let program_id = Pubkey::new_unique();
|
||||
let transaction_context = TransactionContext::new(
|
||||
let mut 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 invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
let address = bpf_loader_upgradeable::id();
|
||||
|
||||
let exceeded_seed = &[127; MAX_SEED_LEN + 1];
|
||||
@@ -3932,12 +3949,12 @@ mod tests {
|
||||
#[test]
|
||||
fn test_find_program_address() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let transaction_context = TransactionContext::new(
|
||||
let mut 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 invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
let cost = invoke_context
|
||||
.get_compute_budget()
|
||||
.create_program_address_units;
|
||||
|
Reference in New Issue
Block a user