diff --git a/programs/bpf_loader/src/serialization.rs b/programs/bpf_loader/src/serialization.rs index d0b0063f4..2eadd33ad 100644 --- a/programs/bpf_loader/src/serialization.rs +++ b/programs/bpf_loader/src/serialization.rs @@ -316,11 +316,13 @@ pub fn deserialize_parameters_aligned( #[cfg(test)] mod tests { use super::*; + use solana_program_runtime::invoke_context::{prepare_mock_invoke_context, ThisInvokeContext}; use solana_sdk::{ account::{Account, AccountSharedData}, account_info::AccountInfo, bpf_loader, entrypoint::deserialize, + process_instruction::InvokeContext, }; use std::{ cell::RefCell, @@ -334,97 +336,137 @@ mod tests { let program_id = solana_sdk::pubkey::new_rand(); let dup_key = solana_sdk::pubkey::new_rand(); let dup_key2 = solana_sdk::pubkey::new_rand(); - let keys = vec![ - dup_key, - dup_key, - solana_sdk::pubkey::new_rand(), - solana_sdk::pubkey::new_rand(), - dup_key2, - dup_key2, - solana_sdk::pubkey::new_rand(), - solana_sdk::pubkey::new_rand(), + let keyed_accounts = [ + ( + false, + false, + program_id, + Rc::new(RefCell::new(AccountSharedData::from(Account { + lamports: 0, + data: vec![], + owner: bpf_loader::id(), + executable: true, + rent_epoch: 0, + }))), + ), + ( + false, + false, + dup_key, + Rc::new(RefCell::new(AccountSharedData::from(Account { + lamports: 1, + data: vec![1u8, 2, 3, 4, 5], + owner: bpf_loader::id(), + executable: false, + rent_epoch: 100, + }))), + ), + ( + false, + false, + dup_key, + Rc::new(RefCell::new(AccountSharedData::from(Account { + lamports: 1, + data: vec![1u8, 2, 3, 4, 5], + owner: bpf_loader::id(), + executable: false, + rent_epoch: 100, + }))), + ), + ( + false, + false, + solana_sdk::pubkey::new_rand(), + Rc::new(RefCell::new(AccountSharedData::from(Account { + lamports: 2, + data: vec![11u8, 12, 13, 14, 15, 16, 17, 18, 19], + owner: bpf_loader::id(), + executable: true, + rent_epoch: 200, + }))), + ), + ( + false, + false, + solana_sdk::pubkey::new_rand(), + Rc::new(RefCell::new(AccountSharedData::from(Account { + lamports: 3, + data: vec![], + owner: bpf_loader::id(), + executable: false, + rent_epoch: 3100, + }))), + ), + ( + false, + true, + dup_key2, + Rc::new(RefCell::new(AccountSharedData::from(Account { + lamports: 4, + data: vec![1u8, 2, 3, 4, 5], + owner: bpf_loader::id(), + executable: false, + rent_epoch: 100, + }))), + ), + ( + false, + true, + dup_key2, + Rc::new(RefCell::new(AccountSharedData::from(Account { + lamports: 4, + data: vec![1u8, 2, 3, 4, 5], + owner: bpf_loader::id(), + executable: false, + rent_epoch: 100, + }))), + ), + ( + false, + true, + solana_sdk::pubkey::new_rand(), + Rc::new(RefCell::new(AccountSharedData::from(Account { + lamports: 5, + data: vec![11u8, 12, 13, 14, 15, 16, 17, 18, 19], + owner: bpf_loader::id(), + executable: true, + rent_epoch: 200, + }))), + ), + ( + false, + true, + solana_sdk::pubkey::new_rand(), + Rc::new(RefCell::new(AccountSharedData::from(Account { + lamports: 6, + data: vec![], + owner: bpf_loader::id(), + executable: false, + rent_epoch: 3100, + }))), + ), ]; - let accounts = [ - RefCell::new(AccountSharedData::from(Account { - lamports: 1, - data: vec![1u8, 2, 3, 4, 5], - owner: bpf_loader::id(), - executable: false, - rent_epoch: 100, - })), - // dup - RefCell::new(AccountSharedData::from(Account { - lamports: 1, - data: vec![1u8, 2, 3, 4, 5], - owner: bpf_loader::id(), - executable: false, - rent_epoch: 100, - })), - RefCell::new(AccountSharedData::from(Account { - lamports: 2, - data: vec![11u8, 12, 13, 14, 15, 16, 17, 18, 19], - owner: bpf_loader::id(), - executable: true, - rent_epoch: 200, - })), - RefCell::new(AccountSharedData::from(Account { - lamports: 3, - data: vec![], - owner: bpf_loader::id(), - executable: false, - rent_epoch: 3100, - })), - RefCell::new(AccountSharedData::from(Account { - lamports: 4, - data: vec![1u8, 2, 3, 4, 5], - owner: bpf_loader::id(), - executable: false, - rent_epoch: 100, - })), - // dup - RefCell::new(AccountSharedData::from(Account { - lamports: 4, - data: vec![1u8, 2, 3, 4, 5], - owner: bpf_loader::id(), - executable: false, - rent_epoch: 100, - })), - RefCell::new(AccountSharedData::from(Account { - lamports: 5, - data: vec![11u8, 12, 13, 14, 15, 16, 17, 18, 19], - owner: bpf_loader::id(), - executable: true, - rent_epoch: 200, - })), - RefCell::new(AccountSharedData::from(Account { - lamports: 6, - data: vec![], - owner: bpf_loader::id(), - executable: false, - rent_epoch: 3100, - })), - ]; - - let keyed_accounts: Vec<_> = keys - .iter() - .zip(&accounts) - .enumerate() - .map(|(i, (key, account))| { - if i <= accounts.len() / 2 { - KeyedAccount::new_readonly(key, false, account) - } else { - KeyedAccount::new(key, false, account) - } - }) - .collect(); let instruction_data = vec![1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; + let program_indices = [0]; + let preparation = + prepare_mock_invoke_context(&program_indices, &instruction_data, &keyed_accounts); + let mut invoke_context = ThisInvokeContext::new_mock(&preparation.accounts, &[]); + invoke_context + .push( + &preparation.message, + &preparation.message.instructions[0], + &program_indices, + Some(&preparation.account_indices), + ) + .unwrap(); // check serialize_parameters_aligned + let ser_keyed_accounts = invoke_context.get_keyed_accounts().unwrap(); let (mut serialized, account_lengths) = serialize_parameters( &bpf_loader::id(), &program_id, - &keyed_accounts, + &ser_keyed_accounts[1..], &instruction_data, ) .unwrap(); @@ -438,8 +480,8 @@ mod tests { (&de_instruction_data[0] as *const u8).align_offset(align_of::()), 0 ); - for ((account, account_info), key) in accounts.iter().zip(de_accounts).zip(keys.clone()) { - assert_eq!(key, *account_info.key); + for ((_, _, key, account), account_info) in keyed_accounts.iter().skip(1).zip(de_accounts) { + assert_eq!(key, account_info.key); let account = account.borrow(); assert_eq!(account.lamports(), account_info.lamports()); assert_eq!(account.data(), &account_info.data.borrow()[..]); @@ -461,31 +503,18 @@ mod tests { ); } - let de_accounts = accounts.clone(); - let de_keyed_accounts: Vec<_> = keys - .iter() - .zip(&de_accounts) - .enumerate() - .map(|(i, (key, account))| { - if i <= accounts.len() / 2 { - KeyedAccount::new_readonly(key, false, account) - } else { - KeyedAccount::new(key, false, account) - } - }) - .collect(); + let de_keyed_accounts = invoke_context.get_keyed_accounts().unwrap(); deserialize_parameters( &bpf_loader::id(), - &de_keyed_accounts, + &de_keyed_accounts[1..], serialized.as_slice(), &account_lengths, true, ) .unwrap(); - for ((account, de_keyed_account), key) in - accounts.iter().zip(de_keyed_accounts).zip(keys.clone()) + for ((_, _, key, account), de_keyed_account) in keyed_accounts.iter().zip(de_keyed_accounts) { - assert_eq!(key, *de_keyed_account.unsigned_key()); + assert_eq!(key, de_keyed_account.unsigned_key()); let account = account.borrow(); assert_eq!(account.executable(), de_keyed_account.executable().unwrap()); assert_eq!(account.rent_epoch(), de_keyed_account.rent_epoch().unwrap()); @@ -493,10 +522,11 @@ mod tests { // check serialize_parameters_unaligned + let ser_keyed_accounts = invoke_context.get_keyed_accounts().unwrap(); let (mut serialized, account_lengths) = serialize_parameters( &bpf_loader_deprecated::id(), &program_id, - &keyed_accounts, + &ser_keyed_accounts[1..], &instruction_data, ) .unwrap(); @@ -505,8 +535,8 @@ mod tests { unsafe { deserialize_unaligned(&mut serialized.as_slice_mut()[0] as *mut u8) }; assert_eq!(&program_id, de_program_id); assert_eq!(instruction_data, de_instruction_data); - for ((account, account_info), key) in accounts.iter().zip(de_accounts).zip(keys.clone()) { - assert_eq!(key, *account_info.key); + for ((_, _, key, account), account_info) in keyed_accounts.iter().skip(1).zip(de_accounts) { + assert_eq!(key, account_info.key); let account = account.borrow(); assert_eq!(account.lamports(), account_info.lamports()); assert_eq!(account.data(), &account_info.data.borrow()[..]); @@ -515,31 +545,18 @@ mod tests { assert_eq!(account.rent_epoch(), account_info.rent_epoch); } - let de_accounts = accounts.clone(); - let de_keyed_accounts: Vec<_> = keys - .iter() - .zip(&de_accounts) - .enumerate() - .map(|(i, (key, account))| { - if i < accounts.len() / 2 { - KeyedAccount::new_readonly(key, false, account) - } else { - KeyedAccount::new(key, false, account) - } - }) - .collect(); + let de_keyed_accounts = invoke_context.get_keyed_accounts().unwrap(); deserialize_parameters( &bpf_loader_deprecated::id(), - &de_keyed_accounts, + &de_keyed_accounts[1..], serialized.as_slice(), &account_lengths, true, ) .unwrap(); - for ((account, de_keyed_account), key) in - accounts.iter().zip(de_keyed_accounts).zip(keys.clone()) + for ((_, _, key, account), de_keyed_account) in keyed_accounts.iter().zip(de_keyed_accounts) { - assert_eq!(key, *de_keyed_account.unsigned_key()); + assert_eq!(key, de_keyed_account.unsigned_key()); let account = account.borrow(); assert_eq!(account.lamports(), de_keyed_account.lamports().unwrap()); assert_eq!(