Migrate config tests to Bank
This commit is contained in:
		| @@ -137,6 +137,7 @@ impl BudgetTransaction { | |||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
|     use super::*; |     use super::*; | ||||||
|  |     use crate::budget_expr::BudgetExpr; | ||||||
|     use bincode::{deserialize, serialize}; |     use bincode::{deserialize, serialize}; | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ fn process_instruction( | |||||||
|     _program_id: &Pubkey, |     _program_id: &Pubkey, | ||||||
|     keyed_accounts: &mut [KeyedAccount], |     keyed_accounts: &mut [KeyedAccount], | ||||||
|     data: &[u8], |     data: &[u8], | ||||||
|  |     _tick_height: u64, | ||||||
| ) -> Result<(), ProgramError> { | ) -> Result<(), ProgramError> { | ||||||
|     if !check_id(&keyed_accounts[0].account.owner) { |     if !check_id(&keyed_accounts[0].account.owner) { | ||||||
|         error!("account[0] is not assigned to the config program"); |         error!("account[0] is not assigned to the config program"); | ||||||
| @@ -36,13 +37,13 @@ fn entrypoint( | |||||||
|     program_id: &Pubkey, |     program_id: &Pubkey, | ||||||
|     keyed_accounts: &mut [KeyedAccount], |     keyed_accounts: &mut [KeyedAccount], | ||||||
|     data: &[u8], |     data: &[u8], | ||||||
|     _tick_height: u64, |     tick_height: u64, | ||||||
| ) -> Result<(), ProgramError> { | ) -> Result<(), ProgramError> { | ||||||
|     solana_logger::setup(); |     solana_logger::setup(); | ||||||
|  |  | ||||||
|     trace!("process_instruction: {:?}", data); |     trace!("process_instruction: {:?}", data); | ||||||
|     trace!("keyed_accounts: {:?}", keyed_accounts); |     trace!("keyed_accounts: {:?}", keyed_accounts); | ||||||
|     process_instruction(program_id, keyed_accounts, data) |     process_instruction(program_id, keyed_accounts, data, tick_height) | ||||||
| } | } | ||||||
|  |  | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| @@ -50,14 +51,13 @@ mod tests { | |||||||
|     use super::*; |     use super::*; | ||||||
|     use bincode::{deserialize, serialized_size}; |     use bincode::{deserialize, serialized_size}; | ||||||
|     use serde_derive::{Deserialize, Serialize}; |     use serde_derive::{Deserialize, Serialize}; | ||||||
|     use solana_config_api::{id, ConfigInstruction, ConfigState, ConfigTransaction}; |     use solana_config_api::{id, ConfigInstruction, ConfigState}; | ||||||
|     use solana_runtime::runtime; |     use solana_runtime::bank::Bank; | ||||||
|     use solana_sdk::account::Account; |     use solana_runtime::bank_client::BankClient; | ||||||
|     use solana_sdk::hash::Hash; |     use solana_sdk::genesis_block::GenesisBlock; | ||||||
|     use solana_sdk::signature::{Keypair, KeypairUtil}; |     use solana_sdk::signature::{Keypair, KeypairUtil}; | ||||||
|     use solana_sdk::system_instruction::SystemInstruction; |     use solana_sdk::system_instruction::SystemInstruction; | ||||||
|     use solana_sdk::system_program; |     use solana_sdk::transaction::{Instruction, Transaction}; | ||||||
|     use solana_sdk::transaction::Transaction; |  | ||||||
|  |  | ||||||
|     #[derive(Serialize, Deserialize, Default, Debug, PartialEq)] |     #[derive(Serialize, Deserialize, Default, Debug, PartialEq)] | ||||||
|     struct MyConfig { |     struct MyConfig { | ||||||
| @@ -78,125 +78,95 @@ mod tests { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn create_config_account() -> Account { |     fn create_bank(lamports: u64) -> (Bank, Keypair) { | ||||||
|         Account::new(1, MyConfig::max_space() as usize, &id()) |         let (genesis_block, mint_keypair) = GenesisBlock::new(lamports); | ||||||
|  |         let mut bank = Bank::new(&genesis_block); | ||||||
|  |         bank.add_instruction_processor(id(), process_instruction); | ||||||
|  |         (bank, mint_keypair) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn process_transaction( |     fn create_account_instruction(from_pubkey: &Pubkey, config_pubkey: &Pubkey) -> Instruction { | ||||||
|         tx: &Transaction, |         ConfigInstruction::new_account::<MyConfig>(&from_pubkey, &config_pubkey, 1) | ||||||
|         tx_accounts: &mut Vec<Account>, |     } | ||||||
|     ) -> Result<(), ProgramError> { |  | ||||||
|         runtime::process_transaction(tx, tx_accounts, process_instruction) |     fn create_config_client(bank: &Bank, from_keypair: Keypair) -> BankClient { | ||||||
|  |         let from_client = BankClient::new(&bank, from_keypair); | ||||||
|  |         let from_pubkey = from_client.pubkey(); | ||||||
|  |         let config_client = BankClient::new(&bank, Keypair::new()); | ||||||
|  |         let config_pubkey = config_client.pubkey(); | ||||||
|  |  | ||||||
|  |         let instruction = create_account_instruction(&from_pubkey, &config_pubkey); | ||||||
|  |         from_client.process_script(vec![instruction]).unwrap(); | ||||||
|  |  | ||||||
|  |         config_client | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_process_create_ok() { |     fn test_process_create_ok() { | ||||||
|         solana_logger::setup(); |         solana_logger::setup(); | ||||||
|         let from_account_keypair = Keypair::new(); |         let (bank, from_keypair) = create_bank(10_000); | ||||||
|         let from_account = Account::new(1, 0, &system_program::id()); |         let config_client = create_config_client(&bank, from_keypair); | ||||||
|  |         let config_account = bank.get_account(&config_client.pubkey()).unwrap(); | ||||||
|         let config_account_keypair = Keypair::new(); |         assert_eq!(id(), config_account.owner); | ||||||
|         let config_account = Account::new(0, 0, &system_program::id()); |  | ||||||
|  |  | ||||||
|         let transaction = ConfigTransaction::new_account::<MyConfig>( |  | ||||||
|             &from_account_keypair, |  | ||||||
|             &config_account_keypair.pubkey(), |  | ||||||
|             Hash::default(), |  | ||||||
|             1, |  | ||||||
|             0, |  | ||||||
|         ); |  | ||||||
|         let mut accounts = vec![from_account, config_account]; |  | ||||||
|         process_transaction(&transaction, &mut accounts).unwrap(); |  | ||||||
|  |  | ||||||
|         assert_eq!(id(), accounts[1].owner); |  | ||||||
|         assert_eq!( |         assert_eq!( | ||||||
|             MyConfig::default(), |             MyConfig::default(), | ||||||
|             MyConfig::deserialize(&accounts[1].data).unwrap() |             MyConfig::deserialize(&config_account.data).unwrap() | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_process_store_ok() { |     fn test_process_store_ok() { | ||||||
|         solana_logger::setup(); |         solana_logger::setup(); | ||||||
|         let config_account_keypair = Keypair::new(); |         let (bank, from_keypair) = create_bank(10_000); | ||||||
|         let config_account = create_config_account(); |         let config_client = create_config_client(&bank, from_keypair); | ||||||
|  |         let config_pubkey = config_client.pubkey(); | ||||||
|  |  | ||||||
|         let new_config_state = MyConfig::new(42); |         let my_config = MyConfig::new(42); | ||||||
|  |         let instruction = ConfigInstruction::new_store(&config_pubkey, &my_config); | ||||||
|         let transaction = ConfigTransaction::new_store( |         config_client.process_script(vec![instruction]).unwrap(); | ||||||
|             &config_account_keypair, |  | ||||||
|             &new_config_state, |  | ||||||
|             Hash::default(), |  | ||||||
|             0, |  | ||||||
|         ); |  | ||||||
|  |  | ||||||
|         let mut accounts = vec![config_account]; |  | ||||||
|         process_transaction(&transaction, &mut accounts).unwrap(); |  | ||||||
|  |  | ||||||
|  |         let config_account = bank.get_account(&config_pubkey).unwrap(); | ||||||
|         assert_eq!( |         assert_eq!( | ||||||
|             new_config_state, |             my_config, | ||||||
|             MyConfig::deserialize(&accounts[0].data).unwrap() |             MyConfig::deserialize(&config_account.data).unwrap() | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_process_store_fail_instruction_data_too_large() { |     fn test_process_store_fail_instruction_data_too_large() { | ||||||
|         solana_logger::setup(); |         solana_logger::setup(); | ||||||
|         let config_account_keypair = Keypair::new(); |         let (bank, from_keypair) = create_bank(10_000); | ||||||
|         let config_account = create_config_account(); |         let config_client = create_config_client(&bank, from_keypair); | ||||||
|  |         let config_pubkey = config_client.pubkey(); | ||||||
|  |  | ||||||
|         let new_config_state = MyConfig::new(42); |         let my_config = MyConfig::new(42); | ||||||
|  |         let instruction = ConfigInstruction::new_store(&config_pubkey, &my_config); | ||||||
|         let mut transaction = ConfigTransaction::new_store( |  | ||||||
|             &config_account_keypair, |  | ||||||
|             &new_config_state, |  | ||||||
|             Hash::default(), |  | ||||||
|             0, |  | ||||||
|         ); |  | ||||||
|  |  | ||||||
|         // Replace instruction data with a vector that's too large |         // Replace instruction data with a vector that's too large | ||||||
|  |         let mut transaction = Transaction::new(vec![instruction]); | ||||||
|         transaction.instructions[0].data = vec![0; 123]; |         transaction.instructions[0].data = vec![0; 123]; | ||||||
|  |         config_client.process_transaction(transaction).unwrap_err(); | ||||||
|         let mut accounts = vec![config_account]; |  | ||||||
|         process_transaction(&transaction, &mut accounts).unwrap_err(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn test_process_store_fail_account0_invalid_owner() { |  | ||||||
|         solana_logger::setup(); |  | ||||||
|         let config_account_keypair = Keypair::new(); |  | ||||||
|         let mut config_account = create_config_account(); |  | ||||||
|         config_account.owner = Pubkey::default(); // <-- Invalid owner |  | ||||||
|  |  | ||||||
|         let new_config_state = MyConfig::new(42); |  | ||||||
|  |  | ||||||
|         let transaction = ConfigTransaction::new_store( |  | ||||||
|             &config_account_keypair, |  | ||||||
|             &new_config_state, |  | ||||||
|             Hash::default(), |  | ||||||
|             0, |  | ||||||
|         ); |  | ||||||
|         let mut accounts = vec![config_account]; |  | ||||||
|         process_transaction(&transaction, &mut accounts).unwrap_err(); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_process_store_fail_account0_not_signer() { |     fn test_process_store_fail_account0_not_signer() { | ||||||
|         solana_logger::setup(); |         solana_logger::setup(); | ||||||
|         let system_account_keypair = Keypair::new(); |         let (bank, from_keypair) = create_bank(10_000); | ||||||
|         let system_account = Account::new(42, 0, &system_program::id()); |         let system_keypair = Keypair::new(); | ||||||
|  |         let system_pubkey = system_keypair.pubkey(); | ||||||
|  |         bank.transfer(42, &from_keypair, &system_pubkey, bank.last_blockhash()) | ||||||
|  |             .unwrap(); | ||||||
|  |         let config_client = create_config_client(&bank, from_keypair); | ||||||
|  |         let config_pubkey = config_client.pubkey(); | ||||||
|  |  | ||||||
|         let config_account_keypair = Keypair::new(); |         let move_instruction = SystemInstruction::new_move(&system_pubkey, &Pubkey::default(), 42); | ||||||
|         let config_account = create_config_account(); |         let my_config = MyConfig::new(42); | ||||||
|  |         let store_instruction = ConfigInstruction::new_store(&config_pubkey, &my_config); | ||||||
|  |  | ||||||
|         let mut transaction = Transaction::new(vec![ |         // Don't sign the transaction with `config_client` | ||||||
|             SystemInstruction::new_move(&system_account_keypair.pubkey(), &Pubkey::default(), 42), |         let mut transaction = Transaction::new(vec![move_instruction, store_instruction]); | ||||||
|             ConfigInstruction::new_store(&config_account_keypair.pubkey(), &MyConfig::new(42)), |         transaction.sign_unchecked(&[&system_keypair], bank.last_blockhash()); | ||||||
|         ]); |         let system_client = BankClient::new(&bank, system_keypair); | ||||||
|  |         system_client.process_transaction(transaction).unwrap_err(); | ||||||
|         // Don't sign the transaction with `config_account_keypair` |  | ||||||
|         transaction.sign_unchecked(&[&system_account_keypair], Hash::default()); |  | ||||||
|         let mut accounts = vec![system_account, config_account]; |  | ||||||
|         process_transaction(&transaction, &mut accounts).unwrap_err(); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,45 +0,0 @@ | |||||||
| use crate::config_instruction::ConfigInstruction; |  | ||||||
| use crate::ConfigState; |  | ||||||
| use solana_sdk::hash::Hash; |  | ||||||
| use solana_sdk::pubkey::Pubkey; |  | ||||||
| use solana_sdk::signature::{Keypair, KeypairUtil}; |  | ||||||
| use solana_sdk::transaction::Transaction; |  | ||||||
|  |  | ||||||
| pub struct ConfigTransaction {} |  | ||||||
|  |  | ||||||
| impl ConfigTransaction { |  | ||||||
|     /// Create a new, empty configuration account |  | ||||||
|     pub fn new_account<T: ConfigState>( |  | ||||||
|         from_keypair: &Keypair, |  | ||||||
|         config_account_pubkey: &Pubkey, |  | ||||||
|         recent_blockhash: Hash, |  | ||||||
|         lamports: u64, |  | ||||||
|         fee: u64, |  | ||||||
|     ) -> Transaction { |  | ||||||
|         let mut transaction = Transaction::new(vec![ConfigInstruction::new_account::<T>( |  | ||||||
|             &from_keypair.pubkey(), |  | ||||||
|             config_account_pubkey, |  | ||||||
|             lamports, |  | ||||||
|         )]); |  | ||||||
|         transaction.fee = fee; |  | ||||||
|  |  | ||||||
|         transaction.sign(&[from_keypair], recent_blockhash); |  | ||||||
|         transaction |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// Store new state in a configuration account |  | ||||||
|     pub fn new_store<T: ConfigState>( |  | ||||||
|         config_account_keypair: &Keypair, |  | ||||||
|         data: &T, |  | ||||||
|         recent_blockhash: Hash, |  | ||||||
|         fee: u64, |  | ||||||
|     ) -> Transaction { |  | ||||||
|         let mut transaction = Transaction::new(vec![ConfigInstruction::new_store( |  | ||||||
|             &config_account_keypair.pubkey(), |  | ||||||
|             data, |  | ||||||
|         )]); |  | ||||||
|         transaction.fee = fee; |  | ||||||
|         transaction.sign(&[config_account_keypair], recent_blockhash); |  | ||||||
|         transaction |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -2,10 +2,8 @@ use serde::Serialize; | |||||||
| use solana_sdk::pubkey::Pubkey; | use solana_sdk::pubkey::Pubkey; | ||||||
|  |  | ||||||
| mod config_instruction; | mod config_instruction; | ||||||
| mod config_transaction; |  | ||||||
|  |  | ||||||
| pub use config_instruction::ConfigInstruction; | pub use config_instruction::ConfigInstruction; | ||||||
| pub use config_transaction::ConfigTransaction; |  | ||||||
|  |  | ||||||
| const CONFIG_PROGRAM_ID: [u8; 32] = [ | const CONFIG_PROGRAM_ID: [u8; 32] = [ | ||||||
|     133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |     133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user