diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index 2f4739318d..8d6f2defa6 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -94,4 +94,396 @@ pub fn process_instruction( } #[cfg(test)] -mod tests {} +mod tests { + use super::*; + use crate::{config_instruction, get_config_data, id, ConfigKeys, ConfigState}; + use bincode::serialized_size; + use serde_derive::{Deserialize, Serialize}; + use solana_sdk::{ + account::{create_keyed_is_signer_accounts, Account}, + signature::{Keypair, KeypairUtil}, + system_instruction::SystemInstruction, + }; + + #[derive(Serialize, Deserialize, Debug, PartialEq)] + struct MyConfig { + pub item: u64, + } + impl Default for MyConfig { + fn default() -> Self { + Self { item: 123456789 } + } + } + impl MyConfig { + pub fn new(item: u64) -> Self { + Self { item } + } + pub fn deserialize(input: &[u8]) -> Option { + deserialize(input).ok() + } + } + + impl ConfigState for MyConfig { + fn max_space() -> u64 { + serialized_size(&Self::default()).unwrap() + } + } + + fn create_config_account(keys: Vec<(Pubkey, bool)>) -> (Keypair, Account) { + let from_pubkey = Pubkey::new_rand(); + let config_keypair = Keypair::new(); + let config_pubkey = config_keypair.pubkey(); + + let instructions = + config_instruction::create_account::(&from_pubkey, &config_pubkey, 1, keys); + + let system_instruction = limited_deserialize(&instructions[0].data).unwrap(); + let space = match system_instruction { + SystemInstruction::CreateAccount { + lamports: _, + space, + program_id: _, + } => space, + _ => panic!("Not a CreateAccount system instruction"), + }; + let mut config_account = Account { + data: vec![0; space as usize], + ..Account::default() + }; + let mut accounts = vec![(&config_pubkey, true, &mut config_account)]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instructions[1].data), + Ok(()) + ); + + (config_keypair, config_account) + } + + #[test] + fn test_process_create_ok() { + solana_logger::setup(); + let keys = vec![]; + let (_, config_account) = create_config_account(keys.clone()); + assert_eq!( + Some(MyConfig::default()), + deserialize(get_config_data(&config_account.data).unwrap()).ok() + ); + } + + #[test] + fn test_process_store_ok() { + solana_logger::setup(); + let keys = vec![]; + let (config_keypair, mut config_account) = create_config_account(keys.clone()); + let config_pubkey = config_keypair.pubkey(); + let my_config = MyConfig::new(42); + + let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); + let mut accounts = vec![(&config_pubkey, true, &mut config_account)]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Ok(()) + ); + assert_eq!( + Some(my_config), + deserialize(get_config_data(&config_account.data).unwrap()).ok() + ); + } + + #[test] + fn test_process_store_fail_instruction_data_too_large() { + solana_logger::setup(); + let keys = vec![]; + let (config_keypair, mut config_account) = create_config_account(keys.clone()); + let config_pubkey = config_keypair.pubkey(); + let my_config = MyConfig::new(42); + + let mut instruction = + config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); + instruction.data = vec![0; 123]; // <-- Replace data with a vector that's too large + let mut accounts = vec![(&config_pubkey, true, &mut config_account)]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Err(InstructionError::InvalidInstructionData) + ); + } + + #[test] + fn test_process_store_fail_account0_not_signer() { + solana_logger::setup(); + let keys = vec![]; + let (config_keypair, mut config_account) = create_config_account(keys.clone()); + let config_pubkey = config_keypair.pubkey(); + let my_config = MyConfig::new(42); + + let mut instruction = config_instruction::store(&config_pubkey, true, vec![], &my_config); + instruction.accounts[0].is_signer = false; // <----- not a signer + let mut accounts = vec![(&config_pubkey, false, &mut config_account)]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Err(InstructionError::MissingRequiredSignature) + ); + } + + #[test] + fn test_process_store_with_additional_signers() { + solana_logger::setup(); + let pubkey = Pubkey::new_rand(); + let signer0_pubkey = Pubkey::new_rand(); + let signer1_pubkey = Pubkey::new_rand(); + let keys = vec![ + (pubkey, false), + (signer0_pubkey, true), + (signer1_pubkey, true), + ]; + let (config_keypair, mut config_account) = create_config_account(keys.clone()); + let config_pubkey = config_keypair.pubkey(); + let my_config = MyConfig::new(42); + + let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); + let mut signer0_account = Account::default(); + let mut signer1_account = Account::default(); + let mut accounts = vec![ + (&config_pubkey, true, &mut config_account), + (&signer0_pubkey, true, &mut signer0_account), + (&signer1_pubkey, true, &mut signer1_account), + ]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Ok(()) + ); + let meta_data: ConfigKeys = deserialize(&config_account.data).unwrap(); + assert_eq!(meta_data.keys, keys); + assert_eq!( + Some(my_config), + deserialize(get_config_data(&config_account.data).unwrap()).ok() + ); + } + + #[test] + fn test_process_store_without_config_signer() { + solana_logger::setup(); + let pubkey = Pubkey::new_rand(); + let signer0_pubkey = Pubkey::new_rand(); + let keys = vec![(pubkey, false), (signer0_pubkey, true)]; + let (config_keypair, _) = create_config_account(keys.clone()); + let config_pubkey = config_keypair.pubkey(); + let my_config = MyConfig::new(42); + + let instruction = + config_instruction::store(&config_pubkey, false, keys.clone(), &my_config); + let mut signer0_account = Account::default(); + let mut accounts = vec![(&signer0_pubkey, true, &mut signer0_account)]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Err(InstructionError::InvalidAccountData) + ); + } + + #[test] + fn test_process_store_with_bad_additional_signer() { + solana_logger::setup(); + let signer0_pubkey = Pubkey::new_rand(); + let signer1_pubkey = Pubkey::new_rand(); + let mut signer0_account = Account::default(); + let mut signer1_account = Account::default(); + let keys = vec![(signer0_pubkey, true)]; + let (config_keypair, mut config_account) = create_config_account(keys.clone()); + let config_pubkey = config_keypair.pubkey(); + let my_config = MyConfig::new(42); + + let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); + + // Config-data pubkey doesn't match signer + let mut accounts = vec![ + (&config_pubkey, true, &mut config_account), + (&signer1_pubkey, true, &mut signer1_account), + ]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Err(InstructionError::MissingRequiredSignature) + ); + + // Config-data pubkey not a signer + let mut accounts = vec![ + (&config_pubkey, true, &mut config_account), + (&signer0_pubkey, false, &mut signer0_account), + ]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Err(InstructionError::MissingRequiredSignature) + ); + } + + #[test] + fn test_config_updates() { + solana_logger::setup(); + let pubkey = Pubkey::new_rand(); + let signer0_pubkey = Pubkey::new_rand(); + let signer1_pubkey = Pubkey::new_rand(); + let signer2_pubkey = Pubkey::new_rand(); + let mut signer0_account = Account::default(); + let mut signer1_account = Account::default(); + let mut signer2_account = Account::default(); + let keys = vec![ + (pubkey, false), + (signer0_pubkey, true), + (signer1_pubkey, true), + ]; + let (config_keypair, mut config_account) = create_config_account(keys.clone()); + let config_pubkey = config_keypair.pubkey(); + let my_config = MyConfig::new(42); + + let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); + let mut accounts = vec![ + (&config_pubkey, true, &mut config_account), + (&signer0_pubkey, true, &mut signer0_account), + (&signer1_pubkey, true, &mut signer1_account), + ]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Ok(()) + ); + + // Update with expected signatures + let new_config = MyConfig::new(84); + let instruction = + config_instruction::store(&config_pubkey, false, keys.clone(), &new_config); + let mut accounts = vec![ + (&config_pubkey, false, &mut config_account), + (&signer0_pubkey, true, &mut signer0_account), + (&signer1_pubkey, true, &mut signer1_account), + ]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Ok(()) + ); + let meta_data: ConfigKeys = deserialize(&config_account.data).unwrap(); + assert_eq!(meta_data.keys, keys); + assert_eq!( + new_config, + MyConfig::deserialize(get_config_data(&config_account.data).unwrap()).unwrap() + ); + + // Attempt update with incomplete signatures + let keys = vec![(pubkey, false), (signer0_pubkey, true)]; + let instruction = + config_instruction::store(&config_pubkey, false, keys.clone(), &my_config); + let mut accounts = vec![ + (&config_pubkey, false, &mut config_account), + (&signer0_pubkey, true, &mut signer0_account), + (&signer1_pubkey, false, &mut signer1_account), + ]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Err(InstructionError::MissingRequiredSignature) + ); + + // Attempt update with incorrect signatures + let keys = vec![ + (pubkey, false), + (signer0_pubkey, true), + (signer2_pubkey, true), + ]; + let instruction = + config_instruction::store(&config_pubkey, false, keys.clone(), &my_config); + let mut accounts = vec![ + (&config_pubkey, false, &mut config_account), + (&signer0_pubkey, true, &mut signer0_account), + (&signer2_pubkey, true, &mut signer2_account), + ]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Err(InstructionError::MissingRequiredSignature) + ); + } + + #[test] + fn test_config_updates_requiring_config() { + solana_logger::setup(); + let pubkey = Pubkey::new_rand(); + let signer0_pubkey = Pubkey::new_rand(); + let mut signer0_account = Account::default(); + let keys = vec![ + (pubkey, false), + (signer0_pubkey, true), + (signer0_pubkey, true), + ]; // Dummy keys for account sizing + let (config_keypair, mut config_account) = create_config_account(keys.clone()); + let config_pubkey = config_keypair.pubkey(); + let my_config = MyConfig::new(42); + + let keys = vec![ + (pubkey, false), + (signer0_pubkey, true), + (config_keypair.pubkey(), true), + ]; + + let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); + let mut accounts = vec![ + (&config_pubkey, true, &mut config_account), + (&signer0_pubkey, true, &mut signer0_account), + ]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Ok(()) + ); + + // Update with expected signatures + let new_config = MyConfig::new(84); + let instruction = + config_instruction::store(&config_pubkey, true, keys.clone(), &new_config); + let mut accounts = vec![ + (&config_pubkey, true, &mut config_account), + (&signer0_pubkey, true, &mut signer0_account), + ]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Ok(()) + ); + let meta_data: ConfigKeys = deserialize(&config_account.data).unwrap(); + assert_eq!(meta_data.keys, keys); + assert_eq!( + new_config, + MyConfig::deserialize(get_config_data(&config_account.data).unwrap()).unwrap() + ); + + // Attempt update with incomplete signatures + let keys = vec![(pubkey, false), (config_keypair.pubkey(), true)]; + let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); + let mut accounts = vec![(&config_pubkey, true, &mut config_account)]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instruction.data), + Err(InstructionError::MissingRequiredSignature) + ); + } + + #[test] + fn test_config_initialize_no_panic() { + let from_pubkey = Pubkey::new_rand(); + let config_pubkey = Pubkey::new_rand(); + let instructions = + config_instruction::create_account::(&from_pubkey, &config_pubkey, 1, vec![]); + let mut accounts = vec![]; + let mut keyed_accounts = create_keyed_is_signer_accounts(&mut accounts); + assert_eq!( + process_instruction(&id(), &mut keyed_accounts, &instructions[1].data), + Err(InstructionError::NotEnoughAccountKeys) + ); + } +} diff --git a/programs/config_tests/Cargo.toml b/programs/config_tests/Cargo.toml deleted file mode 100644 index f34f1fccbf..0000000000 --- a/programs/config_tests/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "solana-config-tests" -version = "0.22.0" -description = "Solana config api tests" -authors = ["Solana Maintainers "] -repository = "https://github.com/solana-labs/solana" -license = "Apache-2.0" -homepage = "https://solana.com/" -edition = "2018" - -[dependencies] -bincode = "1.2.0" -log = "0.4.8" -serde = "1.0.103" -serde_derive = "1.0.103" -solana-logger = { path = "../../logger", version = "0.22.0" } -solana-sdk = { path = "../../sdk", version = "0.22.0" } -solana-config-program = { path = "../config", version = "0.22.0" } - - -[dev-dependencies] -solana-runtime = { path = "../../runtime", version = "0.22.0" } -assert_matches = "1.3.0" diff --git a/programs/config_tests/tests/config_processor.rs b/programs/config_tests/tests/config_processor.rs deleted file mode 100644 index 939d6967c2..0000000000 --- a/programs/config_tests/tests/config_processor.rs +++ /dev/null @@ -1,392 +0,0 @@ -//! Config program - -use bincode::{deserialize, serialized_size}; -use serde_derive::{Deserialize, Serialize}; -use solana_config_program::{ - config_instruction, config_processor::process_instruction, get_config_data, id, ConfigKeys, - ConfigState, -}; -use solana_runtime::{bank::Bank, bank_client::BankClient}; -use solana_sdk::{ - client::SyncClient, - genesis_config::create_genesis_config, - instruction::InstructionError, - message::Message, - pubkey::Pubkey, - signature::{Keypair, KeypairUtil}, - system_instruction, - transaction::TransactionError, -}; - -#[derive(Serialize, Deserialize, Debug, PartialEq)] -struct MyConfig { - pub item: u64, -} -impl Default for MyConfig { - fn default() -> Self { - Self { item: 123456789 } - } -} -impl MyConfig { - pub fn new(item: u64) -> Self { - Self { item } - } - pub fn deserialize(input: &[u8]) -> Option { - deserialize(input).ok() - } -} - -impl ConfigState for MyConfig { - fn max_space() -> u64 { - serialized_size(&Self::default()).unwrap() - } -} - -fn create_bank(lamports: u64) -> (Bank, Keypair) { - let (genesis_config, mint_keypair) = create_genesis_config(lamports); - let mut bank = Bank::new(&genesis_config); - bank.add_instruction_processor(id(), process_instruction); - (bank, mint_keypair) -} - -fn create_config_account( - bank: Bank, - mint_keypair: &Keypair, - keys: Vec<(Pubkey, bool)>, -) -> (BankClient, Keypair) { - let config_keypair = Keypair::new(); - let config_pubkey = config_keypair.pubkey(); - - let bank_client = BankClient::new(bank); - bank_client - .send_message( - &[mint_keypair, &config_keypair], - Message::new(config_instruction::create_account::( - &mint_keypair.pubkey(), - &config_pubkey, - 1, - keys, - )), - ) - .expect("new_account"); - - (bank_client, config_keypair) -} - -#[test] -fn test_process_create_ok() { - solana_logger::setup(); - let (bank, mint_keypair) = create_bank(10_000); - let (bank_client, config_keypair) = create_config_account(bank, &mint_keypair, vec![]); - let config_account_data = bank_client - .get_account_data(&config_keypair.pubkey()) - .unwrap() - .unwrap(); - assert_eq!( - Some(MyConfig::default()), - deserialize(get_config_data(&config_account_data).unwrap()).ok() - ); -} - -#[test] -fn test_process_store_ok() { - solana_logger::setup(); - let (bank, mint_keypair) = create_bank(10_000); - let keys = vec![]; - let (bank_client, config_keypair) = create_config_account(bank, &mint_keypair, keys.clone()); - let config_pubkey = config_keypair.pubkey(); - - let my_config = MyConfig::new(42); - - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - - bank_client - .send_message(&[&mint_keypair, &config_keypair], message) - .unwrap(); - - let config_account_data = bank_client - .get_account_data(&config_pubkey) - .unwrap() - .unwrap(); - assert_eq!( - Some(my_config), - deserialize(get_config_data(&config_account_data).unwrap()).ok() - ); -} - -#[test] -fn test_process_store_fail_instruction_data_too_large() { - solana_logger::setup(); - let (bank, mint_keypair) = create_bank(10_000); - let (bank_client, config_keypair) = create_config_account(bank, &mint_keypair, vec![]); - let config_pubkey = config_keypair.pubkey(); - - let my_config = MyConfig::new(42); - - let mut instruction = config_instruction::store(&config_pubkey, true, vec![], &my_config); - instruction.data = vec![0; 123]; // <-- Replace data with a vector that's too large - let message = Message::new(vec![instruction]); - bank_client - .send_message(&[&config_keypair], message) - .unwrap_err(); -} - -#[test] -fn test_process_store_fail_account0_not_signer() { - solana_logger::setup(); - let (bank, mint_keypair) = create_bank(10_000); - let system_keypair = Keypair::new(); - let system_pubkey = system_keypair.pubkey(); - - bank.transfer(42, &mint_keypair, &system_pubkey).unwrap(); - let (bank_client, config_keypair) = create_config_account(bank, &mint_keypair, vec![]); - let config_pubkey = config_keypair.pubkey(); - - let transfer_instruction = - system_instruction::transfer(&system_pubkey, &Pubkey::new_rand(), 42); - let my_config = MyConfig::new(42); - let mut store_instruction = config_instruction::store(&config_pubkey, true, vec![], &my_config); - store_instruction.accounts[0].is_signer = false; // <----- not a signer - - let message = Message::new(vec![transfer_instruction, store_instruction]); - bank_client - .send_message(&[&system_keypair], message) - .unwrap_err(); -} - -#[test] -fn test_process_store_with_additional_signers() { - solana_logger::setup(); - let (bank, mint_keypair) = create_bank(10_000); - let pubkey = Pubkey::new_rand(); - let signer0 = Keypair::new(); - let signer1 = Keypair::new(); - let keys = vec![ - (pubkey, false), - (signer0.pubkey(), true), - (signer1.pubkey(), true), - ]; - let (bank_client, config_keypair) = create_config_account(bank, &mint_keypair, keys.clone()); - let config_pubkey = config_keypair.pubkey(); - - let my_config = MyConfig::new(42); - - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - - bank_client - .send_message( - &[&mint_keypair, &config_keypair, &signer0, &signer1], - message, - ) - .unwrap(); - - let config_account_data = bank_client - .get_account_data(&config_pubkey) - .unwrap() - .unwrap(); - let meta_data: ConfigKeys = deserialize(&config_account_data).unwrap(); - assert_eq!(meta_data.keys, keys); - assert_eq!( - Some(my_config), - deserialize(get_config_data(&config_account_data).unwrap()).ok() - ); -} - -#[test] -fn test_process_store_without_config_signer() { - solana_logger::setup(); - let (bank, mint_keypair) = create_bank(10_000); - let pubkey = Pubkey::new_rand(); - let signer0 = Keypair::new(); - let keys = vec![(pubkey, false), (signer0.pubkey(), true)]; - let (bank_client, config_keypair) = create_config_account(bank, &mint_keypair, keys.clone()); - let config_pubkey = config_keypair.pubkey(); - - let my_config = MyConfig::new(42); - - let instruction = config_instruction::store(&config_pubkey, false, keys.clone(), &my_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - - bank_client - .send_message(&[&mint_keypair, &signer0], message) - .unwrap_err(); -} - -#[test] -fn test_process_store_with_bad_additional_signer() { - solana_logger::setup(); - let (bank, mint_keypair) = create_bank(10_000); - let signer0 = Keypair::new(); - let signer1 = Keypair::new(); - let keys = vec![(signer0.pubkey(), true)]; - let (bank_client, config_keypair) = create_config_account(bank, &mint_keypair, keys.clone()); - let config_pubkey = config_keypair.pubkey(); - - let my_config = MyConfig::new(42); - - // Config-data pubkey doesn't match signer - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); - let mut message = - Message::new_with_payer(vec![instruction.clone()], Some(&mint_keypair.pubkey())); - message.account_keys[2] = signer1.pubkey(); - bank_client - .send_message(&[&mint_keypair, &config_keypair, &signer1], message) - .unwrap_err(); - - // Config-data pubkey not a signer - let mut message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - message.header.num_required_signatures = 2; - bank_client - .send_message(&[&mint_keypair, &config_keypair], message) - .unwrap_err(); -} - -#[test] -fn test_config_updates() { - solana_logger::setup(); - let (bank, mint_keypair) = create_bank(10_000); - let pubkey = Pubkey::new_rand(); - let signer0 = Keypair::new(); - let signer1 = Keypair::new(); - let keys = vec![ - (pubkey, false), - (signer0.pubkey(), true), - (signer1.pubkey(), true), - ]; - let (bank_client, config_keypair) = create_config_account(bank, &mint_keypair, keys.clone()); - let config_pubkey = config_keypair.pubkey(); - - let my_config = MyConfig::new(42); - - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - - bank_client - .send_message( - &[&mint_keypair, &config_keypair, &signer0, &signer1], - message, - ) - .unwrap(); - - // Update with expected signatures - let new_config = MyConfig::new(84); - let instruction = config_instruction::store(&config_pubkey, false, keys.clone(), &new_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - bank_client - .send_message(&[&mint_keypair, &signer0, &signer1], message) - .unwrap(); - - let config_account_data = bank_client - .get_account_data(&config_pubkey) - .unwrap() - .unwrap(); - let meta_data: ConfigKeys = deserialize(&config_account_data).unwrap(); - assert_eq!(meta_data.keys, keys); - assert_eq!( - new_config, - MyConfig::deserialize(get_config_data(&config_account_data).unwrap()).unwrap() - ); - - // Attempt update with incomplete signatures - let keys = vec![(pubkey, false), (signer0.pubkey(), true)]; - let instruction = config_instruction::store(&config_pubkey, false, keys.clone(), &my_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - bank_client - .send_message(&[&mint_keypair, &signer0], message) - .unwrap_err(); - - // Attempt update with incorrect signatures - let signer2 = Keypair::new(); - let keys = vec![ - (pubkey, false), - (signer0.pubkey(), true), - (signer2.pubkey(), true), - ]; - let instruction = config_instruction::store(&config_pubkey, false, keys.clone(), &my_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - bank_client - .send_message(&[&mint_keypair, &signer0, &signer2], message) - .unwrap_err(); -} - -#[test] -fn test_config_updates_requiring_config() { - solana_logger::setup(); - let (bank, mint_keypair) = create_bank(10_000); - let pubkey = Pubkey::new_rand(); - let signer0 = Keypair::new(); - let keys = vec![ - (pubkey, false), - (signer0.pubkey(), true), - (signer0.pubkey(), true), - ]; // Dummy keys for account sizing - let (bank_client, config_keypair) = create_config_account(bank, &mint_keypair, keys.clone()); - let config_pubkey = config_keypair.pubkey(); - let keys = vec![ - (pubkey, false), - (signer0.pubkey(), true), - (config_keypair.pubkey(), true), - ]; - - let my_config = MyConfig::new(42); - - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - - bank_client - .send_message(&[&mint_keypair, &config_keypair, &signer0], message) - .unwrap(); - - // Update with expected signatures - let new_config = MyConfig::new(84); - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &new_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - bank_client - .send_message(&[&mint_keypair, &config_keypair, &signer0], message) - .unwrap(); - - let config_account_data = bank_client - .get_account_data(&config_pubkey) - .unwrap() - .unwrap(); - let meta_data: ConfigKeys = deserialize(&config_account_data).unwrap(); - assert_eq!(meta_data.keys, keys); - assert_eq!( - new_config, - MyConfig::deserialize(get_config_data(&config_account_data).unwrap()).unwrap() - ); - - // Attempt update with incomplete signatures - let keys = vec![(pubkey, false), (config_keypair.pubkey(), true)]; - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); - let message = Message::new_with_payer(vec![instruction], Some(&mint_keypair.pubkey())); - bank_client - .send_message(&[&mint_keypair, &config_keypair], message) - .unwrap_err(); -} - -#[test] -fn test_config_initialize_no_panic() { - let (bank, alice_keypair) = create_bank(3); - let bank_client = BankClient::new(bank); - let config_account = Keypair::new(); - - let mut instructions = config_instruction::create_account::( - &alice_keypair.pubkey(), - &config_account.pubkey(), - 1, - vec![], - ); - instructions[1].accounts = vec![]; //