From fa482b6bfd8bc9af3b1b78cc0fee992146117189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 16 Mar 2021 12:02:51 +0100 Subject: [PATCH 01/33] Adds keyed_accounts property and getter to InvokeContext. --- runtime/src/message_processor.rs | 5 +++++ sdk/src/process_instruction.rs | 13 ++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index ed9c45498c5f31..aa02918520ce24 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -255,6 +255,7 @@ pub struct ThisInvokeContext<'a> { pre_accounts: Vec, executables: &'a [(Pubkey, Rc>)], account_deps: &'a [(Pubkey, Rc>)], + keyed_accounts: &'a [KeyedAccount<'a>], programs: &'a [(Pubkey, ProcessInstructionWithContext)], logger: Rc>, bpf_compute_budget: BpfComputeBudget, @@ -292,6 +293,7 @@ impl<'a> ThisInvokeContext<'a> { pre_accounts, executables, account_deps, + keyed_accounts: &[], // TODO [KeyedAccounts to InvokeContext refactoring] programs, logger: Rc::new(RefCell::new(ThisLogger { log_collector })), bpf_compute_budget, @@ -353,6 +355,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .last() .ok_or(InstructionError::GenericError) } + fn get_keyed_accounts(&self) -> &[KeyedAccount] { + self.keyed_accounts + } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { self.programs } diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 3384a7267c5041..35b5fb644d9b74 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -41,6 +41,8 @@ pub trait InvokeContext { ) -> Result<(), InstructionError>; /// Get the program ID of the currently executing program fn get_caller(&self) -> Result<&Pubkey, InstructionError>; + /// Get the list of keyed accounts + fn get_keyed_accounts(&self) -> &[KeyedAccount]; /// Get a list of built-in programs fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)]; /// Get this invocation's logger @@ -276,17 +278,18 @@ impl Logger for MockLogger { } } -pub struct MockInvokeContext { +pub struct MockInvokeContext<'a> { pub key: Pubkey, pub logger: MockLogger, pub bpf_compute_budget: BpfComputeBudget, pub compute_meter: MockComputeMeter, + pub keyed_accounts: &'a [KeyedAccount<'a>], pub programs: Vec<(Pubkey, ProcessInstructionWithContext)>, pub accounts: Vec<(Pubkey, Rc>)>, pub invoke_depth: usize, pub sysvars: Vec<(Pubkey, Option>>)>, } -impl Default for MockInvokeContext { +impl<'a> Default for MockInvokeContext<'a> { fn default() -> Self { MockInvokeContext { key: Pubkey::default(), @@ -295,6 +298,7 @@ impl Default for MockInvokeContext { compute_meter: MockComputeMeter { remaining: std::i64::MAX as u64, }, + keyed_accounts: &[], // TODO [KeyedAccounts to InvokeContext refactoring] programs: vec![], accounts: vec![], invoke_depth: 0, @@ -302,7 +306,7 @@ impl Default for MockInvokeContext { } } } -impl InvokeContext for MockInvokeContext { +impl<'a> InvokeContext for MockInvokeContext<'a> { fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> { self.invoke_depth = self.invoke_depth.saturating_add(1); Ok(()) @@ -325,6 +329,9 @@ impl InvokeContext for MockInvokeContext { fn get_caller(&self) -> Result<&Pubkey, InstructionError> { Ok(&self.key) } + fn get_keyed_accounts(&self) -> &[KeyedAccount] { + self.keyed_accounts + } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { &self.programs } From bf35b5b666a8f26a7171749abb0ccb605cfa1462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 29 Mar 2021 15:56:51 +0200 Subject: [PATCH 02/33] Adds keyed_accounts parameter to MockInvokeContext constructor. --- programs/bpf/benches/bpf_loader.rs | 7 +- programs/bpf/tests/programs.rs | 2 +- programs/bpf_loader/src/lib.rs | 896 +++++++++++--------- programs/bpf_loader/src/syscalls.rs | 8 +- programs/config/src/config_processor.rs | 34 +- programs/stake/src/stake_instruction.rs | 198 ++--- programs/stake/src/stake_state.rs | 19 +- programs/vote/src/vote_instruction.rs | 4 +- runtime/src/system_instruction_processor.rs | 54 +- sdk/src/nonce_keyed_account.rs | 86 +- sdk/src/process_instruction.rs | 6 +- 11 files changed, 685 insertions(+), 629 deletions(-) diff --git a/programs/bpf/benches/bpf_loader.rs b/programs/bpf/benches/bpf_loader.rs index 926eff8e79c5aa..2d9342c28207b2 100644 --- a/programs/bpf/benches/bpf_loader.rs +++ b/programs/bpf/benches/bpf_loader.rs @@ -91,7 +91,7 @@ fn bench_program_alu(bencher: &mut Bencher) { .unwrap(); inner_iter.write_u64::(0).unwrap(); let loader_id = bpf_loader::id(); - let mut invoke_context = MockInvokeContext::default(); + let mut invoke_context = MockInvokeContext::new(&[]); let elf = load_elf("bench_alu").unwrap(); let mut executable = @@ -195,8 +195,6 @@ fn bench_program_execute_noop(bencher: &mut Bencher) { fn bench_instruction_count_tuner(_bencher: &mut Bencher) { const BUDGET: u64 = 200_000; let loader_id = bpf_loader::id(); - let mut invoke_context = MockInvokeContext::default(); - invoke_context.compute_meter.remaining = BUDGET; let accounts = [RefCell::new(AccountSharedData::new( 1, @@ -211,6 +209,9 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) { .collect(); let instruction_data = vec![0u8]; + let mut invoke_context = MockInvokeContext::new(&keyed_accounts); + invoke_context.compute_meter.remaining = BUDGET; + // Serialize account data let mut serialized = serialize_parameters( &bpf_loader::id(), diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 62758ddbc6832d..f0f1a1195a390a 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -188,7 +188,7 @@ fn run_program( let mut data = vec![]; file.read_to_end(&mut data).unwrap(); let loader_id = bpf_loader::id(); - let mut invoke_context = MockInvokeContext::default(); + let mut invoke_context = MockInvokeContext::new(parameter_accounts); let parameter_bytes = serialize_parameters( &bpf_loader::id(), program_id, diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 7c67fcc3343f4b..cde303fa22cdf1 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -891,7 +891,7 @@ mod tests { instruction::Instruction, instruction::{AccountMeta, InstructionError}, message::Message, - process_instruction::{MockComputeMeter, MockInvokeContext}, + process_instruction::{BpfComputeBudget, MockComputeMeter, MockInvokeContext, MockLogger}, pubkey::Pubkey, rent::Rent, signature::{Keypair, Signer}, @@ -964,7 +964,7 @@ mod tests { &bpf_loader::id(), &[], &instruction_data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&[]) ) ); @@ -975,7 +975,7 @@ mod tests { &bpf_loader::id(), &keyed_accounts, &instruction_data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -989,7 +989,7 @@ mod tests { &bpf_loader::id(), &keyed_accounts, &instruction_data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); assert_eq!( @@ -1007,7 +1007,7 @@ mod tests { &bpf_loader::id(), &keyed_accounts, &instruction_data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); } @@ -1033,7 +1033,7 @@ mod tests { &bpf_loader::id(), &[], &instruction_data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&[]) ) ); @@ -1044,7 +1044,7 @@ mod tests { &bpf_loader::id(), &keyed_accounts, &instruction_data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -1056,7 +1056,7 @@ mod tests { &bpf_loader::id(), &keyed_accounts, &instruction_data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); assert!(keyed_accounts[0].account.borrow().executable); @@ -1072,7 +1072,7 @@ mod tests { &bpf_loader::id(), &keyed_accounts, &instruction_data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); } @@ -1092,25 +1092,33 @@ mod tests { let mut keyed_accounts = vec![KeyedAccount::new(&program_key, false, &program_account)]; - let mut invoke_context = MockInvokeContext::default(); - // Case: Empty keyed accounts assert_eq!( Err(InstructionError::NotEnoughAccountKeys), - process_instruction(&program_id, &[], &[], &mut invoke_context) + process_instruction(&program_id, &[], &[], &mut MockInvokeContext::new(&[])) ); // Case: Only a program account assert_eq!( Ok(()), - process_instruction(&program_key, &keyed_accounts, &[], &mut invoke_context) + process_instruction( + &program_key, + &keyed_accounts, + &[], + &mut MockInvokeContext::new(&keyed_accounts) + ) ); // Case: Account not a program keyed_accounts[0].account.borrow_mut().executable = false; assert_eq!( Err(InstructionError::InvalidInstructionData), - process_instruction(&program_id, &keyed_accounts, &[], &mut invoke_context) + process_instruction( + &program_id, + &keyed_accounts, + &[], + &mut MockInvokeContext::new(&keyed_accounts) + ) ); keyed_accounts[0].account.borrow_mut().executable = true; @@ -1119,15 +1127,25 @@ mod tests { keyed_accounts.push(KeyedAccount::new(&program_key, false, ¶meter_account)); assert_eq!( Ok(()), - process_instruction(&program_key, &keyed_accounts, &[], &mut invoke_context) + process_instruction( + &program_key, + &keyed_accounts, + &[], + &mut MockInvokeContext::new(&keyed_accounts) + ) ); // Case: limited budget - let program_id = Pubkey::default(); let mut invoke_context = MockInvokeContext { - key: program_id, + key: Pubkey::default(), + logger: MockLogger::default(), + bpf_compute_budget: BpfComputeBudget::default(), compute_meter: MockComputeMeter::default(), - ..MockInvokeContext::default() + keyed_accounts: &keyed_accounts, + programs: vec![], + accounts: vec![], + invoke_depth: 0, + sysvars: vec![], }; assert_eq!( Err(InstructionError::ProgramFailedToComplete), @@ -1146,7 +1164,7 @@ mod tests { &program_key, &keyed_accounts, &[], - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); } @@ -1174,7 +1192,7 @@ mod tests { &program_key, &keyed_accounts, &[], - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -1190,7 +1208,7 @@ mod tests { &program_key, &keyed_accounts, &[], - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); } @@ -1218,7 +1236,7 @@ mod tests { &program_key, &keyed_accounts, &[], - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -1234,7 +1252,7 @@ mod tests { &program_key, &keyed_accounts, &[], - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); } @@ -1257,16 +1275,17 @@ mod tests { ); // Case: Success + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&authority_address, false, &authority_account), + ]; assert_eq!( Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&authority_address, false, &authority_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -1278,16 +1297,17 @@ mod tests { ); // Case: Already initialized + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&authority_address, false, &authority_account), + ]; assert_eq!( Err(InstructionError::AccountAlreadyInitialized), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&authority_address, false, &authority_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -1314,16 +1334,17 @@ mod tests { bytes: vec![42; 9], }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&buffer_address, true, &buffer_account), + ]; assert_eq!( Err(InstructionError::InvalidAccountData), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&buffer_address, true, &buffer_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -1339,16 +1360,17 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&buffer_address, true, &buffer_account), + ]; assert_eq!( Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&buffer_address, true, &buffer_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -1381,16 +1403,17 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&buffer_address, true, &buffer_account), + ]; assert_eq!( Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&buffer_address, true, &buffer_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -1418,16 +1441,17 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + ]; assert_eq!( Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&buffer_address, false, &buffer_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -1443,16 +1467,17 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&buffer_address, true, &buffer_account), + ]; assert_eq!( Err(InstructionError::AccountDataTooSmall), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&buffer_address, true, &buffer_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -1468,16 +1493,17 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&buffer_address, true, &buffer_account), + ]; assert_eq!( Err(InstructionError::AccountDataTooSmall), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&buffer_address, true, &buffer_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -1494,16 +1520,17 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&authority_address, true, &buffer_account), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&authority_address, true, &buffer_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -1520,16 +1547,17 @@ mod tests { authority_address: None, }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&authority_address, true, &buffer_account), + ]; assert_eq!( Err(InstructionError::Immutable), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&authority_address, true, &buffer_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); } @@ -2209,6 +2237,8 @@ mod tests { Pubkey::find_program_address(&[program_address.as_ref()], &id()); let spill_address = Pubkey::new_unique(); let upgrade_authority_account = AccountSharedData::new_ref(1, 0, &Pubkey::new_unique()); + let rent_id = sysvar::rent::id(); + let clock_id = sysvar::clock::id(); #[allow(clippy::type_complexity)] fn get_accounts( @@ -2285,25 +2315,26 @@ mod tests { min_program_balance, min_programdata_balance, ); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); assert_eq!(0, buffer_account.borrow().lamports); @@ -2347,25 +2378,26 @@ mod tests { upgrade_authority_address: None, }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::Immutable), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2380,25 +2412,27 @@ mod tests { min_program_balance, min_programdata_balance, ); + let invalid_upgrade_authority_address = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &invalid_upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &Pubkey::new_unique(), - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2413,25 +2447,26 @@ mod tests { min_program_balance, min_programdata_balance, ); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + false, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - false, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2447,25 +2482,26 @@ mod tests { min_programdata_balance, ); program_account.borrow_mut().executable = false; + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::AccountNotExecutable), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2481,25 +2517,26 @@ mod tests { min_programdata_balance, ); program_account.borrow_mut().owner = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::IncorrectProgramId), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2514,25 +2551,26 @@ mod tests { min_program_balance, min_programdata_balance, ); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new_readonly(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new_readonly(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2551,25 +2589,26 @@ mod tests { .borrow_mut() .set_state(&UpgradeableLoaderState::Uninitialized) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::InvalidAccountData), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2584,25 +2623,27 @@ mod tests { min_program_balance, min_programdata_balance, ); + let invalid_programdata_address = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&invalid_programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&Pubkey::new_unique(), false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2621,25 +2662,26 @@ mod tests { .borrow_mut() .set_state(&UpgradeableLoaderState::Uninitialized) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2665,25 +2707,26 @@ mod tests { authority_address: Some(upgrade_authority_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::AccountDataTooSmall), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2705,25 +2748,26 @@ mod tests { }) .unwrap(); truncate_data(&mut buffer_account.borrow_mut(), 5); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::InvalidAccountData), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2738,25 +2782,26 @@ mod tests { min_program_balance, min_programdata_balance, ); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2777,25 +2822,26 @@ mod tests { authority_address: None, }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2823,25 +2869,26 @@ mod tests { upgrade_authority_address: None, }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new(&program_address, false, &program_account), + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&spill_address, false, &spill_account), + KeyedAccount::new_readonly(&rent_id, false, &rent_account), + KeyedAccount::new_readonly(&clock_id, false, &clock_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new(&program_address, false, &program_account), - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&spill_address, false, &spill_account), - KeyedAccount::new_readonly(&sysvar::rent::id(), false, &rent_account), - KeyedAccount::new_readonly(&sysvar::clock::id(), false, &clock_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); } @@ -2871,25 +2918,26 @@ mod tests { upgrade_authority_address: Some(upgrade_authority_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + KeyedAccount::new_readonly( + &new_upgrade_authority_address, + false, + &new_upgrade_authority_account, + ), + ]; assert_eq!( Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ), - KeyedAccount::new_readonly( - &new_upgrade_authority_address, - false, - &new_upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); let state: UpgradeableLoaderState = programdata_account.borrow().state().unwrap(); @@ -2909,20 +2957,21 @@ mod tests { upgrade_authority_address: Some(upgrade_authority_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - true, - &upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); let state: UpgradeableLoaderState = programdata_account.borrow().state().unwrap(); @@ -2942,20 +2991,21 @@ mod tests { upgrade_authority_address: Some(upgrade_authority_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new_readonly( + &upgrade_authority_address, + false, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new_readonly( - &upgrade_authority_address, - false, - &upgrade_authority_account - ), - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2967,25 +3017,27 @@ mod tests { upgrade_authority_address: Some(upgrade_authority_address), }) .unwrap(); + let invalid_upgrade_authority_address = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new_readonly( + &invalid_upgrade_authority_address, + true, + &upgrade_authority_account, + ), + KeyedAccount::new_readonly( + &new_upgrade_authority_address, + false, + &new_upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new_readonly( - &Pubkey::new_unique(), - true, - &upgrade_authority_account - ), - KeyedAccount::new_readonly( - &new_upgrade_authority_address, - false, - &new_upgrade_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -2997,20 +3049,22 @@ mod tests { upgrade_authority_address: None, }) .unwrap(); + let invalid_upgrade_authority_address = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new_readonly( + &invalid_upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::Immutable), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new_readonly( - &Pubkey::new_unique(), - true, - &upgrade_authority_account - ), - ], + &keyed_accounts, &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -3021,20 +3075,22 @@ mod tests { programdata_address: Pubkey::new_unique(), }) .unwrap(); + let invalid_upgrade_authority_address = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&programdata_address, false, &programdata_account), + KeyedAccount::new_readonly( + &invalid_upgrade_authority_address, + true, + &upgrade_authority_account, + ), + ]; assert_eq!( Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&programdata_address, false, &programdata_account), - KeyedAccount::new_readonly( - &Pubkey::new_unique(), - true, - &upgrade_authority_account - ), - ], + &keyed_accounts, &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); } @@ -3060,21 +3116,18 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new_readonly(&authority_address, true, &authority_account), + KeyedAccount::new_readonly(&new_authority_address, false, &new_authority_account), + ]; assert_eq!( Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new_readonly(&authority_address, true, &authority_account), - KeyedAccount::new_readonly( - &new_authority_address, - false, - &new_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -3092,16 +3145,17 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new_readonly(&authority_address, true, &authority_account), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new_readonly(&authority_address, true, &authority_account) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -3119,21 +3173,18 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new_readonly(&authority_address, false, &authority_account), + KeyedAccount::new_readonly(&new_authority_address, false, &new_authority_account), + ]; assert_eq!( Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new_readonly(&authority_address, false, &authority_account), - KeyedAccount::new_readonly( - &new_authority_address, - false, - &new_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -3144,21 +3195,19 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); + let invalid_authority_address = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new_readonly(&invalid_authority_address, true, &authority_account), + KeyedAccount::new_readonly(&new_authority_address, false, &new_authority_account), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new_readonly(&Pubkey::new_unique(), true, &authority_account), - KeyedAccount::new_readonly( - &new_authority_address, - false, - &new_authority_account - ) - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -3169,21 +3218,19 @@ mod tests { authority_address: None, }) .unwrap(); + let invalid_authority_address = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new_readonly(&invalid_authority_address, true, &authority_account), + KeyedAccount::new_readonly(&new_authority_address, false, &new_authority_account), + ]; assert_eq!( Err(InstructionError::Immutable), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new_readonly(&Pubkey::new_unique(), true, &authority_account), - KeyedAccount::new_readonly( - &new_authority_address, - false, - &new_authority_account - ) - ], + &keyed_accounts, &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -3194,16 +3241,18 @@ mod tests { programdata_address: Pubkey::new_unique(), }) .unwrap(); + let invalid_authority_address = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new_readonly(&invalid_authority_address, true, &authority_account), + ]; assert_eq!( Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new_readonly(&Pubkey::new_unique(), true, &authority_account), - ], + &keyed_accounts, &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); @@ -3214,16 +3263,17 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new_readonly(&authority_address, true, &authority_account), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new_readonly(&authority_address, true, &authority_account), - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ) ); } @@ -3249,17 +3299,18 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&recipient_address, false, &recipient_account), + KeyedAccount::new_readonly(&authority_address, true, &authority_account), + ]; assert_eq!( Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&recipient_address, false, &recipient_account), - KeyedAccount::new_readonly(&authority_address, true, &authority_account), - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts), ) ); assert_eq!(0, buffer_account.borrow().lamports()); @@ -3277,17 +3328,19 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); + let incorrect_authority_address = Pubkey::new_unique(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&recipient_address, false, &recipient_account), + KeyedAccount::new_readonly(&incorrect_authority_address, true, &authority_account), + ]; assert_eq!( Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&recipient_address, false, &recipient_account), - KeyedAccount::new_readonly(&Pubkey::new_unique(), true, &authority_account), - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts), ) ); @@ -3298,17 +3351,18 @@ mod tests { programdata_address: Pubkey::new_unique(), }) .unwrap(); + let keyed_accounts = [ + KeyedAccount::new(&buffer_address, false, &buffer_account), + KeyedAccount::new(&recipient_address, false, &recipient_account), + KeyedAccount::new_readonly(&incorrect_authority_address, true, &authority_account), + ]; assert_eq!( Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &[ - KeyedAccount::new(&buffer_address, false, &buffer_account), - KeyedAccount::new(&recipient_address, false, &recipient_account), - KeyedAccount::new_readonly(&Pubkey::new_unique(), true, &authority_account), - ], + &keyed_accounts, &instruction, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts), ) ); } @@ -3369,7 +3423,7 @@ mod tests { &bpf_loader::id(), &keyed_accounts, &[], - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&keyed_accounts), ); }, ); diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 989247ae59be7e..5dbd978550aef8 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -2683,7 +2683,7 @@ mod tests { leader_schedule_epoch: 4, unix_timestamp: 5, }; - let mut invoke_context = MockInvokeContext::default(); + let mut invoke_context = MockInvokeContext::new(&[]); let mut data = vec![]; bincode::serialize_into(&mut data, &src_clock).unwrap(); invoke_context @@ -2725,7 +2725,7 @@ mod tests { first_normal_epoch: 3, first_normal_slot: 4, }; - let mut invoke_context = MockInvokeContext::default(); + let mut invoke_context = MockInvokeContext::new(&[]); let mut data = vec![]; bincode::serialize_into(&mut data, &src_epochschedule).unwrap(); invoke_context @@ -2773,7 +2773,7 @@ mod tests { lamports_per_signature: 1, }, }; - let mut invoke_context = MockInvokeContext::default(); + let mut invoke_context = MockInvokeContext::new(&[]); let mut data = vec![]; bincode::serialize_into(&mut data, &src_fees).unwrap(); invoke_context @@ -2813,7 +2813,7 @@ mod tests { exemption_threshold: 2.0, burn_percent: 3, }; - let mut invoke_context = MockInvokeContext::default(); + let mut invoke_context = MockInvokeContext::new(&[]); let mut data = vec![]; bincode::serialize_into(&mut data, &src_rent).unwrap(); invoke_context diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index 105cf8a36e1be4..794ac54fdd8298 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -192,7 +192,7 @@ mod tests { &id(), &keyed_accounts, &instructions[1].data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Ok(()) ); @@ -227,7 +227,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Ok(()) ); @@ -254,7 +254,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::InvalidInstructionData) ); @@ -277,7 +277,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -312,7 +312,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Ok(()) ); @@ -346,7 +346,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::InvalidAccountData) ); @@ -377,7 +377,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -393,7 +393,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -430,7 +430,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Ok(()) ); @@ -450,7 +450,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Ok(()) ); @@ -476,7 +476,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -499,7 +499,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -537,7 +537,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Ok(()) ); @@ -556,7 +556,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Ok(()) ); @@ -578,7 +578,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -597,7 +597,7 @@ mod tests { &id(), &keyed_accounts, &instructions[1].data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys) ); @@ -628,7 +628,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::InvalidAccountOwner) ); diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 722994ddb285e6..788bf3fb241258 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -709,7 +709,7 @@ mod tests { &Pubkey::default(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&keyed_accounts), ) } } @@ -924,196 +924,198 @@ mod tests { Lockup::default() )) .unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&[]) ), Err(InstructionError::NotEnoughAccountKeys), ); // no account for rent + let stake_address = Pubkey::default(); + let stake_account = create_default_stake_account(); + let keyed_accounts = [KeyedAccount::new(&stake_address, false, &stake_account)]; assert_eq!( super::process_instruction( &Pubkey::default(), - &[KeyedAccount::new( - &Pubkey::default(), - false, - &create_default_stake_account(), - )], + &keyed_accounts, &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default() )) .unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys), ); // rent fails to deserialize + let stake_address = Pubkey::default(); + let stake_account = create_default_stake_account(); + let rent_address = sysvar::rent::id(); + let rent_account = create_default_account(); + let keyed_accounts = [ + KeyedAccount::new(&stake_address, false, &stake_account), + KeyedAccount::new(&rent_address, false, &rent_account), + ]; assert_eq!( super::process_instruction( &Pubkey::default(), - &[ - KeyedAccount::new(&Pubkey::default(), false, &create_default_stake_account()), - KeyedAccount::new(&sysvar::rent::id(), false, &create_default_account()) - ], + &keyed_accounts, &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default() )) .unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::InvalidArgument), ); // fails to deserialize stake state + let stake_address = Pubkey::default(); + let stake_account = create_default_stake_account(); + let rent_address = sysvar::rent::id(); + let rent_account = RefCell::new(account::create_account_shared_data_for_test( + &Rent::default(), + )); + let keyed_accounts = [ + KeyedAccount::new(&stake_address, false, &stake_account), + KeyedAccount::new(&rent_address, false, &rent_account), + ]; assert_eq!( super::process_instruction( &Pubkey::default(), - &[ - KeyedAccount::new(&Pubkey::default(), false, &create_default_stake_account()), - KeyedAccount::new( - &sysvar::rent::id(), - false, - &RefCell::new(account::create_account_shared_data_for_test( - &Rent::default() - )) - ) - ], + &keyed_accounts, &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default() )) .unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::InvalidAccountData), ); // gets the first check in delegate, wrong number of accounts + let stake_address = Pubkey::default(); + let stake_account = create_default_stake_account(); + let keyed_accounts = [KeyedAccount::new(&stake_address, false, &stake_account)]; assert_eq!( super::process_instruction( &Pubkey::default(), - &[KeyedAccount::new( - &Pubkey::default(), - false, - &create_default_stake_account() - ),], + &keyed_accounts, &serialize(&StakeInstruction::DelegateStake).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys), ); // gets the sub-check for number of args + let stake_address = Pubkey::default(); + let stake_account = create_default_stake_account(); + let keyed_accounts = [KeyedAccount::new(&stake_address, false, &stake_account)]; assert_eq!( super::process_instruction( &Pubkey::default(), - &[KeyedAccount::new( - &Pubkey::default(), - false, - &create_default_stake_account() - )], + &keyed_accounts, &serialize(&StakeInstruction::DelegateStake).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys), ); // gets the check non-deserialize-able account in delegate_stake + let stake_address = Pubkey::default(); + let stake_account = create_default_stake_account(); + let vote_address = Pubkey::default(); let mut bad_vote_account = create_default_account(); bad_vote_account.get_mut().owner = solana_vote_program::id(); + let clock_address = sysvar::clock::id(); + let clock_account = RefCell::new(account::create_account_shared_data_for_test( + &sysvar::clock::Clock::default(), + )); + let stake_history_address = sysvar::stake_history::id(); + let stake_history_account = RefCell::new(account::create_account_shared_data_for_test( + &sysvar::stake_history::StakeHistory::default(), + )); + let config_address = config::id(); + let config_account = RefCell::new(config::create_account(0, &config::Config::default())); + let keyed_accounts = [ + KeyedAccount::new(&stake_address, true, &stake_account), + KeyedAccount::new(&vote_address, false, &bad_vote_account), + KeyedAccount::new(&clock_address, false, &clock_account), + KeyedAccount::new(&stake_history_address, false, &stake_history_account), + KeyedAccount::new(&config_address, false, &config_account), + ]; assert_eq!( super::process_instruction( &Pubkey::default(), - &[ - KeyedAccount::new(&Pubkey::default(), true, &create_default_stake_account()), - KeyedAccount::new(&Pubkey::default(), false, &bad_vote_account), - KeyedAccount::new( - &sysvar::clock::id(), - false, - &RefCell::new(account::create_account_shared_data_for_test( - &sysvar::clock::Clock::default(), - )) - ), - KeyedAccount::new( - &sysvar::stake_history::id(), - false, - &RefCell::new(account::create_account_shared_data_for_test( - &sysvar::stake_history::StakeHistory::default(), - )) - ), - KeyedAccount::new( - &config::id(), - false, - &RefCell::new(config::create_account(0, &config::Config::default())) - ), - ], + &keyed_accounts, &serialize(&StakeInstruction::DelegateStake).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::InvalidAccountData), ); // Tests 3rd keyed account is of correct type (Clock instead of rewards) in withdraw + let stake_address = Pubkey::default(); + let stake_account = create_default_stake_account(); + let vote_address = Pubkey::default(); + let vote_account = create_default_account(); + let rewards_address = sysvar::rewards::id(); + let rewards_account = RefCell::new(account::create_account_shared_data_for_test( + &sysvar::rewards::Rewards::new(0.0), + )); + let stake_history_address = sysvar::stake_history::id(); + let stake_history_account = RefCell::new(account::create_account_shared_data_for_test( + &StakeHistory::default(), + )); + let keyed_accounts = [ + KeyedAccount::new(&stake_address, false, &stake_account), + KeyedAccount::new(&vote_address, false, &vote_account), + KeyedAccount::new(&rewards_address, false, &rewards_account), + KeyedAccount::new(&stake_history_address, false, &stake_history_account), + ]; assert_eq!( super::process_instruction( &Pubkey::default(), - &[ - KeyedAccount::new(&Pubkey::default(), false, &create_default_stake_account()), - KeyedAccount::new(&Pubkey::default(), false, &create_default_account()), - KeyedAccount::new( - &sysvar::rewards::id(), - false, - &RefCell::new(account::create_account_shared_data_for_test( - &sysvar::rewards::Rewards::new(0.0), - )) - ), - KeyedAccount::new( - &sysvar::stake_history::id(), - false, - &RefCell::new(account::create_account_shared_data_for_test( - &StakeHistory::default(), - )) - ), - ], + &keyed_accounts, &serialize(&StakeInstruction::Withdraw(42)).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::InvalidArgument), ); // Tests correct number of accounts are provided in withdraw + let stake_address = Pubkey::default(); + let stake_account = create_default_stake_account(); + let keyed_accounts = [KeyedAccount::new(&stake_address, false, &stake_account)]; assert_eq!( super::process_instruction( &Pubkey::default(), - &[KeyedAccount::new( - &Pubkey::default(), - false, - &create_default_stake_account() - )], + &keyed_accounts, &serialize(&StakeInstruction::Withdraw(42)).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys), ); // Tests 2nd keyed account is of correct type (Clock instead of rewards) in deactivate + let stake_address = Pubkey::default(); + let stake_account = create_default_stake_account(); + let rewards_address = sysvar::rewards::id(); + let rewards_account = RefCell::new(account::create_account_shared_data_for_test( + &sysvar::rewards::Rewards::new(0.0), + )); + let keyed_accounts = [ + KeyedAccount::new(&stake_address, false, &stake_account), + KeyedAccount::new(&rewards_address, false, &rewards_account), + ]; assert_eq!( super::process_instruction( &Pubkey::default(), - &[ - KeyedAccount::new(&Pubkey::default(), false, &create_default_stake_account()), - KeyedAccount::new( - &sysvar::rewards::id(), - false, - &RefCell::new(account::create_account_shared_data_for_test( - &sysvar::rewards::Rewards::new(0.0), - )) - ), - ], + &keyed_accounts, &serialize(&StakeInstruction::Deactivate).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&keyed_accounts) ), Err(InstructionError::InvalidArgument), ); @@ -1122,9 +1124,9 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &[], + &keyed_accounts, &serialize(&StakeInstruction::Deactivate).unwrap(), - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&[]) ), Err(InstructionError::NotEnoughAccountKeys), ); diff --git a/programs/stake/src/stake_state.rs b/programs/stake/src/stake_state.rs index bb54eb9d13ef21..8f6a6e90514cc4 100644 --- a/programs/stake/src/stake_state.rs +++ b/programs/stake/src/stake_state.rs @@ -5103,9 +5103,9 @@ mod tests { let source_stake_pubkey = solana_sdk::pubkey::new_rand(); let authorized_pubkey = solana_sdk::pubkey::new_rand(); let stake_lamports = 42; - let invoke_context = MockInvokeContext::default(); let signers = vec![authorized_pubkey].into_iter().collect(); + let invoke_context = MockInvokeContext::new(&[]); for state in &[ StakeState::Initialized(Meta::auto(&authorized_pubkey)), @@ -5213,7 +5213,7 @@ mod tests { #[test] fn test_merge_self_fails() { - let invoke_context = MockInvokeContext::default(); + let invoke_context = MockInvokeContext::new(&[]); let stake_address = Pubkey::new_unique(); let authority_pubkey = Pubkey::new_unique(); let signers = HashSet::from_iter(vec![authority_pubkey]); @@ -5257,7 +5257,6 @@ mod tests { #[test] fn test_merge_incorrect_authorized_staker() { - let invoke_context = MockInvokeContext::default(); let stake_pubkey = solana_sdk::pubkey::new_rand(); let source_stake_pubkey = solana_sdk::pubkey::new_rand(); let authorized_pubkey = solana_sdk::pubkey::new_rand(); @@ -5266,6 +5265,7 @@ mod tests { let signers = vec![authorized_pubkey].into_iter().collect(); let wrong_signers = vec![wrong_authorized_pubkey].into_iter().collect(); + let invoke_context = MockInvokeContext::new(&[]); for state in &[ StakeState::Initialized(Meta::auto(&authorized_pubkey)), @@ -5327,12 +5327,12 @@ mod tests { #[test] fn test_merge_invalid_account_data() { - let invoke_context = MockInvokeContext::default(); let stake_pubkey = solana_sdk::pubkey::new_rand(); let source_stake_pubkey = solana_sdk::pubkey::new_rand(); let authorized_pubkey = solana_sdk::pubkey::new_rand(); let stake_lamports = 42; let signers = vec![authorized_pubkey].into_iter().collect(); + let invoke_context = MockInvokeContext::new(&[]); for state in &[ StakeState::Uninitialized, @@ -5379,7 +5379,6 @@ mod tests { #[test] fn test_merge_fake_stake_source() { - let invoke_context = MockInvokeContext::default(); let stake_pubkey = solana_sdk::pubkey::new_rand(); let source_stake_pubkey = solana_sdk::pubkey::new_rand(); let authorized_pubkey = solana_sdk::pubkey::new_rand(); @@ -5411,6 +5410,7 @@ mod tests { .expect("source_stake_account"); let source_stake_keyed_account = KeyedAccount::new(&source_stake_pubkey, true, &source_stake_account); + let invoke_context = MockInvokeContext::new(&[]); assert_eq!( stake_keyed_account.merge( @@ -5426,7 +5426,6 @@ mod tests { #[test] fn test_merge_active_stake() { - let invoke_context = MockInvokeContext::default(); let base_lamports = 4242424242; let stake_address = Pubkey::new_unique(); let source_address = Pubkey::new_unique(); @@ -5480,6 +5479,7 @@ mod tests { let mut clock = Clock::default(); let mut stake_history = StakeHistory::default(); + let invoke_context = MockInvokeContext::new(&[]); clock.epoch = 0; let mut effective = base_lamports; @@ -6144,7 +6144,6 @@ mod tests { #[test] fn test_things_can_merge() { - let invoke_context = MockInvokeContext::default(); let good_stake = Stake { credits_observed: 4242, delegation: Delegation { @@ -6154,6 +6153,7 @@ mod tests { ..Delegation::default() }, }; + let invoke_context = MockInvokeContext::new(&[]); let identical = good_stake; assert!( @@ -6314,7 +6314,6 @@ mod tests { #[test] fn test_merge_kind_get_if_mergeable() { - let invoke_context = MockInvokeContext::default(); let authority_pubkey = Pubkey::new_unique(); let initial_lamports = 4242424242; let rent = Rent::default(); @@ -6333,9 +6332,9 @@ mod tests { ) .expect("stake_account"); let stake_keyed_account = KeyedAccount::new(&authority_pubkey, true, &stake_account); - let mut clock = Clock::default(); let mut stake_history = StakeHistory::default(); + let invoke_context = MockInvokeContext::new(&[]); // Uninitialized state fails assert_eq!( @@ -6547,7 +6546,6 @@ mod tests { #[test] fn test_merge_kind_merge() { - let invoke_context = MockInvokeContext::default(); let lamports = 424242; let meta = Meta { rent_exempt_reserve: 42, @@ -6563,6 +6561,7 @@ mod tests { let inactive = MergeKind::Inactive(Meta::default(), lamports); let activation_epoch = MergeKind::ActivationEpoch(meta, stake); let fully_active = MergeKind::FullyActive(meta, stake); + let invoke_context = MockInvokeContext::new(&[]); assert_eq!( inactive diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index 402a19c0675fec..2cfccdfdfe5b3f 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -357,7 +357,7 @@ mod tests { &Pubkey::default(), &[], &[], - &mut MockInvokeContext::default() + &mut MockInvokeContext::new(&[]) ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -403,7 +403,7 @@ mod tests { &Pubkey::default(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&keyed_accounts), ) } } diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index d336dfe8365aeb..f917bd88379021 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -482,7 +482,7 @@ mod tests { owner, keyed_accounts, instruction_data, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(keyed_accounts), ) } @@ -616,7 +616,7 @@ mod tests { Address::create( &to, Some((&from, seed, &owner)), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ), Err(SystemError::AddressWithSeedMismatch.into()) ); @@ -634,7 +634,7 @@ mod tests { let to_address = Address::create( &to, Some((&from, seed, &new_owner)), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); @@ -647,7 +647,7 @@ mod tests { 2, &new_owner, &HashSet::new(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ), Err(InstructionError::MissingRequiredSignature) ); @@ -674,7 +674,7 @@ mod tests { 2, &new_owner, &[to].iter().cloned().collect::>(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ), Ok(()) ); @@ -706,7 +706,7 @@ mod tests { 2, &new_owner, &[from, to].iter().cloned().collect::>(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::ResultWithNegativeLamports.into())); } @@ -730,7 +730,7 @@ mod tests { MAX_PERMITTED_DATA_LENGTH + 1, &system_program::id(), &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert!(result.is_err()); assert_eq!( @@ -747,7 +747,7 @@ mod tests { MAX_PERMITTED_DATA_LENGTH, &system_program::id(), &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert!(result.is_ok()); assert_eq!(to_account.borrow().lamports, 50); @@ -780,7 +780,7 @@ mod tests { 2, &new_owner, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); @@ -799,7 +799,7 @@ mod tests { 2, &new_owner, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); let from_lamports = from_account.borrow().lamports; @@ -817,7 +817,7 @@ mod tests { 2, &new_owner, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); assert_eq!(from_lamports, 100); @@ -845,7 +845,7 @@ mod tests { 2, &new_owner, &[owned_key].iter().cloned().collect::>(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); @@ -859,7 +859,7 @@ mod tests { 2, &new_owner, &[from].iter().cloned().collect::>(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); @@ -873,7 +873,7 @@ mod tests { 2, &new_owner, &[owned_key].iter().cloned().collect::>(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Ok(())); } @@ -899,7 +899,7 @@ mod tests { 2, &sysvar::id(), &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::InvalidProgramId.into())); @@ -933,7 +933,7 @@ mod tests { 2, &new_owner, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); } @@ -967,7 +967,7 @@ mod tests { 0, &solana_sdk::pubkey::new_rand(), &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ), Err(InstructionError::InvalidArgument), ); @@ -986,7 +986,7 @@ mod tests { &pubkey.into(), &new_owner, &HashSet::new(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ), Err(InstructionError::MissingRequiredSignature) ); @@ -997,7 +997,7 @@ mod tests { &pubkey.into(), &system_program::id(), &HashSet::new(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ), Ok(()) ); @@ -1026,7 +1026,7 @@ mod tests { &from.into(), &new_owner, &[from].iter().cloned().collect::>(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ), Err(SystemError::InvalidProgramId.into()) ); @@ -1067,7 +1067,7 @@ mod tests { &from_keyed_account, &to_keyed_account, 50, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let from_lamports = from_keyed_account.account.borrow().lamports; @@ -1081,7 +1081,7 @@ mod tests { &from_keyed_account, &to_keyed_account, 100, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::ResultWithNegativeLamports.into())); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1094,7 +1094,7 @@ mod tests { &from_keyed_account, &to_keyed_account, 0, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .is_ok(),); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1121,7 +1121,7 @@ mod tests { &from_owner, &to_keyed_account, 50, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let from_lamports = from_keyed_account.account.borrow().lamports; @@ -1138,7 +1138,7 @@ mod tests { &from_owner, &to_keyed_account, 100, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::ResultWithNegativeLamports.into())); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1153,7 +1153,7 @@ mod tests { &from_owner, &to_keyed_account, 0, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .is_ok(),); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1184,7 +1184,7 @@ mod tests { &KeyedAccount::new(&from, true, &from_account), &KeyedAccount::new(&to, false, &to_account), 50, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ), Err(InstructionError::InvalidArgument), ) diff --git a/sdk/src/nonce_keyed_account.rs b/sdk/src/nonce_keyed_account.rs index fc9ae7517661f8..522fb92d8d2732 100644 --- a/sdk/src/nonce_keyed_account.rs +++ b/sdk/src/nonce_keyed_account.rs @@ -300,7 +300,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(keyed_account) @@ -318,7 +318,7 @@ mod test { .advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(keyed_account) @@ -336,7 +336,7 @@ mod test { .advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(keyed_account) @@ -362,7 +362,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); // Empties Account balance @@ -396,7 +396,7 @@ mod test { &authority, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let pubkey = nonce_account.account.borrow().owner; @@ -415,7 +415,7 @@ mod test { let result = nonce_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }) @@ -438,14 +438,14 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let recent_blockhashes = vec![].into_iter().collect(); let result = keyed_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into())); }) @@ -468,13 +468,13 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let result = keyed_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::NotExpired.into())); }) @@ -494,7 +494,7 @@ mod test { let result = keyed_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -518,7 +518,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let mut signers = HashSet::new(); @@ -527,7 +527,7 @@ mod test { let result = nonce_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Ok(())); }); @@ -552,13 +552,13 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let result = nonce_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }); @@ -592,7 +592,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -631,7 +631,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }) @@ -661,7 +661,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -691,7 +691,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -711,7 +711,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -741,7 +741,7 @@ mod test { &authority, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -765,7 +765,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -791,7 +791,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -819,7 +819,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { @@ -832,7 +832,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::NotExpired.into())); }) @@ -854,7 +854,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { @@ -868,7 +868,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -890,7 +890,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { @@ -904,7 +904,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -926,7 +926,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); with_test_keyed_account(55, false, |to_keyed| { @@ -940,7 +940,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -967,7 +967,7 @@ mod test { &authority, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); let data = nonce::state::Data { authority, @@ -998,7 +998,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into())); }) @@ -1019,7 +1019,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let recent_blockhashes = create_test_recent_blockhashes(0); @@ -1027,7 +1027,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -1047,7 +1047,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -1070,7 +1070,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let authority = Pubkey::default(); @@ -1082,7 +1082,7 @@ mod test { let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Ok(())); let state = AccountUtilsState::::state(nonce_account) @@ -1105,7 +1105,7 @@ mod test { let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -1128,13 +1128,13 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); }) @@ -1155,7 +1155,7 @@ mod test { &authorized, &recent_blockhashes, &Rent::free(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); assert!(verify_nonce_account( @@ -1190,7 +1190,7 @@ mod test { &authorized, &recent_blockhashes, &Rent::free(), - &mut MockInvokeContext::default(), + &mut MockInvokeContext::new(&[]), ) .unwrap(); assert!(!verify_nonce_account( diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 35b5fb644d9b74..8f927723d46adc 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -289,8 +289,8 @@ pub struct MockInvokeContext<'a> { pub invoke_depth: usize, pub sysvars: Vec<(Pubkey, Option>>)>, } -impl<'a> Default for MockInvokeContext<'a> { - fn default() -> Self { +impl<'a> MockInvokeContext<'a> { + pub fn new(keyed_accounts: &'a [KeyedAccount<'a>]) -> Self { MockInvokeContext { key: Pubkey::default(), logger: MockLogger::default(), @@ -298,7 +298,7 @@ impl<'a> Default for MockInvokeContext<'a> { compute_meter: MockComputeMeter { remaining: std::i64::MAX as u64, }, - keyed_accounts: &[], // TODO [KeyedAccounts to InvokeContext refactoring] + keyed_accounts, programs: vec![], accounts: vec![], invoke_depth: 0, From cd4c2f6a086d787b9e4bdf68fb031de762cf8eaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 5 Apr 2021 15:37:04 +0200 Subject: [PATCH 03/33] Adds keyed_accounts parameter to ThisInvokeContext constructor. --- runtime/src/message_processor.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index aa02918520ce24..55ed39eec2048b 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -276,6 +276,7 @@ impl<'a> ThisInvokeContext<'a> { pre_accounts: Vec, executables: &'a [(Pubkey, Rc>)], account_deps: &'a [(Pubkey, Rc>)], + keyed_accounts: &'a [KeyedAccount<'a>], programs: &'a [(Pubkey, ProcessInstructionWithContext)], log_collector: Option>, bpf_compute_budget: BpfComputeBudget, @@ -293,7 +294,7 @@ impl<'a> ThisInvokeContext<'a> { pre_accounts, executables, account_deps, - keyed_accounts: &[], // TODO [KeyedAccounts to InvokeContext refactoring] + keyed_accounts, programs, logger: Rc::new(RefCell::new(ThisLogger { log_collector })), bpf_compute_budget, @@ -1096,12 +1097,20 @@ impl MessageProcessor { let pre_accounts = Self::create_pre_accounts(message, instruction, accounts); let program_id = instruction.program_id(&message.account_keys); + let keyed_accounts = Self::create_keyed_accounts( + message, + instruction, + executable_accounts, + accounts, + demote_sysvar_write_locks, + ); let mut invoke_context = ThisInvokeContext::new( program_id, rent_collector.rent, pre_accounts, executable_accounts, account_deps, + keyed_accounts.as_slice(), &self.programs, log_collector, bpf_compute_budget, @@ -1111,13 +1120,6 @@ impl MessageProcessor { account_db, ancestors, ); - let keyed_accounts = Self::create_keyed_accounts( - message, - instruction, - executable_accounts, - accounts, - demote_sysvar_write_locks, - ); self.process_instruction( program_id, &keyed_accounts, @@ -1230,6 +1232,7 @@ mod tests { &[], &[], &[], + &[], None, BpfComputeBudget::default(), Rc::new(RefCell::new(Executors::default())), @@ -2145,6 +2148,7 @@ mod tests { ], &[], &[], + &[], programs.as_slice(), None, BpfComputeBudget::default(), From 871ece893af8f7a98a4a39a4bda74f8530ec91c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 5 Apr 2021 15:37:40 +0200 Subject: [PATCH 04/33] Replaces next_keyed_account() by keyed_account_at_index() --- programs/bpf_loader/src/lib.rs | 66 ++++++++++----------- programs/budget/src/budget_processor.rs | 25 ++++---- programs/config/src/config_processor.rs | 9 ++- programs/ownable/src/ownable_processor.rs | 7 +-- programs/stake/src/stake_instruction.rs | 55 +++++++++-------- programs/vest/src/vest_processor.rs | 21 ++++--- programs/vote/src/vote_instruction.rs | 19 +++--- programs/vote/src/vote_state/mod.rs | 7 +-- runtime/src/native_loader.rs | 9 ++- runtime/src/system_instruction_processor.rs | 58 ++++++++++-------- sdk/src/keyed_account.rs | 11 ++++ 11 files changed, 148 insertions(+), 139 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index cde303fa22cdf1..0647080a811f78 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -33,7 +33,7 @@ use solana_sdk::{ feature_set::{skip_ro_deserialization, upgradeable_close_instruction}, ic_logger_msg, ic_msg, instruction::InstructionError, - keyed_account::{from_keyed_account, next_keyed_account, KeyedAccount}, + keyed_account::{from_keyed_account, keyed_account_at_index, KeyedAccount}, loader_instruction::LoaderInstruction, loader_upgradeable_instruction::UpgradeableLoaderInstruction, process_instruction::{stable_log, ComputeMeter, Executor, InvokeContext}, @@ -198,8 +198,7 @@ fn process_instruction_common( ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); - let account_iter = &mut keyed_accounts.iter(); - let first_account = next_keyed_account(account_iter)?; + let first_account = keyed_account_at_index(keyed_accounts, 0)?; if first_account.executable()? { if first_account.unsigned_key() != program_id { ic_logger_msg!(logger, "Program id mismatch"); @@ -212,7 +211,7 @@ fn process_instruction_common( programdata_address, } = first_account.state()? { - let programdata = next_keyed_account(account_iter)?; + let programdata = keyed_account_at_index(keyed_accounts, 1)?; if programdata_address != *programdata.unsigned_key() { ic_logger_msg!( logger, @@ -292,26 +291,25 @@ fn process_loader_upgradeable_instruction( use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); - let account_iter = &mut keyed_accounts.iter(); match limited_deserialize(instruction_data)? { UpgradeableLoaderInstruction::InitializeBuffer => { - let buffer = next_keyed_account(account_iter)?; + let buffer = keyed_account_at_index(keyed_accounts, 0)?; if UpgradeableLoaderState::Uninitialized != buffer.state()? { ic_logger_msg!(logger, "Buffer account already initialized"); return Err(InstructionError::AccountAlreadyInitialized); } - let authority = next_keyed_account(account_iter)?; + let authority = keyed_account_at_index(keyed_accounts, 1)?; buffer.set_state(&UpgradeableLoaderState::Buffer { authority_address: Some(*authority.unsigned_key()), })?; } UpgradeableLoaderInstruction::Write { offset, bytes } => { - let buffer = next_keyed_account(account_iter)?; - let authority = next_keyed_account(account_iter)?; + let buffer = keyed_account_at_index(keyed_accounts, 0)?; + let authority = keyed_account_at_index(keyed_accounts, 1)?; if let UpgradeableLoaderState::Buffer { authority_address } = buffer.state()? { if authority_address.is_none() { @@ -338,14 +336,14 @@ fn process_loader_upgradeable_instruction( )?; } UpgradeableLoaderInstruction::DeployWithMaxDataLen { max_data_len } => { - let payer = next_keyed_account(account_iter)?; - let programdata = next_keyed_account(account_iter)?; - let program = next_keyed_account(account_iter)?; - let buffer = next_keyed_account(account_iter)?; - let rent = from_keyed_account::(next_keyed_account(account_iter)?)?; - let clock = from_keyed_account::(next_keyed_account(account_iter)?)?; - let system = next_keyed_account(account_iter)?; - let authority = next_keyed_account(account_iter)?; + let payer = keyed_account_at_index(keyed_accounts, 0)?; + let programdata = keyed_account_at_index(keyed_accounts, 1)?; + let program = keyed_account_at_index(keyed_accounts, 2)?; + let buffer = keyed_account_at_index(keyed_accounts, 3)?; + let rent = from_keyed_account::(keyed_account_at_index(keyed_accounts, 4)?)?; + let clock = from_keyed_account::(keyed_account_at_index(keyed_accounts, 5)?)?; + let system = keyed_account_at_index(keyed_accounts, 6)?; + let authority = keyed_account_at_index(keyed_accounts, 7)?; let upgrade_authority_address = Some(*authority.unsigned_key()); let upgrade_authority_signer = authority.signer_key().is_none(); @@ -452,13 +450,13 @@ fn process_loader_upgradeable_instruction( ic_logger_msg!(logger, "Deployed program {:?}", program.unsigned_key()); } UpgradeableLoaderInstruction::Upgrade => { - let programdata = next_keyed_account(account_iter)?; - let program = next_keyed_account(account_iter)?; - let buffer = next_keyed_account(account_iter)?; - let spill = next_keyed_account(account_iter)?; - let rent = from_keyed_account::(next_keyed_account(account_iter)?)?; - let clock = from_keyed_account::(next_keyed_account(account_iter)?)?; - let authority = next_keyed_account(account_iter)?; + let programdata = keyed_account_at_index(keyed_accounts, 0)?; + let program = keyed_account_at_index(keyed_accounts, 1)?; + let buffer = keyed_account_at_index(keyed_accounts, 2)?; + let spill = keyed_account_at_index(keyed_accounts, 3)?; + let rent = from_keyed_account::(keyed_account_at_index(keyed_accounts, 4)?)?; + let clock = from_keyed_account::(keyed_account_at_index(keyed_accounts, 5)?)?; + let authority = keyed_account_at_index(keyed_accounts, 6)?; // Verify Program account @@ -581,9 +579,9 @@ fn process_loader_upgradeable_instruction( ic_logger_msg!(logger, "Upgraded program {:?}", program.unsigned_key()); } UpgradeableLoaderInstruction::SetAuthority => { - let account = next_keyed_account(account_iter)?; - let present_authority = next_keyed_account(account_iter)?; - let new_authority = next_keyed_account(account_iter) + let account = keyed_account_at_index(keyed_accounts, 0)?; + let present_authority = keyed_account_at_index(keyed_accounts, 1)?; + let new_authority = keyed_account_at_index(keyed_accounts, 2) .ok() .map(|account| account.unsigned_key()); @@ -642,9 +640,9 @@ fn process_loader_upgradeable_instruction( if !invoke_context.is_feature_active(&upgradeable_close_instruction::id()) { return Err(InstructionError::InvalidInstructionData); } - let close_account = next_keyed_account(account_iter)?; - let recipient_account = next_keyed_account(account_iter)?; - let authority = next_keyed_account(account_iter)?; + let close_account = keyed_account_at_index(keyed_accounts, 0)?; + let recipient_account = keyed_account_at_index(keyed_accounts, 1)?; + let authority = keyed_account_at_index(keyed_accounts, 2)?; if close_account.unsigned_key() == recipient_account.unsigned_key() { ic_logger_msg!(logger, "Recipient is the same as the account being closed"); @@ -689,9 +687,7 @@ fn process_loader_instruction( invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { - let account_iter = &mut keyed_accounts.iter(); - - let program = next_keyed_account(account_iter)?; + let program = keyed_account_at_index(keyed_accounts, 0)?; if program.owner()? != *program_id { ic_msg!( invoke_context, @@ -781,10 +777,8 @@ impl Executor for BpfExecutor { let logger = invoke_context.get_logger(); let invoke_depth = invoke_context.invoke_depth(); - let mut keyed_accounts_iter = keyed_accounts.iter(); - let _ = next_keyed_account(&mut keyed_accounts_iter)?; - let parameter_accounts = keyed_accounts_iter.as_slice(); let mut serialize_time = Measure::start("serialize"); + let parameter_accounts = &keyed_accounts[1..]; let mut parameter_bytes = serialize_parameters(loader_id, program_id, parameter_accounts, &instruction_data)?; serialize_time.stop(); diff --git a/programs/budget/src/budget_processor.rs b/programs/budget/src/budget_processor.rs index 9b0dc96335756f..df685f07d30cb2 100644 --- a/programs/budget/src/budget_processor.rs +++ b/programs/budget/src/budget_processor.rs @@ -10,7 +10,7 @@ use solana_sdk::{ account::{ReadableAccount, WritableAccount}, hash::hash, instruction::InstructionError, - keyed_account::{next_keyed_account, KeyedAccount}, + keyed_account::{keyed_account_at_index, KeyedAccount}, process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey, @@ -120,18 +120,17 @@ pub fn process_instruction( data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts_iter = &mut keyed_accounts.iter(); let instruction = limited_deserialize(data)?; trace!("process_instruction: {:?}", instruction); match instruction { BudgetInstruction::InitializeAccount(expr) => { - let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?; + let contract_keyed_account = keyed_account_at_index(keyed_accounts, 0)?; if let Some(payment) = expr.final_payment() { let to_keyed_account = contract_keyed_account; - let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?; + let contract_keyed_account = keyed_account_at_index(keyed_accounts, 1)?; contract_keyed_account.try_account_ref_mut()?.lamports = 0; to_keyed_account.try_account_ref_mut()?.lamports += payment.lamports; return Ok(()); @@ -154,8 +153,8 @@ pub fn process_instruction( ) } BudgetInstruction::ApplyTimestamp(dt) => { - let witness_keyed_account = next_keyed_account(keyed_accounts_iter)?; - let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?; + let witness_keyed_account = keyed_account_at_index(keyed_accounts, 0)?; + let contract_keyed_account = keyed_account_at_index(keyed_accounts, 1)?; let mut budget_state = BudgetState::deserialize(&contract_keyed_account.try_account_ref()?.data())?; if !budget_state.is_pending() { @@ -173,7 +172,7 @@ pub fn process_instruction( &mut budget_state, witness_keyed_account, contract_keyed_account, - next_keyed_account(keyed_accounts_iter), + keyed_account_at_index(keyed_accounts, 2), dt, )?; trace!("apply timestamp committed"); @@ -184,8 +183,8 @@ pub fn process_instruction( ) } BudgetInstruction::ApplySignature => { - let witness_keyed_account = next_keyed_account(keyed_accounts_iter)?; - let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?; + let witness_keyed_account = keyed_account_at_index(keyed_accounts, 0)?; + let contract_keyed_account = keyed_account_at_index(keyed_accounts, 1)?; let mut budget_state = BudgetState::deserialize(&contract_keyed_account.try_account_ref()?.data())?; if !budget_state.is_pending() { @@ -203,7 +202,7 @@ pub fn process_instruction( &mut budget_state, witness_keyed_account, contract_keyed_account, - next_keyed_account(keyed_accounts_iter), + keyed_account_at_index(keyed_accounts, 2), )?; trace!("apply signature committed"); budget_state.serialize( @@ -213,8 +212,8 @@ pub fn process_instruction( ) } BudgetInstruction::ApplyAccountData => { - let witness_keyed_account = next_keyed_account(keyed_accounts_iter)?; - let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?; + let witness_keyed_account = keyed_account_at_index(keyed_accounts, 0)?; + let contract_keyed_account = keyed_account_at_index(keyed_accounts, 1)?; let mut budget_state = BudgetState::deserialize(&contract_keyed_account.try_account_ref()?.data())?; if !budget_state.is_pending() { @@ -228,7 +227,7 @@ pub fn process_instruction( &mut budget_state, witness_keyed_account, contract_keyed_account, - next_keyed_account(keyed_accounts_iter), + keyed_account_at_index(keyed_accounts, 2), )?; trace!("apply account data committed"); budget_state.serialize( diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index 794ac54fdd8298..698e334d460d22 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -6,7 +6,7 @@ use solana_sdk::{ account::{ReadableAccount, WritableAccount}, feature_set, ic_msg, instruction::InstructionError, - keyed_account::{next_keyed_account, KeyedAccount}, + keyed_account::{keyed_account_at_index, KeyedAccount}, process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey, @@ -19,9 +19,7 @@ pub fn process_instruction( invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let key_list: ConfigKeys = limited_deserialize(data)?; - let keyed_accounts_iter = &mut keyed_accounts.iter(); - let config_keyed_account = &mut next_keyed_account(keyed_accounts_iter)?; - + let config_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; let current_data: ConfigKeys = { let config_account = config_keyed_account.try_account_ref_mut()?; if invoke_context.is_feature_active(&feature_set::check_program_owner::id()) @@ -55,6 +53,7 @@ pub fn process_instruction( } let mut counter = 0; + let mut keyed_accounts_iter = keyed_accounts.iter().skip(1); for (signer, _) in key_list.keys.iter().filter(|(_, is_signer)| *is_signer) { counter += 1; if signer != config_keyed_account.unsigned_key() { @@ -628,7 +627,7 @@ mod tests { &id(), &keyed_accounts, &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(&keyed_accounts), ), Err(InstructionError::InvalidAccountOwner) ); diff --git a/programs/ownable/src/ownable_processor.rs b/programs/ownable/src/ownable_processor.rs index b5be6e6abe06be..13c217c8180138 100644 --- a/programs/ownable/src/ownable_processor.rs +++ b/programs/ownable/src/ownable_processor.rs @@ -5,7 +5,7 @@ use bincode::serialize_into; use solana_sdk::{ account::{ReadableAccount, WritableAccount}, instruction::InstructionError, - keyed_account::{next_keyed_account, KeyedAccount}, + keyed_account::{keyed_account_at_index, KeyedAccount}, process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey, @@ -35,15 +35,14 @@ pub fn process_instruction( _invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let new_owner_pubkey: Pubkey = limited_deserialize(data)?; - let keyed_accounts_iter = &mut keyed_accounts.iter(); - let account_keyed_account = &mut next_keyed_account(keyed_accounts_iter)?; + let account_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; let mut account_owner_pubkey: Pubkey = limited_deserialize(&account_keyed_account.try_account_ref()?.data())?; if account_owner_pubkey == Pubkey::default() { account_owner_pubkey = new_owner_pubkey; } else { - let owner_keyed_account = &mut next_keyed_account(keyed_accounts_iter)?; + let owner_keyed_account = &mut keyed_account_at_index(keyed_accounts, 1)?; set_owner( &mut account_owner_pubkey, new_owner_pubkey, diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 788bf3fb241258..dfb1d0015a86b4 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -10,7 +10,7 @@ use solana_sdk::{ decode_error::DecodeError, feature_set, instruction::{AccountMeta, Instruction, InstructionError}, - keyed_account::{from_keyed_account, get_signers, next_keyed_account, KeyedAccount}, + keyed_account::{from_keyed_account, get_signers, keyed_account_at_index, KeyedAccount}, process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey, @@ -492,8 +492,7 @@ pub fn process_instruction( let signers = get_signers(keyed_accounts); - let keyed_accounts = &mut keyed_accounts.iter(); - let me = &next_keyed_account(keyed_accounts)?; + let me = &keyed_account_at_index(keyed_accounts, 0)?; if me.owner()? != id() { if invoke_context.is_feature_active(&feature_set::check_program_owner::id()) { @@ -507,7 +506,7 @@ pub fn process_instruction( StakeInstruction::Initialize(authorized, lockup) => me.initialize( &authorized, &lockup, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 1)?)?, ), StakeInstruction::Authorize(authorized_pubkey, stake_authorize) => { let require_custodian_for_locked_stake_authorize = invoke_context.is_feature_active( @@ -515,9 +514,11 @@ pub fn process_instruction( ); if require_custodian_for_locked_stake_authorize { - let clock = from_keyed_account::(next_keyed_account(keyed_accounts)?)?; - let _current_authority = next_keyed_account(keyed_accounts)?; - let custodian = keyed_accounts.next().map(|ka| ka.unsigned_key()); + let clock = + from_keyed_account::(keyed_account_at_index(keyed_accounts, 1)?)?; + let _current_authority = keyed_account_at_index(keyed_accounts, 2)?; + let custodian = + keyed_account_at_index(keyed_accounts, 3).map(|ka| ka.unsigned_key()); me.authorize( &signers, @@ -525,7 +526,7 @@ pub fn process_instruction( stake_authorize, require_custodian_for_locked_stake_authorize, &clock, - custodian, + custodian.ok(), ) } else { me.authorize( @@ -539,14 +540,16 @@ pub fn process_instruction( } } StakeInstruction::AuthorizeWithSeed(args) => { - let authority_base = next_keyed_account(keyed_accounts)?; + let authority_base = keyed_account_at_index(keyed_accounts, 1)?; let require_custodian_for_locked_stake_authorize = invoke_context.is_feature_active( &feature_set::require_custodian_for_locked_stake_authorize::id(), ); if require_custodian_for_locked_stake_authorize { - let clock = from_keyed_account::(next_keyed_account(keyed_accounts)?)?; - let custodian = keyed_accounts.next().map(|ka| ka.unsigned_key()); + let clock = + from_keyed_account::(keyed_account_at_index(keyed_accounts, 2)?)?; + let custodian = + keyed_account_at_index(keyed_accounts, 3).map(|ka| ka.unsigned_key()); me.authorize_with_seed( &authority_base, @@ -556,7 +559,7 @@ pub fn process_instruction( args.stake_authorize, require_custodian_for_locked_stake_authorize, &clock, - custodian, + custodian.ok(), ) } else { me.authorize_with_seed( @@ -572,44 +575,44 @@ pub fn process_instruction( } } StakeInstruction::DelegateStake => { - let vote = next_keyed_account(keyed_accounts)?; + let vote = keyed_account_at_index(keyed_accounts, 1)?; me.delegate( &vote, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, - &config::from_keyed_account(next_keyed_account(keyed_accounts)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 2)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 3)?)?, + &config::from_keyed_account(keyed_account_at_index(keyed_accounts, 4)?)?, &signers, ) } StakeInstruction::Split(lamports) => { - let split_stake = &next_keyed_account(keyed_accounts)?; + let split_stake = &keyed_account_at_index(keyed_accounts, 1)?; me.split(lamports, split_stake, &signers) } StakeInstruction::Merge => { - let source_stake = &next_keyed_account(keyed_accounts)?; + let source_stake = &keyed_account_at_index(keyed_accounts, 1)?; me.merge( invoke_context, source_stake, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 2)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 3)?)?, &signers, ) } StakeInstruction::Withdraw(lamports) => { - let to = &next_keyed_account(keyed_accounts)?; + let to = &keyed_account_at_index(keyed_accounts, 1)?; me.withdraw( lamports, to, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, - next_keyed_account(keyed_accounts)?, - keyed_accounts.next(), + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 2)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 3)?)?, + keyed_account_at_index(keyed_accounts, 4)?, + keyed_account_at_index(keyed_accounts, 5).ok(), ) } StakeInstruction::Deactivate => me.deactivate( - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 1)?)?, &signers, ), diff --git a/programs/vest/src/vest_processor.rs b/programs/vest/src/vest_processor.rs index 3dd5d82cba32ce..ed29abb4d60ea8 100644 --- a/programs/vest/src/vest_processor.rs +++ b/programs/vest/src/vest_processor.rs @@ -10,7 +10,7 @@ use solana_sdk::{ account::{AccountSharedData, ReadableAccount, WritableAccount}, feature_set, instruction::InstructionError, - keyed_account::{next_keyed_account, KeyedAccount}, + keyed_account::{keyed_account_at_index, KeyedAccount}, process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey, @@ -63,8 +63,7 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts_iter = &mut keyed_accounts.iter(); - let contract_account = &mut next_keyed_account(keyed_accounts_iter)?.try_account_ref_mut()?; + let contract_account = &mut keyed_account_at_index(keyed_accounts, 0)?.try_account_ref_mut()?; if invoke_context.is_feature_active(&feature_set::check_program_owner::id()) && contract_account.owner != crate::id() { @@ -97,25 +96,25 @@ pub fn process_instruction( VestInstruction::InitializeAccount { .. } => {} VestInstruction::SetTerminator(new_pubkey) => { verify_signed_account( - next_keyed_account(keyed_accounts_iter)?, + keyed_account_at_index(keyed_accounts, 1)?, &vest_state.terminator_pubkey, )?; vest_state.terminator_pubkey = new_pubkey; } VestInstruction::SetPayee(new_pubkey) => { verify_signed_account( - next_keyed_account(keyed_accounts_iter)?, + keyed_account_at_index(keyed_accounts, 1)?, &vest_state.payee_pubkey, )?; vest_state.payee_pubkey = new_pubkey; } VestInstruction::RedeemTokens => { let current_date = verify_date_account( - next_keyed_account(keyed_accounts_iter)?, + keyed_account_at_index(keyed_accounts, 1)?, &vest_state.date_pubkey, )?; let mut payee_account = verify_account( - next_keyed_account(keyed_accounts_iter)?, + keyed_account_at_index(keyed_accounts, 2)?, &vest_state.payee_pubkey, )?; vest_state.redeem_tokens(contract_account, current_date, &mut payee_account); @@ -127,11 +126,11 @@ pub fn process_instruction( contract_account.lamports }; let terminator_account = verify_signed_account( - next_keyed_account(keyed_accounts_iter)?, + keyed_account_at_index(keyed_accounts, 1)?, &vest_state.terminator_pubkey, )?; - let payee_keyed_account = keyed_accounts_iter.next(); - let mut payee_account = if let Some(payee_keyed_account) = payee_keyed_account { + let payee_keyed_account = keyed_account_at_index(keyed_accounts, 2); + let mut payee_account = if let Ok(payee_keyed_account) = payee_keyed_account { payee_keyed_account.try_account_ref_mut()? } else { terminator_account @@ -140,7 +139,7 @@ pub fn process_instruction( } VestInstruction::VestAll => { verify_signed_account( - next_keyed_account(keyed_accounts_iter)?, + keyed_account_at_index(keyed_accounts, 1)?, &vest_state.terminator_pubkey, )?; vest_state.vest_all(); diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index 2cfccdfdfe5b3f..d0beffd6b53ba8 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -14,7 +14,7 @@ use solana_sdk::{ feature_set, hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, - keyed_account::{from_keyed_account, get_signers, next_keyed_account, KeyedAccount}, + keyed_account::{from_keyed_account, get_signers, keyed_account_at_index, KeyedAccount}, process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey, @@ -286,8 +286,7 @@ pub fn process_instruction( let signers: HashSet = get_signers(keyed_accounts); - let keyed_accounts = &mut keyed_accounts.iter(); - let me = &mut next_keyed_account(keyed_accounts)?; + let me = &mut keyed_account_at_index(keyed_accounts, 0)?; if invoke_context.is_feature_active(&feature_set::check_program_owner::id()) && me.owner()? != id() @@ -297,12 +296,12 @@ pub fn process_instruction( match limited_deserialize(data)? { VoteInstruction::InitializeAccount(vote_init) => { - verify_rent_exemption(me, next_keyed_account(keyed_accounts)?)?; + verify_rent_exemption(me, keyed_account_at_index(keyed_accounts, 1)?)?; vote_state::initialize_account( me, &vote_init, &signers, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 2)?)?, invoke_context.is_feature_active(&feature_set::check_init_vote_data::id()), ) } @@ -311,11 +310,11 @@ pub fn process_instruction( &voter_pubkey, vote_authorize, &signers, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 1)?)?, ), VoteInstruction::UpdateValidatorIdentity => vote_state::update_validator_identity( me, - next_keyed_account(keyed_accounts)?.unsigned_key(), + keyed_account_at_index(keyed_accounts, 1)?.unsigned_key(), &signers, ), VoteInstruction::UpdateCommission(commission) => { @@ -325,14 +324,14 @@ pub fn process_instruction( inc_new_counter_info!("vote-native", 1); vote_state::process_vote( me, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, - &from_keyed_account::(next_keyed_account(keyed_accounts)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 1)?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 2)?)?, &vote, &signers, ) } VoteInstruction::Withdraw(lamports) => { - let to = next_keyed_account(keyed_accounts)?; + let to = keyed_account_at_index(keyed_accounts, 1)?; vote_state::withdraw(me, lamports, to, &signers) } } diff --git a/programs/vote/src/vote_state/mod.rs b/programs/vote/src/vote_state/mod.rs index ae64453028686d..cb21e424a1f26c 100644 --- a/programs/vote/src/vote_state/mod.rs +++ b/programs/vote/src/vote_state/mod.rs @@ -788,7 +788,7 @@ mod tests { account::AccountSharedData, account_utils::StateMut, hash::hash, - keyed_account::{get_signers, next_keyed_account}, + keyed_account::{get_signers, keyed_account_at_index}, }; use std::cell::RefCell; @@ -1715,9 +1715,8 @@ mod tests { KeyedAccount::new(&authorized_withdrawer_pubkey, true, &withdrawer_account), ]; let signers: HashSet = get_signers(keyed_accounts); - let keyed_accounts = &mut keyed_accounts.iter(); - let vote_keyed_account = next_keyed_account(keyed_accounts).unwrap(); - let withdrawer_keyed_account = next_keyed_account(keyed_accounts).unwrap(); + let vote_keyed_account = keyed_account_at_index(keyed_accounts, 0).unwrap(); + let withdrawer_keyed_account = keyed_account_at_index(keyed_accounts, 1).unwrap(); let res = withdraw( vote_keyed_account, lamports, diff --git a/runtime/src/native_loader.rs b/runtime/src/native_loader.rs index b60b5877081eec..0ce58472ae2ef5 100644 --- a/runtime/src/native_loader.rs +++ b/runtime/src/native_loader.rs @@ -10,7 +10,7 @@ use solana_sdk::{ decode_error::DecodeError, entrypoint_native::ProgramEntrypoint, instruction::InstructionError, - keyed_account::{next_keyed_account, KeyedAccount}, + keyed_account::{keyed_account_at_index, KeyedAccount}, native_loader, process_instruction::{InvokeContext, LoaderEntrypoint}, pubkey::Pubkey, @@ -139,8 +139,7 @@ impl NativeLoader { instruction_data: &[u8], invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { - let mut keyed_accounts_iter = keyed_accounts.iter(); - let program = next_keyed_account(&mut keyed_accounts_iter)?; + let program = keyed_account_at_index(keyed_accounts, 0)?; if native_loader::id() != *program_id { error!("Program id mismatch"); return Err(InstructionError::IncorrectProgramId); @@ -150,8 +149,8 @@ impl NativeLoader { return Err(InstructionError::IncorrectProgramId); } - let params = keyed_accounts_iter.as_slice(); - let account = program.try_account_ref()?; + let params = &keyed_accounts[1..]; + let account = &program.try_account_ref()?; let name = match str::from_utf8(account.data()) { Ok(v) => v, Err(e) => { diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index f917bd88379021..38cf30072483a9 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -4,7 +4,7 @@ use solana_sdk::{ account_utils::StateMut, ic_msg, instruction::InstructionError, - keyed_account::{from_keyed_account, get_signers, next_keyed_account, KeyedAccount}, + keyed_account::{from_keyed_account, get_signers, keyed_account_at_index, KeyedAccount}, nonce, nonce_keyed_account::NonceKeyedAccount, process_instruction::InvokeContext, @@ -265,7 +265,6 @@ pub fn process_instruction( trace!("keyed_accounts: {:?}", keyed_accounts); let signers = get_signers(keyed_accounts); - let keyed_accounts_iter = &mut keyed_accounts.iter(); match instruction { SystemInstruction::CreateAccount { @@ -273,8 +272,8 @@ pub fn process_instruction( space, owner, } => { - let from = next_keyed_account(keyed_accounts_iter)?; - let to = next_keyed_account(keyed_accounts_iter)?; + let from = keyed_account_at_index(keyed_accounts, 0)?; + let to = keyed_account_at_index(keyed_accounts, 1)?; let to_address = Address::create(to.unsigned_key(), None, invoke_context)?; create_account( from, @@ -294,8 +293,8 @@ pub fn process_instruction( space, owner, } => { - let from = next_keyed_account(keyed_accounts_iter)?; - let to = next_keyed_account(keyed_accounts_iter)?; + let from = keyed_account_at_index(keyed_accounts, 0)?; + let to = keyed_account_at_index(keyed_accounts, 1)?; let to_address = Address::create( &to.unsigned_key(), Some((&base, &seed, &owner)), @@ -313,14 +312,14 @@ pub fn process_instruction( ) } SystemInstruction::Assign { owner } => { - let keyed_account = next_keyed_account(keyed_accounts_iter)?; + let keyed_account = keyed_account_at_index(keyed_accounts, 0)?; let mut account = keyed_account.try_account_ref_mut()?; let address = Address::create(keyed_account.unsigned_key(), None, invoke_context)?; assign(&mut account, &address, &owner, &signers, invoke_context) } SystemInstruction::Transfer { lamports } => { - let from = next_keyed_account(keyed_accounts_iter)?; - let to = next_keyed_account(keyed_accounts_iter)?; + let from = keyed_account_at_index(keyed_accounts, 0)?; + let to = keyed_account_at_index(keyed_accounts, 1)?; transfer(from, to, lamports, invoke_context) } SystemInstruction::TransferWithSeed { @@ -328,9 +327,9 @@ pub fn process_instruction( from_seed, from_owner, } => { - let from = next_keyed_account(keyed_accounts_iter)?; - let base = next_keyed_account(keyed_accounts_iter)?; - let to = next_keyed_account(keyed_accounts_iter)?; + let from = keyed_account_at_index(keyed_accounts, 0)?; + let base = keyed_account_at_index(keyed_accounts, 1)?; + let to = keyed_account_at_index(keyed_accounts, 2)?; transfer_with_seed( from, base, @@ -342,40 +341,49 @@ pub fn process_instruction( ) } SystemInstruction::AdvanceNonceAccount => { - let me = &mut next_keyed_account(keyed_accounts_iter)?; + let me = &mut keyed_account_at_index(keyed_accounts, 0)?; me.advance_nonce_account( - &from_keyed_account::(next_keyed_account(keyed_accounts_iter)?)?, + &from_keyed_account::(keyed_account_at_index( + keyed_accounts, + 1, + )?)?, &signers, invoke_context, ) } SystemInstruction::WithdrawNonceAccount(lamports) => { - let me = &mut next_keyed_account(keyed_accounts_iter)?; - let to = &mut next_keyed_account(keyed_accounts_iter)?; + let me = &mut keyed_account_at_index(keyed_accounts, 0)?; + let to = &mut keyed_account_at_index(keyed_accounts, 1)?; me.withdraw_nonce_account( lamports, to, - &from_keyed_account::(next_keyed_account(keyed_accounts_iter)?)?, - &from_keyed_account::(next_keyed_account(keyed_accounts_iter)?)?, + &from_keyed_account::(keyed_account_at_index( + keyed_accounts, + 2, + )?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 3)?)?, &signers, invoke_context, ) } SystemInstruction::InitializeNonceAccount(authorized) => { - let me = &mut next_keyed_account(keyed_accounts_iter)?; + let me = &mut keyed_account_at_index(keyed_accounts, 0)?; me.initialize_nonce_account( &authorized, - &from_keyed_account::(next_keyed_account(keyed_accounts_iter)?)?, - &from_keyed_account::(next_keyed_account(keyed_accounts_iter)?)?, + &from_keyed_account::(keyed_account_at_index( + keyed_accounts, + 1, + )?)?, + &from_keyed_account::(keyed_account_at_index(keyed_accounts, 2)?)?, invoke_context, ) } SystemInstruction::AuthorizeNonceAccount(nonce_authority) => { - let me = &mut next_keyed_account(keyed_accounts_iter)?; + let me = &mut keyed_account_at_index(keyed_accounts, 0)?; me.authorize_nonce_account(&nonce_authority, &signers, invoke_context) } SystemInstruction::Allocate { space } => { - let keyed_account = next_keyed_account(keyed_accounts_iter)?; + let keyed_account = keyed_account_at_index(keyed_accounts, 0)?; let mut account = keyed_account.try_account_ref_mut()?; let address = Address::create(keyed_account.unsigned_key(), None, invoke_context)?; allocate(&mut account, &address, space, &signers, invoke_context) @@ -386,7 +394,7 @@ pub fn process_instruction( space, owner, } => { - let keyed_account = next_keyed_account(keyed_accounts_iter)?; + let keyed_account = keyed_account_at_index(keyed_accounts, 0)?; let mut account = keyed_account.try_account_ref_mut()?; let address = Address::create( keyed_account.unsigned_key(), @@ -403,7 +411,7 @@ pub fn process_instruction( ) } SystemInstruction::AssignWithSeed { base, seed, owner } => { - let keyed_account = next_keyed_account(keyed_accounts_iter)?; + let keyed_account = keyed_account_at_index(keyed_accounts, 0)?; let mut account = keyed_account.try_account_ref_mut()?; let address = Address::create( keyed_account.unsigned_key(), diff --git a/sdk/src/keyed_account.rs b/sdk/src/keyed_account.rs index 3f60387a3b10fe..531b3bf8a9894a 100644 --- a/sdk/src/keyed_account.rs +++ b/sdk/src/keyed_account.rs @@ -186,6 +186,7 @@ where .collect::() } +#[deprecated(since = "1.7.0", note = "Please use keyed_account_at_index instead")] /// Return the next KeyedAccount or a NotEnoughAccountKeys error pub fn next_keyed_account<'a, 'b, I: Iterator>>( iter: &mut I, @@ -193,6 +194,16 @@ pub fn next_keyed_account<'a, 'b, I: Iterator>>( iter.next().ok_or(InstructionError::NotEnoughAccountKeys) } +/// Return the KeyedAccount at the specified index or a NotEnoughAccountKeys error +pub fn keyed_account_at_index<'a>( + keyed_accounts: &'a [KeyedAccount], + index: usize, +) -> Result<&'a KeyedAccount<'a>, InstructionError> { + keyed_accounts + .get(index) + .ok_or(InstructionError::NotEnoughAccountKeys) +} + /// Return true if the first keyed_account is executable, used to determine if /// the loader should call a program's 'main' pub fn is_executable(keyed_accounts: &[KeyedAccount]) -> Result { From 7ba55f808330b3029a286c3826f4aaeddcb20459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 31 Mar 2021 13:35:24 +0200 Subject: [PATCH 05/33] Adds "&keyed_accounts[1..]" expressions to invoke_context. --- programs/bpf_loader/src/lib.rs | 6 ++++++ runtime/src/message_processor.rs | 15 +++++++++++++++ runtime/src/native_loader.rs | 5 ++++- sdk/src/process_instruction.rs | 9 +++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 0647080a811f78..d3bc1a61b34d0e 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -219,6 +219,9 @@ fn process_instruction_common( ); return Err(InstructionError::InvalidArgument); } + // TODO [KeyedAccounts to InvokeContext refactoring] + // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); + invoke_context.pop_first_keyed_account(); ( programdata, &keyed_accounts[1..], @@ -778,6 +781,9 @@ impl Executor for BpfExecutor { let invoke_depth = invoke_context.invoke_depth(); let mut serialize_time = Measure::start("serialize"); + // TODO [KeyedAccounts to InvokeContext refactoring] + // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); + invoke_context.pop_first_keyed_account(); let parameter_accounts = &keyed_accounts[1..]; let mut parameter_bytes = serialize_parameters(loader_id, program_id, parameter_accounts, &instruction_data)?; diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 55ed39eec2048b..9f8c8087b2d96a 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -356,6 +356,13 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .last() .ok_or(InstructionError::GenericError) } + // TODO [KeyedAccounts to InvokeContext refactoring] + /*fn set_keyed_accounts(&mut self, keyed_accounts: &'a [KeyedAccount<'a>]) { + self.keyed_accounts = keyed_accounts; + }*/ + fn pop_first_keyed_account(&mut self) { + self.keyed_accounts = &self.keyed_accounts[1..]; + } fn get_keyed_accounts(&self) -> &[KeyedAccount] { self.keyed_accounts } @@ -595,6 +602,9 @@ impl MessageProcessor { if native_loader::check_id(&root_account.owner()?) { for (id, process_instruction) in &self.programs { if id == root_id { + // TODO [KeyedAccounts to InvokeContext refactoring] + // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); + invoke_context.pop_first_keyed_account(); // Call the builtin program return process_instruction( &program_id, @@ -886,6 +896,9 @@ impl MessageProcessor { accounts, demote_sysvar_write_locks, ); + // TODO [KeyedAccounts to InvokeContext refactoring] + // let previous_keyed_accounts = invoke_context.get_keyed_accounts(); + // invoke_context.set_keyed_accounts(&keyed_accounts); // Invoke callee invoke_context.push(program_id)?; @@ -906,6 +919,8 @@ impl MessageProcessor { result = invoke_context.verify_and_update(message, instruction, accounts, None); } invoke_context.pop(); + // TODO [KeyedAccounts to InvokeContext refactoring] + // invoke_context.set_keyed_accounts(previous_keyed_accounts); result } else { diff --git a/runtime/src/native_loader.rs b/runtime/src/native_loader.rs index 0ce58472ae2ef5..f0c9c88a010456 100644 --- a/runtime/src/native_loader.rs +++ b/runtime/src/native_loader.rs @@ -137,7 +137,7 @@ impl NativeLoader { program_id: &Pubkey, keyed_accounts: &[KeyedAccount], instruction_data: &[u8], - invoke_context: &dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let program = keyed_account_at_index(keyed_accounts, 0)?; if native_loader::id() != *program_id { @@ -149,6 +149,9 @@ impl NativeLoader { return Err(InstructionError::IncorrectProgramId); } + // TODO [KeyedAccounts to InvokeContext refactoring] + // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); + invoke_context.pop_first_keyed_account(); let params = &keyed_accounts[1..]; let account = &program.try_account_ref()?; let name = match str::from_utf8(account.data()) { diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 8f927723d46adc..ad9103424af1e1 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -41,6 +41,8 @@ pub trait InvokeContext { ) -> Result<(), InstructionError>; /// Get the program ID of the currently executing program fn get_caller(&self) -> Result<&Pubkey, InstructionError>; + /// Removes the first keyed account + fn pop_first_keyed_account(&mut self); /// Get the list of keyed accounts fn get_keyed_accounts(&self) -> &[KeyedAccount]; /// Get a list of built-in programs @@ -329,6 +331,13 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { fn get_caller(&self) -> Result<&Pubkey, InstructionError> { Ok(&self.key) } + // TODO [KeyedAccounts to InvokeContext refactoring] + /*fn set_keyed_accounts(&mut self, keyed_accounts: &'a [KeyedAccount<'a>]) { + self.keyed_accounts = keyed_accounts; + }*/ + fn pop_first_keyed_account(&mut self) { + self.keyed_accounts = &self.keyed_accounts[1..]; + } fn get_keyed_accounts(&self) -> &[KeyedAccount] { self.keyed_accounts } From cd70e40d7d85322f3d580cc57fdad6f5e82ef8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 22 Feb 2021 16:06:02 +0100 Subject: [PATCH 06/33] Save and restore invoke_context.keyed_accounts in message_processor::process_cross_program_instruction() --- runtime/src/message_processor.rs | 23 +++++++++++++++++------ sdk/src/process_instruction.rs | 8 +++++--- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 9f8c8087b2d96a..4080bb567c8e0b 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -357,9 +357,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .ok_or(InstructionError::GenericError) } // TODO [KeyedAccounts to InvokeContext refactoring] - /*fn set_keyed_accounts(&mut self, keyed_accounts: &'a [KeyedAccount<'a>]) { - self.keyed_accounts = keyed_accounts; - }*/ + fn set_keyed_accounts(&mut self, keyed_accounts: &[KeyedAccount]) { + self.keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; + } fn pop_first_keyed_account(&mut self) { self.keyed_accounts = &self.keyed_accounts[1..]; } @@ -897,8 +897,14 @@ impl MessageProcessor { demote_sysvar_write_locks, ); // TODO [KeyedAccounts to InvokeContext refactoring] - // let previous_keyed_accounts = invoke_context.get_keyed_accounts(); - // invoke_context.set_keyed_accounts(&keyed_accounts); + let previous_keyed_accounts = { + let previous_keyed_accounts = invoke_context.get_keyed_accounts(); + ( + previous_keyed_accounts.as_ptr() as u64, + previous_keyed_accounts.len(), + ) + }; + invoke_context.set_keyed_accounts(&keyed_accounts); // Invoke callee invoke_context.push(program_id)?; @@ -921,7 +927,12 @@ impl MessageProcessor { invoke_context.pop(); // TODO [KeyedAccounts to InvokeContext refactoring] // invoke_context.set_keyed_accounts(previous_keyed_accounts); - + invoke_context.set_keyed_accounts(unsafe { + std::slice::from_raw_parts( + previous_keyed_accounts.0 as *const _, + previous_keyed_accounts.1, + ) + }); result } else { // This function is always called with a valid instruction, if that changes return an error diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index ad9103424af1e1..043b4971b9641e 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -41,6 +41,8 @@ pub trait InvokeContext { ) -> Result<(), InstructionError>; /// Get the program ID of the currently executing program fn get_caller(&self) -> Result<&Pubkey, InstructionError>; + /// Set the list of keyed accounts + fn set_keyed_accounts(&mut self, keyed_accounts: &[KeyedAccount]); /// Removes the first keyed account fn pop_first_keyed_account(&mut self); /// Get the list of keyed accounts @@ -332,9 +334,9 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { Ok(&self.key) } // TODO [KeyedAccounts to InvokeContext refactoring] - /*fn set_keyed_accounts(&mut self, keyed_accounts: &'a [KeyedAccount<'a>]) { - self.keyed_accounts = keyed_accounts; - }*/ + fn set_keyed_accounts(&mut self, keyed_accounts: &[KeyedAccount]) { + self.keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; + } fn pop_first_keyed_account(&mut self) { self.keyed_accounts = &self.keyed_accounts[1..]; } From d66465bd55d7874b7a678d45cb0cba5365d7e6d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 22 Feb 2021 18:40:48 +0100 Subject: [PATCH 07/33] Debug assert equality of old and new way of keyed_accounts. --- programs/bpf_loader/src/lib.rs | 2 ++ runtime/src/message_processor.rs | 1 + runtime/src/native_loader.rs | 1 + 3 files changed, 4 insertions(+) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index d3bc1a61b34d0e..af0d5414234e84 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -197,6 +197,7 @@ fn process_instruction_common( use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); + debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let first_account = keyed_account_at_index(keyed_accounts, 0)?; if first_account.executable()? { @@ -779,6 +780,7 @@ impl Executor for BpfExecutor { ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); let invoke_depth = invoke_context.invoke_depth(); + debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let mut serialize_time = Measure::start("serialize"); // TODO [KeyedAccounts to InvokeContext refactoring] diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 4080bb567c8e0b..9f4eab9cdc446c 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -597,6 +597,7 @@ impl MessageProcessor { instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); if let Some(root_account) = keyed_accounts.iter().next() { let root_id = root_account.unsigned_key(); if native_loader::check_id(&root_account.owner()?) { diff --git a/runtime/src/native_loader.rs b/runtime/src/native_loader.rs index f0c9c88a010456..3001e03a8bec92 100644 --- a/runtime/src/native_loader.rs +++ b/runtime/src/native_loader.rs @@ -139,6 +139,7 @@ impl NativeLoader { instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let program = keyed_account_at_index(keyed_accounts, 0)?; if native_loader::id() != *program_id { error!("Program id mismatch"); From 3f333dde144dd8e21e4bdc04cd0492cf75ab88f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 19 Apr 2021 12:17:49 +0200 Subject: [PATCH 08/33] Changes bpf_loader::create_and_cache_executor() to use account indices not references. --- programs/bpf_loader/src/lib.rs | 91 +++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index af0d5414234e84..260ad7dbfc11b7 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -70,40 +70,53 @@ fn map_ebpf_error( } pub fn create_and_cache_executor( - key: &Pubkey, - data: &[u8], + program_id: Option<&Pubkey>, + program_account_index: usize, + program_data_offset: usize, invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result, InstructionError> { + let syscall_registry = syscalls::register_syscalls(invoke_context).map_err(|e| { + ic_msg!(invoke_context, "Failed to register syscalls: {}", e); + InstructionError::ProgramEnvironmentSetupFailure + })?; let bpf_compute_budget = invoke_context.get_bpf_compute_budget(); - let mut program = >::from_elf( - data, - None, - Config { - max_call_depth: bpf_compute_budget.max_call_depth, - stack_frame_size: bpf_compute_budget.stack_frame_size, - enable_instruction_meter: true, - enable_instruction_tracing: log_enabled!(Trace), - }, - ) + let config = Config { + max_call_depth: bpf_compute_budget.max_call_depth, + stack_frame_size: bpf_compute_budget.stack_frame_size, + enable_instruction_meter: true, + enable_instruction_tracing: log_enabled!(Trace), + }; + let mut executable = { + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, program_account_index)?; + let account = program.try_account_ref()?; + let data = &account.data()[program_data_offset..]; + >::from_elf(data, None, config) + } .map_err(|e| map_ebpf_error(invoke_context, e))?; - let (_, elf_bytes) = program + let (_, elf_bytes) = executable .get_text_bytes() .map_err(|e| map_ebpf_error(invoke_context, e))?; bpf_verifier::check(elf_bytes) .map_err(|e| map_ebpf_error(invoke_context, EbpfError::UserError(e)))?; - let syscall_registry = syscalls::register_syscalls(invoke_context).map_err(|e| { - ic_msg!(invoke_context, "Failed to register syscalls: {}", e); - InstructionError::ProgramEnvironmentSetupFailure - })?; - program.set_syscall_registry(syscall_registry); + executable.set_syscall_registry(syscall_registry); if use_jit { - if let Err(err) = program.jit_compile() { + if let Err(err) = executable.jit_compile() { ic_msg!(invoke_context, "Failed to compile program {:?}", err); return Err(InstructionError::ProgramFailedToCompile); } } - let executor = Arc::new(BpfExecutor { program }); + let executor = Arc::new(BpfExecutor { + program: executable, + }); + let key = if let Some(program_id) = program_id { + program_id + } else { + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, program_account_index)?; + program.unsigned_key() + }; invoke_context.add_executor(key, executor.clone()); Ok(executor) } @@ -206,7 +219,7 @@ fn process_instruction_common( return Err(InstructionError::IncorrectProgramId); } - let (program, keyed_accounts, offset) = + let (keyed_accounts, program_data_offset) = if bpf_loader_upgradeable::check_id(&first_account.owner()?) { if let UpgradeableLoaderState::Program { programdata_address, @@ -224,7 +237,6 @@ fn process_instruction_common( // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); invoke_context.pop_first_keyed_account(); ( - programdata, &keyed_accounts[1..], UpgradeableLoaderState::programdata_data_offset()?, ) @@ -233,10 +245,14 @@ fn process_instruction_common( return Err(InstructionError::InvalidAccountData); } } else { - (first_account, keyed_accounts, 0) + (keyed_accounts, 0) }; - let loader_id = &program.owner()?; + let loader_id = { + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, 0)?; + &program.owner()? + }; if !check_loader_id(loader_id) { ic_logger_msg!(logger, "Executable account not owned by the BPF loader"); @@ -246,8 +262,9 @@ fn process_instruction_common( let executor = match invoke_context.get_executor(program_id) { Some(executor) => executor, None => create_and_cache_executor( - program_id, - &program.try_account_ref()?.data()[offset..], + Some(program_id), + 0, + program_data_offset, invoke_context, use_jit, )?, @@ -295,6 +312,7 @@ fn process_loader_upgradeable_instruction( use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); + debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); match limited_deserialize(instruction_data)? { UpgradeableLoaderInstruction::InitializeBuffer => { @@ -426,8 +444,9 @@ fn process_loader_upgradeable_instruction( // Load and verify the program bits let _ = create_and_cache_executor( - program_id, - &buffer.try_account_ref()?.data()[buffer_data_offset..], + Some(program_id), + 3, + buffer_data_offset, invoke_context, use_jit, )?; @@ -551,12 +570,8 @@ fn process_loader_upgradeable_instruction( // Load and verify the program bits - let _ = create_and_cache_executor( - program.unsigned_key(), - &buffer.try_account_ref()?.data()[buffer_data_offset..], - invoke_context, - use_jit, - )?; + let _ = + create_and_cache_executor(None, 2, buffer_data_offset, invoke_context, use_jit)?; // Update the ProgramData account, record the upgraded data, and zero // the rest @@ -691,6 +706,7 @@ fn process_loader_instruction( invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { + debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let program = keyed_account_at_index(keyed_accounts, 0)?; if program.owner()? != *program_id { ic_msg!( @@ -718,12 +734,7 @@ fn process_loader_instruction( return Err(InstructionError::MissingRequiredSignature); } - let _ = create_and_cache_executor( - program.unsigned_key(), - &program.try_account_ref()?.data(), - invoke_context, - use_jit, - )?; + let _ = create_and_cache_executor(None, 0, 0, invoke_context, use_jit)?; program.try_account_ref_mut()?.executable = true; ic_msg!( invoke_context, From cd6b6955c80f265ebe6874a5c53b9848d45cd116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 24 Feb 2021 14:34:42 +0100 Subject: [PATCH 09/33] Splits off caching part from bpf_loader::create_and_cache_executor(). --- programs/bpf_loader/src/lib.rs | 52 ++++++++++++++-------------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 260ad7dbfc11b7..a440b8f38b5342 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -69,8 +69,7 @@ fn map_ebpf_error( InstructionError::InvalidAccountData } -pub fn create_and_cache_executor( - program_id: Option<&Pubkey>, +pub fn create_executor( program_account_index: usize, program_data_offset: usize, invoke_context: &mut dyn InvokeContext, @@ -107,18 +106,9 @@ pub fn create_and_cache_executor( return Err(InstructionError::ProgramFailedToCompile); } } - let executor = Arc::new(BpfExecutor { + Ok(Arc::new(BpfExecutor { program: executable, - }); - let key = if let Some(program_id) = program_id { - program_id - } else { - let keyed_accounts = invoke_context.get_keyed_accounts(); - let program = keyed_account_at_index(keyed_accounts, program_account_index)?; - program.unsigned_key() - }; - invoke_context.add_executor(key, executor.clone()); - Ok(executor) + })) } fn write_program_data( @@ -261,13 +251,11 @@ fn process_instruction_common( let executor = match invoke_context.get_executor(program_id) { Some(executor) => executor, - None => create_and_cache_executor( - Some(program_id), - 0, - program_data_offset, - invoke_context, - use_jit, - )?, + None => { + let executor = create_executor(0, program_data_offset, invoke_context, use_jit)?; + invoke_context.add_executor(program_id, executor.clone()); + executor + } }; executor.execute( loader_id, @@ -443,13 +431,8 @@ fn process_loader_upgradeable_instruction( )?; // Load and verify the program bits - let _ = create_and_cache_executor( - Some(program_id), - 3, - buffer_data_offset, - invoke_context, - use_jit, - )?; + let executor = create_executor(3, buffer_data_offset, invoke_context, use_jit)?; + invoke_context.add_executor(program_id, executor); // Update the ProgramData account and record the program bits programdata.set_state(&UpgradeableLoaderState::ProgramData { @@ -570,8 +553,12 @@ fn process_loader_upgradeable_instruction( // Load and verify the program bits - let _ = - create_and_cache_executor(None, 2, buffer_data_offset, invoke_context, use_jit)?; + let executor = create_executor(2, buffer_data_offset, invoke_context, use_jit)?; + { + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, 1)?; + invoke_context.add_executor(program.unsigned_key(), executor); + } // Update the ProgramData account, record the upgraded data, and zero // the rest @@ -734,7 +721,12 @@ fn process_loader_instruction( return Err(InstructionError::MissingRequiredSignature); } - let _ = create_and_cache_executor(None, 0, 0, invoke_context, use_jit)?; + let executor = create_executor(0, 0, invoke_context, use_jit)?; + { + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, 0)?; + invoke_context.add_executor(program.unsigned_key(), executor); + } program.try_account_ref_mut()?.executable = true; ic_msg!( invoke_context, From 907d19a29e457d35b5933d18caed3ffe65d8b1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 16 Mar 2021 13:09:42 +0100 Subject: [PATCH 10/33] Changes bpf_loader::write_program_data() to use account indices not references. --- programs/bpf_loader/src/lib.rs | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index a440b8f38b5342..02741fbc79a49f 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -61,10 +61,7 @@ pub enum BpfError { } impl UserDefinedError for BpfError {} -fn map_ebpf_error( - invoke_context: &mut dyn InvokeContext, - e: EbpfError, -) -> InstructionError { +fn map_ebpf_error(invoke_context: &dyn InvokeContext, e: EbpfError) -> InstructionError { ic_msg!(invoke_context, "{}", e); InstructionError::InvalidAccountData } @@ -112,22 +109,26 @@ pub fn create_executor( } fn write_program_data( - data: &mut [u8], - offset: usize, + program_account_index: usize, + program_data_offset: usize, bytes: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, program_account_index)?; + let mut account = program.try_account_ref_mut()?; + let data = &mut account.data_as_mut_slice(); let len = bytes.len(); - if data.len() < offset + len { + if data.len() < program_data_offset + len { ic_msg!( invoke_context, "Write overflow: {} < {}", data.len(), - offset + len + program_data_offset + len ); return Err(InstructionError::AccountDataTooSmall); } - data[offset..offset + len].copy_from_slice(&bytes); + data[program_data_offset..program_data_offset + len].copy_from_slice(&bytes); Ok(()) } @@ -339,7 +340,7 @@ fn process_loader_upgradeable_instruction( return Err(InstructionError::InvalidAccountData); } write_program_data( - buffer.try_account_ref_mut()?.data_as_mut_slice(), + 0, UpgradeableLoaderState::buffer_data_offset()? + offset as usize, &bytes, invoke_context, @@ -708,12 +709,7 @@ fn process_loader_instruction( ic_msg!(invoke_context, "Program account did not sign"); return Err(InstructionError::MissingRequiredSignature); } - write_program_data( - &mut program.try_account_ref_mut()?.data_as_mut_slice(), - offset as usize, - &bytes, - invoke_context, - )?; + write_program_data(0, offset as usize, &bytes, invoke_context)?; } LoaderInstruction::Finalize => { if program.signer_key().is_none() { From b8727951924d65af4bd922746444a64731716ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 24 Feb 2021 17:31:20 +0100 Subject: [PATCH 11/33] Removes callers_keyed_accounts from SyscallInvokeSigned. --- programs/bpf/benches/bpf_loader.rs | 2 -- programs/bpf/tests/programs.rs | 1 - programs/bpf_loader/src/lib.rs | 10 +--------- programs/bpf_loader/src/syscalls.rs | 17 ++--------------- 4 files changed, 3 insertions(+), 27 deletions(-) diff --git a/programs/bpf/benches/bpf_loader.rs b/programs/bpf/benches/bpf_loader.rs index 2d9342c28207b2..021b95f6946935 100644 --- a/programs/bpf/benches/bpf_loader.rs +++ b/programs/bpf/benches/bpf_loader.rs @@ -105,7 +105,6 @@ fn bench_program_alu(bencher: &mut Bencher) { &loader_id, executable.as_ref(), &mut inner_iter, - &[], &mut invoke_context, ) .unwrap(); @@ -232,7 +231,6 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) { &loader_id, executable.as_ref(), &mut serialized, - &[], &mut invoke_context, ) .unwrap(); diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index f0f1a1195a390a..f193cf5f5052f0 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -217,7 +217,6 @@ fn run_program( &loader_id, executable.as_ref(), &mut parameter_bytes, - parameter_accounts, &mut invoke_context, ) .unwrap(); diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 02741fbc79a49f..3cf95a16d3e6b2 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -147,19 +147,12 @@ pub fn create_vm<'a>( loader_id: &'a Pubkey, program: &'a dyn Executable, parameter_bytes: &mut [u8], - parameter_accounts: &'a [KeyedAccount<'a>], invoke_context: &'a mut dyn InvokeContext, ) -> Result, EbpfError> { let heap = vec![0_u8; DEFAULT_HEAP_SIZE]; let heap_region = MemoryRegion::new_from_slice(&heap, MM_HEAP_START, 0, true); let mut vm = EbpfVm::new(program, parameter_bytes, &[heap_region])?; - syscalls::bind_syscall_context_objects( - loader_id, - &mut vm, - parameter_accounts, - invoke_context, - heap, - )?; + syscalls::bind_syscall_context_objects(loader_id, &mut vm, invoke_context, heap)?; Ok(vm) } @@ -797,7 +790,6 @@ impl Executor for BpfExecutor { loader_id, self.program.as_ref(), &mut parameter_bytes, - ¶meter_accounts, invoke_context, ) { Ok(info) => info, diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 5dbd978550aef8..1da864363993c7 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -169,7 +169,6 @@ macro_rules! bind_feature_gated_syscall_context_object { pub fn bind_syscall_context_objects<'a>( loader_id: &'a Pubkey, vm: &mut EbpfVm<'a, BpfError, crate::ThisInstructionMeter>, - callers_keyed_accounts: &'a [KeyedAccount<'a>], invoke_context: &'a mut dyn InvokeContext, heap: Vec, ) -> Result<(), EbpfError> { @@ -299,7 +298,6 @@ pub fn bind_syscall_context_objects<'a>( // Cross-program invocation syscalls vm.bind_syscall_context_object( Box::new(SyscallInvokeSignedC { - callers_keyed_accounts, invoke_context: invoke_context.clone(), loader_id, }), @@ -307,7 +305,6 @@ pub fn bind_syscall_context_objects<'a>( )?; vm.bind_syscall_context_object( Box::new(SyscallInvokeSignedRust { - callers_keyed_accounts, invoke_context: invoke_context.clone(), loader_id, }), @@ -1029,7 +1026,6 @@ type TranslatedAccounts<'a> = ( trait SyscallInvokeSigned<'a> { fn get_context_mut(&self) -> Result, EbpfError>; fn get_context(&self) -> Result, EbpfError>; - fn get_callers_keyed_accounts(&self) -> &'a [KeyedAccount<'a>]; fn translate_instruction( &self, addr: u64, @@ -1055,7 +1051,6 @@ trait SyscallInvokeSigned<'a> { /// Cross-program invocation called from Rust pub struct SyscallInvokeSignedRust<'a> { - callers_keyed_accounts: &'a [KeyedAccount<'a>], invoke_context: Rc>, loader_id: &'a Pubkey, } @@ -1070,9 +1065,6 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> { .try_borrow() .map_err(|_| SyscallError::InvokeContextBorrowFailed.into()) } - fn get_callers_keyed_accounts(&self) -> &'a [KeyedAccount<'a>] { - self.callers_keyed_accounts - } fn translate_instruction( &self, addr: u64, @@ -1350,7 +1342,6 @@ struct SolSignerSeedsC { /// Cross-program invocation called from C pub struct SyscallInvokeSignedC<'a> { - callers_keyed_accounts: &'a [KeyedAccount<'a>], invoke_context: Rc>, loader_id: &'a Pubkey, } @@ -1366,10 +1357,6 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> { .map_err(|_| SyscallError::InvokeContextBorrowFailed.into()) } - fn get_callers_keyed_accounts(&self) -> &'a [KeyedAccount<'a>] { - self.callers_keyed_accounts - } - fn translate_instruction( &self, addr: u64, @@ -1777,8 +1764,8 @@ fn call<'a>( signers_seeds_len, memory_mapping, )?; - let keyed_account_refs = syscall - .get_callers_keyed_accounts() + let keyed_account_refs = invoke_context + .get_keyed_accounts() .iter() .collect::>(); let (message, callee_program_id, callee_program_id_index) = From ecdf08584bdf1416e8d8ec25083255df130b3905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 31 Mar 2021 13:36:06 +0200 Subject: [PATCH 12/33] Changes message_processor::native_invoke() to use account indices not references. --- programs/bpf_loader/src/lib.rs | 5 +- runtime/src/message_processor.rs | 97 ++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 43 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 3cf95a16d3e6b2..2ed20288d97760 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -346,7 +346,8 @@ fn process_loader_upgradeable_instruction( let buffer = keyed_account_at_index(keyed_accounts, 3)?; let rent = from_keyed_account::(keyed_account_at_index(keyed_accounts, 4)?)?; let clock = from_keyed_account::(keyed_account_at_index(keyed_accounts, 5)?)?; - let system = keyed_account_at_index(keyed_accounts, 6)?; + // TODO [KeyedAccounts to InvokeContext refactoring] + // let _system = keyed_account_at_index(keyed_accounts, 6)?; let authority = keyed_account_at_index(keyed_accounts, 7)?; let upgrade_authority_address = Some(*authority.unsigned_key()); let upgrade_authority_signer = authority.signer_key().is_none(); @@ -420,7 +421,7 @@ fn process_loader_upgradeable_instruction( programdata_len as u64, program_id, ), - &[payer, programdata, system], + &[0, 1, 6], &[&[program.unsigned_key().as_ref(), &[bump_seed]]], )?; diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 9f4eab9cdc446c..1e24106e73adb8 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -14,7 +14,7 @@ use solana_sdk::{ }, ic_msg, instruction::{CompiledInstruction, Instruction, InstructionError}, - keyed_account::{create_keyed_readonly_accounts, KeyedAccount}, + keyed_account::{create_keyed_readonly_accounts, keyed_account_at_index, KeyedAccount}, message::Message, native_loader, process_instruction::{ @@ -721,7 +721,7 @@ impl MessageProcessor { pub fn native_invoke( invoke_context: &mut dyn InvokeContext, instruction: Instruction, - keyed_accounts: &[&KeyedAccount], + keyed_account_indices: &[usize], signers_seeds: &[&[&[u8]]], ) -> Result<(), InstructionError> { let invoke_context = RefCell::new(invoke_context); @@ -730,7 +730,7 @@ impl MessageProcessor { message, executables, accounts, - account_refs, + keyed_account_indices_reordered, caller_write_privileges, demote_sysvar_write_locks, ) = { @@ -744,20 +744,28 @@ impl MessageProcessor { .iter() .map(|seeds| Pubkey::create_program_address(&seeds, caller_program_id)) .collect::, solana_sdk::pubkey::PubkeyError>>()?; - let mut caller_write_privileges = keyed_accounts + let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = keyed_account_indices .iter() - .map(|keyed_account| keyed_account.is_writable()) - .collect::>(); - caller_write_privileges.insert(0, false); + .map(|index| keyed_account_at_index(keyed_accounts, *index)) + .collect::, InstructionError>>()?; let (message, callee_program_id, _) = Self::create_message(&instruction, &keyed_accounts, &signers, &invoke_context)?; + let keyed_accounts = invoke_context.get_keyed_accounts(); + let mut caller_write_privileges = keyed_account_indices + .iter() + .map(|index| keyed_accounts[*index].is_writable()) + .collect::>(); + caller_write_privileges.insert(0, false); let mut accounts = vec![]; - let mut account_refs = vec![]; + let mut keyed_account_indices_reordered = vec![]; + let keyed_accounts = invoke_context.get_keyed_accounts(); 'root: for account_key in message.account_keys.iter() { - for keyed_account in keyed_accounts { + for keyed_account_index in keyed_account_indices { + let keyed_account = &keyed_accounts[*keyed_account_index]; if account_key == keyed_account.unsigned_key() { accounts.push(Rc::new(keyed_account.account.clone())); - account_refs.push(keyed_account); + keyed_account_indices_reordered.push(*keyed_account_index); continue 'root; } } @@ -788,42 +796,41 @@ impl MessageProcessor { ); return Err(InstructionError::AccountNotExecutable); } - let programdata_executable = - if program_account.borrow().owner == bpf_loader_upgradeable::id() { - if let UpgradeableLoaderState::Program { - programdata_address, - } = program_account.borrow().state()? - { - if let Some(account) = invoke_context.get_account(&programdata_address) { - Some((programdata_address, account)) - } else { - ic_msg!( - invoke_context, - "Unknown upgradeable programdata account {}", - programdata_address, - ); - return Err(InstructionError::MissingAccount); - } + let programdata = if program_account.borrow().owner == bpf_loader_upgradeable::id() { + if let UpgradeableLoaderState::Program { + programdata_address, + } = program_account.borrow().state()? + { + if let Some(account) = invoke_context.get_account(&programdata_address) { + Some((programdata_address, account)) } else { ic_msg!( invoke_context, - "Upgradeable program account state not valid {}", - callee_program_id, + "Unknown upgradeable programdata account {}", + programdata_address, ); return Err(InstructionError::MissingAccount); } } else { - None - }; + ic_msg!( + invoke_context, + "Upgradeable program account state not valid {}", + callee_program_id, + ); + return Err(InstructionError::MissingAccount); + } + } else { + None + }; let mut executables = vec![(callee_program_id, program_account)]; - if let Some(programdata) = programdata_executable { + if let Some(programdata) = programdata { executables.push(programdata); } ( message, executables, accounts, - account_refs, + keyed_account_indices_reordered, caller_write_privileges, invoke_context.is_feature_active(&demote_sysvar_write_locks::id()), ) @@ -842,13 +849,19 @@ impl MessageProcessor { { let invoke_context = invoke_context.borrow(); - for (i, (account, account_ref)) in accounts.iter().zip(account_refs).enumerate() { - let account = account.borrow(); - if message.is_writable(i, demote_sysvar_write_locks) && !account.executable { - account_ref.try_account_ref_mut()?.lamports = account.lamports; - account_ref.try_account_ref_mut()?.owner = account.owner; - if account_ref.data_len()? != account.data().len() - && account_ref.data_len()? != 0 + let keyed_accounts = invoke_context.get_keyed_accounts(); + for (src_keyed_account_index, (account, dst_keyed_account_index)) in accounts + .iter() + .zip(keyed_account_indices_reordered) + .enumerate() + { + let dst_keyed_account = &keyed_accounts[dst_keyed_account_index]; + let src_keyed_account = account.borrow(); + if message.is_writable(src_keyed_account_index, demote_sysvar_write_locks) + && !src_keyed_account.executable + { + if dst_keyed_account.data_len()? != src_keyed_account.data().len() + && dst_keyed_account.data_len()? != 0 { // Only support for `CreateAccount` at this time. // Need a way to limit total realloc size across multiple CPI calls @@ -858,9 +871,11 @@ impl MessageProcessor { ); return Err(InstructionError::InvalidRealloc); } - account_ref + dst_keyed_account.try_account_ref_mut()?.lamports = src_keyed_account.lamports; + dst_keyed_account.try_account_ref_mut()?.owner = src_keyed_account.owner; + dst_keyed_account .try_account_ref_mut()? - .set_data(account.data().clone()); + .set_data(src_keyed_account.data().clone()); } } } From 690067c5bed987830b590afc3ed91e3f56b86eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 16 Mar 2021 13:24:41 +0100 Subject: [PATCH 13/33] Removed use of the keyed_accounts parameter in bpf_loader::process_loader_upgradeable_instruction(). --- programs/bpf_loader/src/lib.rs | 59 ++++++++++++++++++++------------ runtime/src/message_processor.rs | 12 ++----- runtime/src/native_loader.rs | 3 +- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 2ed20288d97760..d8336827cd6801 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -194,7 +194,8 @@ fn process_instruction_common( use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); - debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let first_account = keyed_account_at_index(keyed_accounts, 0)?; if first_account.executable()? { @@ -288,13 +289,15 @@ fn process_instruction_common( fn process_loader_upgradeable_instruction( program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); - debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + let keyed_accounts = invoke_context.get_keyed_accounts(); + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(_keyed_accounts, keyed_accounts); match limited_deserialize(instruction_data)? { UpgradeableLoaderInstruction::InitializeBuffer => { @@ -412,23 +415,35 @@ fn process_loader_upgradeable_instruction( return Err(InstructionError::InvalidArgument); } + let instruction = system_instruction::create_account( + payer.unsigned_key(), + programdata.unsigned_key(), + 1.max(rent.minimum_balance(programdata_len)), + programdata_len as u64, + program_id, + ); + let caller_program_id = invoke_context.get_caller()?; + let signers = [&[program.unsigned_key().as_ref(), &[bump_seed]]] + .iter() + .map(|seeds| Pubkey::create_program_address(*seeds, caller_program_id)) + .collect::, solana_sdk::pubkey::PubkeyError>>()?; MessageProcessor::native_invoke( invoke_context, - system_instruction::create_account( - payer.unsigned_key(), - programdata.unsigned_key(), - 1.max(rent.minimum_balance(programdata_len)), - programdata_len as u64, - program_id, - ), + instruction, &[0, 1, 6], - &[&[program.unsigned_key().as_ref(), &[bump_seed]]], + signers.as_slice(), )?; // Load and verify the program bits let executor = create_executor(3, buffer_data_offset, invoke_context, use_jit)?; invoke_context.add_executor(program_id, executor); + let keyed_accounts = invoke_context.get_keyed_accounts(); + let payer = keyed_account_at_index(keyed_accounts, 0)?; + let programdata = keyed_account_at_index(keyed_accounts, 1)?; + let program = keyed_account_at_index(keyed_accounts, 2)?; + let buffer = keyed_account_at_index(keyed_accounts, 3)?; + // Update the ProgramData account and record the program bits programdata.set_state(&UpgradeableLoaderState::ProgramData { slot: clock.slot, @@ -454,7 +469,6 @@ fn process_loader_upgradeable_instruction( let programdata = keyed_account_at_index(keyed_accounts, 0)?; let program = keyed_account_at_index(keyed_accounts, 1)?; let buffer = keyed_account_at_index(keyed_accounts, 2)?; - let spill = keyed_account_at_index(keyed_accounts, 3)?; let rent = from_keyed_account::(keyed_account_at_index(keyed_accounts, 4)?)?; let clock = from_keyed_account::(keyed_account_at_index(keyed_accounts, 5)?)?; let authority = keyed_account_at_index(keyed_accounts, 6)?; @@ -547,17 +561,18 @@ fn process_loader_upgradeable_instruction( } // Load and verify the program bits - let executor = create_executor(2, buffer_data_offset, invoke_context, use_jit)?; - { - let keyed_accounts = invoke_context.get_keyed_accounts(); - let program = keyed_account_at_index(keyed_accounts, 1)?; - invoke_context.add_executor(program.unsigned_key(), executor); - } + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, 1)?; + invoke_context.add_executor(program.unsigned_key(), executor); + + let programdata = keyed_account_at_index(keyed_accounts, 0)?; + let buffer = keyed_account_at_index(keyed_accounts, 2)?; + let spill = keyed_account_at_index(keyed_accounts, 3)?; + let authority = keyed_account_at_index(keyed_accounts, 6)?; // Update the ProgramData account, record the upgraded data, and zero // the rest - programdata.set_state(&UpgradeableLoaderState::ProgramData { slot: clock.slot, upgrade_authority_address: Some(*authority.unsigned_key()), @@ -688,7 +703,8 @@ fn process_loader_instruction( invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { - debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let program = keyed_account_at_index(keyed_accounts, 0)?; if program.owner()? != *program_id { ic_msg!( @@ -773,7 +789,8 @@ impl Executor for BpfExecutor { ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); let invoke_depth = invoke_context.invoke_depth(); - debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let mut serialize_time = Measure::start("serialize"); // TODO [KeyedAccounts to InvokeContext refactoring] diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 1e24106e73adb8..bb2e8740cb5658 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -597,7 +597,8 @@ impl MessageProcessor { instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); if let Some(root_account) = keyed_accounts.iter().next() { let root_id = root_account.unsigned_key(); if native_loader::check_id(&root_account.owner()?) { @@ -722,7 +723,7 @@ impl MessageProcessor { invoke_context: &mut dyn InvokeContext, instruction: Instruction, keyed_account_indices: &[usize], - signers_seeds: &[&[&[u8]]], + signers: &[Pubkey], ) -> Result<(), InstructionError> { let invoke_context = RefCell::new(invoke_context); @@ -736,14 +737,7 @@ impl MessageProcessor { ) = { let invoke_context = invoke_context.borrow(); - let caller_program_id = invoke_context.get_caller()?; - // Translate and verify caller's data - - let signers = signers_seeds - .iter() - .map(|seeds| Pubkey::create_program_address(&seeds, caller_program_id)) - .collect::, solana_sdk::pubkey::PubkeyError>>()?; let keyed_accounts = invoke_context.get_keyed_accounts(); let keyed_accounts = keyed_account_indices .iter() diff --git a/runtime/src/native_loader.rs b/runtime/src/native_loader.rs index 3001e03a8bec92..6820a11a68b55f 100644 --- a/runtime/src/native_loader.rs +++ b/runtime/src/native_loader.rs @@ -139,7 +139,8 @@ impl NativeLoader { instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - debug_assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let program = keyed_account_at_index(keyed_accounts, 0)?; if native_loader::id() != *program_id { error!("Program id mismatch"); From db7ef72b2a5345669f1b9f819d81daabbf515c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 16 Mar 2021 13:32:38 +0100 Subject: [PATCH 14/33] Removed use of the keyed_accounts parameter in bpf_loader::process_loader_instruction() and in bpf_loader::Executor::execute(). --- programs/bpf_loader/src/lib.rs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index d8336827cd6801..c29817ca02758d 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -218,8 +218,6 @@ fn process_instruction_common( ); return Err(InstructionError::InvalidArgument); } - // TODO [KeyedAccounts to InvokeContext refactoring] - // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); invoke_context.pop_first_keyed_account(); ( &keyed_accounts[1..], @@ -698,13 +696,14 @@ fn process_loader_upgradeable_instruction( fn process_loader_instruction( program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); let program = keyed_account_at_index(keyed_accounts, 0)?; if program.owner()? != *program_id { ic_msg!( @@ -728,11 +727,9 @@ fn process_loader_instruction( } let executor = create_executor(0, 0, invoke_context, use_jit)?; - { - let keyed_accounts = invoke_context.get_keyed_accounts(); - let program = keyed_account_at_index(keyed_accounts, 0)?; - invoke_context.add_executor(program.unsigned_key(), executor); - } + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, 0)?; + invoke_context.add_executor(program.unsigned_key(), executor); program.try_account_ref_mut()?.executable = true; ic_msg!( invoke_context, @@ -782,23 +779,26 @@ impl Executor for BpfExecutor { &self, loader_id: &Pubkey, program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + let keyed_accounts = invoke_context.get_keyed_accounts(); + assert_eq!(_keyed_accounts, keyed_accounts); + let logger = invoke_context.get_logger(); let invoke_depth = invoke_context.invoke_depth(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); - let mut serialize_time = Measure::start("serialize"); // TODO [KeyedAccounts to InvokeContext refactoring] // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); invoke_context.pop_first_keyed_account(); - let parameter_accounts = &keyed_accounts[1..]; + + let mut serialize_time = Measure::start("serialize"); + let keyed_accounts = invoke_context.get_keyed_accounts(); let mut parameter_bytes = - serialize_parameters(loader_id, program_id, parameter_accounts, &instruction_data)?; + serialize_parameters(loader_id, program_id, keyed_accounts, &instruction_data)?; serialize_time.stop(); let mut create_vm_time = Measure::start("create_vm"); let mut execute_time; @@ -867,9 +867,10 @@ impl Executor for BpfExecutor { execute_time.stop(); } let mut deserialize_time = Measure::start("deserialize"); + let keyed_accounts = invoke_context.get_keyed_accounts(); deserialize_parameters( loader_id, - parameter_accounts, + keyed_accounts, ¶meter_bytes, invoke_context.is_feature_active(&skip_ro_deserialization::id()), )?; From 7418f0811cc629e102c23ade9b58b45d70d50c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Thu, 25 Feb 2021 16:20:03 +0100 Subject: [PATCH 15/33] Removed use of the keyed_accounts parameter in bpf_loader::process_instruction(), bpf_loader::process_instruction_jit() and bpf_loader::process_instruction_common(). --- programs/bpf_loader/src/lib.rs | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index c29817ca02758d..0cd9eb7fabe649 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -158,13 +158,13 @@ pub fn create_vm<'a>( pub fn process_instruction( program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { process_instruction_common( program_id, - keyed_accounts, + _keyed_accounts, instruction_data, invoke_context, false, @@ -173,13 +173,13 @@ pub fn process_instruction( pub fn process_instruction_jit( program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { process_instruction_common( program_id, - keyed_accounts, + _keyed_accounts, instruction_data, invoke_context, true, @@ -188,14 +188,15 @@ pub fn process_instruction_jit( fn process_instruction_common( program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); let first_account = keyed_account_at_index(keyed_accounts, 0)?; if first_account.executable()? { @@ -204,7 +205,7 @@ fn process_instruction_common( return Err(InstructionError::IncorrectProgramId); } - let (keyed_accounts, program_data_offset) = + let (_keyed_accounts, program_data_offset) = if bpf_loader_upgradeable::check_id(&first_account.owner()?) { if let UpgradeableLoaderState::Program { programdata_address, @@ -220,7 +221,7 @@ fn process_instruction_common( } invoke_context.pop_first_keyed_account(); ( - &keyed_accounts[1..], + &_keyed_accounts[1..], UpgradeableLoaderState::programdata_data_offset()?, ) } else { @@ -228,14 +229,12 @@ fn process_instruction_common( return Err(InstructionError::InvalidAccountData); } } else { - (keyed_accounts, 0) + (_keyed_accounts, 0) }; - let loader_id = { - let keyed_accounts = invoke_context.get_keyed_accounts(); - let program = keyed_account_at_index(keyed_accounts, 0)?; - &program.owner()? - }; + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, 0)?; + let loader_id = &program.owner()?; if !check_loader_id(loader_id) { ic_logger_msg!(logger, "Executable account not owned by the BPF loader"); @@ -253,7 +252,7 @@ fn process_instruction_common( executor.execute( loader_id, program_id, - keyed_accounts, + _keyed_accounts, instruction_data, invoke_context, use_jit, @@ -267,7 +266,7 @@ fn process_instruction_common( if bpf_loader_upgradeable::check_id(program_id) { process_loader_upgradeable_instruction( program_id, - keyed_accounts, + _keyed_accounts, instruction_data, invoke_context, use_jit, @@ -275,7 +274,7 @@ fn process_instruction_common( } else { process_loader_instruction( program_id, - keyed_accounts, + _keyed_accounts, instruction_data, invoke_context, use_jit, From ed06314a12338c39b49a8a04e2edce4fd696eef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Fri, 26 Feb 2021 10:04:07 +0100 Subject: [PATCH 16/33] Removes unused keyed_accounts parameter in bpf_loader. --- programs/bpf_loader/src/lib.rs | 81 +++++++++------------------------- runtime/src/bank.rs | 1 - sdk/src/process_instruction.rs | 1 - 3 files changed, 20 insertions(+), 63 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 0cd9eb7fabe649..0551183d0ee684 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -162,13 +162,7 @@ pub fn process_instruction( instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - process_instruction_common( - program_id, - _keyed_accounts, - instruction_data, - invoke_context, - false, - ) + process_instruction_common(program_id, instruction_data, invoke_context, false) } pub fn process_instruction_jit( @@ -177,26 +171,17 @@ pub fn process_instruction_jit( instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - process_instruction_common( - program_id, - _keyed_accounts, - instruction_data, - invoke_context, - true, - ) + process_instruction_common(program_id, instruction_data, invoke_context, true) } fn process_instruction_common( program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); let first_account = keyed_account_at_index(keyed_accounts, 0)?; if first_account.executable()? { @@ -205,32 +190,25 @@ fn process_instruction_common( return Err(InstructionError::IncorrectProgramId); } - let (_keyed_accounts, program_data_offset) = - if bpf_loader_upgradeable::check_id(&first_account.owner()?) { - if let UpgradeableLoaderState::Program { - programdata_address, - } = first_account.state()? - { - let programdata = keyed_account_at_index(keyed_accounts, 1)?; - if programdata_address != *programdata.unsigned_key() { - ic_logger_msg!( - logger, - "Wrong ProgramData account for this Program account" - ); - return Err(InstructionError::InvalidArgument); - } - invoke_context.pop_first_keyed_account(); - ( - &_keyed_accounts[1..], - UpgradeableLoaderState::programdata_data_offset()?, - ) - } else { - ic_logger_msg!(logger, "Invalid Program account"); - return Err(InstructionError::InvalidAccountData); + let program_data_offset = if bpf_loader_upgradeable::check_id(&first_account.owner()?) { + if let UpgradeableLoaderState::Program { + programdata_address, + } = first_account.state()? + { + let programdata = keyed_account_at_index(keyed_accounts, 1)?; + if programdata_address != *programdata.unsigned_key() { + ic_logger_msg!(logger, "Wrong ProgramData account for this Program account"); + return Err(InstructionError::InvalidArgument); } + invoke_context.pop_first_keyed_account(); + UpgradeableLoaderState::programdata_data_offset()? } else { - (_keyed_accounts, 0) - }; + ic_logger_msg!(logger, "Invalid Program account"); + return Err(InstructionError::InvalidAccountData); + } + } else { + 0 + }; let keyed_accounts = invoke_context.get_keyed_accounts(); let program = keyed_account_at_index(keyed_accounts, 0)?; @@ -252,7 +230,6 @@ fn process_instruction_common( executor.execute( loader_id, program_id, - _keyed_accounts, instruction_data, invoke_context, use_jit, @@ -266,19 +243,12 @@ fn process_instruction_common( if bpf_loader_upgradeable::check_id(program_id) { process_loader_upgradeable_instruction( program_id, - _keyed_accounts, instruction_data, invoke_context, use_jit, )?; } else { - process_loader_instruction( - program_id, - _keyed_accounts, - instruction_data, - invoke_context, - use_jit, - )?; + process_loader_instruction(program_id, instruction_data, invoke_context, use_jit)?; } } Ok(()) @@ -286,15 +256,12 @@ fn process_instruction_common( fn process_loader_upgradeable_instruction( program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); match limited_deserialize(instruction_data)? { UpgradeableLoaderInstruction::InitializeBuffer => { @@ -695,14 +662,11 @@ fn process_loader_upgradeable_instruction( fn process_loader_instruction( program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); let program = keyed_account_at_index(keyed_accounts, 0)?; if program.owner()? != *program_id { ic_msg!( @@ -778,15 +742,10 @@ impl Executor for BpfExecutor { &self, loader_id: &Pubkey, program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { - // TODO [KeyedAccounts to InvokeContext refactoring] - let keyed_accounts = invoke_context.get_keyed_accounts(); - assert_eq!(_keyed_accounts, keyed_accounts); - let logger = invoke_context.get_logger(); let invoke_depth = invoke_context.invoke_depth(); diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index b8854bfbf28383..cbd4bff626fae5 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -10962,7 +10962,6 @@ pub(crate) mod tests { &self, _loader_id: &Pubkey, _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], _instruction_data: &[u8], _invoke_context: &mut dyn InvokeContext, _use_jit: bool, diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 043b4971b9641e..21dfad4db54cbd 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -244,7 +244,6 @@ pub trait Executor: Debug + Send + Sync { &self, loader_id: &Pubkey, program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, use_jit: bool, From 982ff93377355e0c4bb48602521c954d0c5f926f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 16 Mar 2021 13:38:02 +0100 Subject: [PATCH 17/33] Adds more assertions of invoke_context.get_keyed_accounts() being equal to the keyed_accounts parameter. --- program-test/src/lib.rs | 3 +++ programs/budget/src/budget_processor.rs | 5 ++++- programs/config/src/config_processor.rs | 3 +++ programs/exchange/src/exchange_processor.rs | 5 ++++- programs/ownable/src/ownable_processor.rs | 4 +++- programs/stake/src/stake_instruction.rs | 2 ++ programs/vest/src/vest_processor.rs | 3 +++ programs/vote/src/vote_instruction.rs | 3 +++ runtime/src/bank.rs | 24 +++++++++++++++------ runtime/src/builtins.rs | 3 +++ runtime/src/message_processor.rs | 18 +++++++++++----- runtime/src/system_instruction_processor.rs | 2 ++ 12 files changed, 60 insertions(+), 15 deletions(-) diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index b462a1088fa923..aafdb52daab92c 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -105,6 +105,9 @@ pub fn builtin_process_instruction( ) -> Result<(), InstructionError> { set_invoke_context(invoke_context); + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); + // Copy all the accounts into a HashMap to ensure there are no duplicates let mut accounts: HashMap = keyed_accounts .iter() diff --git a/programs/budget/src/budget_processor.rs b/programs/budget/src/budget_processor.rs index df685f07d30cb2..ec248f0aa64947 100644 --- a/programs/budget/src/budget_processor.rs +++ b/programs/budget/src/budget_processor.rs @@ -118,8 +118,11 @@ pub fn process_instruction( _program_id: &Pubkey, keyed_accounts: &[KeyedAccount], data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + let instruction = limited_deserialize(data)?; trace!("process_instruction: {:?}", instruction); diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index 698e334d460d22..769644243ff731 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -18,6 +18,9 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + let key_list: ConfigKeys = limited_deserialize(data)?; let config_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; let current_data: ConfigKeys = { diff --git a/programs/exchange/src/exchange_processor.rs b/programs/exchange/src/exchange_processor.rs index 200126c17f6bef..fb5bfbea119797 100644 --- a/programs/exchange/src/exchange_processor.rs +++ b/programs/exchange/src/exchange_processor.rs @@ -489,10 +489,13 @@ pub fn process_instruction( _program_id: &Pubkey, keyed_accounts: &[KeyedAccount], data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { solana_logger::setup(); + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + match limited_deserialize::(data)? { ExchangeInstruction::AccountRequest => { ExchangeProcessor::do_account_request(keyed_accounts) diff --git a/programs/ownable/src/ownable_processor.rs b/programs/ownable/src/ownable_processor.rs index 13c217c8180138..143bfe2232ee61 100644 --- a/programs/ownable/src/ownable_processor.rs +++ b/programs/ownable/src/ownable_processor.rs @@ -32,8 +32,10 @@ pub fn process_instruction( _program_id: &Pubkey, keyed_accounts: &[KeyedAccount], data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let new_owner_pubkey: Pubkey = limited_deserialize(data)?; let account_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; let mut account_owner_pubkey: Pubkey = diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index dfb1d0015a86b4..35a4c032da69e7 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -487,6 +487,8 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); trace!("process_instruction: {:?}", data); trace!("keyed_accounts: {:?}", keyed_accounts); diff --git a/programs/vest/src/vest_processor.rs b/programs/vest/src/vest_processor.rs index ed29abb4d60ea8..906f110a37eeb3 100644 --- a/programs/vest/src/vest_processor.rs +++ b/programs/vest/src/vest_processor.rs @@ -63,6 +63,9 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + let contract_account = &mut keyed_account_at_index(keyed_accounts, 0)?.try_account_ref_mut()?; if invoke_context.is_feature_active(&feature_set::check_program_owner::id()) && contract_account.owner != crate::id() diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index d0beffd6b53ba8..3d104175296df6 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -281,6 +281,9 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + trace!("process_instruction: {:?}", data); trace!("keyed_accounts: {:?}", keyed_accounts); diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index cbd4bff626fae5..fb916a8de0eeea 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -5432,8 +5432,10 @@ pub(crate) mod tests { _program_id: &Pubkey, keyed_accounts: &[KeyedAccount], data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockInstruction::Deduction => { @@ -9007,10 +9009,12 @@ pub(crate) mod tests { } fn mock_vote_processor( program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], + keyed_accounts: &[KeyedAccount], _instruction_data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); if mock_vote_program_id() != *program_id { return Err(InstructionError::IncorrectProgramId); } @@ -9852,8 +9856,10 @@ pub(crate) mod tests { _program_id: &Pubkey, keyed_accounts: &[KeyedAccount], data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); let lamports = data[0] as u64; { let mut to_account = keyed_accounts[1].try_account_ref_mut()?; @@ -9904,10 +9910,12 @@ pub(crate) mod tests { #[allow(clippy::unnecessary_wraps)] fn mock_process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], + keyed_accounts: &[KeyedAccount], _data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); Ok(()) } @@ -10344,8 +10352,10 @@ pub(crate) mod tests { _program_id: &Pubkey, keyed_accounts: &[KeyedAccount], _data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); assert_eq!(42, keyed_accounts[0].lamports().unwrap()); let mut account = keyed_accounts[0].try_account_ref_mut()?; account.lamports += 1; diff --git a/runtime/src/builtins.rs b/runtime/src/builtins.rs index 03a9dfc7ec1ede..b7917e20894472 100644 --- a/runtime/src/builtins.rs +++ b/runtime/src/builtins.rs @@ -18,6 +18,9 @@ fn process_instruction_with_program_logging( instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + let logger = invoke_context.get_logger(); stable_log::program_invoke(&logger, program_id, invoke_context.invoke_depth()); diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index bb2e8740cb5658..b7fe68d6568879 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -1789,8 +1789,10 @@ mod tests { _program_id: &Pubkey, keyed_accounts: &[KeyedAccount], data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockSystemInstruction::Correct => Ok(()), @@ -1942,8 +1944,10 @@ mod tests { _program_id: &Pubkey, keyed_accounts: &[KeyedAccount], data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockSystemInstruction::BorrowFail => { @@ -2121,8 +2125,10 @@ mod tests { program_id: &Pubkey, keyed_accounts: &[KeyedAccount], data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); assert_eq!(*program_id, keyed_accounts[0].owner()?); assert_ne!( keyed_accounts[1].owner()?, @@ -2268,10 +2274,12 @@ mod tests { #[allow(clippy::unnecessary_wraps)] fn mock_process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], + keyed_accounts: &[KeyedAccount], _data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); Ok(()) } #[allow(clippy::unnecessary_wraps)] diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index 38cf30072483a9..e9a26b9eae7adb 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -259,6 +259,8 @@ pub fn process_instruction( instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + // TODO [KeyedAccounts to InvokeContext refactoring] + assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); let instruction = limited_deserialize(instruction_data)?; trace!("process_instruction: {:?}", instruction); From 843bbb124c6771424dcf519d6e8a491b89d4a5dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 5 Apr 2021 16:13:40 +0200 Subject: [PATCH 18/33] Changes all native programs to use "invoke_context.get_keyed_accounts()". --- programs/budget/src/budget_processor.rs | 5 +- programs/config/src/config_processor.rs | 5 +- programs/exchange/src/exchange_processor.rs | 8 +- programs/noop/src/lib.rs | 4 +- programs/ownable/src/ownable_processor.rs | 6 +- programs/stake/src/stake_instruction.rs | 6 +- programs/vest/src/vest_processor.rs | 5 +- programs/vote/src/vote_instruction.rs | 5 +- runtime/src/bank.rs | 24 +++-- runtime/src/message_processor.rs | 19 ++-- runtime/src/system_instruction_processor.rs | 73 ++++++------- sdk/src/nonce_keyed_account.rs | 110 +++++++++----------- 12 files changed, 139 insertions(+), 131 deletions(-) diff --git a/programs/budget/src/budget_processor.rs b/programs/budget/src/budget_processor.rs index ec248f0aa64947..f0d55cb2a5c684 100644 --- a/programs/budget/src/budget_processor.rs +++ b/programs/budget/src/budget_processor.rs @@ -116,12 +116,13 @@ fn apply_account_data( pub fn process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); let instruction = limited_deserialize(data)?; diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index 769644243ff731..fa2d2737d9f4a1 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -14,12 +14,13 @@ use solana_sdk::{ pub fn process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); let key_list: ConfigKeys = limited_deserialize(data)?; let config_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; diff --git a/programs/exchange/src/exchange_processor.rs b/programs/exchange/src/exchange_processor.rs index fb5bfbea119797..504adbff0a51d7 100644 --- a/programs/exchange/src/exchange_processor.rs +++ b/programs/exchange/src/exchange_processor.rs @@ -487,15 +487,15 @@ impl ExchangeProcessor { pub fn process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - solana_logger::setup(); - + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); + solana_logger::setup(); match limited_deserialize::(data)? { ExchangeInstruction::AccountRequest => { ExchangeProcessor::do_account_request(keyed_accounts) diff --git a/programs/noop/src/lib.rs b/programs/noop/src/lib.rs index 8bfc2d9d6de522..d5c6ccc37c6aca 100644 --- a/programs/noop/src/lib.rs +++ b/programs/noop/src/lib.rs @@ -12,13 +12,13 @@ solana_sdk::declare_program!( pub fn process_instruction( program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { solana_logger::setup(); trace!("noop: program_id: {:?}", program_id); - trace!("noop: keyed_accounts: {:#?}", keyed_accounts); + trace!("noop: keyed_accounts: {:#?}", _keyed_accounts); trace!("noop: data: {:?}", data); Ok(()) } diff --git a/programs/ownable/src/ownable_processor.rs b/programs/ownable/src/ownable_processor.rs index 143bfe2232ee61..87a34aa39c9228 100644 --- a/programs/ownable/src/ownable_processor.rs +++ b/programs/ownable/src/ownable_processor.rs @@ -30,12 +30,14 @@ fn set_owner( pub fn process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); + let new_owner_pubkey: Pubkey = limited_deserialize(data)?; let account_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; let mut account_owner_pubkey: Pubkey = diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 35a4c032da69e7..7d685b01f5b006 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -483,12 +483,14 @@ pub fn set_lockup( pub fn process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); + trace!("process_instruction: {:?}", data); trace!("keyed_accounts: {:?}", keyed_accounts); diff --git a/programs/vest/src/vest_processor.rs b/programs/vest/src/vest_processor.rs index 906f110a37eeb3..44265ec39518bf 100644 --- a/programs/vest/src/vest_processor.rs +++ b/programs/vest/src/vest_processor.rs @@ -59,12 +59,13 @@ fn verify_signed_account<'a>( pub fn process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); let contract_account = &mut keyed_account_at_index(keyed_accounts, 0)?.try_account_ref_mut()?; if invoke_context.is_feature_active(&feature_set::check_program_owner::id()) diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index 3d104175296df6..08ad32718d80f8 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -277,12 +277,13 @@ fn verify_rent_exemption( pub fn process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); trace!("process_instruction: {:?}", data); trace!("keyed_accounts: {:?}", keyed_accounts); diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index fb916a8de0eeea..3cb0e8a349d7e5 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -5430,12 +5430,13 @@ pub(crate) mod tests { fn mock_process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); + assert_eq!(_keyed_accounts, keyed_accounts); if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockInstruction::Deduction => { @@ -9009,12 +9010,13 @@ pub(crate) mod tests { } fn mock_vote_processor( program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], _instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); + assert_eq!(_keyed_accounts, keyed_accounts); if mock_vote_program_id() != *program_id { return Err(InstructionError::IncorrectProgramId); } @@ -9854,12 +9856,13 @@ pub(crate) mod tests { fn mock_process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); + assert_eq!(_keyed_accounts, keyed_accounts); let lamports = data[0] as u64; { let mut to_account = keyed_accounts[1].try_account_ref_mut()?; @@ -9910,12 +9913,12 @@ pub(crate) mod tests { #[allow(clippy::unnecessary_wraps)] fn mock_process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], _data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); + assert_eq!(invoke_context.get_keyed_accounts(), _keyed_accounts); Ok(()) } @@ -10350,12 +10353,13 @@ pub(crate) mod tests { fn test_same_program_id_uses_unqiue_executable_accounts() { fn nested_processor( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], _data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); + assert_eq!(_keyed_accounts, keyed_accounts); assert_eq!(42, keyed_accounts[0].lamports().unwrap()); let mut account = keyed_accounts[0].try_account_ref_mut()?; account.lamports += 1; diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index b7fe68d6568879..d60606acde75f8 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -1787,12 +1787,13 @@ mod tests { fn mock_system_process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockSystemInstruction::Correct => Ok(()), @@ -1942,12 +1943,13 @@ mod tests { fn mock_system_process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockSystemInstruction::BorrowFail => { @@ -2123,12 +2125,13 @@ mod tests { fn mock_process_instruction( program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); assert_eq!(*program_id, keyed_accounts[0].owner()?); assert_ne!( keyed_accounts[1].owner()?, @@ -2274,12 +2277,12 @@ mod tests { #[allow(clippy::unnecessary_wraps)] fn mock_process_instruction( _program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], _data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, invoke_context.get_keyed_accounts()); Ok(()) } #[allow(clippy::unnecessary_wraps)] diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index e9a26b9eae7adb..2c17ced1e0118f 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -35,7 +35,7 @@ impl Address { fn create( address: &Pubkey, with_seed: Option<(&Pubkey, &str, &Pubkey)>, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result { let base = if let Some((base, seed, owner)) = with_seed { let address_with_seed = Pubkey::create_with_seed(base, seed, owner)?; @@ -66,7 +66,7 @@ fn allocate( address: &Address, space: u64, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { if !address.is_signer(signers) { ic_msg!( @@ -108,7 +108,7 @@ fn assign( address: &Address, owner: &Pubkey, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { // no work to do, just return if account.owner == *owner { @@ -136,7 +136,7 @@ fn allocate_and_assign( space: u64, owner: &Pubkey, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { allocate(to, to_address, space, signers, invoke_context)?; assign(to, to_address, owner, signers, invoke_context) @@ -150,7 +150,7 @@ fn create_account( space: u64, owner: &Pubkey, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { // if it looks like the `to` account is already in use, bail { @@ -173,7 +173,7 @@ fn transfer_verified( from: &KeyedAccount, to: &KeyedAccount, lamports: u64, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { if !from.data_is_empty()? { ic_msg!(invoke_context, "Transfer: `from` must not carry data"); @@ -198,7 +198,7 @@ fn transfer( from: &KeyedAccount, to: &KeyedAccount, lamports: u64, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { if lamports == 0 { return Ok(()); @@ -223,7 +223,7 @@ fn transfer_with_seed( from_owner: &Pubkey, to: &KeyedAccount, lamports: u64, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { if lamports == 0 { return Ok(()); @@ -255,12 +255,13 @@ fn transfer_with_seed( pub fn process_instruction( _owner: &Pubkey, - keyed_accounts: &[KeyedAccount], + _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { + let keyed_accounts = invoke_context.get_keyed_accounts(); // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); + assert_eq!(_keyed_accounts, keyed_accounts); let instruction = limited_deserialize(instruction_data)?; trace!("process_instruction: {:?}", instruction); @@ -626,7 +627,7 @@ mod tests { Address::create( &to, Some((&from, seed, &owner)), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ), Err(SystemError::AddressWithSeedMismatch.into()) ); @@ -644,7 +645,7 @@ mod tests { let to_address = Address::create( &to, Some((&from, seed, &new_owner)), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); @@ -657,7 +658,7 @@ mod tests { 2, &new_owner, &HashSet::new(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ), Err(InstructionError::MissingRequiredSignature) ); @@ -684,7 +685,7 @@ mod tests { 2, &new_owner, &[to].iter().cloned().collect::>(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ), Ok(()) ); @@ -716,7 +717,7 @@ mod tests { 2, &new_owner, &[from, to].iter().cloned().collect::>(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::ResultWithNegativeLamports.into())); } @@ -740,7 +741,7 @@ mod tests { MAX_PERMITTED_DATA_LENGTH + 1, &system_program::id(), &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert!(result.is_err()); assert_eq!( @@ -757,7 +758,7 @@ mod tests { MAX_PERMITTED_DATA_LENGTH, &system_program::id(), &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert!(result.is_ok()); assert_eq!(to_account.borrow().lamports, 50); @@ -790,7 +791,7 @@ mod tests { 2, &new_owner, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); @@ -809,7 +810,7 @@ mod tests { 2, &new_owner, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); let from_lamports = from_account.borrow().lamports; @@ -827,7 +828,7 @@ mod tests { 2, &new_owner, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); assert_eq!(from_lamports, 100); @@ -855,7 +856,7 @@ mod tests { 2, &new_owner, &[owned_key].iter().cloned().collect::>(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); @@ -869,7 +870,7 @@ mod tests { 2, &new_owner, &[from].iter().cloned().collect::>(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); @@ -883,7 +884,7 @@ mod tests { 2, &new_owner, &[owned_key].iter().cloned().collect::>(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Ok(())); } @@ -909,7 +910,7 @@ mod tests { 2, &sysvar::id(), &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::InvalidProgramId.into())); @@ -943,7 +944,7 @@ mod tests { 2, &new_owner, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); } @@ -977,7 +978,7 @@ mod tests { 0, &solana_sdk::pubkey::new_rand(), &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ), Err(InstructionError::InvalidArgument), ); @@ -996,7 +997,7 @@ mod tests { &pubkey.into(), &new_owner, &HashSet::new(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ), Err(InstructionError::MissingRequiredSignature) ); @@ -1007,7 +1008,7 @@ mod tests { &pubkey.into(), &system_program::id(), &HashSet::new(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ), Ok(()) ); @@ -1036,7 +1037,7 @@ mod tests { &from.into(), &new_owner, &[from].iter().cloned().collect::>(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ), Err(SystemError::InvalidProgramId.into()) ); @@ -1077,7 +1078,7 @@ mod tests { &from_keyed_account, &to_keyed_account, 50, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let from_lamports = from_keyed_account.account.borrow().lamports; @@ -1091,7 +1092,7 @@ mod tests { &from_keyed_account, &to_keyed_account, 100, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::ResultWithNegativeLamports.into())); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1104,7 +1105,7 @@ mod tests { &from_keyed_account, &to_keyed_account, 0, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .is_ok(),); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1131,7 +1132,7 @@ mod tests { &from_owner, &to_keyed_account, 50, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let from_lamports = from_keyed_account.account.borrow().lamports; @@ -1148,7 +1149,7 @@ mod tests { &from_owner, &to_keyed_account, 100, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(SystemError::ResultWithNegativeLamports.into())); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1163,7 +1164,7 @@ mod tests { &from_owner, &to_keyed_account, 0, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .is_ok(),); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1194,7 +1195,7 @@ mod tests { &KeyedAccount::new(&from, true, &from_account), &KeyedAccount::new(&to, false, &to_account), 50, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ), Err(InstructionError::InvalidArgument), ) diff --git a/sdk/src/nonce_keyed_account.rs b/sdk/src/nonce_keyed_account.rs index 522fb92d8d2732..bff9ccc77a6bba 100644 --- a/sdk/src/nonce_keyed_account.rs +++ b/sdk/src/nonce_keyed_account.rs @@ -16,7 +16,7 @@ pub trait NonceKeyedAccount { &self, recent_blockhashes: &RecentBlockhashes, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError>; fn withdraw_nonce_account( &self, @@ -25,20 +25,20 @@ pub trait NonceKeyedAccount { recent_blockhashes: &RecentBlockhashes, rent: &Rent, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError>; fn initialize_nonce_account( &self, nonce_authority: &Pubkey, recent_blockhashes: &RecentBlockhashes, rent: &Rent, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError>; fn authorize_nonce_account( &self, nonce_authority: &Pubkey, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError>; } @@ -47,7 +47,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { &self, recent_blockhashes: &RecentBlockhashes, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { if recent_blockhashes.is_empty() { ic_msg!( @@ -102,7 +102,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { recent_blockhashes: &RecentBlockhashes, rent: &Rent, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { let signer = match AccountUtilsState::::state(self)?.convert_to_current() { State::Uninitialized => { @@ -170,7 +170,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { nonce_authority: &Pubkey, recent_blockhashes: &RecentBlockhashes, rent: &Rent, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { if recent_blockhashes.is_empty() { ic_msg!( @@ -214,7 +214,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { &self, nonce_authority: &Pubkey, signers: &HashSet, - invoke_context: &mut dyn InvokeContext, + invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { match AccountUtilsState::::state(self)?.convert_to_current() { State::Initialized(data) => { @@ -300,7 +300,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(keyed_account) @@ -315,11 +315,7 @@ mod test { assert_eq!(state, State::Initialized(data.clone())); let recent_blockhashes = create_test_recent_blockhashes(63); keyed_account - .advance_nonce_account( - &recent_blockhashes, - &signers, - &mut MockInvokeContext::new(&[]), - ) + .advance_nonce_account(&recent_blockhashes, &signers, &MockInvokeContext::new(&[])) .unwrap(); let state = AccountUtilsState::::state(keyed_account) .unwrap() @@ -333,11 +329,7 @@ mod test { assert_eq!(state, State::Initialized(data.clone())); let recent_blockhashes = create_test_recent_blockhashes(31); keyed_account - .advance_nonce_account( - &recent_blockhashes, - &signers, - &mut MockInvokeContext::new(&[]), - ) + .advance_nonce_account(&recent_blockhashes, &signers, &MockInvokeContext::new(&[])) .unwrap(); let state = AccountUtilsState::::state(keyed_account) .unwrap() @@ -362,7 +354,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); // Empties Account balance @@ -396,7 +388,7 @@ mod test { &authority, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let pubkey = nonce_account.account.borrow().owner; @@ -415,7 +407,7 @@ mod test { let result = nonce_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }) @@ -438,14 +430,14 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let recent_blockhashes = vec![].into_iter().collect(); let result = keyed_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into())); }) @@ -468,13 +460,13 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let result = keyed_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::NotExpired.into())); }) @@ -494,7 +486,7 @@ mod test { let result = keyed_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -518,7 +510,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let mut signers = HashSet::new(); @@ -527,7 +519,7 @@ mod test { let result = nonce_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Ok(())); }); @@ -552,13 +544,13 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let result = nonce_account.advance_nonce_account( &recent_blockhashes, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }); @@ -592,7 +584,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -631,7 +623,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }) @@ -661,7 +653,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -691,7 +683,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -711,7 +703,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -741,7 +733,7 @@ mod test { &authority, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -765,7 +757,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -791,7 +783,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -819,7 +811,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { @@ -832,7 +824,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::NotExpired.into())); }) @@ -854,7 +846,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { @@ -868,7 +860,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -890,7 +882,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { @@ -904,7 +896,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -926,7 +918,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); with_test_keyed_account(55, false, |to_keyed| { @@ -940,7 +932,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -967,7 +959,7 @@ mod test { &authority, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); let data = nonce::state::Data { authority, @@ -998,7 +990,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into())); }) @@ -1019,7 +1011,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let recent_blockhashes = create_test_recent_blockhashes(0); @@ -1027,7 +1019,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -1047,7 +1039,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -1070,7 +1062,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let authority = Pubkey::default(); @@ -1082,7 +1074,7 @@ mod test { let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Ok(())); let state = AccountUtilsState::::state(nonce_account) @@ -1105,7 +1097,7 @@ mod test { let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -1128,13 +1120,13 @@ mod test { &authorized, &recent_blockhashes, &rent, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); }) @@ -1155,7 +1147,7 @@ mod test { &authorized, &recent_blockhashes, &Rent::free(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); assert!(verify_nonce_account( @@ -1190,7 +1182,7 @@ mod test { &authorized, &recent_blockhashes, &Rent::free(), - &mut MockInvokeContext::new(&[]), + &MockInvokeContext::new(&[]), ) .unwrap(); assert!(!verify_nonce_account( From 071c541ab75b394b792232fe9de011d6d754342e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 5 Apr 2021 14:28:40 +0200 Subject: [PATCH 19/33] Removes the "keyed_accounts" parameter from all "process_instruction" functions. --- program-test/src/lib.rs | 7 +-- programs/bpf_loader/src/lib.rs | 67 ++------------------- programs/budget/src/budget_processor.rs | 3 - programs/config/src/config_processor.rs | 22 +------ programs/exchange/src/exchange_processor.rs | 3 - programs/failure/src/lib.rs | 4 +- programs/noop/src/lib.rs | 5 +- programs/ownable/src/ownable_processor.rs | 3 - programs/secp256k1/src/lib.rs | 4 +- programs/stake/src/stake_instruction.rs | 18 +----- programs/vest/src/vest_processor.rs | 3 - programs/vote/src/vote_instruction.rs | 11 +--- runtime/benches/bank.rs | 2 - runtime/src/bank.rs | 34 ++--------- runtime/src/builtins.rs | 13 +--- runtime/src/message_processor.rs | 46 ++------------ runtime/src/native_loader.rs | 52 ++++++++-------- runtime/src/system_instruction_processor.rs | 4 -- sdk/src/entrypoint_native.rs | 7 +-- sdk/src/process_instruction.rs | 3 +- 20 files changed, 53 insertions(+), 258 deletions(-) diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index aafdb52daab92c..d39749c507d4ae 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -25,7 +25,6 @@ use { hash::Hash, instruction::Instruction, instruction::InstructionError, - keyed_account::KeyedAccount, message::Message, native_token::sol_to_lamports, process_instruction::{ @@ -99,14 +98,12 @@ fn get_invoke_context<'a>() -> &'a mut dyn InvokeContext { pub fn builtin_process_instruction( process_instruction: solana_sdk::entrypoint::ProcessInstruction, program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], input: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { set_invoke_context(invoke_context); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(invoke_context.get_keyed_accounts(), keyed_accounts); + let keyed_accounts = invoke_context.get_keyed_accounts(); // Copy all the accounts into a HashMap to ensure there are no duplicates let mut accounts: HashMap = keyed_accounts @@ -175,13 +172,11 @@ macro_rules! processor { ($process_instruction:expr) => { Some( |program_id: &Pubkey, - keyed_accounts: &[solana_sdk::keyed_account::KeyedAccount], input: &[u8], invoke_context: &mut dyn solana_sdk::process_instruction::InvokeContext| { $crate::builtin_process_instruction( $process_instruction, program_id, - keyed_accounts, input, invoke_context, ) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 0551183d0ee684..e6c98d2e2b94fe 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -33,7 +33,7 @@ use solana_sdk::{ feature_set::{skip_ro_deserialization, upgradeable_close_instruction}, ic_logger_msg, ic_msg, instruction::InstructionError, - keyed_account::{from_keyed_account, keyed_account_at_index, KeyedAccount}, + keyed_account::{from_keyed_account, keyed_account_at_index}, loader_instruction::LoaderInstruction, loader_upgradeable_instruction::UpgradeableLoaderInstruction, process_instruction::{stable_log, ComputeMeter, Executor, InvokeContext}, @@ -158,7 +158,6 @@ pub fn create_vm<'a>( pub fn process_instruction( program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { @@ -167,7 +166,6 @@ pub fn process_instruction( pub fn process_instruction_jit( program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { @@ -860,6 +858,7 @@ mod tests { genesis_config::create_genesis_config, instruction::Instruction, instruction::{AccountMeta, InstructionError}, + keyed_account::KeyedAccount, message::Message, process_instruction::{BpfComputeBudget, MockComputeMeter, MockInvokeContext, MockLogger}, pubkey::Pubkey, @@ -932,7 +931,6 @@ mod tests { Err(InstructionError::NotEnoughAccountKeys), process_instruction( &bpf_loader::id(), - &[], &instruction_data, &mut MockInvokeContext::new(&[]) ) @@ -943,7 +941,6 @@ mod tests { Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader::id(), - &keyed_accounts, &instruction_data, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -957,7 +954,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader::id(), - &keyed_accounts, &instruction_data, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -975,7 +971,6 @@ mod tests { Err(InstructionError::AccountDataTooSmall), process_instruction( &bpf_loader::id(), - &keyed_accounts, &instruction_data, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1001,7 +996,6 @@ mod tests { Err(InstructionError::NotEnoughAccountKeys), process_instruction( &bpf_loader::id(), - &[], &instruction_data, &mut MockInvokeContext::new(&[]) ) @@ -1012,7 +1006,6 @@ mod tests { Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader::id(), - &keyed_accounts, &instruction_data, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1024,7 +1017,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader::id(), - &keyed_accounts, &instruction_data, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1040,7 +1032,6 @@ mod tests { Err(InstructionError::InvalidAccountData), process_instruction( &bpf_loader::id(), - &keyed_accounts, &instruction_data, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1065,7 +1056,7 @@ mod tests { // Case: Empty keyed accounts assert_eq!( Err(InstructionError::NotEnoughAccountKeys), - process_instruction(&program_id, &[], &[], &mut MockInvokeContext::new(&[])) + process_instruction(&program_id, &[], &mut MockInvokeContext::new(&[])) ); // Case: Only a program account @@ -1073,7 +1064,6 @@ mod tests { Ok(()), process_instruction( &program_key, - &keyed_accounts, &[], &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1085,7 +1075,6 @@ mod tests { Err(InstructionError::InvalidInstructionData), process_instruction( &program_id, - &keyed_accounts, &[], &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1099,7 +1088,6 @@ mod tests { Ok(()), process_instruction( &program_key, - &keyed_accounts, &[], &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1119,7 +1107,7 @@ mod tests { }; assert_eq!( Err(InstructionError::ProgramFailedToComplete), - process_instruction(&program_key, &keyed_accounts, &[], &mut invoke_context) + process_instruction(&program_key, &[], &mut invoke_context) ); // Case: With duplicate accounts @@ -1132,7 +1120,6 @@ mod tests { Ok(()), process_instruction( &program_key, - &keyed_accounts, &[], &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1160,7 +1147,6 @@ mod tests { Ok(()), process_instruction( &program_key, - &keyed_accounts, &[], &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1176,7 +1162,6 @@ mod tests { Ok(()), process_instruction( &program_key, - &keyed_accounts, &[], &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1204,7 +1189,6 @@ mod tests { Ok(()), process_instruction( &program_key, - &keyed_accounts, &[], &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1220,7 +1204,6 @@ mod tests { Ok(()), process_instruction( &program_key, - &keyed_accounts, &[], &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1253,7 +1236,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1275,7 +1257,6 @@ mod tests { Err(InstructionError::AccountAlreadyInitialized), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1312,7 +1293,6 @@ mod tests { Err(InstructionError::InvalidAccountData), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1338,7 +1318,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1381,7 +1360,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1419,7 +1397,6 @@ mod tests { Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1445,7 +1422,6 @@ mod tests { Err(InstructionError::AccountDataTooSmall), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1471,7 +1447,6 @@ mod tests { Err(InstructionError::AccountDataTooSmall), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1498,7 +1473,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -1525,7 +1499,6 @@ mod tests { Err(InstructionError::Immutable), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2302,7 +2275,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2365,7 +2337,6 @@ mod tests { Err(InstructionError::Immutable), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2400,7 +2371,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2434,7 +2404,6 @@ mod tests { Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2469,7 +2438,6 @@ mod tests { Err(InstructionError::AccountNotExecutable), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2504,7 +2472,6 @@ mod tests { Err(InstructionError::IncorrectProgramId), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2538,7 +2505,6 @@ mod tests { Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2576,7 +2542,6 @@ mod tests { Err(InstructionError::InvalidAccountData), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2611,7 +2576,6 @@ mod tests { Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2649,7 +2613,6 @@ mod tests { Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2694,7 +2657,6 @@ mod tests { Err(InstructionError::AccountDataTooSmall), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2735,7 +2697,6 @@ mod tests { Err(InstructionError::InvalidAccountData), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2769,7 +2730,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2809,7 +2769,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2856,7 +2815,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2905,7 +2863,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2939,7 +2896,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -2973,7 +2929,6 @@ mod tests { Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3005,7 +2960,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3032,7 +2986,6 @@ mod tests { Err(InstructionError::Immutable), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3058,7 +3011,6 @@ mod tests { Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3095,7 +3047,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3123,7 +3074,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3152,7 +3102,6 @@ mod tests { Err(InstructionError::MissingRequiredSignature), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3175,7 +3124,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3198,7 +3146,6 @@ mod tests { Err(InstructionError::Immutable), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3220,7 +3167,6 @@ mod tests { Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3241,7 +3187,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts) ) @@ -3278,7 +3223,6 @@ mod tests { Ok(()), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts), ) @@ -3308,7 +3252,6 @@ mod tests { Err(InstructionError::IncorrectAuthority), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts), ) @@ -3330,7 +3273,6 @@ mod tests { Err(InstructionError::InvalidArgument), process_instruction( &bpf_loader_upgradeable::id(), - &keyed_accounts, &instruction, &mut MockInvokeContext::new(&keyed_accounts), ) @@ -3391,7 +3333,6 @@ mod tests { let _result = process_instruction( &bpf_loader::id(), - &keyed_accounts, &[], &mut MockInvokeContext::new(&keyed_accounts), ); diff --git a/programs/budget/src/budget_processor.rs b/programs/budget/src/budget_processor.rs index f0d55cb2a5c684..940da7a8151a67 100644 --- a/programs/budget/src/budget_processor.rs +++ b/programs/budget/src/budget_processor.rs @@ -116,13 +116,10 @@ fn apply_account_data( pub fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); let instruction = limited_deserialize(data)?; diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index fa2d2737d9f4a1..0facda3e7032c9 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -6,7 +6,7 @@ use solana_sdk::{ account::{ReadableAccount, WritableAccount}, feature_set, ic_msg, instruction::InstructionError, - keyed_account::{keyed_account_at_index, KeyedAccount}, + keyed_account::keyed_account_at_index, process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey, @@ -14,13 +14,10 @@ use solana_sdk::{ pub fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); let key_list: ConfigKeys = limited_deserialize(data)?; let config_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; @@ -193,7 +190,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instructions[1].data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -228,7 +224,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -255,7 +250,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -278,7 +272,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -313,7 +306,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -347,7 +339,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -378,7 +369,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -394,7 +384,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -431,7 +420,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -451,7 +439,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -477,7 +464,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -500,7 +486,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -538,7 +523,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -557,7 +541,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -579,7 +562,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -598,7 +580,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instructions[1].data, &mut MockInvokeContext::new(&keyed_accounts) ), @@ -629,7 +610,6 @@ mod tests { assert_eq!( process_instruction( &id(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts), ), diff --git a/programs/exchange/src/exchange_processor.rs b/programs/exchange/src/exchange_processor.rs index 504adbff0a51d7..8ff11bb91a07b8 100644 --- a/programs/exchange/src/exchange_processor.rs +++ b/programs/exchange/src/exchange_processor.rs @@ -487,13 +487,10 @@ impl ExchangeProcessor { pub fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); solana_logger::setup(); match limited_deserialize::(data)? { diff --git a/programs/failure/src/lib.rs b/programs/failure/src/lib.rs index f55ae06f5df8c8..afebc3fed90715 100644 --- a/programs/failure/src/lib.rs +++ b/programs/failure/src/lib.rs @@ -1,6 +1,5 @@ use solana_sdk::{ - instruction::InstructionError, keyed_account::KeyedAccount, process_instruction::InvokeContext, - pubkey::Pubkey, + instruction::InstructionError, process_instruction::InvokeContext, pubkey::Pubkey, }; solana_sdk::declare_program!( @@ -11,7 +10,6 @@ solana_sdk::declare_program!( fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], _data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { diff --git a/programs/noop/src/lib.rs b/programs/noop/src/lib.rs index d5c6ccc37c6aca..3e4acad2dad746 100644 --- a/programs/noop/src/lib.rs +++ b/programs/noop/src/lib.rs @@ -1,7 +1,6 @@ use log::*; use solana_sdk::{ - instruction::InstructionError, keyed_account::KeyedAccount, process_instruction::InvokeContext, - pubkey::Pubkey, + instruction::InstructionError, process_instruction::InvokeContext, pubkey::Pubkey, }; solana_sdk::declare_program!( @@ -12,13 +11,11 @@ solana_sdk::declare_program!( pub fn process_instruction( program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { solana_logger::setup(); trace!("noop: program_id: {:?}", program_id); - trace!("noop: keyed_accounts: {:#?}", _keyed_accounts); trace!("noop: data: {:?}", data); Ok(()) } diff --git a/programs/ownable/src/ownable_processor.rs b/programs/ownable/src/ownable_processor.rs index 87a34aa39c9228..c111b66edb9e8c 100644 --- a/programs/ownable/src/ownable_processor.rs +++ b/programs/ownable/src/ownable_processor.rs @@ -30,13 +30,10 @@ fn set_owner( pub fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); let new_owner_pubkey: Pubkey = limited_deserialize(data)?; let account_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; diff --git a/programs/secp256k1/src/lib.rs b/programs/secp256k1/src/lib.rs index 9be513ea54e473..ebb29bd80153b4 100644 --- a/programs/secp256k1/src/lib.rs +++ b/programs/secp256k1/src/lib.rs @@ -1,11 +1,9 @@ use solana_sdk::{ - instruction::InstructionError, keyed_account::KeyedAccount, process_instruction::InvokeContext, - pubkey::Pubkey, + instruction::InstructionError, process_instruction::InvokeContext, pubkey::Pubkey, }; pub fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], _data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 7d685b01f5b006..7784345d08befd 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -10,7 +10,7 @@ use solana_sdk::{ decode_error::DecodeError, feature_set, instruction::{AccountMeta, Instruction, InstructionError}, - keyed_account::{from_keyed_account, get_signers, keyed_account_at_index, KeyedAccount}, + keyed_account::{from_keyed_account, get_signers, keyed_account_at_index}, process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey, @@ -483,13 +483,10 @@ pub fn set_lockup( pub fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); trace!("process_instruction: {:?}", data); trace!("keyed_accounts: {:?}", keyed_accounts); @@ -630,6 +627,7 @@ mod tests { use bincode::serialize; use solana_sdk::{ account::{self, Account, AccountSharedData}, + keyed_account::KeyedAccount, process_instruction::MockInvokeContext, rent::Rent, sysvar::stake_history::StakeHistory, @@ -714,7 +712,6 @@ mod tests { .collect(); super::process_instruction( &Pubkey::default(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts), ) @@ -925,7 +922,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &[], &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default() @@ -943,7 +939,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default() @@ -966,7 +961,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default() @@ -991,7 +985,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default() @@ -1009,7 +1002,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::DelegateStake).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ), @@ -1023,7 +1015,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::DelegateStake).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ), @@ -1056,7 +1047,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::DelegateStake).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ), @@ -1085,7 +1075,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::Withdraw(42)).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ), @@ -1099,7 +1088,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::Withdraw(42)).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ), @@ -1120,7 +1108,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::Deactivate).unwrap(), &mut MockInvokeContext::new(&keyed_accounts) ), @@ -1131,7 +1118,6 @@ mod tests { assert_eq!( super::process_instruction( &Pubkey::default(), - &keyed_accounts, &serialize(&StakeInstruction::Deactivate).unwrap(), &mut MockInvokeContext::new(&[]) ), diff --git a/programs/vest/src/vest_processor.rs b/programs/vest/src/vest_processor.rs index 44265ec39518bf..c4583954950e9b 100644 --- a/programs/vest/src/vest_processor.rs +++ b/programs/vest/src/vest_processor.rs @@ -59,13 +59,10 @@ fn verify_signed_account<'a>( pub fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); let contract_account = &mut keyed_account_at_index(keyed_accounts, 0)?.try_account_ref_mut()?; if invoke_context.is_feature_active(&feature_set::check_program_owner::id()) diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index 08ad32718d80f8..4c42083525303d 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -277,13 +277,10 @@ fn verify_rent_exemption( pub fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); trace!("process_instruction: {:?}", data); trace!("keyed_accounts: {:?}", keyed_accounts); @@ -356,12 +353,7 @@ mod tests { #[test] fn test_vote_process_instruction_decode_bail() { assert_eq!( - super::process_instruction( - &Pubkey::default(), - &[], - &[], - &mut MockInvokeContext::new(&[]) - ), + super::process_instruction(&Pubkey::default(), &[], &mut MockInvokeContext::new(&[])), Err(InstructionError::NotEnoughAccountKeys), ); } @@ -404,7 +396,6 @@ mod tests { .collect(); super::process_instruction( &Pubkey::default(), - &keyed_accounts, &instruction.data, &mut MockInvokeContext::new(&keyed_accounts), ) diff --git a/runtime/benches/bank.rs b/runtime/benches/bank.rs index 6fd9aa445bfd6e..e739050d0caeb9 100644 --- a/runtime/benches/bank.rs +++ b/runtime/benches/bank.rs @@ -11,7 +11,6 @@ use solana_sdk::{ clock::MAX_RECENT_BLOCKHASHES, genesis_config::create_genesis_config, instruction::InstructionError, - keyed_account::KeyedAccount, message::Message, process_instruction::InvokeContext, pubkey::Pubkey, @@ -34,7 +33,6 @@ const NOOP_PROGRAM_ID: [u8; 32] = [ #[allow(clippy::unnecessary_wraps)] fn process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], _data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 3cb0e8a349d7e5..eec2e9744921e0 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -208,7 +208,7 @@ impl AbiExample for Builtin { Self { name: String::default(), id: Pubkey::default(), - process_instruction_with_context: |_, _, _, _| Ok(()), + process_instruction_with_context: |_, _, _| Ok(()), } } } @@ -5071,7 +5071,6 @@ pub(crate) mod tests { feature::Feature, genesis_config::create_genesis_config, instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError}, - keyed_account::KeyedAccount, message::{Message, MessageHeader}, nonce, poh_config::PohConfig, @@ -5430,13 +5429,10 @@ pub(crate) mod tests { fn mock_process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockInstruction::Deduction => { @@ -9010,13 +9006,9 @@ pub(crate) mod tests { } fn mock_vote_processor( program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], _instruction_data: &[u8], - invoke_context: &mut dyn InvokeContext, + _invoke_context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); if mock_vote_program_id() != *program_id { return Err(InstructionError::IncorrectProgramId); } @@ -9071,7 +9063,6 @@ pub(crate) mod tests { fn mock_vote_processor( _pubkey: &Pubkey, - _ka: &[KeyedAccount], _data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { @@ -9122,7 +9113,6 @@ pub(crate) mod tests { fn mock_ix_processor( _pubkey: &Pubkey, - _ka: &[KeyedAccount], _data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { @@ -9856,13 +9846,10 @@ pub(crate) mod tests { fn mock_process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); let lamports = data[0] as u64; { let mut to_account = keyed_accounts[1].try_account_ref_mut()?; @@ -9913,12 +9900,9 @@ pub(crate) mod tests { #[allow(clippy::unnecessary_wraps)] fn mock_process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], _data: &[u8], - invoke_context: &mut dyn InvokeContext, + _invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(invoke_context.get_keyed_accounts(), _keyed_accounts); Ok(()) } @@ -10102,7 +10086,6 @@ pub(crate) mod tests { #[allow(clippy::unnecessary_wraps)] fn mock_ok_vote_processor( _pubkey: &Pubkey, - _ka: &[KeyedAccount], _data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { @@ -10353,13 +10336,10 @@ pub(crate) mod tests { fn test_same_program_id_uses_unqiue_executable_accounts() { fn nested_processor( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], _data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); assert_eq!(42, keyed_accounts[0].lamports().unwrap()); let mut account = keyed_accounts[0].try_account_ref_mut()?; account.lamports += 1; @@ -10636,7 +10616,6 @@ pub(crate) mod tests { #[allow(clippy::unnecessary_wraps)] fn mock_ix_processor( _pubkey: &Pubkey, - _ka: &[KeyedAccount], _data: &[u8], _invoke_context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { @@ -10682,7 +10661,6 @@ pub(crate) mod tests { #[allow(clippy::unnecessary_wraps)] fn mock_ix_processor( _pubkey: &Pubkey, - _ka: &[KeyedAccount], _data: &[u8], _context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { @@ -12415,12 +12393,12 @@ pub(crate) mod tests { fn mock_ix_processor( _pubkey: &Pubkey, - ka: &[KeyedAccount], _data: &[u8], - _invoke_context: &mut dyn InvokeContext, + invoke_context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { use solana_sdk::account::WritableAccount; - let mut data = ka[1].try_account_ref_mut()?; + let keyed_accounts = invoke_context.get_keyed_accounts(); + let mut data = keyed_accounts[1].try_account_ref_mut()?; data.data_as_mut_slice()[0] = 5; Ok(()) } diff --git a/runtime/src/builtins.rs b/runtime/src/builtins.rs index b7917e20894472..899ad9a04e98c0 100644 --- a/runtime/src/builtins.rs +++ b/runtime/src/builtins.rs @@ -5,7 +5,6 @@ use crate::{ use solana_sdk::{ feature_set, instruction::InstructionError, - keyed_account::KeyedAccount, process_instruction::{stable_log, InvokeContext, ProcessInstructionWithContext}, pubkey::Pubkey, system_program, @@ -14,17 +13,13 @@ use solana_sdk::{ fn process_instruction_with_program_logging( process_instruction: ProcessInstructionWithContext, program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); - let logger = invoke_context.get_logger(); stable_log::program_invoke(&logger, program_id, invoke_context.invoke_depth()); - let result = process_instruction(program_id, keyed_accounts, instruction_data, invoke_context); + let result = process_instruction(program_id, instruction_data, invoke_context); match &result { Ok(()) => stable_log::program_success(&logger, program_id), @@ -35,14 +30,10 @@ fn process_instruction_with_program_logging( macro_rules! with_program_logging { ($process_instruction:expr) => { - |program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], - instruction_data: &[u8], - invoke_context: &mut dyn InvokeContext| { + |program_id: &Pubkey, instruction_data: &[u8], invoke_context: &mut dyn InvokeContext| { process_instruction_with_program_logging( $process_instruction, program_id, - keyed_accounts, instruction_data, invoke_context, ) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index d60606acde75f8..ee4ed0cf3a5887 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -489,7 +489,6 @@ impl std::fmt::Debug for MessageProcessor { // These are just type aliases for work around of Debug-ing above pointers type ErasedProcessInstructionWithContext = fn( &'static Pubkey, - &'static [KeyedAccount<'static>], &'static [u8], &'static mut dyn InvokeContext, ) -> Result<(), InstructionError>; @@ -593,33 +592,22 @@ impl MessageProcessor { fn process_instruction( &self, program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); - if let Some(root_account) = keyed_accounts.iter().next() { + if let Some(root_account) = invoke_context.get_keyed_accounts().iter().next() { let root_id = root_account.unsigned_key(); if native_loader::check_id(&root_account.owner()?) { for (id, process_instruction) in &self.programs { if id == root_id { - // TODO [KeyedAccounts to InvokeContext refactoring] - // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); invoke_context.pop_first_keyed_account(); // Call the builtin program - return process_instruction( - &program_id, - &keyed_accounts[1..], - instruction_data, - invoke_context, - ); + return process_instruction(&program_id, instruction_data, invoke_context); } } // Call the program via the native loader return self.native_loader.process_instruction( &native_loader::id(), - keyed_accounts, instruction_data, invoke_context, ); @@ -628,12 +616,7 @@ impl MessageProcessor { for (id, process_instruction) in &self.programs { if id == owner_id { // Call the program via a builtin loader - return process_instruction( - &program_id, - keyed_accounts, - instruction_data, - invoke_context, - ); + return process_instruction(&program_id, instruction_data, invoke_context); } } } @@ -926,7 +909,6 @@ impl MessageProcessor { let mut result = message_processor.process_instruction( program_id, - &keyed_accounts, &instruction.data, invoke_context, ); @@ -1156,12 +1138,7 @@ impl MessageProcessor { account_db, ancestors, ); - self.process_instruction( - program_id, - &keyed_accounts, - &instruction.data, - &mut invoke_context, - )?; + self.process_instruction(program_id, &instruction.data, &mut invoke_context)?; Self::verify( message, instruction, @@ -1787,13 +1764,10 @@ mod tests { fn mock_system_process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockSystemInstruction::Correct => Ok(()), @@ -1943,13 +1917,10 @@ mod tests { fn mock_system_process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockSystemInstruction::BorrowFail => { @@ -2125,13 +2096,10 @@ mod tests { fn mock_process_instruction( program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); assert_eq!(*program_id, keyed_accounts[0].owner()?); assert_ne!( keyed_accounts[1].owner()?, @@ -2277,18 +2245,14 @@ mod tests { #[allow(clippy::unnecessary_wraps)] fn mock_process_instruction( _program_id: &Pubkey, - _keyed_accounts: &[KeyedAccount], _data: &[u8], - invoke_context: &mut dyn InvokeContext, + _invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, invoke_context.get_keyed_accounts()); Ok(()) } #[allow(clippy::unnecessary_wraps)] fn mock_ix_processor( _pubkey: &Pubkey, - _ka: &[KeyedAccount], _data: &[u8], _context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { diff --git a/runtime/src/native_loader.rs b/runtime/src/native_loader.rs index 6820a11a68b55f..5a7129c2380f0b 100644 --- a/runtime/src/native_loader.rs +++ b/runtime/src/native_loader.rs @@ -10,7 +10,7 @@ use solana_sdk::{ decode_error::DecodeError, entrypoint_native::ProgramEntrypoint, instruction::InstructionError, - keyed_account::{keyed_account_at_index, KeyedAccount}, + keyed_account::keyed_account_at_index, native_loader, process_instruction::{InvokeContext, LoaderEntrypoint}, pubkey::Pubkey, @@ -135,28 +135,28 @@ impl NativeLoader { pub fn process_instruction( &self, program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(keyed_accounts, invoke_context.get_keyed_accounts()); - let program = keyed_account_at_index(keyed_accounts, 0)?; - if native_loader::id() != *program_id { - error!("Program id mismatch"); - return Err(InstructionError::IncorrectProgramId); - } - if program.owner()? != *program_id { - error!("Executable account now owned by loader"); - return Err(InstructionError::IncorrectProgramId); - } + let (program_id, name_vec) = { + let keyed_accounts = invoke_context.get_keyed_accounts(); + let program = keyed_account_at_index(keyed_accounts, 0)?; + if native_loader::id() != *program_id { + error!("Program id mismatch"); + return Err(InstructionError::IncorrectProgramId); + } + if program.owner()? != *program_id { + error!("Executable account now owned by loader"); + return Err(InstructionError::IncorrectProgramId); + } + // TODO [KeyedAccounts to InvokeContext refactoring] + ( + *program.unsigned_key(), + &program.try_account_ref()?.data().clone(), + ) + }; - // TODO [KeyedAccounts to InvokeContext refactoring] - // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); - invoke_context.pop_first_keyed_account(); - let params = &keyed_accounts[1..]; - let account = &program.try_account_ref()?; - let name = match str::from_utf8(account.data()) { + let name = match str::from_utf8(name_vec) { Ok(v) => v, Err(e) => { error!("Invalid UTF-8 sequence: {}", e); @@ -168,21 +168,21 @@ impl NativeLoader { return Err(NativeLoaderError::InvalidAccountData.into()); } trace!("Call native {:?}", name); + invoke_context.pop_first_keyed_account(); if name.ends_with("loader_program") { let entrypoint = Self::get_entrypoint::(name, &self.loader_symbol_cache)?; + unsafe { entrypoint(&program_id, instruction_data, invoke_context) } + } else { + let entrypoint = + Self::get_entrypoint::(name, &self.program_symbol_cache)?; unsafe { entrypoint( - program.unsigned_key(), - params, + &program_id, + invoke_context.get_keyed_accounts(), instruction_data, - invoke_context, ) } - } else { - let entrypoint = - Self::get_entrypoint::(name, &self.program_symbol_cache)?; - unsafe { entrypoint(program.unsigned_key(), params, instruction_data) } } } } diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index 2c17ced1e0118f..97bea476716fec 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -255,13 +255,10 @@ fn transfer_with_seed( pub fn process_instruction( _owner: &Pubkey, - _keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let keyed_accounts = invoke_context.get_keyed_accounts(); - // TODO [KeyedAccounts to InvokeContext refactoring] - assert_eq!(_keyed_accounts, keyed_accounts); let instruction = limited_deserialize(instruction_data)?; trace!("process_instruction: {:?}", instruction); @@ -491,7 +488,6 @@ mod tests { ) -> Result<(), InstructionError> { super::process_instruction( owner, - keyed_accounts, instruction_data, &mut MockInvokeContext::new(keyed_accounts), ) diff --git a/sdk/src/entrypoint_native.rs b/sdk/src/entrypoint_native.rs index 6e49d59f38e49d..ecbff8a6ad734b 100644 --- a/sdk/src/entrypoint_native.rs +++ b/sdk/src/entrypoint_native.rs @@ -89,14 +89,12 @@ macro_rules! declare_name { /// use solana_sdk::{ /// declare_program, /// instruction::InstructionError, -/// keyed_account::KeyedAccount, /// process_instruction::InvokeContext, /// pubkey::Pubkey, /// }; /// /// fn my_process_instruction( /// program_id: &Pubkey, -/// keyed_accounts: &[KeyedAccount], /// instruction_data: &[u8], /// invoke_context: &mut dyn InvokeContext, /// ) -> Result<(), InstructionError> { @@ -124,14 +122,12 @@ macro_rules! declare_name { /// use solana_sdk::{ /// declare_program, /// instruction::InstructionError, -/// keyed_account::KeyedAccount, /// process_instruction::InvokeContext, /// pubkey::Pubkey, /// }; /// /// fn my_process_instruction( /// program_id: &Pubkey, -/// keyed_accounts: &[KeyedAccount], /// instruction_data: &[u8], /// invoke_context: &mut dyn InvokeContext, /// ) -> Result<(), InstructionError> { @@ -158,11 +154,10 @@ macro_rules! declare_program( #[no_mangle] pub extern "C" fn $name( program_id: &$crate::pubkey::Pubkey, - keyed_accounts: &[$crate::keyed_account::KeyedAccount], instruction_data: &[u8], invoke_context: &mut dyn $crate::process_instruction::InvokeContext, ) -> Result<(), $crate::instruction::InstructionError> { - $entrypoint(program_id, keyed_accounts, instruction_data, invoke_context) + $entrypoint(program_id, instruction_data, invoke_context) } ) ); diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 21dfad4db54cbd..258fb8bc92fe12 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -15,13 +15,12 @@ use std::{cell::RefCell, fmt::Debug, rc::Rc, sync::Arc}; /// invoke_context: Invocation context pub type LoaderEntrypoint = unsafe extern "C" fn( program_id: &Pubkey, - keyed_accounts: &[KeyedAccount], instruction_data: &[u8], invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError>; pub type ProcessInstructionWithContext = - fn(&Pubkey, &[KeyedAccount], &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>; + fn(&Pubkey, &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>; /// Invocation context passed to loaders pub trait InvokeContext { From 20596f45f356d66bcc85a49eee92389e3faef9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 13 Apr 2021 11:31:28 +0200 Subject: [PATCH 20/33] Fixes test of process_cross_program_instruction() to include keyed_accounts. --- runtime/src/message_processor.rs | 78 +++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index ee4ed0cf3a5887..608d4b34cec604 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -2128,7 +2128,6 @@ mod tests { let mut program_account = AccountSharedData::new(1, 0, &native_loader::id()); program_account.executable = true; - let executable_preaccount = PreAccount::new(&callee_program_id, &program_account); let executable_accounts = vec![( callee_program_id, Rc::new(RefCell::new(program_account.clone())), @@ -2136,11 +2135,9 @@ mod tests { let owned_key = solana_sdk::pubkey::new_rand(); let owned_account = AccountSharedData::new(42, 1, &callee_program_id); - let owned_preaccount = PreAccount::new(&owned_key, &owned_account); let not_owned_key = solana_sdk::pubkey::new_rand(); let not_owned_account = AccountSharedData::new(84, 1, &solana_sdk::pubkey::new_rand()); - let not_owned_preaccount = PreAccount::new(¬_owned_key, ¬_owned_account); #[allow(unused_mut)] let mut accounts = vec![ @@ -2148,20 +2145,40 @@ mod tests { Rc::new(RefCell::new(not_owned_account)), Rc::new(RefCell::new(program_account)), ]; + + let compiled_instruction = CompiledInstruction::new(2, &(), vec![0, 1, 2]); let programs: Vec<(_, ProcessInstructionWithContext)> = vec![(callee_program_id, mock_process_instruction)]; + let metas = vec![ + AccountMeta::new(owned_key, false), + AccountMeta::new(not_owned_key, false), + ]; + + let instruction = Instruction::new_with_bincode( + callee_program_id, + &MockInstruction::NoopSuccess, + metas.clone(), + ); + let message = Message::new(&[instruction], None); + + let pre_accounts = + MessageProcessor::create_pre_accounts(&message, &compiled_instruction, &accounts); + let demote_sysvar_write_locks = true; + let keyed_accounts = MessageProcessor::create_keyed_accounts( + &message, + &compiled_instruction, + &executable_accounts, + &accounts, + demote_sysvar_write_locks, + ); let ancestors = Ancestors::default(); let mut invoke_context = ThisInvokeContext::new( &caller_program_id, Rent::default(), - vec![ - owned_preaccount, - not_owned_preaccount, - executable_preaccount, - ], - &[], - &[], + pre_accounts, + &executable_accounts, &[], + keyed_accounts.as_slice(), programs.as_slice(), None, BpfComputeBudget::default(), @@ -2171,26 +2188,15 @@ mod tests { Arc::new(Accounts::default()), &ancestors, ); - let metas = vec![ - AccountMeta::new(owned_key, false), - AccountMeta::new(not_owned_key, false), - ]; // not owned account modified by the caller (before the invoke) - accounts[0].borrow_mut().data_as_mut_slice()[0] = 1; - let instruction = Instruction::new_with_bincode( - callee_program_id, - &MockInstruction::NoopSuccess, - metas.clone(), - ); - let demote_sysvar_write_locks = true; - let message = Message::new(&[instruction], None); let caller_write_privileges = message .account_keys .iter() .enumerate() .map(|(i, _)| message.is_writable(i, demote_sysvar_write_locks)) .collect::>(); + accounts[0].borrow_mut().data_as_mut_slice()[0] = 1; assert_eq!( MessageProcessor::process_cross_program_instruction( &message, @@ -2220,6 +2226,34 @@ mod tests { let instruction = Instruction::new_with_bincode(callee_program_id, &case.0, metas.clone()); let message = Message::new(&[instruction], None); + + let pre_accounts = + MessageProcessor::create_pre_accounts(&message, &compiled_instruction, &accounts); + let keyed_accounts = MessageProcessor::create_keyed_accounts( + &message, + &compiled_instruction, + &executable_accounts, + &accounts, + demote_sysvar_write_locks, + ); + let ancestors = Ancestors::default(); + let mut invoke_context = ThisInvokeContext::new( + &caller_program_id, + Rent::default(), + pre_accounts, + &executable_accounts, + &[], + keyed_accounts.as_slice(), + programs.as_slice(), + None, + BpfComputeBudget::default(), + Rc::new(RefCell::new(Executors::default())), + None, + Arc::new(FeatureSet::all_enabled()), + Arc::new(Accounts::default()), + &ancestors, + ); + let caller_write_privileges = message .account_keys .iter() From 9c9690840b5ee43a8c2e41b8d724fc7abbd8ffea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 31 Mar 2021 13:38:27 +0200 Subject: [PATCH 21/33] Moves InvokeContext::set_keyed_accounts() into push() and pop(). --- programs/bpf_loader/src/lib.rs | 2 -- runtime/src/message_processor.rs | 50 ++++++++++++++------------------ runtime/src/native_loader.rs | 4 ++- sdk/src/process_instruction.rs | 30 ++++++++++++------- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index e6c98d2e2b94fe..7a41b67f497539 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -747,8 +747,6 @@ impl Executor for BpfExecutor { let logger = invoke_context.get_logger(); let invoke_depth = invoke_context.invoke_depth(); - // TODO [KeyedAccounts to InvokeContext refactoring] - // invoke_context.set_keyed_accounts(&keyed_accounts[1..]); invoke_context.pop_first_keyed_account(); let mut serialize_time = Measure::start("serialize"); diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 608d4b34cec604..927918bd0b34c3 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -312,7 +312,11 @@ impl<'a> ThisInvokeContext<'a> { } } impl<'a> InvokeContext for ThisInvokeContext<'a> { - fn push(&mut self, key: &Pubkey) -> Result<(), InstructionError> { + fn push( + &mut self, + keyed_accounts: &[KeyedAccount], + key: &Pubkey, + ) -> Result<&[KeyedAccount], InstructionError> { if self.program_ids.len() > self.bpf_compute_budget.max_invoke_depth { return Err(InstructionError::CallDepth); } @@ -321,10 +325,13 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { return Err(InstructionError::ReentrancyNotAllowed); } self.program_ids.push(*key); - Ok(()) + let mut keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; + std::mem::swap(&mut self.keyed_accounts, &mut keyed_accounts); + Ok(keyed_accounts) } - fn pop(&mut self) { + fn pop(&mut self, keyed_accounts: &[KeyedAccount]) { self.program_ids.pop(); + self.keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; } fn invoke_depth(&self) -> usize { self.program_ids.len() @@ -356,10 +363,6 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .last() .ok_or(InstructionError::GenericError) } - // TODO [KeyedAccounts to InvokeContext refactoring] - fn set_keyed_accounts(&mut self, keyed_accounts: &[KeyedAccount]) { - self.keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; - } fn pop_first_keyed_account(&mut self) { self.keyed_accounts = &self.keyed_accounts[1..]; } @@ -889,18 +892,15 @@ impl MessageProcessor { accounts, demote_sysvar_write_locks, ); - // TODO [KeyedAccounts to InvokeContext refactoring] - let previous_keyed_accounts = { - let previous_keyed_accounts = invoke_context.get_keyed_accounts(); - ( - previous_keyed_accounts.as_ptr() as u64, - previous_keyed_accounts.len(), - ) - }; - invoke_context.set_keyed_accounts(&keyed_accounts); // Invoke callee - invoke_context.push(program_id)?; + let previous_keyed_accounts = invoke_context.push(&keyed_accounts, program_id)?; + + // Make Rust forget about lifetimes for a moment. + // Otherwise we can not keep this slice to restore it later, + // as it is also borrowed in invoke_context. + let previous_keyed_accounts = + unsafe { std::mem::transmute::<_, &[KeyedAccount]>(previous_keyed_accounts) }; let mut message_processor = MessageProcessor::default(); for (program_id, process_instruction) in invoke_context.get_programs().iter() { @@ -916,15 +916,9 @@ impl MessageProcessor { // Verify the called program has not misbehaved result = invoke_context.verify_and_update(message, instruction, accounts, None); } - invoke_context.pop(); - // TODO [KeyedAccounts to InvokeContext refactoring] - // invoke_context.set_keyed_accounts(previous_keyed_accounts); - invoke_context.set_keyed_accounts(unsafe { - std::slice::from_raw_parts( - previous_keyed_accounts.0 as *const _, - previous_keyed_accounts.1, - ) - }); + + // Restore previous state + invoke_context.pop(previous_keyed_accounts); result } else { // This function is always called with a valid instruction, if that changes return an error @@ -1258,7 +1252,7 @@ mod tests { // Check call depth increases and has a limit let mut depth_reached = 1; for program_id in program_ids.iter().skip(1) { - if Err(InstructionError::CallDepth) == invoke_context.push(program_id) { + if Err(InstructionError::CallDepth) == invoke_context.push(&[], program_id) { break; } depth_reached += 1; @@ -1324,7 +1318,7 @@ mod tests { ); accounts[not_owned_index].borrow_mut().data_as_mut_slice()[0] = data; - invoke_context.pop(); + invoke_context.pop(&[]); } } diff --git a/runtime/src/native_loader.rs b/runtime/src/native_loader.rs index 5a7129c2380f0b..8ab177180de0c6 100644 --- a/runtime/src/native_loader.rs +++ b/runtime/src/native_loader.rs @@ -149,7 +149,9 @@ impl NativeLoader { error!("Executable account now owned by loader"); return Err(InstructionError::IncorrectProgramId); } - // TODO [KeyedAccounts to InvokeContext refactoring] + // TODO: Remove these two copies (* deref is also a copy) + // Both could be avoided as we know that the first KeyedAccount + // still exists even after invoke_context.pop_first_keyed_account() is called ( *program.unsigned_key(), &program.try_account_ref()?.data().clone(), diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 258fb8bc92fe12..74dcbfbf85bacb 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -25,9 +25,16 @@ pub type ProcessInstructionWithContext = /// Invocation context passed to loaders pub trait InvokeContext { /// Push a program ID on to the invocation stack - fn push(&mut self, key: &Pubkey) -> Result<(), InstructionError>; + /// + /// It returns the keyed_accounts_to_restore + /// to be used in the matching pop call. + fn push( + &mut self, + keyed_accounts: &[KeyedAccount], + key: &Pubkey, + ) -> Result<&[KeyedAccount], InstructionError>; /// Pop a program ID off of the invocation stack - fn pop(&mut self); + fn pop(&mut self, keyed_accounts_to_restore: &[KeyedAccount]); /// Current depth of the invocation stake fn invoke_depth(&self) -> usize; /// Verify and update PreAccount state based on program execution @@ -40,8 +47,6 @@ pub trait InvokeContext { ) -> Result<(), InstructionError>; /// Get the program ID of the currently executing program fn get_caller(&self) -> Result<&Pubkey, InstructionError>; - /// Set the list of keyed accounts - fn set_keyed_accounts(&mut self, keyed_accounts: &[KeyedAccount]); /// Removes the first keyed account fn pop_first_keyed_account(&mut self); /// Get the list of keyed accounts @@ -309,12 +314,19 @@ impl<'a> MockInvokeContext<'a> { } } impl<'a> InvokeContext for MockInvokeContext<'a> { - fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> { + fn push( + &mut self, + keyed_accounts: &[KeyedAccount], + _key: &Pubkey, + ) -> Result<&[KeyedAccount], InstructionError> { self.invoke_depth = self.invoke_depth.saturating_add(1); - Ok(()) + let mut keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; + std::mem::swap(&mut self.keyed_accounts, &mut keyed_accounts); + Ok(keyed_accounts) } - fn pop(&mut self) { + fn pop(&mut self, keyed_accounts: &[KeyedAccount]) { self.invoke_depth = self.invoke_depth.saturating_sub(1); + self.keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; } fn invoke_depth(&self) -> usize { self.invoke_depth @@ -331,10 +343,6 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { fn get_caller(&self) -> Result<&Pubkey, InstructionError> { Ok(&self.key) } - // TODO [KeyedAccounts to InvokeContext refactoring] - fn set_keyed_accounts(&mut self, keyed_accounts: &[KeyedAccount]) { - self.keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; - } fn pop_first_keyed_account(&mut self) { self.keyed_accounts = &self.keyed_accounts[1..]; } From 08c39b98b0444df1599bb020a2ff5127e75ed945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 8 Mar 2021 18:55:52 +0100 Subject: [PATCH 22/33] Renames pop_first_keyed_account => remove_first_keyed_account --- programs/bpf_loader/src/lib.rs | 4 ++-- runtime/src/message_processor.rs | 4 ++-- runtime/src/native_loader.rs | 4 ++-- sdk/src/process_instruction.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 7a41b67f497539..fce5a9b761ce84 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -198,7 +198,7 @@ fn process_instruction_common( ic_logger_msg!(logger, "Wrong ProgramData account for this Program account"); return Err(InstructionError::InvalidArgument); } - invoke_context.pop_first_keyed_account(); + invoke_context.remove_first_keyed_account(); UpgradeableLoaderState::programdata_data_offset()? } else { ic_logger_msg!(logger, "Invalid Program account"); @@ -747,7 +747,7 @@ impl Executor for BpfExecutor { let logger = invoke_context.get_logger(); let invoke_depth = invoke_context.invoke_depth(); - invoke_context.pop_first_keyed_account(); + invoke_context.remove_first_keyed_account(); let mut serialize_time = Measure::start("serialize"); let keyed_accounts = invoke_context.get_keyed_accounts(); diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 927918bd0b34c3..e64024dbae1d72 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -363,7 +363,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .last() .ok_or(InstructionError::GenericError) } - fn pop_first_keyed_account(&mut self) { + fn remove_first_keyed_account(&mut self) { self.keyed_accounts = &self.keyed_accounts[1..]; } fn get_keyed_accounts(&self) -> &[KeyedAccount] { @@ -603,7 +603,7 @@ impl MessageProcessor { if native_loader::check_id(&root_account.owner()?) { for (id, process_instruction) in &self.programs { if id == root_id { - invoke_context.pop_first_keyed_account(); + invoke_context.remove_first_keyed_account(); // Call the builtin program return process_instruction(&program_id, instruction_data, invoke_context); } diff --git a/runtime/src/native_loader.rs b/runtime/src/native_loader.rs index 8ab177180de0c6..76ca151a247d30 100644 --- a/runtime/src/native_loader.rs +++ b/runtime/src/native_loader.rs @@ -151,7 +151,7 @@ impl NativeLoader { } // TODO: Remove these two copies (* deref is also a copy) // Both could be avoided as we know that the first KeyedAccount - // still exists even after invoke_context.pop_first_keyed_account() is called + // still exists even after invoke_context.remove_first_keyed_account() is called ( *program.unsigned_key(), &program.try_account_ref()?.data().clone(), @@ -170,7 +170,7 @@ impl NativeLoader { return Err(NativeLoaderError::InvalidAccountData.into()); } trace!("Call native {:?}", name); - invoke_context.pop_first_keyed_account(); + invoke_context.remove_first_keyed_account(); if name.ends_with("loader_program") { let entrypoint = Self::get_entrypoint::(name, &self.loader_symbol_cache)?; diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 74dcbfbf85bacb..2346c547bf7a10 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -48,7 +48,7 @@ pub trait InvokeContext { /// Get the program ID of the currently executing program fn get_caller(&self) -> Result<&Pubkey, InstructionError>; /// Removes the first keyed account - fn pop_first_keyed_account(&mut self); + fn remove_first_keyed_account(&mut self); /// Get the list of keyed accounts fn get_keyed_accounts(&self) -> &[KeyedAccount]; /// Get a list of built-in programs @@ -343,7 +343,7 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { fn get_caller(&self) -> Result<&Pubkey, InstructionError> { Ok(&self.key) } - fn pop_first_keyed_account(&mut self) { + fn remove_first_keyed_account(&mut self) { self.keyed_accounts = &self.keyed_accounts[1..]; } fn get_keyed_accounts(&self) -> &[KeyedAccount] { From bdf27efdadddada7100395ce2987d27cf8f9b777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 13 Apr 2021 16:01:24 +0200 Subject: [PATCH 23/33] Merges InvokeContext keyed_accounts and program_ids into invoke_stack. --- programs/bpf_loader/src/lib.rs | 4 +- runtime/src/message_processor.rs | 68 +++++++++++++++----------------- sdk/src/process_instruction.rs | 42 ++++++++++---------- 3 files changed, 54 insertions(+), 60 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index fce5a9b761ce84..10f51f2fe2fc4c 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -1093,14 +1093,12 @@ mod tests { // Case: limited budget let mut invoke_context = MockInvokeContext { - key: Pubkey::default(), + invoke_stack: vec![(Pubkey::default(), &keyed_accounts)], logger: MockLogger::default(), bpf_compute_budget: BpfComputeBudget::default(), compute_meter: MockComputeMeter::default(), - keyed_accounts: &keyed_accounts, programs: vec![], accounts: vec![], - invoke_depth: 0, sysvars: vec![], }; assert_eq!( diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index e64024dbae1d72..b37155a3d0090f 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -250,12 +250,11 @@ impl ComputeMeter for ThisComputeMeter { } } pub struct ThisInvokeContext<'a> { - program_ids: Vec, + invoke_stack: Vec<(Pubkey, &'a [KeyedAccount<'a>])>, rent: Rent, pre_accounts: Vec, executables: &'a [(Pubkey, Rc>)], account_deps: &'a [(Pubkey, Rc>)], - keyed_accounts: &'a [KeyedAccount<'a>], programs: &'a [(Pubkey, ProcessInstructionWithContext)], logger: Rc>, bpf_compute_budget: BpfComputeBudget, @@ -286,15 +285,14 @@ impl<'a> ThisInvokeContext<'a> { account_db: Arc, ancestors: &'a Ancestors, ) -> Self { - let mut program_ids = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); - program_ids.push(*program_id); + let mut invoke_stack = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); + invoke_stack.push((*program_id, keyed_accounts)); Self { - program_ids, + invoke_stack, rent, pre_accounts, executables, account_deps, - keyed_accounts, programs, logger: Rc::new(RefCell::new(ThisLogger { log_collector })), bpf_compute_budget, @@ -317,24 +315,23 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { keyed_accounts: &[KeyedAccount], key: &Pubkey, ) -> Result<&[KeyedAccount], InstructionError> { - if self.program_ids.len() > self.bpf_compute_budget.max_invoke_depth { + if self.invoke_stack.len() > self.bpf_compute_budget.max_invoke_depth { return Err(InstructionError::CallDepth); } - if self.program_ids.contains(key) && self.program_ids.last() != Some(key) { + let frame_index = self.invoke_stack.iter().position(|frame| frame.0 == *key); + if frame_index != None && frame_index != Some(self.invoke_stack.len() - 1) { // Reentrancy not allowed unless caller is calling itself return Err(InstructionError::ReentrancyNotAllowed); } - self.program_ids.push(*key); - let mut keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; - std::mem::swap(&mut self.keyed_accounts, &mut keyed_accounts); - Ok(keyed_accounts) + let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; + self.invoke_stack.push((*key, keyed_accounts)); + Ok(&self.invoke_stack[self.invoke_stack.len() - 2].1) } - fn pop(&mut self, keyed_accounts: &[KeyedAccount]) { - self.program_ids.pop(); - self.keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; + fn pop(&mut self) { + self.invoke_stack.pop(); } fn invoke_depth(&self) -> usize { - self.program_ids.len() + self.invoke_stack.len() } fn verify_and_update( &mut self, @@ -343,8 +340,8 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { accounts: &[Rc>], caller_write_privileges: Option<&[bool]>, ) -> Result<(), InstructionError> { - match self.program_ids.last() { - Some(program_id) => MessageProcessor::verify_and_update( + match self.invoke_stack.last() { + Some((program_id, _keyed_accounts)) => MessageProcessor::verify_and_update( message, instruction, &mut self.pre_accounts, @@ -359,15 +356,18 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { } } fn get_caller(&self) -> Result<&Pubkey, InstructionError> { - self.program_ids + self.invoke_stack .last() + .map(|frame| &frame.0) .ok_or(InstructionError::GenericError) } fn remove_first_keyed_account(&mut self) { - self.keyed_accounts = &self.keyed_accounts[1..]; + let index = self.invoke_stack.len() - 1; + let last_frame = &mut self.invoke_stack[index]; + last_frame.1 = &last_frame.1[1..]; } fn get_keyed_accounts(&self) -> &[KeyedAccount] { - self.keyed_accounts + &self.invoke_stack[self.invoke_stack.len() - 1].1 } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { self.programs @@ -894,13 +894,7 @@ impl MessageProcessor { ); // Invoke callee - let previous_keyed_accounts = invoke_context.push(&keyed_accounts, program_id)?; - - // Make Rust forget about lifetimes for a moment. - // Otherwise we can not keep this slice to restore it later, - // as it is also borrowed in invoke_context. - let previous_keyed_accounts = - unsafe { std::mem::transmute::<_, &[KeyedAccount]>(previous_keyed_accounts) }; + invoke_context.push(&keyed_accounts, program_id)?; let mut message_processor = MessageProcessor::default(); for (program_id, process_instruction) in invoke_context.get_programs().iter() { @@ -918,7 +912,7 @@ impl MessageProcessor { } // Restore previous state - invoke_context.pop(previous_keyed_accounts); + invoke_context.pop(); result } else { // This function is always called with a valid instruction, if that changes return an error @@ -1212,28 +1206,28 @@ mod tests { #[test] fn test_invoke_context() { const MAX_DEPTH: usize = 10; - let mut program_ids = vec![]; + let mut invoke_stack = vec![]; let mut keys = vec![]; let mut pre_accounts = vec![]; let mut accounts = vec![]; for i in 0..MAX_DEPTH { - program_ids.push(solana_sdk::pubkey::new_rand()); + invoke_stack.push(solana_sdk::pubkey::new_rand()); keys.push(solana_sdk::pubkey::new_rand()); accounts.push(Rc::new(RefCell::new(AccountSharedData::new( i as u64, 1, - &program_ids[i], + &invoke_stack[i], )))); pre_accounts.push(PreAccount::new(&keys[i], &accounts[i].borrow())) } let account = AccountSharedData::new(1, 1, &solana_sdk::pubkey::Pubkey::default()); - for program_id in program_ids.iter() { + for program_id in invoke_stack.iter() { pre_accounts.push(PreAccount::new(program_id, &account.clone())); } let ancestors = Ancestors::default(); let mut invoke_context = ThisInvokeContext::new( - &program_ids[0], + &invoke_stack[0], Rent::default(), pre_accounts, &[], @@ -1251,7 +1245,7 @@ mod tests { // Check call depth increases and has a limit let mut depth_reached = 1; - for program_id in program_ids.iter().skip(1) { + for program_id in invoke_stack.iter().skip(1) { if Err(InstructionError::CallDepth) == invoke_context.push(&[], program_id) { break; } @@ -1269,7 +1263,7 @@ mod tests { ]; let message = Message::new( &[Instruction::new_with_bytes( - program_ids[owned_index], + invoke_stack[owned_index], &[0], metas, )], @@ -1318,7 +1312,7 @@ mod tests { ); accounts[not_owned_index].borrow_mut().data_as_mut_slice()[0] = data; - invoke_context.pop(&[]); + invoke_context.pop(); } } diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 2346c547bf7a10..e8c619842d121d 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -34,7 +34,7 @@ pub trait InvokeContext { key: &Pubkey, ) -> Result<&[KeyedAccount], InstructionError>; /// Pop a program ID off of the invocation stack - fn pop(&mut self, keyed_accounts_to_restore: &[KeyedAccount]); + fn pop(&mut self); /// Current depth of the invocation stake fn invoke_depth(&self) -> usize; /// Verify and update PreAccount state based on program execution @@ -286,29 +286,28 @@ impl Logger for MockLogger { } pub struct MockInvokeContext<'a> { - pub key: Pubkey, + pub invoke_stack: Vec<(Pubkey, &'a [KeyedAccount<'a>])>, pub logger: MockLogger, pub bpf_compute_budget: BpfComputeBudget, pub compute_meter: MockComputeMeter, - pub keyed_accounts: &'a [KeyedAccount<'a>], pub programs: Vec<(Pubkey, ProcessInstructionWithContext)>, pub accounts: Vec<(Pubkey, Rc>)>, - pub invoke_depth: usize, pub sysvars: Vec<(Pubkey, Option>>)>, } impl<'a> MockInvokeContext<'a> { pub fn new(keyed_accounts: &'a [KeyedAccount<'a>]) -> Self { + let bpf_compute_budget = BpfComputeBudget::default(); + let mut invoke_stack = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); + invoke_stack.push((Pubkey::default(), keyed_accounts)); MockInvokeContext { - key: Pubkey::default(), + invoke_stack, logger: MockLogger::default(), - bpf_compute_budget: BpfComputeBudget::default(), + bpf_compute_budget, compute_meter: MockComputeMeter { remaining: std::i64::MAX as u64, }, - keyed_accounts, programs: vec![], accounts: vec![], - invoke_depth: 0, sysvars: vec![], } } @@ -317,19 +316,17 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { fn push( &mut self, keyed_accounts: &[KeyedAccount], - _key: &Pubkey, + key: &Pubkey, ) -> Result<&[KeyedAccount], InstructionError> { - self.invoke_depth = self.invoke_depth.saturating_add(1); - let mut keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; - std::mem::swap(&mut self.keyed_accounts, &mut keyed_accounts); - Ok(keyed_accounts) + let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; + self.invoke_stack.push((*key, keyed_accounts)); + Ok(&self.invoke_stack[self.invoke_stack.len() - 2].1) } - fn pop(&mut self, keyed_accounts: &[KeyedAccount]) { - self.invoke_depth = self.invoke_depth.saturating_sub(1); - self.keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; + fn pop(&mut self) { + self.invoke_stack.pop(); } fn invoke_depth(&self) -> usize { - self.invoke_depth + self.invoke_stack.len() } fn verify_and_update( &mut self, @@ -341,13 +338,18 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { Ok(()) } fn get_caller(&self) -> Result<&Pubkey, InstructionError> { - Ok(&self.key) + self.invoke_stack + .last() + .map(|frame| &frame.0) + .ok_or(InstructionError::GenericError) } fn remove_first_keyed_account(&mut self) { - self.keyed_accounts = &self.keyed_accounts[1..]; + let index = self.invoke_stack.len() - 1; + let last_frame = &mut self.invoke_stack[index]; + last_frame.1 = &last_frame.1[1..]; } fn get_keyed_accounts(&self) -> &[KeyedAccount] { - self.keyed_accounts + &self.invoke_stack[self.invoke_stack.len() - 1].1 } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { &self.programs From 05deb6d8e3209277a73b8b7d40e4d482e1d343d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 31 Mar 2021 13:45:51 +0200 Subject: [PATCH 24/33] Removes unprotected integer arithmetic. --- runtime/src/message_processor.rs | 51 +++++++++++++++++++------------- sdk/src/process_instruction.rs | 22 +++++++++----- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index b37155a3d0090f..7ccbfdbf5e8135 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -314,18 +314,18 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { &mut self, keyed_accounts: &[KeyedAccount], key: &Pubkey, - ) -> Result<&[KeyedAccount], InstructionError> { + ) -> Result<(), InstructionError> { if self.invoke_stack.len() > self.bpf_compute_budget.max_invoke_depth { return Err(InstructionError::CallDepth); } let frame_index = self.invoke_stack.iter().position(|frame| frame.0 == *key); - if frame_index != None && frame_index != Some(self.invoke_stack.len() - 1) { + if frame_index != None && frame_index != Some(self.invoke_stack.len().saturating_sub(1)) { // Reentrancy not allowed unless caller is calling itself return Err(InstructionError::ReentrancyNotAllowed); } let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; self.invoke_stack.push((*key, keyed_accounts)); - Ok(&self.invoke_stack[self.invoke_stack.len() - 2].1) + Ok(()) } fn pop(&mut self) { self.invoke_stack.pop(); @@ -340,20 +340,21 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { accounts: &[Rc>], caller_write_privileges: Option<&[bool]>, ) -> Result<(), InstructionError> { - match self.invoke_stack.last() { - Some((program_id, _keyed_accounts)) => MessageProcessor::verify_and_update( - message, - instruction, - &mut self.pre_accounts, - accounts, - program_id, - &self.rent, - caller_write_privileges, - &mut self.timings, - self.feature_set.is_active(&demote_sysvar_write_locks::id()), - ), - None => Err(InstructionError::GenericError), // Should never happen - } + let (program_id, _keyed_accounts) = self + .invoke_stack + .last() + .ok_or(InstructionError::GenericError)?; + MessageProcessor::verify_and_update( + message, + instruction, + &mut self.pre_accounts, + accounts, + program_id, + &self.rent, + caller_write_privileges, + &mut self.timings, + self.feature_set.is_active(&demote_sysvar_write_locks::id()), + ) } fn get_caller(&self) -> Result<&Pubkey, InstructionError> { self.invoke_stack @@ -362,12 +363,20 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .ok_or(InstructionError::GenericError) } fn remove_first_keyed_account(&mut self) { - let index = self.invoke_stack.len() - 1; - let last_frame = &mut self.invoke_stack[index]; - last_frame.1 = &last_frame.1[1..]; + let mut stack_frame = &mut self + .invoke_stack + .last_mut() + .ok_or(InstructionError::GenericError) + .unwrap(); + stack_frame.1 = &stack_frame.1[1..]; } fn get_keyed_accounts(&self) -> &[KeyedAccount] { - &self.invoke_stack[self.invoke_stack.len() - 1].1 + &self + .invoke_stack + .last() + .ok_or(InstructionError::GenericError) + .unwrap() + .1 } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { self.programs diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index e8c619842d121d..c36d02e8b31ace 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -32,7 +32,7 @@ pub trait InvokeContext { &mut self, keyed_accounts: &[KeyedAccount], key: &Pubkey, - ) -> Result<&[KeyedAccount], InstructionError>; + ) -> Result<(), InstructionError>; /// Pop a program ID off of the invocation stack fn pop(&mut self); /// Current depth of the invocation stake @@ -317,10 +317,10 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { &mut self, keyed_accounts: &[KeyedAccount], key: &Pubkey, - ) -> Result<&[KeyedAccount], InstructionError> { + ) -> Result<(), InstructionError> { let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; self.invoke_stack.push((*key, keyed_accounts)); - Ok(&self.invoke_stack[self.invoke_stack.len() - 2].1) + Ok(()) } fn pop(&mut self) { self.invoke_stack.pop(); @@ -344,12 +344,20 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { .ok_or(InstructionError::GenericError) } fn remove_first_keyed_account(&mut self) { - let index = self.invoke_stack.len() - 1; - let last_frame = &mut self.invoke_stack[index]; - last_frame.1 = &last_frame.1[1..]; + let mut stack_frame = &mut self + .invoke_stack + .last_mut() + .ok_or(InstructionError::GenericError) + .unwrap(); + stack_frame.1 = &stack_frame.1[1..]; } fn get_keyed_accounts(&self) -> &[KeyedAccount] { - &self.invoke_stack[self.invoke_stack.len() - 1].1 + &self + .invoke_stack + .last() + .ok_or(InstructionError::GenericError) + .unwrap() + .1 } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { &self.programs From 63ce1c79ef5a7ac7493d9f875cbaec7c0f1c0233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Thu, 18 Mar 2021 11:25:42 +0100 Subject: [PATCH 25/33] Replaces unwrap() by Result. --- program-test/src/lib.rs | 2 +- programs/bpf_loader/src/lib.rs | 26 ++++++++--------- programs/bpf_loader/src/syscalls.rs | 1 + programs/budget/src/budget_processor.rs | 2 +- programs/config/src/config_processor.rs | 2 +- programs/exchange/src/exchange_processor.rs | 2 +- programs/ownable/src/ownable_processor.rs | 2 +- programs/stake/src/stake_instruction.rs | 2 +- programs/vest/src/vest_processor.rs | 2 +- programs/vote/src/vote_instruction.rs | 2 +- runtime/src/bank.rs | 8 +++--- runtime/src/message_processor.rs | 32 ++++++++++----------- runtime/src/native_loader.rs | 6 ++-- runtime/src/system_instruction_processor.rs | 2 +- sdk/src/process_instruction.rs | 18 ++++++------ 15 files changed, 53 insertions(+), 56 deletions(-) diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index d39749c507d4ae..e0041c5815de83 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -103,7 +103,7 @@ pub fn builtin_process_instruction( ) -> Result<(), InstructionError> { set_invoke_context(invoke_context); - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; // Copy all the accounts into a HashMap to ensure there are no duplicates let mut accounts: HashMap = keyed_accounts diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 10f51f2fe2fc4c..4a382fbde23f4c 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -84,7 +84,7 @@ pub fn create_executor( enable_instruction_tracing: log_enabled!(Trace), }; let mut executable = { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let program = keyed_account_at_index(keyed_accounts, program_account_index)?; let account = program.try_account_ref()?; let data = &account.data()[program_data_offset..]; @@ -114,7 +114,7 @@ fn write_program_data( bytes: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let program = keyed_account_at_index(keyed_accounts, program_account_index)?; let mut account = program.try_account_ref_mut()?; let data = &mut account.data_as_mut_slice(); @@ -179,7 +179,7 @@ fn process_instruction_common( use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); - 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, 0)?; if first_account.executable()? { @@ -198,7 +198,7 @@ fn process_instruction_common( ic_logger_msg!(logger, "Wrong ProgramData account for this Program account"); return Err(InstructionError::InvalidArgument); } - invoke_context.remove_first_keyed_account(); + invoke_context.remove_first_keyed_account()?; UpgradeableLoaderState::programdata_data_offset()? } else { ic_logger_msg!(logger, "Invalid Program account"); @@ -208,7 +208,7 @@ fn process_instruction_common( 0 }; - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let program = keyed_account_at_index(keyed_accounts, 0)?; let loader_id = &program.owner()?; @@ -259,7 +259,7 @@ fn process_loader_upgradeable_instruction( use_jit: bool, ) -> Result<(), InstructionError> { let logger = invoke_context.get_logger(); - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; match limited_deserialize(instruction_data)? { UpgradeableLoaderInstruction::InitializeBuffer => { @@ -400,7 +400,7 @@ fn process_loader_upgradeable_instruction( let executor = create_executor(3, buffer_data_offset, invoke_context, use_jit)?; invoke_context.add_executor(program_id, executor); - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let payer = keyed_account_at_index(keyed_accounts, 0)?; let programdata = keyed_account_at_index(keyed_accounts, 1)?; let program = keyed_account_at_index(keyed_accounts, 2)?; @@ -524,7 +524,7 @@ fn process_loader_upgradeable_instruction( // Load and verify the program bits let executor = create_executor(2, buffer_data_offset, invoke_context, use_jit)?; - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let program = keyed_account_at_index(keyed_accounts, 1)?; invoke_context.add_executor(program.unsigned_key(), executor); @@ -664,7 +664,7 @@ fn process_loader_instruction( invoke_context: &mut dyn InvokeContext, use_jit: bool, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let program = keyed_account_at_index(keyed_accounts, 0)?; if program.owner()? != *program_id { ic_msg!( @@ -688,7 +688,7 @@ fn process_loader_instruction( } let executor = create_executor(0, 0, invoke_context, use_jit)?; - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let program = keyed_account_at_index(keyed_accounts, 0)?; invoke_context.add_executor(program.unsigned_key(), executor); program.try_account_ref_mut()?.executable = true; @@ -747,10 +747,10 @@ impl Executor for BpfExecutor { let logger = invoke_context.get_logger(); let invoke_depth = invoke_context.invoke_depth(); - invoke_context.remove_first_keyed_account(); + invoke_context.remove_first_keyed_account()?; let mut serialize_time = Measure::start("serialize"); - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let mut parameter_bytes = serialize_parameters(loader_id, program_id, keyed_accounts, &instruction_data)?; serialize_time.stop(); @@ -821,7 +821,7 @@ impl Executor for BpfExecutor { execute_time.stop(); } let mut deserialize_time = Measure::start("deserialize"); - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; deserialize_parameters( loader_id, keyed_accounts, diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 1da864363993c7..90811a5fd9e6fa 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -1766,6 +1766,7 @@ fn call<'a>( )?; let keyed_account_refs = invoke_context .get_keyed_accounts() + .map_err(SyscallError::InstructionError)? .iter() .collect::>(); let (message, callee_program_id, callee_program_id_index) = diff --git a/programs/budget/src/budget_processor.rs b/programs/budget/src/budget_processor.rs index 940da7a8151a67..5e68cc4687e061 100644 --- a/programs/budget/src/budget_processor.rs +++ b/programs/budget/src/budget_processor.rs @@ -119,7 +119,7 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let instruction = limited_deserialize(data)?; diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index 0facda3e7032c9..5c98d6735ad407 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -17,7 +17,7 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let key_list: ConfigKeys = limited_deserialize(data)?; let config_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; diff --git a/programs/exchange/src/exchange_processor.rs b/programs/exchange/src/exchange_processor.rs index 8ff11bb91a07b8..f2a36630b57812 100644 --- a/programs/exchange/src/exchange_processor.rs +++ b/programs/exchange/src/exchange_processor.rs @@ -490,7 +490,7 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; solana_logger::setup(); match limited_deserialize::(data)? { diff --git a/programs/ownable/src/ownable_processor.rs b/programs/ownable/src/ownable_processor.rs index c111b66edb9e8c..d9532922cada79 100644 --- a/programs/ownable/src/ownable_processor.rs +++ b/programs/ownable/src/ownable_processor.rs @@ -33,7 +33,7 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let new_owner_pubkey: Pubkey = limited_deserialize(data)?; let account_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?; diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 7784345d08befd..8c043157cb1516 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -486,7 +486,7 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; trace!("process_instruction: {:?}", data); trace!("keyed_accounts: {:?}", keyed_accounts); diff --git a/programs/vest/src/vest_processor.rs b/programs/vest/src/vest_processor.rs index c4583954950e9b..6adc653652cd24 100644 --- a/programs/vest/src/vest_processor.rs +++ b/programs/vest/src/vest_processor.rs @@ -62,7 +62,7 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let contract_account = &mut keyed_account_at_index(keyed_accounts, 0)?.try_account_ref_mut()?; if invoke_context.is_feature_active(&feature_set::check_program_owner::id()) diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index 4c42083525303d..b890251defa527 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -280,7 +280,7 @@ pub fn process_instruction( data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; trace!("process_instruction: {:?}", data); trace!("keyed_accounts: {:?}", keyed_accounts); diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index eec2e9744921e0..0616d55b04ce56 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -5432,7 +5432,7 @@ pub(crate) mod tests { data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockInstruction::Deduction => { @@ -9849,7 +9849,7 @@ pub(crate) mod tests { data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let lamports = data[0] as u64; { let mut to_account = keyed_accounts[1].try_account_ref_mut()?; @@ -10339,7 +10339,7 @@ pub(crate) mod tests { _data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> result::Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; assert_eq!(42, keyed_accounts[0].lamports().unwrap()); let mut account = keyed_accounts[0].try_account_ref_mut()?; account.lamports += 1; @@ -12397,7 +12397,7 @@ pub(crate) mod tests { invoke_context: &mut dyn InvokeContext, ) -> std::result::Result<(), InstructionError> { use solana_sdk::account::WritableAccount; - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let mut data = keyed_accounts[1].try_account_ref_mut()?; data.data_as_mut_slice()[0] = 5; Ok(()) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 7ccbfdbf5e8135..7d75645cfd8106 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -362,21 +362,19 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .map(|frame| &frame.0) .ok_or(InstructionError::GenericError) } - fn remove_first_keyed_account(&mut self) { + fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> { let mut stack_frame = &mut self .invoke_stack .last_mut() - .ok_or(InstructionError::GenericError) - .unwrap(); + .ok_or(InstructionError::GenericError)?; stack_frame.1 = &stack_frame.1[1..]; + Ok(()) } - fn get_keyed_accounts(&self) -> &[KeyedAccount] { - &self - .invoke_stack + fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { + self.invoke_stack .last() + .map(|frame| frame.1) .ok_or(InstructionError::GenericError) - .unwrap() - .1 } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { self.programs @@ -607,12 +605,12 @@ impl MessageProcessor { instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - if let Some(root_account) = invoke_context.get_keyed_accounts().iter().next() { + if let Some(root_account) = invoke_context.get_keyed_accounts()?.iter().next() { let root_id = root_account.unsigned_key(); if native_loader::check_id(&root_account.owner()?) { for (id, process_instruction) in &self.programs { if id == root_id { - invoke_context.remove_first_keyed_account(); + invoke_context.remove_first_keyed_account()?; // Call the builtin program return process_instruction(&program_id, instruction_data, invoke_context); } @@ -733,14 +731,14 @@ impl MessageProcessor { let invoke_context = invoke_context.borrow(); // Translate and verify caller's data - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let keyed_accounts = keyed_account_indices .iter() .map(|index| keyed_account_at_index(keyed_accounts, *index)) .collect::, InstructionError>>()?; let (message, callee_program_id, _) = Self::create_message(&instruction, &keyed_accounts, &signers, &invoke_context)?; - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let mut caller_write_privileges = keyed_account_indices .iter() .map(|index| keyed_accounts[*index].is_writable()) @@ -748,7 +746,7 @@ impl MessageProcessor { caller_write_privileges.insert(0, false); let mut accounts = vec![]; let mut keyed_account_indices_reordered = vec![]; - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; 'root: for account_key in message.account_keys.iter() { for keyed_account_index in keyed_account_indices { let keyed_account = &keyed_accounts[*keyed_account_index]; @@ -838,7 +836,7 @@ impl MessageProcessor { { let invoke_context = invoke_context.borrow(); - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; for (src_keyed_account_index, (account, dst_keyed_account_index)) in accounts .iter() .zip(keyed_account_indices_reordered) @@ -1764,7 +1762,7 @@ mod tests { data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockSystemInstruction::Correct => Ok(()), @@ -1917,7 +1915,7 @@ mod tests { data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; if let Ok(instruction) = bincode::deserialize(data) { match instruction { MockSystemInstruction::BorrowFail => { @@ -2096,7 +2094,7 @@ mod tests { data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; assert_eq!(*program_id, keyed_accounts[0].owner()?); assert_ne!( keyed_accounts[1].owner()?, diff --git a/runtime/src/native_loader.rs b/runtime/src/native_loader.rs index 76ca151a247d30..9b810ef9d8da1d 100644 --- a/runtime/src/native_loader.rs +++ b/runtime/src/native_loader.rs @@ -139,7 +139,7 @@ impl NativeLoader { invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { let (program_id, name_vec) = { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let program = keyed_account_at_index(keyed_accounts, 0)?; if native_loader::id() != *program_id { error!("Program id mismatch"); @@ -170,7 +170,7 @@ impl NativeLoader { return Err(NativeLoaderError::InvalidAccountData.into()); } trace!("Call native {:?}", name); - invoke_context.remove_first_keyed_account(); + invoke_context.remove_first_keyed_account()?; if name.ends_with("loader_program") { let entrypoint = Self::get_entrypoint::(name, &self.loader_symbol_cache)?; @@ -181,7 +181,7 @@ impl NativeLoader { unsafe { entrypoint( &program_id, - invoke_context.get_keyed_accounts(), + invoke_context.get_keyed_accounts()?, instruction_data, ) } diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index 97bea476716fec..f59244f43094ca 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -258,7 +258,7 @@ pub fn process_instruction( instruction_data: &[u8], invoke_context: &mut dyn InvokeContext, ) -> Result<(), InstructionError> { - let keyed_accounts = invoke_context.get_keyed_accounts(); + let keyed_accounts = invoke_context.get_keyed_accounts()?; let instruction = limited_deserialize(instruction_data)?; trace!("process_instruction: {:?}", instruction); diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index c36d02e8b31ace..70267ada0e770b 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -48,9 +48,9 @@ pub trait InvokeContext { /// Get the program ID of the currently executing program fn get_caller(&self) -> Result<&Pubkey, InstructionError>; /// Removes the first keyed account - fn remove_first_keyed_account(&mut self); + fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError>; /// Get the list of keyed accounts - fn get_keyed_accounts(&self) -> &[KeyedAccount]; + fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError>; /// Get a list of built-in programs fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)]; /// Get this invocation's logger @@ -343,21 +343,19 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { .map(|frame| &frame.0) .ok_or(InstructionError::GenericError) } - fn remove_first_keyed_account(&mut self) { + fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> { let mut stack_frame = &mut self .invoke_stack .last_mut() - .ok_or(InstructionError::GenericError) - .unwrap(); + .ok_or(InstructionError::GenericError)?; stack_frame.1 = &stack_frame.1[1..]; + Ok(()) } - fn get_keyed_accounts(&self) -> &[KeyedAccount] { - &self - .invoke_stack + fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { + self.invoke_stack .last() + .map(|frame| frame.1) .ok_or(InstructionError::GenericError) - .unwrap() - .1 } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { &self.programs From fcbca01e868647ff6cb40f376de42ba975580e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 13 Apr 2021 16:02:15 +0200 Subject: [PATCH 26/33] Replaces tuple by struct. --- programs/bpf_loader/src/lib.rs | 38 ++++++++++++++++++-------------- runtime/src/message_processor.rs | 26 +++++++++++++--------- sdk/src/process_instruction.rs | 23 ++++++++++++++----- 3 files changed, 55 insertions(+), 32 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 4a382fbde23f4c..a454ff3a81ed20 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -858,7 +858,10 @@ mod tests { instruction::{AccountMeta, InstructionError}, keyed_account::KeyedAccount, message::Message, - process_instruction::{BpfComputeBudget, MockComputeMeter, MockInvokeContext, MockLogger}, + process_instruction::{ + BpfComputeBudget, InvokeContextStackFrame, MockComputeMeter, MockInvokeContext, + MockLogger, + }, pubkey::Pubkey, rent::Rent, signature::{Keypair, Signer}, @@ -1091,21 +1094,6 @@ mod tests { ) ); - // Case: limited budget - let mut invoke_context = MockInvokeContext { - invoke_stack: vec![(Pubkey::default(), &keyed_accounts)], - logger: MockLogger::default(), - bpf_compute_budget: BpfComputeBudget::default(), - compute_meter: MockComputeMeter::default(), - programs: vec![], - accounts: vec![], - sysvars: vec![], - }; - assert_eq!( - Err(InstructionError::ProgramFailedToComplete), - process_instruction(&program_key, &[], &mut invoke_context) - ); - // Case: With duplicate accounts let duplicate_key = solana_sdk::pubkey::new_rand(); let parameter_account = AccountSharedData::new_ref(1, 0, &program_id); @@ -1120,6 +1108,24 @@ mod tests { &mut MockInvokeContext::new(&keyed_accounts) ) ); + + // Case: limited budget + let mut invoke_context = MockInvokeContext { + invoke_stack: vec![InvokeContextStackFrame { + key: Pubkey::default(), + keyed_accounts, + }], + logger: MockLogger::default(), + bpf_compute_budget: BpfComputeBudget::default(), + compute_meter: MockComputeMeter::default(), + programs: vec![], + accounts: vec![], + sysvars: vec![], + }; + assert_eq!( + Err(InstructionError::ProgramFailedToComplete), + process_instruction(&program_key, &[], &mut invoke_context) + ); } #[test] diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 7d75645cfd8106..5338258c393b82 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -18,7 +18,7 @@ use solana_sdk::{ message::Message, native_loader, process_instruction::{ - BpfComputeBudget, ComputeMeter, Executor, InvokeContext, Logger, + BpfComputeBudget, ComputeMeter, Executor, InvokeContext, InvokeContextStackFrame, Logger, ProcessInstructionWithContext, }, pubkey::Pubkey, @@ -250,7 +250,7 @@ impl ComputeMeter for ThisComputeMeter { } } pub struct ThisInvokeContext<'a> { - invoke_stack: Vec<(Pubkey, &'a [KeyedAccount<'a>])>, + invoke_stack: Vec>, rent: Rent, pre_accounts: Vec, executables: &'a [(Pubkey, Rc>)], @@ -286,7 +286,10 @@ impl<'a> ThisInvokeContext<'a> { ancestors: &'a Ancestors, ) -> Self { let mut invoke_stack = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); - invoke_stack.push((*program_id, keyed_accounts)); + invoke_stack.push(InvokeContextStackFrame { + key: *program_id, + keyed_accounts, + }); Self { invoke_stack, rent, @@ -318,13 +321,16 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { if self.invoke_stack.len() > self.bpf_compute_budget.max_invoke_depth { return Err(InstructionError::CallDepth); } - let frame_index = self.invoke_stack.iter().position(|frame| frame.0 == *key); + let frame_index = self.invoke_stack.iter().position(|frame| frame.key == *key); if frame_index != None && frame_index != Some(self.invoke_stack.len().saturating_sub(1)) { // Reentrancy not allowed unless caller is calling itself return Err(InstructionError::ReentrancyNotAllowed); } let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; - self.invoke_stack.push((*key, keyed_accounts)); + self.invoke_stack.push(InvokeContextStackFrame { + key: *key, + keyed_accounts, + }); Ok(()) } fn pop(&mut self) { @@ -340,7 +346,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { accounts: &[Rc>], caller_write_privileges: Option<&[bool]>, ) -> Result<(), InstructionError> { - let (program_id, _keyed_accounts) = self + let stack_frame = self .invoke_stack .last() .ok_or(InstructionError::GenericError)?; @@ -349,7 +355,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { instruction, &mut self.pre_accounts, accounts, - program_id, + &stack_frame.key, &self.rent, caller_write_privileges, &mut self.timings, @@ -359,7 +365,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { fn get_caller(&self) -> Result<&Pubkey, InstructionError> { self.invoke_stack .last() - .map(|frame| &frame.0) + .map(|frame| &frame.key) .ok_or(InstructionError::GenericError) } fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> { @@ -367,13 +373,13 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .invoke_stack .last_mut() .ok_or(InstructionError::GenericError)?; - stack_frame.1 = &stack_frame.1[1..]; + stack_frame.keyed_accounts = &stack_frame.keyed_accounts[1..]; Ok(()) } fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { self.invoke_stack .last() - .map(|frame| frame.1) + .map(|frame| frame.keyed_accounts) .ok_or(InstructionError::GenericError) } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 70267ada0e770b..e09fe097adf254 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -22,6 +22,11 @@ pub type LoaderEntrypoint = unsafe extern "C" fn( pub type ProcessInstructionWithContext = fn(&Pubkey, &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>; +pub struct InvokeContextStackFrame<'a> { + pub key: Pubkey, + pub keyed_accounts: &'a [KeyedAccount<'a>], +} + /// Invocation context passed to loaders pub trait InvokeContext { /// Push a program ID on to the invocation stack @@ -286,7 +291,7 @@ impl Logger for MockLogger { } pub struct MockInvokeContext<'a> { - pub invoke_stack: Vec<(Pubkey, &'a [KeyedAccount<'a>])>, + pub invoke_stack: Vec>, pub logger: MockLogger, pub bpf_compute_budget: BpfComputeBudget, pub compute_meter: MockComputeMeter, @@ -298,7 +303,10 @@ impl<'a> MockInvokeContext<'a> { pub fn new(keyed_accounts: &'a [KeyedAccount<'a>]) -> Self { let bpf_compute_budget = BpfComputeBudget::default(); let mut invoke_stack = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); - invoke_stack.push((Pubkey::default(), keyed_accounts)); + invoke_stack.push(InvokeContextStackFrame { + key: Pubkey::default(), + keyed_accounts, + }); MockInvokeContext { invoke_stack, logger: MockLogger::default(), @@ -319,7 +327,10 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { key: &Pubkey, ) -> Result<(), InstructionError> { let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; - self.invoke_stack.push((*key, keyed_accounts)); + self.invoke_stack.push(InvokeContextStackFrame { + key: *key, + keyed_accounts, + }); Ok(()) } fn pop(&mut self) { @@ -340,7 +351,7 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { fn get_caller(&self) -> Result<&Pubkey, InstructionError> { self.invoke_stack .last() - .map(|frame| &frame.0) + .map(|frame| &frame.key) .ok_or(InstructionError::GenericError) } fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> { @@ -348,13 +359,13 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { .invoke_stack .last_mut() .ok_or(InstructionError::GenericError)?; - stack_frame.1 = &stack_frame.1[1..]; + stack_frame.keyed_accounts = &stack_frame.keyed_accounts[1..]; Ok(()) } fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { self.invoke_stack .last() - .map(|frame| frame.1) + .map(|frame| frame.keyed_accounts) .ok_or(InstructionError::GenericError) } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { From 45069ada00f9dac436d00580624ba9d562bc4735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 5 Apr 2021 16:15:12 +0200 Subject: [PATCH 27/33] Replaces slice reference by Vec. --- programs/bpf/benches/bpf_loader.rs | 7 +- programs/bpf/tests/programs.rs | 85 ++++---- programs/bpf_loader/src/lib.rs | 220 ++++++++++---------- programs/bpf_loader/src/syscalls.rs | 8 +- programs/config/src/config_processor.rs | 34 +-- programs/stake/src/stake_instruction.rs | 42 ++-- programs/stake/src/stake_state.rs | 18 +- programs/vote/src/vote_instruction.rs | 8 +- runtime/src/message_processor.rs | 22 +- runtime/src/system_instruction_processor.rs | 108 +++++----- sdk/src/keyed_account.rs | 2 +- sdk/src/nonce_keyed_account.rs | 94 +++++---- sdk/src/process_instruction.rs | 14 +- 13 files changed, 338 insertions(+), 324 deletions(-) diff --git a/programs/bpf/benches/bpf_loader.rs b/programs/bpf/benches/bpf_loader.rs index 021b95f6946935..2e3e7e0af8954f 100644 --- a/programs/bpf/benches/bpf_loader.rs +++ b/programs/bpf/benches/bpf_loader.rs @@ -91,7 +91,7 @@ fn bench_program_alu(bencher: &mut Bencher) { .unwrap(); inner_iter.write_u64::(0).unwrap(); let loader_id = bpf_loader::id(); - let mut invoke_context = MockInvokeContext::new(&[]); + let mut invoke_context = MockInvokeContext::new(vec![]); let elf = load_elf("bench_alu").unwrap(); let mut executable = @@ -208,14 +208,15 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) { .collect(); let instruction_data = vec![0u8]; - let mut invoke_context = MockInvokeContext::new(&keyed_accounts); + let mut invoke_context = MockInvokeContext::new(keyed_accounts); invoke_context.compute_meter.remaining = BUDGET; // Serialize account data + let keyed_accounts = invoke_context.get_keyed_accounts().unwrap(); let mut serialized = serialize_parameters( &bpf_loader::id(), &solana_sdk::pubkey::new_rand(), - &keyed_accounts, + keyed_accounts, &instruction_data, ) .unwrap(); diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index f193cf5f5052f0..406697ad19e636 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -179,7 +179,7 @@ fn upgrade_bpf_program( fn run_program( name: &str, program_id: &Pubkey, - parameter_accounts: &[KeyedAccount], + parameter_accounts: Vec, instruction_data: &[u8], ) -> Result { let path = create_bpf_path(name); @@ -188,14 +188,14 @@ fn run_program( let mut data = vec![]; file.read_to_end(&mut data).unwrap(); let loader_id = bpf_loader::id(); - let mut invoke_context = MockInvokeContext::new(parameter_accounts); let parameter_bytes = serialize_parameters( &bpf_loader::id(), program_id, - parameter_accounts, + ¶meter_accounts, &instruction_data, ) .unwrap(); + let mut invoke_context = MockInvokeContext::new(parameter_accounts); let compute_meter = invoke_context.get_compute_meter(); let mut instruction_meter = ThisInstructionMeter { compute_meter }; @@ -213,19 +213,46 @@ fn run_program( let mut tracer = None; for i in 0..2 { let mut parameter_bytes = parameter_bytes.clone(); - let mut vm = create_vm( - &loader_id, - executable.as_ref(), - &mut parameter_bytes, - &mut invoke_context, - ) - .unwrap(); - let result = if i == 0 { - vm.execute_program_interpreted(&mut instruction_meter) - } else { - vm.execute_program_jit(&mut instruction_meter) - }; - assert_eq!(SUCCESS, result.unwrap()); + { + let mut vm = create_vm( + &loader_id, + executable.as_ref(), + &mut parameter_bytes, + &mut invoke_context, + ) + .unwrap(); + let result = if i == 0 { + vm.execute_program_interpreted(&mut instruction_meter) + } else { + vm.execute_program_jit(&mut instruction_meter) + }; + assert_eq!(SUCCESS, result.unwrap()); + if i == 1 { + assert_eq!(instruction_count, vm.get_total_instruction_count()); + } + instruction_count = vm.get_total_instruction_count(); + if config.enable_instruction_tracing { + if i == 1 { + if !Tracer::compare(tracer.as_ref().unwrap(), vm.get_tracer()) { + let mut tracer_display = String::new(); + tracer + .as_ref() + .unwrap() + .write(&mut tracer_display, vm.get_program()) + .unwrap(); + println!("TRACE (interpreted): {}", tracer_display); + let mut tracer_display = String::new(); + vm.get_tracer() + .write(&mut tracer_display, vm.get_program()) + .unwrap(); + println!("TRACE (jit): {}", tracer_display); + assert!(false); + } + } + tracer = Some(vm.get_tracer().clone()); + } + } + let parameter_accounts = invoke_context.get_keyed_accounts().unwrap(); deserialize_parameters( &bpf_loader::id(), parameter_accounts, @@ -233,30 +260,6 @@ fn run_program( true, ) .unwrap(); - if i == 1 { - assert_eq!(instruction_count, vm.get_total_instruction_count()); - } - instruction_count = vm.get_total_instruction_count(); - if config.enable_instruction_tracing { - if i == 1 { - if !Tracer::compare(tracer.as_ref().unwrap(), vm.get_tracer()) { - let mut tracer_display = String::new(); - tracer - .as_ref() - .unwrap() - .write(&mut tracer_display, vm.get_program()) - .unwrap(); - println!("TRACE (interpreted): {}", tracer_display); - let mut tracer_display = String::new(); - vm.get_tracer() - .write(&mut tracer_display, vm.get_program()) - .unwrap(); - println!("TRACE (jit): {}", tracer_display); - assert!(false); - } - } - tracer = Some(vm.get_tracer().clone()); - } } Ok(instruction_count) @@ -1262,7 +1265,7 @@ fn assert_instruction_count() { let key = solana_sdk::pubkey::new_rand(); let mut account = RefCell::new(AccountSharedData::default()); let parameter_accounts = vec![KeyedAccount::new(&key, false, &mut account)]; - let count = run_program(program.0, &program_id, ¶meter_accounts[..], &[]).unwrap(); + let count = run_program(program.0, &program_id, parameter_accounts, &[]).unwrap(); let diff: i64 = count as i64 - program.1 as i64; println!(" {:30} {:8} {:6} {:+4}", program.0, program.1, count, diff); if count > program.1 { diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index a454ff3a81ed20..af0031429a85ea 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -933,7 +933,7 @@ mod tests { process_instruction( &bpf_loader::id(), &instruction_data, - &mut MockInvokeContext::new(&[]) + &mut MockInvokeContext::new(vec![]) ) ); @@ -943,7 +943,7 @@ mod tests { process_instruction( &bpf_loader::id(), &instruction_data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -951,14 +951,12 @@ mod tests { #[allow(unused_mut)] let mut keyed_accounts = vec![KeyedAccount::new(&program_key, true, &program_account)]; keyed_accounts[0].account.borrow_mut().set_data(vec![0; 6]); + let mut invoke_context = MockInvokeContext::new(keyed_accounts); assert_eq!( Ok(()), - process_instruction( - &bpf_loader::id(), - &instruction_data, - &mut MockInvokeContext::new(&keyed_accounts) - ) + process_instruction(&bpf_loader::id(), &instruction_data, &mut invoke_context) ); + let keyed_accounts = invoke_context.get_keyed_accounts().unwrap(); assert_eq!( &vec![0, 0, 0, 1, 2, 3], keyed_accounts[0].account.borrow().data() @@ -973,7 +971,7 @@ mod tests { process_instruction( &bpf_loader::id(), &instruction_data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); } @@ -998,7 +996,7 @@ mod tests { process_instruction( &bpf_loader::id(), &instruction_data, - &mut MockInvokeContext::new(&[]) + &mut MockInvokeContext::new(vec![]) ) ); @@ -1008,20 +1006,18 @@ mod tests { process_instruction( &bpf_loader::id(), &instruction_data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); // Case: Finalize let keyed_accounts = vec![KeyedAccount::new(&program_key, true, &program_account)]; + let mut invoke_context = MockInvokeContext::new(keyed_accounts); assert_eq!( Ok(()), - process_instruction( - &bpf_loader::id(), - &instruction_data, - &mut MockInvokeContext::new(&keyed_accounts) - ) + process_instruction(&bpf_loader::id(), &instruction_data, &mut invoke_context) ); + let keyed_accounts = invoke_context.get_keyed_accounts().unwrap(); assert!(keyed_accounts[0].account.borrow().executable); program_account.borrow_mut().executable = false; // Un-finalize the account @@ -1034,7 +1030,7 @@ mod tests { process_instruction( &bpf_loader::id(), &instruction_data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); } @@ -1057,7 +1053,7 @@ mod tests { // Case: Empty keyed accounts assert_eq!( Err(InstructionError::NotEnoughAccountKeys), - process_instruction(&program_id, &[], &mut MockInvokeContext::new(&[])) + process_instruction(&program_id, &[], &mut MockInvokeContext::new(vec![])) ); // Case: Only a program account @@ -1066,7 +1062,7 @@ mod tests { process_instruction( &program_key, &[], - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts.clone()) ) ); @@ -1077,7 +1073,7 @@ mod tests { process_instruction( &program_id, &[], - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts.clone()) ) ); keyed_accounts[0].account.borrow_mut().executable = true; @@ -1090,22 +1086,24 @@ mod tests { process_instruction( &program_key, &[], - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts.clone()) ) ); // Case: With duplicate accounts let duplicate_key = solana_sdk::pubkey::new_rand(); let parameter_account = AccountSharedData::new_ref(1, 0, &program_id); - let mut keyed_accounts = vec![KeyedAccount::new(&program_key, false, &program_account)]; - keyed_accounts.push(KeyedAccount::new(&duplicate_key, false, ¶meter_account)); - keyed_accounts.push(KeyedAccount::new(&duplicate_key, false, ¶meter_account)); + let keyed_accounts = vec![ + KeyedAccount::new(&program_key, false, &program_account), + KeyedAccount::new(&duplicate_key, false, ¶meter_account), + KeyedAccount::new(&duplicate_key, false, ¶meter_account), + ]; assert_eq!( Ok(()), process_instruction( &program_key, &[], - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts.clone()) ) ); @@ -1150,7 +1148,7 @@ mod tests { process_instruction( &program_key, &[], - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -1165,7 +1163,7 @@ mod tests { process_instruction( &program_key, &[], - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); } @@ -1192,7 +1190,7 @@ mod tests { process_instruction( &program_key, &[], - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -1207,7 +1205,7 @@ mod tests { process_instruction( &program_key, &[], - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); } @@ -1230,7 +1228,7 @@ mod tests { ); // Case: Success - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&authority_address, false, &authority_account), ]; @@ -1239,7 +1237,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -1251,7 +1249,7 @@ mod tests { ); // Case: Already initialized - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&authority_address, false, &authority_account), ]; @@ -1260,7 +1258,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -1287,7 +1285,7 @@ mod tests { bytes: vec![42; 9], }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&buffer_address, true, &buffer_account), ]; @@ -1296,7 +1294,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -1312,7 +1310,7 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&buffer_address, true, &buffer_account), ]; @@ -1321,7 +1319,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -1354,7 +1352,7 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&buffer_address, true, &buffer_account), ]; @@ -1363,7 +1361,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -1391,7 +1389,7 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&buffer_address, false, &buffer_account), ]; @@ -1400,7 +1398,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -1416,7 +1414,7 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&buffer_address, true, &buffer_account), ]; @@ -1425,7 +1423,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -1441,7 +1439,7 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&buffer_address, true, &buffer_account), ]; @@ -1450,7 +1448,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -1467,7 +1465,7 @@ mod tests { authority_address: Some(buffer_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&authority_address, true, &buffer_account), ]; @@ -1476,7 +1474,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -1493,7 +1491,7 @@ mod tests { authority_address: None, }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&authority_address, true, &buffer_account), ]; @@ -1502,7 +1500,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); } @@ -2260,7 +2258,7 @@ mod tests { min_program_balance, min_programdata_balance, ); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2278,7 +2276,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); assert_eq!(0, buffer_account.borrow().lamports); @@ -2322,7 +2320,7 @@ mod tests { upgrade_authority_address: None, }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2340,7 +2338,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2356,7 +2354,7 @@ mod tests { min_programdata_balance, ); let invalid_upgrade_authority_address = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2374,7 +2372,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2389,7 +2387,7 @@ mod tests { min_program_balance, min_programdata_balance, ); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2407,7 +2405,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2423,7 +2421,7 @@ mod tests { min_programdata_balance, ); program_account.borrow_mut().executable = false; - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2441,7 +2439,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2457,7 +2455,7 @@ mod tests { min_programdata_balance, ); program_account.borrow_mut().owner = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2475,7 +2473,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2490,7 +2488,7 @@ mod tests { min_program_balance, min_programdata_balance, ); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new_readonly(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2508,7 +2506,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2527,7 +2525,7 @@ mod tests { .borrow_mut() .set_state(&UpgradeableLoaderState::Uninitialized) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2545,7 +2543,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2561,7 +2559,7 @@ mod tests { min_programdata_balance, ); let invalid_programdata_address = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&invalid_programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2579,7 +2577,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2598,7 +2596,7 @@ mod tests { .borrow_mut() .set_state(&UpgradeableLoaderState::Uninitialized) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2616,7 +2614,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2642,7 +2640,7 @@ mod tests { authority_address: Some(upgrade_authority_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2660,7 +2658,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2682,7 +2680,7 @@ mod tests { }) .unwrap(); truncate_data(&mut buffer_account.borrow_mut(), 5); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2700,7 +2698,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2715,7 +2713,7 @@ mod tests { min_program_balance, min_programdata_balance, ); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2733,7 +2731,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2754,7 +2752,7 @@ mod tests { authority_address: None, }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2772,7 +2770,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2800,7 +2798,7 @@ mod tests { upgrade_authority_address: None, }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new(&program_address, false, &program_account), KeyedAccount::new(&buffer_address, false, &buffer_account), @@ -2818,7 +2816,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); } @@ -2848,7 +2846,7 @@ mod tests { upgrade_authority_address: Some(upgrade_authority_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new_readonly( &upgrade_authority_address, @@ -2866,7 +2864,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); let state: UpgradeableLoaderState = programdata_account.borrow().state().unwrap(); @@ -2886,7 +2884,7 @@ mod tests { upgrade_authority_address: Some(upgrade_authority_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new_readonly( &upgrade_authority_address, @@ -2899,7 +2897,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); let state: UpgradeableLoaderState = programdata_account.borrow().state().unwrap(); @@ -2919,7 +2917,7 @@ mod tests { upgrade_authority_address: Some(upgrade_authority_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new_readonly( &upgrade_authority_address, @@ -2932,7 +2930,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2945,7 +2943,7 @@ mod tests { }) .unwrap(); let invalid_upgrade_authority_address = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new_readonly( &invalid_upgrade_authority_address, @@ -2963,7 +2961,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -2976,7 +2974,7 @@ mod tests { }) .unwrap(); let invalid_upgrade_authority_address = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new_readonly( &invalid_upgrade_authority_address, @@ -2989,7 +2987,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -3001,7 +2999,7 @@ mod tests { }) .unwrap(); let invalid_upgrade_authority_address = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&programdata_address, false, &programdata_account), KeyedAccount::new_readonly( &invalid_upgrade_authority_address, @@ -3014,7 +3012,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); } @@ -3040,7 +3038,7 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new_readonly(&authority_address, true, &authority_account), KeyedAccount::new_readonly(&new_authority_address, false, &new_authority_account), @@ -3050,7 +3048,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -3068,7 +3066,7 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new_readonly(&authority_address, true, &authority_account), ]; @@ -3077,7 +3075,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap(); @@ -3095,7 +3093,7 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new_readonly(&authority_address, false, &authority_account), KeyedAccount::new_readonly(&new_authority_address, false, &new_authority_account), @@ -3105,7 +3103,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -3117,7 +3115,7 @@ mod tests { }) .unwrap(); let invalid_authority_address = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new_readonly(&invalid_authority_address, true, &authority_account), KeyedAccount::new_readonly(&new_authority_address, false, &new_authority_account), @@ -3127,7 +3125,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -3139,7 +3137,7 @@ mod tests { }) .unwrap(); let invalid_authority_address = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new_readonly(&invalid_authority_address, true, &authority_account), KeyedAccount::new_readonly(&new_authority_address, false, &new_authority_account), @@ -3149,7 +3147,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -3161,7 +3159,7 @@ mod tests { }) .unwrap(); let invalid_authority_address = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new_readonly(&invalid_authority_address, true, &authority_account), ]; @@ -3170,7 +3168,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); @@ -3181,7 +3179,7 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new_readonly(&authority_address, true, &authority_account), ]; @@ -3190,7 +3188,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ) ); } @@ -3216,7 +3214,7 @@ mod tests { authority_address: Some(authority_address), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&recipient_address, false, &recipient_account), KeyedAccount::new_readonly(&authority_address, true, &authority_account), @@ -3226,7 +3224,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts), + &mut MockInvokeContext::new(keyed_accounts), ) ); assert_eq!(0, buffer_account.borrow().lamports()); @@ -3245,7 +3243,7 @@ mod tests { }) .unwrap(); let incorrect_authority_address = Pubkey::new_unique(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&recipient_address, false, &recipient_account), KeyedAccount::new_readonly(&incorrect_authority_address, true, &authority_account), @@ -3255,7 +3253,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts), + &mut MockInvokeContext::new(keyed_accounts), ) ); @@ -3266,7 +3264,7 @@ mod tests { programdata_address: Pubkey::new_unique(), }) .unwrap(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&buffer_address, false, &buffer_account), KeyedAccount::new(&recipient_address, false, &recipient_account), KeyedAccount::new_readonly(&incorrect_authority_address, true, &authority_account), @@ -3276,7 +3274,7 @@ mod tests { process_instruction( &bpf_loader_upgradeable::id(), &instruction, - &mut MockInvokeContext::new(&keyed_accounts), + &mut MockInvokeContext::new(keyed_accounts), ) ); } @@ -3336,7 +3334,7 @@ mod tests { let _result = process_instruction( &bpf_loader::id(), &[], - &mut MockInvokeContext::new(&keyed_accounts), + &mut MockInvokeContext::new(keyed_accounts), ); }, ); diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 90811a5fd9e6fa..1900669cf47619 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -2671,7 +2671,7 @@ mod tests { leader_schedule_epoch: 4, unix_timestamp: 5, }; - let mut invoke_context = MockInvokeContext::new(&[]); + let mut invoke_context = MockInvokeContext::new(vec![]); let mut data = vec![]; bincode::serialize_into(&mut data, &src_clock).unwrap(); invoke_context @@ -2713,7 +2713,7 @@ mod tests { first_normal_epoch: 3, first_normal_slot: 4, }; - let mut invoke_context = MockInvokeContext::new(&[]); + let mut invoke_context = MockInvokeContext::new(vec![]); let mut data = vec![]; bincode::serialize_into(&mut data, &src_epochschedule).unwrap(); invoke_context @@ -2761,7 +2761,7 @@ mod tests { lamports_per_signature: 1, }, }; - let mut invoke_context = MockInvokeContext::new(&[]); + let mut invoke_context = MockInvokeContext::new(vec![]); let mut data = vec![]; bincode::serialize_into(&mut data, &src_fees).unwrap(); invoke_context @@ -2801,7 +2801,7 @@ mod tests { exemption_threshold: 2.0, burn_percent: 3, }; - let mut invoke_context = MockInvokeContext::new(&[]); + let mut invoke_context = MockInvokeContext::new(vec![]); let mut data = vec![]; bincode::serialize_into(&mut data, &src_rent).unwrap(); invoke_context diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index 5c98d6735ad407..a6bb4f6bd1bb0a 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -191,7 +191,7 @@ mod tests { process_instruction( &id(), &instructions[1].data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Ok(()) ); @@ -225,7 +225,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Ok(()) ); @@ -251,7 +251,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::InvalidInstructionData) ); @@ -273,7 +273,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -307,7 +307,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Ok(()) ); @@ -340,7 +340,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::InvalidAccountData) ); @@ -370,7 +370,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -385,7 +385,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -421,7 +421,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Ok(()) ); @@ -440,7 +440,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Ok(()) ); @@ -465,7 +465,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -487,7 +487,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -524,7 +524,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Ok(()) ); @@ -542,7 +542,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Ok(()) ); @@ -563,7 +563,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::MissingRequiredSignature) ); @@ -581,7 +581,7 @@ mod tests { process_instruction( &id(), &instructions[1].data, - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys) ); @@ -611,7 +611,7 @@ mod tests { process_instruction( &id(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts), + &mut MockInvokeContext::new(keyed_accounts), ), Err(InstructionError::InvalidAccountOwner) ); diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 8c043157cb1516..40a6ce2731e6ac 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -713,7 +713,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts), + &mut MockInvokeContext::new(keyed_accounts), ) } } @@ -927,7 +927,7 @@ mod tests { Lockup::default() )) .unwrap(), - &mut MockInvokeContext::new(&[]) + &mut MockInvokeContext::new(vec![]) ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -935,7 +935,7 @@ mod tests { // no account for rent let stake_address = Pubkey::default(); let stake_account = create_default_stake_account(); - let keyed_accounts = [KeyedAccount::new(&stake_address, false, &stake_account)]; + let keyed_accounts = vec![KeyedAccount::new(&stake_address, false, &stake_account)]; assert_eq!( super::process_instruction( &Pubkey::default(), @@ -944,7 +944,7 @@ mod tests { Lockup::default() )) .unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -954,7 +954,7 @@ mod tests { let stake_account = create_default_stake_account(); let rent_address = sysvar::rent::id(); let rent_account = create_default_account(); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&stake_address, false, &stake_account), KeyedAccount::new(&rent_address, false, &rent_account), ]; @@ -966,7 +966,7 @@ mod tests { Lockup::default() )) .unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::InvalidArgument), ); @@ -978,7 +978,7 @@ mod tests { let rent_account = RefCell::new(account::create_account_shared_data_for_test( &Rent::default(), )); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&stake_address, false, &stake_account), KeyedAccount::new(&rent_address, false, &rent_account), ]; @@ -990,7 +990,7 @@ mod tests { Lockup::default() )) .unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::InvalidAccountData), ); @@ -998,12 +998,12 @@ mod tests { // gets the first check in delegate, wrong number of accounts let stake_address = Pubkey::default(); let stake_account = create_default_stake_account(); - let keyed_accounts = [KeyedAccount::new(&stake_address, false, &stake_account)]; + let keyed_accounts = vec![KeyedAccount::new(&stake_address, false, &stake_account)]; assert_eq!( super::process_instruction( &Pubkey::default(), &serialize(&StakeInstruction::DelegateStake).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -1011,12 +1011,12 @@ mod tests { // gets the sub-check for number of args let stake_address = Pubkey::default(); let stake_account = create_default_stake_account(); - let keyed_accounts = [KeyedAccount::new(&stake_address, false, &stake_account)]; + let keyed_accounts = vec![KeyedAccount::new(&stake_address, false, &stake_account)]; assert_eq!( super::process_instruction( &Pubkey::default(), &serialize(&StakeInstruction::DelegateStake).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -1037,7 +1037,7 @@ mod tests { )); let config_address = config::id(); let config_account = RefCell::new(config::create_account(0, &config::Config::default())); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&stake_address, true, &stake_account), KeyedAccount::new(&vote_address, false, &bad_vote_account), KeyedAccount::new(&clock_address, false, &clock_account), @@ -1048,7 +1048,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &serialize(&StakeInstruction::DelegateStake).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::InvalidAccountData), ); @@ -1066,7 +1066,7 @@ mod tests { let stake_history_account = RefCell::new(account::create_account_shared_data_for_test( &StakeHistory::default(), )); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&stake_address, false, &stake_account), KeyedAccount::new(&vote_address, false, &vote_account), KeyedAccount::new(&rewards_address, false, &rewards_account), @@ -1076,7 +1076,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &serialize(&StakeInstruction::Withdraw(42)).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::InvalidArgument), ); @@ -1084,12 +1084,12 @@ mod tests { // Tests correct number of accounts are provided in withdraw let stake_address = Pubkey::default(); let stake_account = create_default_stake_account(); - let keyed_accounts = [KeyedAccount::new(&stake_address, false, &stake_account)]; + let keyed_accounts = vec![KeyedAccount::new(&stake_address, false, &stake_account)]; assert_eq!( super::process_instruction( &Pubkey::default(), &serialize(&StakeInstruction::Withdraw(42)).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -1101,7 +1101,7 @@ mod tests { let rewards_account = RefCell::new(account::create_account_shared_data_for_test( &sysvar::rewards::Rewards::new(0.0), )); - let keyed_accounts = [ + let keyed_accounts = vec![ KeyedAccount::new(&stake_address, false, &stake_account), KeyedAccount::new(&rewards_address, false, &rewards_account), ]; @@ -1109,7 +1109,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &serialize(&StakeInstruction::Deactivate).unwrap(), - &mut MockInvokeContext::new(&keyed_accounts) + &mut MockInvokeContext::new(keyed_accounts) ), Err(InstructionError::InvalidArgument), ); @@ -1119,7 +1119,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &serialize(&StakeInstruction::Deactivate).unwrap(), - &mut MockInvokeContext::new(&[]) + &mut MockInvokeContext::new(vec![]) ), Err(InstructionError::NotEnoughAccountKeys), ); diff --git a/programs/stake/src/stake_state.rs b/programs/stake/src/stake_state.rs index 8f6a6e90514cc4..6280848500482e 100644 --- a/programs/stake/src/stake_state.rs +++ b/programs/stake/src/stake_state.rs @@ -5105,7 +5105,7 @@ mod tests { let stake_lamports = 42; let signers = vec![authorized_pubkey].into_iter().collect(); - let invoke_context = MockInvokeContext::new(&[]); + let invoke_context = MockInvokeContext::new(vec![]); for state in &[ StakeState::Initialized(Meta::auto(&authorized_pubkey)), @@ -5213,7 +5213,7 @@ mod tests { #[test] fn test_merge_self_fails() { - let invoke_context = MockInvokeContext::new(&[]); + let invoke_context = MockInvokeContext::new(vec![]); let stake_address = Pubkey::new_unique(); let authority_pubkey = Pubkey::new_unique(); let signers = HashSet::from_iter(vec![authority_pubkey]); @@ -5265,7 +5265,7 @@ mod tests { let signers = vec![authorized_pubkey].into_iter().collect(); let wrong_signers = vec![wrong_authorized_pubkey].into_iter().collect(); - let invoke_context = MockInvokeContext::new(&[]); + let invoke_context = MockInvokeContext::new(vec![]); for state in &[ StakeState::Initialized(Meta::auto(&authorized_pubkey)), @@ -5332,7 +5332,7 @@ mod tests { let authorized_pubkey = solana_sdk::pubkey::new_rand(); let stake_lamports = 42; let signers = vec![authorized_pubkey].into_iter().collect(); - let invoke_context = MockInvokeContext::new(&[]); + let invoke_context = MockInvokeContext::new(vec![]); for state in &[ StakeState::Uninitialized, @@ -5410,7 +5410,7 @@ mod tests { .expect("source_stake_account"); let source_stake_keyed_account = KeyedAccount::new(&source_stake_pubkey, true, &source_stake_account); - let invoke_context = MockInvokeContext::new(&[]); + let invoke_context = MockInvokeContext::new(vec![]); assert_eq!( stake_keyed_account.merge( @@ -5479,7 +5479,7 @@ mod tests { let mut clock = Clock::default(); let mut stake_history = StakeHistory::default(); - let invoke_context = MockInvokeContext::new(&[]); + let invoke_context = MockInvokeContext::new(vec![]); clock.epoch = 0; let mut effective = base_lamports; @@ -6153,7 +6153,7 @@ mod tests { ..Delegation::default() }, }; - let invoke_context = MockInvokeContext::new(&[]); + let invoke_context = MockInvokeContext::new(vec![]); let identical = good_stake; assert!( @@ -6334,7 +6334,7 @@ mod tests { let stake_keyed_account = KeyedAccount::new(&authority_pubkey, true, &stake_account); let mut clock = Clock::default(); let mut stake_history = StakeHistory::default(); - let invoke_context = MockInvokeContext::new(&[]); + let invoke_context = MockInvokeContext::new(vec![]); // Uninitialized state fails assert_eq!( @@ -6561,7 +6561,7 @@ mod tests { let inactive = MergeKind::Inactive(Meta::default(), lamports); let activation_epoch = MergeKind::ActivationEpoch(meta, stake); let fully_active = MergeKind::FullyActive(meta, stake); - let invoke_context = MockInvokeContext::new(&[]); + let invoke_context = MockInvokeContext::new(vec![]); assert_eq!( inactive diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index b890251defa527..92ce7d98121083 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -353,7 +353,11 @@ mod tests { #[test] fn test_vote_process_instruction_decode_bail() { assert_eq!( - super::process_instruction(&Pubkey::default(), &[], &mut MockInvokeContext::new(&[])), + super::process_instruction( + &Pubkey::default(), + &[], + &mut MockInvokeContext::new(vec![]) + ), Err(InstructionError::NotEnoughAccountKeys), ); } @@ -397,7 +401,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &instruction.data, - &mut MockInvokeContext::new(&keyed_accounts), + &mut MockInvokeContext::new(keyed_accounts), ) } } diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 5338258c393b82..7b67e77ca28799 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -275,7 +275,7 @@ impl<'a> ThisInvokeContext<'a> { pre_accounts: Vec, executables: &'a [(Pubkey, Rc>)], account_deps: &'a [(Pubkey, Rc>)], - keyed_accounts: &'a [KeyedAccount<'a>], + keyed_accounts: Vec>, programs: &'a [(Pubkey, ProcessInstructionWithContext)], log_collector: Option>, bpf_compute_budget: BpfComputeBudget, @@ -315,7 +315,7 @@ impl<'a> ThisInvokeContext<'a> { impl<'a> InvokeContext for ThisInvokeContext<'a> { fn push( &mut self, - keyed_accounts: &[KeyedAccount], + keyed_accounts: Vec, key: &Pubkey, ) -> Result<(), InstructionError> { if self.invoke_stack.len() > self.bpf_compute_budget.max_invoke_depth { @@ -369,17 +369,17 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .ok_or(InstructionError::GenericError) } fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> { - let mut stack_frame = &mut self + let stack_frame = &mut self .invoke_stack .last_mut() .ok_or(InstructionError::GenericError)?; - stack_frame.keyed_accounts = &stack_frame.keyed_accounts[1..]; + stack_frame.keyed_accounts.remove(0); Ok(()) } fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { self.invoke_stack .last() - .map(|frame| frame.keyed_accounts) + .map(|frame| frame.keyed_accounts.as_slice()) .ok_or(InstructionError::GenericError) } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { @@ -907,7 +907,7 @@ impl MessageProcessor { ); // Invoke callee - invoke_context.push(&keyed_accounts, program_id)?; + invoke_context.push(keyed_accounts, program_id)?; let mut message_processor = MessageProcessor::default(); for (program_id, process_instruction) in invoke_context.get_programs().iter() { @@ -1129,7 +1129,7 @@ impl MessageProcessor { pre_accounts, executable_accounts, account_deps, - keyed_accounts.as_slice(), + keyed_accounts, &self.programs, log_collector, bpf_compute_budget, @@ -1245,7 +1245,7 @@ mod tests { pre_accounts, &[], &[], - &[], + vec![], &[], None, BpfComputeBudget::default(), @@ -1259,7 +1259,7 @@ mod tests { // Check call depth increases and has a limit let mut depth_reached = 1; for program_id in invoke_stack.iter().skip(1) { - if Err(InstructionError::CallDepth) == invoke_context.push(&[], program_id) { + if Err(InstructionError::CallDepth) == invoke_context.push(vec![], program_id) { break; } depth_reached += 1; @@ -2179,7 +2179,7 @@ mod tests { pre_accounts, &executable_accounts, &[], - keyed_accounts.as_slice(), + keyed_accounts, programs.as_slice(), None, BpfComputeBudget::default(), @@ -2244,7 +2244,7 @@ mod tests { pre_accounts, &executable_accounts, &[], - keyed_accounts.as_slice(), + keyed_accounts, programs.as_slice(), None, BpfComputeBudget::default(), diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index f59244f43094ca..1a91b2837b0db6 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -483,7 +483,7 @@ mod tests { fn process_instruction( owner: &Pubkey, - keyed_accounts: &[KeyedAccount], + keyed_accounts: Vec, instruction_data: &[u8], ) -> Result<(), InstructionError> { super::process_instruction( @@ -522,7 +522,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new(&from, true, &from_account), KeyedAccount::new(&to, true, &to_account) ], @@ -554,7 +554,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new(&from, true, &from_account), KeyedAccount::new(&to, false, &to_account) ], @@ -590,7 +590,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new(&from, true, &from_account), KeyedAccount::new(&to, false, &to_account), KeyedAccount::new(&base, true, &base_account) @@ -623,7 +623,7 @@ mod tests { Address::create( &to, Some((&from, seed, &owner)), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ), Err(SystemError::AddressWithSeedMismatch.into()) ); @@ -641,7 +641,7 @@ mod tests { let to_address = Address::create( &to, Some((&from, seed, &new_owner)), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); @@ -654,7 +654,7 @@ mod tests { 2, &new_owner, &HashSet::new(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ), Err(InstructionError::MissingRequiredSignature) ); @@ -681,7 +681,7 @@ mod tests { 2, &new_owner, &[to].iter().cloned().collect::>(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ), Ok(()) ); @@ -713,7 +713,7 @@ mod tests { 2, &new_owner, &[from, to].iter().cloned().collect::>(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(SystemError::ResultWithNegativeLamports.into())); } @@ -737,7 +737,7 @@ mod tests { MAX_PERMITTED_DATA_LENGTH + 1, &system_program::id(), &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert!(result.is_err()); assert_eq!( @@ -754,7 +754,7 @@ mod tests { MAX_PERMITTED_DATA_LENGTH, &system_program::id(), &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert!(result.is_ok()); assert_eq!(to_account.borrow().lamports, 50); @@ -787,7 +787,7 @@ mod tests { 2, &new_owner, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); @@ -806,7 +806,7 @@ mod tests { 2, &new_owner, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); let from_lamports = from_account.borrow().lamports; @@ -824,7 +824,7 @@ mod tests { 2, &new_owner, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); assert_eq!(from_lamports, 100); @@ -852,7 +852,7 @@ mod tests { 2, &new_owner, &[owned_key].iter().cloned().collect::>(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); @@ -866,7 +866,7 @@ mod tests { 2, &new_owner, &[from].iter().cloned().collect::>(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); @@ -880,7 +880,7 @@ mod tests { 2, &new_owner, &[owned_key].iter().cloned().collect::>(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Ok(())); } @@ -906,7 +906,7 @@ mod tests { 2, &sysvar::id(), &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(SystemError::InvalidProgramId.into())); @@ -940,7 +940,7 @@ mod tests { 2, &new_owner, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(SystemError::AccountAlreadyInUse.into())); } @@ -974,7 +974,7 @@ mod tests { 0, &solana_sdk::pubkey::new_rand(), &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ), Err(InstructionError::InvalidArgument), ); @@ -993,7 +993,7 @@ mod tests { &pubkey.into(), &new_owner, &HashSet::new(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ), Err(InstructionError::MissingRequiredSignature) ); @@ -1004,7 +1004,7 @@ mod tests { &pubkey.into(), &system_program::id(), &HashSet::new(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ), Ok(()) ); @@ -1013,7 +1013,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[KeyedAccount::new(&pubkey, true, &account)], + vec![KeyedAccount::new(&pubkey, true, &account)], &bincode::serialize(&SystemInstruction::Assign { owner: new_owner }).unwrap() ), Ok(()) @@ -1033,7 +1033,7 @@ mod tests { &from.into(), &new_owner, &[from].iter().cloned().collect::>(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ), Err(SystemError::InvalidProgramId.into()) ); @@ -1046,7 +1046,7 @@ mod tests { owner: solana_sdk::pubkey::new_rand(), }; let data = serialize(&instruction).unwrap(); - let result = process_instruction(&system_program::id(), &[], &data); + let result = process_instruction(&system_program::id(), vec![], &data); assert_eq!(result, Err(InstructionError::NotEnoughAccountKeys)); let from = solana_sdk::pubkey::new_rand(); @@ -1056,7 +1056,7 @@ mod tests { let data = serialize(&instruction).unwrap(); let result = process_instruction( &system_program::id(), - &[KeyedAccount::new(&from, true, &from_account)], + vec![KeyedAccount::new(&from, true, &from_account)], &data, ); assert_eq!(result, Err(InstructionError::NotEnoughAccountKeys)); @@ -1074,7 +1074,7 @@ mod tests { &from_keyed_account, &to_keyed_account, 50, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let from_lamports = from_keyed_account.account.borrow().lamports; @@ -1088,7 +1088,7 @@ mod tests { &from_keyed_account, &to_keyed_account, 100, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(SystemError::ResultWithNegativeLamports.into())); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1101,7 +1101,7 @@ mod tests { &from_keyed_account, &to_keyed_account, 0, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .is_ok(),); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1128,7 +1128,7 @@ mod tests { &from_owner, &to_keyed_account, 50, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let from_lamports = from_keyed_account.account.borrow().lamports; @@ -1145,7 +1145,7 @@ mod tests { &from_owner, &to_keyed_account, 100, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(SystemError::ResultWithNegativeLamports.into())); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1160,7 +1160,7 @@ mod tests { &from_owner, &to_keyed_account, 0, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .is_ok(),); assert_eq!(from_keyed_account.account.borrow().lamports, 50); @@ -1191,7 +1191,7 @@ mod tests { &KeyedAccount::new(&from, true, &from_account), &KeyedAccount::new(&to, false, &to_account), 50, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ), Err(InstructionError::InvalidArgument), ) @@ -1398,7 +1398,7 @@ mod tests { .zip(accounts.iter()) .map(|(meta, account)| KeyedAccount::new(&meta.pubkey, meta.is_signer, account)) .collect(); - process_instruction(&Pubkey::default(), &keyed_accounts, &instruction.data) + process_instruction(&Pubkey::default(), keyed_accounts, &instruction.data) } } @@ -1418,7 +1418,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[], + vec![], &serialize(&SystemInstruction::AdvanceNonceAccount).unwrap() ), Err(InstructionError::NotEnoughAccountKeys), @@ -1430,11 +1430,11 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[KeyedAccount::new( + vec![KeyedAccount::new( &Pubkey::default(), true, &create_default_account(), - ),], + )], &serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), @@ -1446,7 +1446,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new(&Pubkey::default(), true, &create_default_account()), KeyedAccount::new( &sysvar::recent_blockhashes::id(), @@ -1465,7 +1465,7 @@ mod tests { let nonce_acc = nonce_account::create_account(1_000_000); process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new(&Pubkey::default(), true, &nonce_acc), KeyedAccount::new( &sysvar::recent_blockhashes::id(), @@ -1493,7 +1493,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new(&Pubkey::default(), true, &nonce_acc,), KeyedAccount::new( &sysvar::recent_blockhashes::id(), @@ -1525,7 +1525,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[], + vec![], &serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), @@ -1537,11 +1537,11 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[KeyedAccount::new( + vec![KeyedAccount::new( &Pubkey::default(), true, &create_default_account() - ),], + )], &serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), @@ -1553,7 +1553,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new(&Pubkey::default(), true, &create_default_account()), KeyedAccount::new(&Pubkey::default(), false, &create_default_account()), KeyedAccount::new( @@ -1573,7 +1573,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new( &Pubkey::default(), true, @@ -1598,7 +1598,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new( &Pubkey::default(), true, @@ -1623,7 +1623,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[], + vec![], &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), @@ -1635,11 +1635,11 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[KeyedAccount::new( + vec![KeyedAccount::new( &Pubkey::default(), true, &nonce_account::create_account(1_000_000), - ),], + )], &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), @@ -1651,7 +1651,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new( &Pubkey::default(), true, @@ -1674,7 +1674,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new( &Pubkey::default(), true, @@ -1698,7 +1698,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new( &Pubkey::default(), true, @@ -1722,7 +1722,7 @@ mod tests { let nonce_acc = nonce_account::create_account(1_000_000); process_instruction( &Pubkey::default(), - &[ + vec![ KeyedAccount::new(&Pubkey::default(), true, &nonce_acc), KeyedAccount::new( &sysvar::recent_blockhashes::id(), @@ -1737,7 +1737,7 @@ mod tests { assert_eq!( process_instruction( &Pubkey::default(), - &[KeyedAccount::new(&Pubkey::default(), true, &nonce_acc,),], + vec![KeyedAccount::new(&Pubkey::default(), true, &nonce_acc,),], &serialize(&SystemInstruction::AuthorizeNonceAccount(Pubkey::default(),)).unwrap(), ), Ok(()), diff --git a/sdk/src/keyed_account.rs b/sdk/src/keyed_account.rs index 531b3bf8a9894a..e70a19f8123a11 100644 --- a/sdk/src/keyed_account.rs +++ b/sdk/src/keyed_account.rs @@ -10,7 +10,7 @@ use std::{ }; #[repr(C)] -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct KeyedAccount<'a> { is_signer: bool, // Transaction was signed by this account's key is_writable: bool, diff --git a/sdk/src/nonce_keyed_account.rs b/sdk/src/nonce_keyed_account.rs index bff9ccc77a6bba..30d14d2a1dbc28 100644 --- a/sdk/src/nonce_keyed_account.rs +++ b/sdk/src/nonce_keyed_account.rs @@ -300,7 +300,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let state = AccountUtilsState::::state(keyed_account) @@ -315,7 +315,11 @@ mod test { assert_eq!(state, State::Initialized(data.clone())); let recent_blockhashes = create_test_recent_blockhashes(63); keyed_account - .advance_nonce_account(&recent_blockhashes, &signers, &MockInvokeContext::new(&[])) + .advance_nonce_account( + &recent_blockhashes, + &signers, + &MockInvokeContext::new(vec![]), + ) .unwrap(); let state = AccountUtilsState::::state(keyed_account) .unwrap() @@ -329,7 +333,11 @@ mod test { assert_eq!(state, State::Initialized(data.clone())); let recent_blockhashes = create_test_recent_blockhashes(31); keyed_account - .advance_nonce_account(&recent_blockhashes, &signers, &MockInvokeContext::new(&[])) + .advance_nonce_account( + &recent_blockhashes, + &signers, + &MockInvokeContext::new(vec![]), + ) .unwrap(); let state = AccountUtilsState::::state(keyed_account) .unwrap() @@ -354,7 +362,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); // Empties Account balance @@ -388,7 +396,7 @@ mod test { &authority, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let pubkey = nonce_account.account.borrow().owner; @@ -407,7 +415,7 @@ mod test { let result = nonce_account.advance_nonce_account( &recent_blockhashes, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }) @@ -430,14 +438,14 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let recent_blockhashes = vec![].into_iter().collect(); let result = keyed_account.advance_nonce_account( &recent_blockhashes, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into())); }) @@ -460,13 +468,13 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let result = keyed_account.advance_nonce_account( &recent_blockhashes, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(NonceError::NotExpired.into())); }) @@ -486,7 +494,7 @@ mod test { let result = keyed_account.advance_nonce_account( &recent_blockhashes, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -510,7 +518,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let mut signers = HashSet::new(); @@ -519,7 +527,7 @@ mod test { let result = nonce_account.advance_nonce_account( &recent_blockhashes, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Ok(())); }); @@ -544,13 +552,13 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let result = nonce_account.advance_nonce_account( &recent_blockhashes, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }); @@ -584,7 +592,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -623,7 +631,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }) @@ -653,7 +661,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -683,7 +691,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -703,7 +711,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -733,7 +741,7 @@ mod test { &authority, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -757,7 +765,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -783,7 +791,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -811,7 +819,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { @@ -824,7 +832,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(NonceError::NotExpired.into())); }) @@ -846,7 +854,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { @@ -860,7 +868,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -882,7 +890,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { @@ -896,7 +904,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -918,7 +926,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); with_test_keyed_account(55, false, |to_keyed| { @@ -932,7 +940,7 @@ mod test { &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -959,7 +967,7 @@ mod test { &authority, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); let data = nonce::state::Data { authority, @@ -990,7 +998,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into())); }) @@ -1011,7 +1019,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let recent_blockhashes = create_test_recent_blockhashes(0); @@ -1019,7 +1027,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -1039,7 +1047,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -1062,7 +1070,7 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let authority = Pubkey::default(); @@ -1074,7 +1082,7 @@ mod test { let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Ok(())); let state = AccountUtilsState::::state(nonce_account) @@ -1097,7 +1105,7 @@ mod test { let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -1120,13 +1128,13 @@ mod test { &authorized, &recent_blockhashes, &rent, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); }) @@ -1147,7 +1155,7 @@ mod test { &authorized, &recent_blockhashes, &Rent::free(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); assert!(verify_nonce_account( @@ -1182,7 +1190,7 @@ mod test { &authorized, &recent_blockhashes, &Rent::free(), - &MockInvokeContext::new(&[]), + &MockInvokeContext::new(vec![]), ) .unwrap(); assert!(!verify_nonce_account( diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index e09fe097adf254..91b009d5da8a31 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -24,7 +24,7 @@ pub type ProcessInstructionWithContext = pub struct InvokeContextStackFrame<'a> { pub key: Pubkey, - pub keyed_accounts: &'a [KeyedAccount<'a>], + pub keyed_accounts: Vec>, } /// Invocation context passed to loaders @@ -35,7 +35,7 @@ pub trait InvokeContext { /// to be used in the matching pop call. fn push( &mut self, - keyed_accounts: &[KeyedAccount], + keyed_accounts: Vec, key: &Pubkey, ) -> Result<(), InstructionError>; /// Pop a program ID off of the invocation stack @@ -300,7 +300,7 @@ pub struct MockInvokeContext<'a> { pub sysvars: Vec<(Pubkey, Option>>)>, } impl<'a> MockInvokeContext<'a> { - pub fn new(keyed_accounts: &'a [KeyedAccount<'a>]) -> Self { + pub fn new(keyed_accounts: Vec>) -> Self { let bpf_compute_budget = BpfComputeBudget::default(); let mut invoke_stack = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); invoke_stack.push(InvokeContextStackFrame { @@ -323,7 +323,7 @@ impl<'a> MockInvokeContext<'a> { impl<'a> InvokeContext for MockInvokeContext<'a> { fn push( &mut self, - keyed_accounts: &[KeyedAccount], + keyed_accounts: Vec, key: &Pubkey, ) -> Result<(), InstructionError> { let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; @@ -355,17 +355,17 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { .ok_or(InstructionError::GenericError) } fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> { - let mut stack_frame = &mut self + let stack_frame = &mut self .invoke_stack .last_mut() .ok_or(InstructionError::GenericError)?; - stack_frame.keyed_accounts = &stack_frame.keyed_accounts[1..]; + stack_frame.keyed_accounts.remove(0); Ok(()) } fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { self.invoke_stack .last() - .map(|frame| frame.keyed_accounts) + .map(|frame| frame.keyed_accounts.as_slice()) .ok_or(InstructionError::GenericError) } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { From c85989812fe827bd8daca4472fd4c8eefb22af7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 31 Mar 2021 13:52:33 +0200 Subject: [PATCH 28/33] Use ranges instead of removing elements from Vec. --- programs/bpf_loader/src/lib.rs | 2 ++ runtime/src/message_processor.rs | 15 +++++++++++++-- sdk/src/process_instruction.rs | 16 ++++++++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index af0031429a85ea..c05f3d31914eb0 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -1108,10 +1108,12 @@ mod tests { ); // Case: limited budget + let keyed_accounts_range = 0..keyed_accounts.len(); let mut invoke_context = MockInvokeContext { invoke_stack: vec![InvokeContextStackFrame { key: Pubkey::default(), keyed_accounts, + keyed_accounts_range, }], logger: MockLogger::default(), bpf_compute_budget: BpfComputeBudget::default(), diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 7b67e77ca28799..4039e1e1e23610 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -286,9 +286,14 @@ impl<'a> ThisInvokeContext<'a> { ancestors: &'a Ancestors, ) -> Self { let mut invoke_stack = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); + let keyed_accounts_range = std::ops::Range { + start: 0, + end: keyed_accounts.len(), + }; invoke_stack.push(InvokeContextStackFrame { key: *program_id, keyed_accounts, + keyed_accounts_range, }); Self { invoke_stack, @@ -326,10 +331,15 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { // Reentrancy not allowed unless caller is calling itself return Err(InstructionError::ReentrancyNotAllowed); } + let keyed_accounts_range = std::ops::Range { + start: 0, + end: keyed_accounts.len(), + }; let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; self.invoke_stack.push(InvokeContextStackFrame { key: *key, keyed_accounts, + keyed_accounts_range, }); Ok(()) } @@ -373,13 +383,14 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .invoke_stack .last_mut() .ok_or(InstructionError::GenericError)?; - stack_frame.keyed_accounts.remove(0); + stack_frame.keyed_accounts_range.start = + stack_frame.keyed_accounts_range.start.saturating_add(1); Ok(()) } fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { self.invoke_stack .last() - .map(|frame| frame.keyed_accounts.as_slice()) + .map(|frame| &frame.keyed_accounts[frame.keyed_accounts_range.clone()]) .ok_or(InstructionError::GenericError) } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 91b009d5da8a31..36dcf4ceb09d98 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -25,6 +25,7 @@ pub type ProcessInstructionWithContext = pub struct InvokeContextStackFrame<'a> { pub key: Pubkey, pub keyed_accounts: Vec>, + pub keyed_accounts_range: std::ops::Range, } /// Invocation context passed to loaders @@ -303,9 +304,14 @@ impl<'a> MockInvokeContext<'a> { pub fn new(keyed_accounts: Vec>) -> Self { let bpf_compute_budget = BpfComputeBudget::default(); let mut invoke_stack = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); + let keyed_accounts_range = std::ops::Range { + start: 0, + end: keyed_accounts.len(), + }; invoke_stack.push(InvokeContextStackFrame { key: Pubkey::default(), keyed_accounts, + keyed_accounts_range, }); MockInvokeContext { invoke_stack, @@ -326,10 +332,15 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { keyed_accounts: Vec, key: &Pubkey, ) -> Result<(), InstructionError> { + let keyed_accounts_range = std::ops::Range { + start: 0, + end: keyed_accounts.len(), + }; let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; self.invoke_stack.push(InvokeContextStackFrame { key: *key, keyed_accounts, + keyed_accounts_range, }); Ok(()) } @@ -359,13 +370,14 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { .invoke_stack .last_mut() .ok_or(InstructionError::GenericError)?; - stack_frame.keyed_accounts.remove(0); + stack_frame.keyed_accounts_range.start = + stack_frame.keyed_accounts_range.start.saturating_add(1); Ok(()) } fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { self.invoke_stack .last() - .map(|frame| frame.keyed_accounts.as_slice()) + .map(|frame| &frame.keyed_accounts[frame.keyed_accounts_range.clone()]) .ok_or(InstructionError::GenericError) } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { From c20b373690e6b4dfe6a02e4aae2841c6c83c30f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 13 Apr 2021 15:24:57 +0200 Subject: [PATCH 29/33] Moves MessageProcessor::create_keyed_accounts() and MessageProcessor::create_pre_accounts() in InvokeContext::new(). --- runtime/src/message_processor.rs | 180 ++++++++++++++----------------- sdk/src/process_instruction.rs | 71 +++++++----- 2 files changed, 129 insertions(+), 122 deletions(-) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 4039e1e1e23610..d7a1d3cdc2d411 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -14,7 +14,7 @@ use solana_sdk::{ }, ic_msg, instruction::{CompiledInstruction, Instruction, InstructionError}, - keyed_account::{create_keyed_readonly_accounts, keyed_account_at_index, KeyedAccount}, + keyed_account::{keyed_account_at_index, KeyedAccount}, message::Message, native_loader, process_instruction::{ @@ -253,7 +253,7 @@ pub struct ThisInvokeContext<'a> { invoke_stack: Vec>, rent: Rent, pre_accounts: Vec, - executables: &'a [(Pubkey, Rc>)], + executable_accounts: &'a [(Pubkey, Rc>)], account_deps: &'a [(Pubkey, Rc>)], programs: &'a [(Pubkey, ProcessInstructionWithContext)], logger: Rc>, @@ -272,10 +272,11 @@ impl<'a> ThisInvokeContext<'a> { pub fn new( program_id: &Pubkey, rent: Rent, - pre_accounts: Vec, - executables: &'a [(Pubkey, Rc>)], + message: &'a Message, + instruction: &'a CompiledInstruction, + executable_accounts: &'a [(Pubkey, Rc>)], + accounts: &'a [Rc>], account_deps: &'a [(Pubkey, Rc>)], - keyed_accounts: Vec>, programs: &'a [(Pubkey, ProcessInstructionWithContext)], log_collector: Option>, bpf_compute_budget: BpfComputeBudget, @@ -285,21 +286,19 @@ impl<'a> ThisInvokeContext<'a> { account_db: Arc, ancestors: &'a Ancestors, ) -> Self { - let mut invoke_stack = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); - let keyed_accounts_range = std::ops::Range { - start: 0, - end: keyed_accounts.len(), - }; - invoke_stack.push(InvokeContextStackFrame { - key: *program_id, - keyed_accounts, - keyed_accounts_range, - }); - Self { - invoke_stack, + let pre_accounts = MessageProcessor::create_pre_accounts(message, instruction, accounts); + let keyed_accounts = MessageProcessor::create_keyed_accounts( + message, + instruction, + executable_accounts, + accounts, + feature_set.is_active(&demote_sysvar_write_locks::id()), + ); + let mut invoke_context = Self { + invoke_stack: Vec::with_capacity(bpf_compute_budget.max_invoke_depth), rent, pre_accounts, - executables, + executable_accounts, account_deps, programs, logger: Rc::new(RefCell::new(ThisLogger { log_collector })), @@ -314,14 +313,18 @@ impl<'a> ThisInvokeContext<'a> { account_db, ancestors, sysvars: vec![], - } + }; + invoke_context + .invoke_stack + .push(InvokeContextStackFrame::new(*program_id, &keyed_accounts)); + invoke_context } } impl<'a> InvokeContext for ThisInvokeContext<'a> { fn push( &mut self, - keyed_accounts: Vec, key: &Pubkey, + keyed_accounts: &[(&Pubkey, bool, bool, &RefCell)], ) -> Result<(), InstructionError> { if self.invoke_stack.len() > self.bpf_compute_budget.max_invoke_depth { return Err(InstructionError::CallDepth); @@ -331,16 +334,10 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { // Reentrancy not allowed unless caller is calling itself return Err(InstructionError::ReentrancyNotAllowed); } - let keyed_accounts_range = std::ops::Range { - start: 0, - end: keyed_accounts.len(), - }; - let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; - self.invoke_stack.push(InvokeContextStackFrame { - key: *key, - keyed_accounts, - keyed_accounts_range, - }); + self.invoke_stack + .push(InvokeContextStackFrame::new(*key, unsafe { + std::mem::transmute(keyed_accounts) + })); Ok(()) } fn pop(&mut self) { @@ -421,7 +418,11 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { } fn get_account(&self, pubkey: &Pubkey) -> Option>> { if self.is_feature_active(&cpi_share_ro_and_exec_accounts::id()) { - if let Some((_, account)) = self.executables.iter().find(|(key, _)| key == pubkey) { + if let Some((_, account)) = self + .executable_accounts + .iter() + .find(|(key, _)| key == pubkey) + { Some(account.clone()) } else if let Some((_, account)) = self.account_deps.iter().find(|(key, _)| key == pubkey) @@ -593,25 +594,24 @@ impl MessageProcessor { executable_accounts: &'a [(Pubkey, Rc>)], accounts: &'a [Rc>], demote_sysvar_write_locks: bool, - ) -> Vec> { - let mut keyed_accounts = create_keyed_readonly_accounts(&executable_accounts); - let mut keyed_accounts2: Vec<_> = instruction - .accounts + ) -> Vec<(&'a Pubkey, bool, bool, &'a RefCell)> { + executable_accounts .iter() - .map(|&index| { - let is_signer = message.is_signer(index as usize); - let index = index as usize; - let key = &message.account_keys[index]; - let account = &accounts[index]; - if message.is_writable(index, demote_sysvar_write_locks) { - KeyedAccount::new(key, is_signer, account) - } else { - KeyedAccount::new_readonly(key, is_signer, account) - } + .map(|(key, account)| { + let account: &RefCell = account; + (key, false, false, account) }) - .collect(); - keyed_accounts.append(&mut keyed_accounts2); - keyed_accounts + .chain(instruction.accounts.iter().map(|index| { + let index = *index as usize; + let account: &RefCell = &accounts[index]; + ( + &message.account_keys[index], + message.is_signer(index), + message.is_writable(index, demote_sysvar_write_locks), + account, + ) + })) + .collect::>() } /// Process an instruction @@ -739,7 +739,7 @@ impl MessageProcessor { let ( message, - executables, + executable_accounts, accounts, keyed_account_indices_reordered, caller_write_privileges, @@ -826,13 +826,13 @@ impl MessageProcessor { } else { None }; - let mut executables = vec![(callee_program_id, program_account)]; + let mut executable_accounts = vec![(callee_program_id, program_account)]; if let Some(programdata) = programdata { - executables.push(programdata); + executable_accounts.push(programdata); } ( message, - executables, + executable_accounts, accounts, keyed_account_indices_reordered, caller_write_privileges, @@ -843,7 +843,7 @@ impl MessageProcessor { #[allow(clippy::deref_addrof)] MessageProcessor::process_cross_program_instruction( &message, - &executables, + &executable_accounts, &accounts, &caller_write_privileges, *(&mut *(invoke_context.borrow_mut())), @@ -906,19 +906,18 @@ impl MessageProcessor { accounts, Some(caller_write_privileges), )?; - let demote_sysvar_write_locks = - invoke_context.is_feature_active(&demote_sysvar_write_locks::id()); + // Construct keyed accounts let keyed_accounts = Self::create_keyed_accounts( message, instruction, executable_accounts, accounts, - demote_sysvar_write_locks, + invoke_context.is_feature_active(&demote_sysvar_write_locks::id()), ); // Invoke callee - invoke_context.push(keyed_accounts, program_id)?; + invoke_context.push(program_id, &keyed_accounts)?; let mut message_processor = MessageProcessor::default(); for (program_id, process_instruction) in invoke_context.get_programs().iter() { @@ -1125,22 +1124,15 @@ impl MessageProcessor { } } - let pre_accounts = Self::create_pre_accounts(message, instruction, accounts); let program_id = instruction.program_id(&message.account_keys); - let keyed_accounts = Self::create_keyed_accounts( - message, - instruction, - executable_accounts, - accounts, - demote_sysvar_write_locks, - ); let mut invoke_context = ThisInvokeContext::new( program_id, rent_collector.rent, - pre_accounts, + message, + instruction, executable_accounts, + accounts, account_deps, - keyed_accounts, &self.programs, log_collector, bpf_compute_budget, @@ -1232,8 +1224,8 @@ mod tests { const MAX_DEPTH: usize = 10; let mut invoke_stack = vec![]; let mut keys = vec![]; - let mut pre_accounts = vec![]; let mut accounts = vec![]; + let mut metas = vec![]; for i in 0..MAX_DEPTH { invoke_stack.push(solana_sdk::pubkey::new_rand()); keys.push(solana_sdk::pubkey::new_rand()); @@ -1242,21 +1234,30 @@ mod tests { 1, &invoke_stack[i], )))); - pre_accounts.push(PreAccount::new(&keys[i], &accounts[i].borrow())) + metas.push(AccountMeta::new(keys[i], false)); } - let account = AccountSharedData::new(1, 1, &solana_sdk::pubkey::Pubkey::default()); for program_id in invoke_stack.iter() { - pre_accounts.push(PreAccount::new(program_id, &account.clone())); + accounts.push(Rc::new(RefCell::new(AccountSharedData::new( + 1, + 1, + &solana_sdk::pubkey::Pubkey::default(), + )))); + metas.push(AccountMeta::new(*program_id, false)); } + let message = Message::new( + &[Instruction::new_with_bytes(invoke_stack[0], &[0], metas)], + None, + ); let ancestors = Ancestors::default(); let mut invoke_context = ThisInvokeContext::new( &invoke_stack[0], Rent::default(), - pre_accounts, + &message, + &message.instructions[0], &[], + &accounts, &[], - vec![], &[], None, BpfComputeBudget::default(), @@ -1270,7 +1271,7 @@ mod tests { // Check call depth increases and has a limit let mut depth_reached = 1; for program_id in invoke_stack.iter().skip(1) { - if Err(InstructionError::CallDepth) == invoke_context.push(vec![], program_id) { + if Err(InstructionError::CallDepth) == invoke_context.push(program_id, &[]) { break; } depth_reached += 1; @@ -2173,24 +2174,15 @@ mod tests { ); let message = Message::new(&[instruction], None); - let pre_accounts = - MessageProcessor::create_pre_accounts(&message, &compiled_instruction, &accounts); - let demote_sysvar_write_locks = true; - let keyed_accounts = MessageProcessor::create_keyed_accounts( - &message, - &compiled_instruction, - &executable_accounts, - &accounts, - demote_sysvar_write_locks, - ); let ancestors = Ancestors::default(); let mut invoke_context = ThisInvokeContext::new( &caller_program_id, Rent::default(), - pre_accounts, + &message, + &compiled_instruction, &executable_accounts, + &accounts, &[], - keyed_accounts, programs.as_slice(), None, BpfComputeBudget::default(), @@ -2202,6 +2194,8 @@ mod tests { ); // not owned account modified by the caller (before the invoke) + let demote_sysvar_write_locks = + invoke_context.is_feature_active(&demote_sysvar_write_locks::id()); let caller_write_privileges = message .account_keys .iter() @@ -2239,23 +2233,15 @@ mod tests { Instruction::new_with_bincode(callee_program_id, &case.0, metas.clone()); let message = Message::new(&[instruction], None); - let pre_accounts = - MessageProcessor::create_pre_accounts(&message, &compiled_instruction, &accounts); - let keyed_accounts = MessageProcessor::create_keyed_accounts( - &message, - &compiled_instruction, - &executable_accounts, - &accounts, - demote_sysvar_write_locks, - ); let ancestors = Ancestors::default(); let mut invoke_context = ThisInvokeContext::new( &caller_program_id, Rent::default(), - pre_accounts, + &message, + &compiled_instruction, &executable_accounts, + &accounts, &[], - keyed_accounts, programs.as_slice(), None, BpfComputeBudget::default(), diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 36dcf4ceb09d98..af6278fb8377aa 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -28,6 +28,33 @@ pub struct InvokeContextStackFrame<'a> { pub keyed_accounts_range: std::ops::Range, } +impl<'a> InvokeContextStackFrame<'a> { + pub fn new( + key: Pubkey, + keyed_accounts: &[(&'a Pubkey, bool, bool, &'a RefCell)], + ) -> Self { + let keyed_accounts: Vec<_> = keyed_accounts + .iter() + .map(|(key, is_signer, is_writable, account)| { + if *is_writable { + KeyedAccount::new(*key, *is_signer, *account) + } else { + KeyedAccount::new_readonly(*key, *is_signer, *account) + } + }) + .collect(); + let keyed_accounts_range = std::ops::Range { + start: 0, + end: keyed_accounts.len(), + }; + Self { + key, + keyed_accounts, + keyed_accounts_range, + } + } +} + /// Invocation context passed to loaders pub trait InvokeContext { /// Push a program ID on to the invocation stack @@ -36,8 +63,8 @@ pub trait InvokeContext { /// to be used in the matching pop call. fn push( &mut self, - keyed_accounts: Vec, key: &Pubkey, + keyed_accounts: &[(&Pubkey, bool, bool, &RefCell)], ) -> Result<(), InstructionError>; /// Pop a program ID off of the invocation stack fn pop(&mut self); @@ -303,18 +330,8 @@ pub struct MockInvokeContext<'a> { impl<'a> MockInvokeContext<'a> { pub fn new(keyed_accounts: Vec>) -> Self { let bpf_compute_budget = BpfComputeBudget::default(); - let mut invoke_stack = Vec::with_capacity(bpf_compute_budget.max_invoke_depth); - let keyed_accounts_range = std::ops::Range { - start: 0, - end: keyed_accounts.len(), - }; - invoke_stack.push(InvokeContextStackFrame { - key: Pubkey::default(), - keyed_accounts, - keyed_accounts_range, - }); - MockInvokeContext { - invoke_stack, + let mut invoke_context = MockInvokeContext { + invoke_stack: Vec::with_capacity(bpf_compute_budget.max_invoke_depth), logger: MockLogger::default(), bpf_compute_budget, compute_meter: MockComputeMeter { @@ -323,25 +340,29 @@ impl<'a> MockInvokeContext<'a> { programs: vec![], accounts: vec![], sysvars: vec![], - } - } -} -impl<'a> InvokeContext for MockInvokeContext<'a> { - fn push( - &mut self, - keyed_accounts: Vec, - key: &Pubkey, - ) -> Result<(), InstructionError> { + }; let keyed_accounts_range = std::ops::Range { start: 0, end: keyed_accounts.len(), }; - let keyed_accounts = unsafe { std::mem::transmute(keyed_accounts) }; - self.invoke_stack.push(InvokeContextStackFrame { - key: *key, + invoke_context.invoke_stack.push(InvokeContextStackFrame { + key: Pubkey::default(), keyed_accounts, keyed_accounts_range, }); + invoke_context + } +} +impl<'a> InvokeContext for MockInvokeContext<'a> { + fn push( + &mut self, + key: &Pubkey, + keyed_accounts: &[(&Pubkey, bool, bool, &RefCell)], + ) -> Result<(), InstructionError> { + self.invoke_stack + .push(InvokeContextStackFrame::new(*key, unsafe { + std::mem::transmute(keyed_accounts) + })); Ok(()) } fn pop(&mut self) { From b1b5639d4cdf7aa2f5f1ce2b024efa55b90550f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 7 Apr 2021 11:33:22 +0200 Subject: [PATCH 30/33] Recycle existing keys in ThisInvokeContext::push() --- runtime/src/message_processor.rs | 60 +++++++++++++++++++++++++------- sdk/src/process_instruction.rs | 9 ++--- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index d7a1d3cdc2d411..1e324ab86945e6 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -215,8 +215,8 @@ impl PreAccount { self.changed = true; } - pub fn key(&self) -> Pubkey { - self.key + pub fn key(&self) -> &Pubkey { + &self.key } pub fn lamports(&self) -> u64 { @@ -252,6 +252,7 @@ impl ComputeMeter for ThisComputeMeter { pub struct ThisInvokeContext<'a> { invoke_stack: Vec>, rent: Rent, + message: &'a Message, pre_accounts: Vec, executable_accounts: &'a [(Pubkey, Rc>)], account_deps: &'a [(Pubkey, Rc>)], @@ -297,6 +298,7 @@ impl<'a> ThisInvokeContext<'a> { let mut invoke_context = Self { invoke_stack: Vec::with_capacity(bpf_compute_budget.max_invoke_depth), rent, + message, pre_accounts, executable_accounts, account_deps, @@ -334,10 +336,46 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { // Reentrancy not allowed unless caller is calling itself return Err(InstructionError::ReentrancyNotAllowed); } - self.invoke_stack - .push(InvokeContextStackFrame::new(*key, unsafe { - std::mem::transmute(keyed_accounts) - })); + // Alias the keys and account references in the provided keyed_accounts + // with the ones already existing in self, so that the lifetime 'a matches. + let keyed_accounts = keyed_accounts + .iter() + .map(|(search_key, is_signer, is_writable, account)| { + self.account_deps + .iter() + .map(|(key, _account)| key) + .chain(self.message.account_keys.iter()) + .position(|key| key == *search_key) + .map(|mut index| { + if index < self.account_deps.len() { + ( + &self.account_deps[index].0, + *is_signer, + *is_writable, + &self.account_deps[index].1 as &RefCell, + ) + } else { + index = index.saturating_sub(self.account_deps.len()); + ( + &self.message.account_keys[index], + *is_signer, + *is_writable, + // TODO + // Currently we are constructing new accounts on the stack + // before calling MessageProcessor::process_cross_program_instruction + // Ideally we would recycle the existing accounts here like this: + // &self.accounts[index] as &RefCell, + unsafe { std::mem::transmute(*account) }, + ) + } + }) + }) + .collect::>>() + .ok_or(InstructionError::InvalidArgument)?; + self.invoke_stack.push(InvokeContextStackFrame::new( + *key, + keyed_accounts.as_slice(), + )); Ok(()) } fn pop(&mut self) { @@ -597,18 +635,14 @@ impl MessageProcessor { ) -> Vec<(&'a Pubkey, bool, bool, &'a RefCell)> { executable_accounts .iter() - .map(|(key, account)| { - let account: &RefCell = account; - (key, false, false, account) - }) + .map(|(key, account)| (key, false, false, account as &RefCell)) .chain(instruction.accounts.iter().map(|index| { let index = *index as usize; - let account: &RefCell = &accounts[index]; ( &message.account_keys[index], message.is_signer(index), message.is_writable(index, demote_sysvar_write_locks), - account, + &accounts[index] as &RefCell, ) })) .collect::>() @@ -1048,7 +1082,7 @@ impl MessageProcessor { }; // Find the matching PreAccount for pre_account in pre_accounts.iter_mut() { - if *key == pre_account.key() { + if key == pre_account.key() { { // Verify account has no outstanding references let _ = account diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index af6278fb8377aa..1b3ab3a5139134 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -57,16 +57,17 @@ impl<'a> InvokeContextStackFrame<'a> { /// Invocation context passed to loaders pub trait InvokeContext { - /// Push a program ID on to the invocation stack + /// Push a stack frame onto the invocation stack /// - /// It returns the keyed_accounts_to_restore - /// to be used in the matching pop call. + /// Used in MessageProcessor::process_cross_program_instruction fn push( &mut self, key: &Pubkey, keyed_accounts: &[(&Pubkey, bool, bool, &RefCell)], ) -> Result<(), InstructionError>; - /// Pop a program ID off of the invocation stack + /// Pop a stack frame from the invocation stack + /// + /// Used in MessageProcessor::process_cross_program_instruction fn pop(&mut self); /// Current depth of the invocation stake fn invoke_depth(&self) -> usize; From 49e13c072c8c50c6575e28d5ec41c260d226aa3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 14 Apr 2021 21:41:16 +0200 Subject: [PATCH 31/33] Unifies create_keyed_is_signer_accounts() and create_keyed_readonly_accounts() into create_keyed_accounts_unified(). Throws instead CallDepth of GenericError at invoke_stack.last().ok_or(). Renames program => executable. --- programs/bpf_loader/src/lib.rs | 8 +- programs/config/src/config_processor.rs | 98 ++++++++++++------------- runtime/src/message_processor.rs | 31 ++++---- sdk/src/keyed_account.rs | 22 ++++++ sdk/src/process_instruction.rs | 44 ++++------- 5 files changed, 105 insertions(+), 98 deletions(-) diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index c05f3d31914eb0..fab9defc98275f 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -103,9 +103,7 @@ pub fn create_executor( return Err(InstructionError::ProgramFailedToCompile); } } - Ok(Arc::new(BpfExecutor { - program: executable, - })) + Ok(Arc::new(BpfExecutor { executable })) } fn write_program_data( @@ -725,7 +723,7 @@ impl InstructionMeter for ThisInstructionMeter { /// BPF Loader's Executor implementation pub struct BpfExecutor { - program: Box>, + executable: Box>, } // Well, implement Debug for solana_rbpf::vm::Executable in solana-rbpf... @@ -760,7 +758,7 @@ impl Executor for BpfExecutor { let compute_meter = invoke_context.get_compute_meter(); let mut vm = match create_vm( loader_id, - self.program.as_ref(), + self.executable.as_ref(), &mut parameter_bytes, invoke_context, ) { diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index a6bb4f6bd1bb0a..4197eea1c1e3a9 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -132,7 +132,7 @@ mod tests { use serde_derive::{Deserialize, Serialize}; use solana_sdk::{ account::{Account, AccountSharedData}, - keyed_account::create_keyed_is_signer_accounts, + keyed_account::create_keyed_accounts_unified, process_instruction::MockInvokeContext, signature::{Keypair, Signer}, system_instruction::SystemInstruction, @@ -185,8 +185,8 @@ mod tests { owner: id(), ..Account::default() })); - let accounts = vec![(&config_pubkey, true, &config_account)]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let accounts = vec![(true, false, &config_pubkey, &config_account)]; + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -219,8 +219,8 @@ mod tests { let my_config = MyConfig::new(42); let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config); - let accounts = vec![(&config_pubkey, true, &config_account)]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let accounts = vec![(true, false, &config_pubkey, &config_account)]; + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -245,8 +245,8 @@ mod tests { let mut instruction = config_instruction::store(&config_pubkey, true, keys, &my_config); instruction.data = vec![0; 123]; // <-- Replace data with a vector that's too large - let accounts = vec![(&config_pubkey, true, &config_account)]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let accounts = vec![(true, false, &config_pubkey, &config_account)]; + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -267,8 +267,8 @@ mod tests { let mut instruction = config_instruction::store(&config_pubkey, true, vec![], &my_config); instruction.accounts[0].is_signer = false; // <----- not a signer - let accounts = vec![(&config_pubkey, false, &config_account)]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let accounts = vec![(false, false, &config_pubkey, &config_account)]; + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -298,11 +298,11 @@ mod tests { let signer0_account = RefCell::new(AccountSharedData::default()); let signer1_account = RefCell::new(AccountSharedData::default()); let accounts = vec![ - (&config_pubkey, true, &config_account), - (&signer0_pubkey, true, &signer0_account), - (&signer1_pubkey, true, &signer1_account), + (true, false, &config_pubkey, &config_account), + (true, false, &signer0_pubkey, &signer0_account), + (true, false, &signer1_pubkey, &signer1_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -334,8 +334,8 @@ mod tests { owner: id(), ..Account::default() })); - let accounts = vec![(&signer0_pubkey, true, &signer0_account)]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let accounts = vec![(true, false, &signer0_pubkey, &signer0_account)]; + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -362,10 +362,10 @@ mod tests { // Config-data pubkey doesn't match signer let accounts = vec![ - (&config_pubkey, true, &config_account), - (&signer1_pubkey, true, &signer1_account), + (true, false, &config_pubkey, &config_account), + (true, false, &signer1_pubkey, &signer1_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -377,10 +377,10 @@ mod tests { // Config-data pubkey not a signer let accounts = vec![ - (&config_pubkey, true, &config_account), - (&signer0_pubkey, false, &signer0_account), + (true, false, &config_pubkey, &config_account), + (false, false, &signer0_pubkey, &signer0_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -412,11 +412,11 @@ mod tests { let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); let accounts = vec![ - (&config_pubkey, true, &config_account), - (&signer0_pubkey, true, &signer0_account), - (&signer1_pubkey, true, &signer1_account), + (true, false, &config_pubkey, &config_account), + (true, false, &signer0_pubkey, &signer0_account), + (true, false, &signer1_pubkey, &signer1_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -431,11 +431,11 @@ mod tests { let instruction = config_instruction::store(&config_pubkey, false, keys.clone(), &new_config); let accounts = vec![ - (&config_pubkey, false, &config_account), - (&signer0_pubkey, true, &signer0_account), - (&signer1_pubkey, true, &signer1_account), + (false, false, &config_pubkey, &config_account), + (true, false, &signer0_pubkey, &signer0_account), + (true, false, &signer1_pubkey, &signer1_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -456,11 +456,11 @@ mod tests { let keys = vec![(pubkey, false), (signer0_pubkey, true)]; let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config); let accounts = vec![ - (&config_pubkey, false, &config_account), - (&signer0_pubkey, true, &signer0_account), - (&signer1_pubkey, false, &signer1_account), + (false, false, &config_pubkey, &config_account), + (true, false, &signer0_pubkey, &signer0_account), + (false, false, &signer1_pubkey, &signer1_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -478,11 +478,11 @@ mod tests { ]; let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config); let accounts = vec![ - (&config_pubkey, false, &config_account), - (&signer0_pubkey, true, &signer0_account), - (&signer2_pubkey, true, &signer2_account), + (false, false, &config_pubkey, &config_account), + (true, false, &signer0_pubkey, &signer0_account), + (true, false, &signer2_pubkey, &signer2_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -516,10 +516,10 @@ mod tests { let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); let accounts = vec![ - (&config_pubkey, true, &config_account), - (&signer0_pubkey, true, &signer0_account), + (true, false, &config_pubkey, &config_account), + (true, false, &signer0_pubkey, &signer0_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -534,10 +534,10 @@ mod tests { let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &new_config); let accounts = vec![ - (&config_pubkey, true, &config_account), - (&signer0_pubkey, true, &signer0_account), + (true, false, &config_pubkey, &config_account), + (true, false, &signer0_pubkey, &signer0_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -557,8 +557,8 @@ mod tests { // Attempt update with incomplete signatures let keys = vec![(pubkey, false), (config_keypair.pubkey(), true)]; let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config); - let accounts = vec![(&config_pubkey, true, &config_account)]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let accounts = vec![(true, false, &config_pubkey, &config_account)]; + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -576,7 +576,7 @@ mod tests { let instructions = config_instruction::create_account::(&from_pubkey, &config_pubkey, 1, vec![]); let accounts = vec![]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), @@ -603,10 +603,10 @@ mod tests { let instruction = config_instruction::store(&config_pubkey, true, keys, &new_config); let accounts = vec![ - (&config_pubkey, true, &config_account), - (&signer0_pubkey, true, &signer0_account), + (true, false, &config_pubkey, &config_account), + (true, false, &signer0_pubkey, &signer0_account), ]; - let keyed_accounts = create_keyed_is_signer_accounts(&accounts); + let keyed_accounts = create_keyed_accounts_unified(&accounts); assert_eq!( process_instruction( &id(), diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 1e324ab86945e6..9e7974aca507d2 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -14,7 +14,7 @@ use solana_sdk::{ }, ic_msg, instruction::{CompiledInstruction, Instruction, InstructionError}, - keyed_account::{keyed_account_at_index, KeyedAccount}, + keyed_account::{create_keyed_accounts_unified, keyed_account_at_index, KeyedAccount}, message::Message, native_loader, process_instruction::{ @@ -318,7 +318,10 @@ impl<'a> ThisInvokeContext<'a> { }; invoke_context .invoke_stack - .push(InvokeContextStackFrame::new(*program_id, &keyed_accounts)); + .push(InvokeContextStackFrame::new( + *program_id, + create_keyed_accounts_unified(&keyed_accounts), + )); invoke_context } } @@ -326,7 +329,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { fn push( &mut self, key: &Pubkey, - keyed_accounts: &[(&Pubkey, bool, bool, &RefCell)], + keyed_accounts: &[(bool, bool, &Pubkey, &RefCell)], ) -> Result<(), InstructionError> { if self.invoke_stack.len() > self.bpf_compute_budget.max_invoke_depth { return Err(InstructionError::CallDepth); @@ -340,7 +343,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { // with the ones already existing in self, so that the lifetime 'a matches. let keyed_accounts = keyed_accounts .iter() - .map(|(search_key, is_signer, is_writable, account)| { + .map(|(is_signer, is_writable, search_key, account)| { self.account_deps .iter() .map(|(key, _account)| key) @@ -349,17 +352,17 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .map(|mut index| { if index < self.account_deps.len() { ( - &self.account_deps[index].0, *is_signer, *is_writable, + &self.account_deps[index].0, &self.account_deps[index].1 as &RefCell, ) } else { index = index.saturating_sub(self.account_deps.len()); ( - &self.message.account_keys[index], *is_signer, *is_writable, + &self.message.account_keys[index], // TODO // Currently we are constructing new accounts on the stack // before calling MessageProcessor::process_cross_program_instruction @@ -374,7 +377,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .ok_or(InstructionError::InvalidArgument)?; self.invoke_stack.push(InvokeContextStackFrame::new( *key, - keyed_accounts.as_slice(), + create_keyed_accounts_unified(keyed_accounts.as_slice()), )); Ok(()) } @@ -394,7 +397,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { let stack_frame = self .invoke_stack .last() - .ok_or(InstructionError::GenericError)?; + .ok_or(InstructionError::CallDepth)?; MessageProcessor::verify_and_update( message, instruction, @@ -411,13 +414,13 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { self.invoke_stack .last() .map(|frame| &frame.key) - .ok_or(InstructionError::GenericError) + .ok_or(InstructionError::CallDepth) } fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> { let stack_frame = &mut self .invoke_stack .last_mut() - .ok_or(InstructionError::GenericError)?; + .ok_or(InstructionError::CallDepth)?; stack_frame.keyed_accounts_range.start = stack_frame.keyed_accounts_range.start.saturating_add(1); Ok(()) @@ -426,7 +429,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { self.invoke_stack .last() .map(|frame| &frame.keyed_accounts[frame.keyed_accounts_range.clone()]) - .ok_or(InstructionError::GenericError) + .ok_or(InstructionError::CallDepth) } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { self.programs @@ -632,16 +635,16 @@ impl MessageProcessor { executable_accounts: &'a [(Pubkey, Rc>)], accounts: &'a [Rc>], demote_sysvar_write_locks: bool, - ) -> Vec<(&'a Pubkey, bool, bool, &'a RefCell)> { + ) -> Vec<(bool, bool, &'a Pubkey, &'a RefCell)> { executable_accounts .iter() - .map(|(key, account)| (key, false, false, account as &RefCell)) + .map(|(key, account)| (false, false, key, account as &RefCell)) .chain(instruction.accounts.iter().map(|index| { let index = *index as usize; ( - &message.account_keys[index], message.is_signer(index), message.is_writable(index, demote_sysvar_write_locks), + &message.account_keys[index], &accounts[index] as &RefCell, ) })) diff --git a/sdk/src/keyed_account.rs b/sdk/src/keyed_account.rs index e70a19f8123a11..30e9eeb3ece273 100644 --- a/sdk/src/keyed_account.rs +++ b/sdk/src/keyed_account.rs @@ -146,6 +146,10 @@ pub fn create_keyed_accounts<'a>( accounts.iter().map(Into::into).collect() } +#[deprecated( + since = "1.7.0", + note = "Please use create_keyed_accounts_unified instead" +)] pub fn create_keyed_is_signer_accounts<'a>( accounts: &'a [(&'a Pubkey, bool, &'a RefCell)], ) -> Vec> { @@ -160,6 +164,10 @@ pub fn create_keyed_is_signer_accounts<'a>( .collect() } +#[deprecated( + since = "1.7.0", + note = "Please use create_keyed_accounts_unified instead" +)] pub fn create_keyed_readonly_accounts( accounts: &[(Pubkey, Rc>)], ) -> Vec { @@ -174,6 +182,20 @@ pub fn create_keyed_readonly_accounts( .collect() } +pub fn create_keyed_accounts_unified<'a>( + accounts: &[(bool, bool, &'a Pubkey, &'a RefCell)], +) -> Vec> { + accounts + .iter() + .map(|(is_signer, is_writable, key, account)| KeyedAccount { + is_signer: *is_signer, + is_writable: *is_writable, + key, + account, + }) + .collect() +} + /// Return all the signers from a set of KeyedAccounts pub fn get_signers(keyed_accounts: &[KeyedAccount]) -> A where diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 1b3ab3a5139134..c9bbf96e9703e7 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -1,7 +1,7 @@ use solana_sdk::{ account::AccountSharedData, instruction::{CompiledInstruction, Instruction, InstructionError}, - keyed_account::KeyedAccount, + keyed_account::{create_keyed_accounts_unified, KeyedAccount}, message::Message, pubkey::Pubkey, }; @@ -29,20 +29,7 @@ pub struct InvokeContextStackFrame<'a> { } impl<'a> InvokeContextStackFrame<'a> { - pub fn new( - key: Pubkey, - keyed_accounts: &[(&'a Pubkey, bool, bool, &'a RefCell)], - ) -> Self { - let keyed_accounts: Vec<_> = keyed_accounts - .iter() - .map(|(key, is_signer, is_writable, account)| { - if *is_writable { - KeyedAccount::new(*key, *is_signer, *account) - } else { - KeyedAccount::new_readonly(*key, *is_signer, *account) - } - }) - .collect(); + pub fn new(key: Pubkey, keyed_accounts: Vec>) -> Self { let keyed_accounts_range = std::ops::Range { start: 0, end: keyed_accounts.len(), @@ -63,7 +50,7 @@ pub trait InvokeContext { fn push( &mut self, key: &Pubkey, - keyed_accounts: &[(&Pubkey, bool, bool, &RefCell)], + keyed_accounts: &[(bool, bool, &Pubkey, &RefCell)], ) -> Result<(), InstructionError>; /// Pop a stack frame from the invocation stack /// @@ -342,15 +329,12 @@ impl<'a> MockInvokeContext<'a> { accounts: vec![], sysvars: vec![], }; - let keyed_accounts_range = std::ops::Range { - start: 0, - end: keyed_accounts.len(), - }; - invoke_context.invoke_stack.push(InvokeContextStackFrame { - key: Pubkey::default(), - keyed_accounts, - keyed_accounts_range, - }); + invoke_context + .invoke_stack + .push(InvokeContextStackFrame::new( + Pubkey::default(), + keyed_accounts, + )); invoke_context } } @@ -358,11 +342,11 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { fn push( &mut self, key: &Pubkey, - keyed_accounts: &[(&Pubkey, bool, bool, &RefCell)], + keyed_accounts: &[(bool, bool, &Pubkey, &RefCell)], ) -> Result<(), InstructionError> { self.invoke_stack .push(InvokeContextStackFrame::new(*key, unsafe { - std::mem::transmute(keyed_accounts) + std::mem::transmute(create_keyed_accounts_unified(keyed_accounts)) })); Ok(()) } @@ -385,13 +369,13 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { self.invoke_stack .last() .map(|frame| &frame.key) - .ok_or(InstructionError::GenericError) + .ok_or(InstructionError::CallDepth) } fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> { let stack_frame = &mut self .invoke_stack .last_mut() - .ok_or(InstructionError::GenericError)?; + .ok_or(InstructionError::CallDepth)?; stack_frame.keyed_accounts_range.start = stack_frame.keyed_accounts_range.start.saturating_add(1); Ok(()) @@ -400,7 +384,7 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { self.invoke_stack .last() .map(|frame| &frame.keyed_accounts[frame.keyed_accounts_range.clone()]) - .ok_or(InstructionError::GenericError) + .ok_or(InstructionError::CallDepth) } fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] { &self.programs From 788ff6f486082460723f471e592dfc1d37b7cd16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 19 Apr 2021 13:15:41 +0200 Subject: [PATCH 32/33] Makes unsafe transmute more obvious. --- runtime/src/message_processor.rs | 5 ++++- sdk/src/process_instruction.rs | 11 +++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 9e7974aca507d2..8f774cfa786f6b 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -341,6 +341,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { } // Alias the keys and account references in the provided keyed_accounts // with the ones already existing in self, so that the lifetime 'a matches. + fn transmute_lifetime<'a, 'b, T: Sized>(value: &'a T) -> &'b T { + unsafe { std::mem::transmute(value) } + } let keyed_accounts = keyed_accounts .iter() .map(|(is_signer, is_writable, search_key, account)| { @@ -368,7 +371,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { // before calling MessageProcessor::process_cross_program_instruction // Ideally we would recycle the existing accounts here like this: // &self.accounts[index] as &RefCell, - unsafe { std::mem::transmute(*account) }, + transmute_lifetime(*account), ) } }) diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index c9bbf96e9703e7..d591c84ac7477a 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -344,10 +344,13 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { key: &Pubkey, keyed_accounts: &[(bool, bool, &Pubkey, &RefCell)], ) -> Result<(), InstructionError> { - self.invoke_stack - .push(InvokeContextStackFrame::new(*key, unsafe { - std::mem::transmute(create_keyed_accounts_unified(keyed_accounts)) - })); + fn transmute_lifetime<'a, 'b>(value: Vec>) -> Vec> { + unsafe { std::mem::transmute(value) } + } + self.invoke_stack.push(InvokeContextStackFrame::new( + *key, + transmute_lifetime(create_keyed_accounts_unified(keyed_accounts)), + )); Ok(()) } fn pop(&mut self) { From 06897631a3140d86ff83b62e645a0de7910d8b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 19 Apr 2021 13:20:52 +0200 Subject: [PATCH 33/33] Silence warnings about missing "dyn" before traits. --- programs/bpf/benches/bpf_loader.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/bpf/benches/bpf_loader.rs b/programs/bpf/benches/bpf_loader.rs index 2e3e7e0af8954f..d4cf722fa32b2f 100644 --- a/programs/bpf/benches/bpf_loader.rs +++ b/programs/bpf/benches/bpf_loader.rs @@ -76,7 +76,7 @@ fn bench_program_create_executable(bencher: &mut Bencher) { bencher.iter(|| { let _ = - Executable::::from_elf(&elf, None, Config::default()) + >::from_elf(&elf, None, Config::default()) .unwrap(); }); } @@ -95,7 +95,7 @@ fn bench_program_alu(bencher: &mut Bencher) { let elf = load_elf("bench_alu").unwrap(); let mut executable = - Executable::::from_elf(&elf, None, Config::default()) + >::from_elf(&elf, None, Config::default()) .unwrap(); executable.set_syscall_registry(register_syscalls(&mut invoke_context).unwrap()); executable.jit_compile().unwrap(); @@ -223,7 +223,7 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) { let elf = load_elf("tuner").unwrap(); let mut executable = - Executable::::from_elf(&elf, None, Config::default()) + >::from_elf(&elf, None, Config::default()) .unwrap(); executable.set_syscall_registry(register_syscalls(&mut invoke_context).unwrap()); let compute_meter = invoke_context.get_compute_meter();