diff --git a/programs/budget_api/src/budget_processor.rs b/programs/budget_api/src/budget_processor.rs index d20e34b2c9..4c76a78f8b 100644 --- a/programs/budget_api/src/budget_processor.rs +++ b/programs/budget_api/src/budget_processor.rs @@ -172,7 +172,7 @@ mod tests { bank_client .send_message(&[&alice_keypair], message) .unwrap(); - assert_eq!(bank_client.get_balance(&bob_pubkey), 100); + assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 100); } #[test] @@ -214,11 +214,11 @@ mod tests { // Ensure the transaction fails because of the unsigned key. assert_eq!( - bank_client.send_message(&[&mallory_keypair], message), - Err(TransactionError::InstructionError( - 0, - InstructionError::MissingRequiredSignature - )) + bank_client + .send_message(&[&mallory_keypair], message) + .unwrap_err() + .unwrap(), + TransactionError::InstructionError(0, InstructionError::MissingRequiredSignature) ); } @@ -262,11 +262,11 @@ mod tests { // Ensure the transaction fails because of the unsigned key. assert_eq!( - bank_client.send_message(&[&mallory_keypair], message), - Err(TransactionError::InstructionError( - 0, - InstructionError::MissingRequiredSignature - )) + bank_client + .send_message(&[&mallory_keypair], message) + .unwrap_err() + .unwrap(), + TransactionError::InstructionError(0, InstructionError::MissingRequiredSignature) ); } @@ -292,10 +292,13 @@ mod tests { bank_client .send_message(&[&alice_keypair], message) .unwrap(); - assert_eq!(bank_client.get_balance(&alice_pubkey), 1); - assert_eq!(bank_client.get_balance(&budget_pubkey), 1); + assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1); + assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 1); - let contract_account = bank_client.get_account_data(&budget_pubkey).unwrap(); + let contract_account = bank_client + .get_account_data(&budget_pubkey) + .unwrap() + .unwrap(); let budget_state = BudgetState::deserialize(&contract_account).unwrap(); assert!(budget_state.is_pending()); @@ -305,17 +308,21 @@ mod tests { assert_eq!( bank_client .send_instruction(&alice_keypair, instruction) - .unwrap_err(), + .unwrap_err() + .unwrap(), TransactionError::InstructionError( 0, InstructionError::CustomError(serialize(&BudgetError::DestinationMissing).unwrap()) ) ); - assert_eq!(bank_client.get_balance(&alice_pubkey), 1); - assert_eq!(bank_client.get_balance(&budget_pubkey), 1); - assert_eq!(bank_client.get_balance(&bob_pubkey), 0); + assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1); + assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 1); + assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 0); - let contract_account = bank_client.get_account_data(&budget_pubkey).unwrap(); + let contract_account = bank_client + .get_account_data(&budget_pubkey) + .unwrap() + .unwrap(); let budget_state = BudgetState::deserialize(&contract_account).unwrap(); assert!(budget_state.is_pending()); @@ -326,10 +333,10 @@ mod tests { bank_client .send_instruction(&alice_keypair, instruction) .unwrap(); - assert_eq!(bank_client.get_balance(&alice_pubkey), 1); - assert_eq!(bank_client.get_balance(&budget_pubkey), 0); - assert_eq!(bank_client.get_balance(&bob_pubkey), 1); - assert_eq!(bank_client.get_account_data(&budget_pubkey), None); + assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1); + assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 0); + assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 1); + assert_eq!(bank_client.get_account_data(&budget_pubkey).unwrap(), None); } #[test] @@ -354,10 +361,13 @@ mod tests { bank_client .send_message(&[&alice_keypair], message) .unwrap(); - assert_eq!(bank_client.get_balance(&alice_pubkey), 2); - assert_eq!(bank_client.get_balance(&budget_pubkey), 1); + assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 2); + assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 1); - let contract_account = bank_client.get_account_data(&budget_pubkey).unwrap(); + let contract_account = bank_client + .get_account_data(&budget_pubkey) + .unwrap() + .unwrap(); let budget_state = BudgetState::deserialize(&contract_account).unwrap(); assert!(budget_state.is_pending()); @@ -367,7 +377,7 @@ mod tests { bank_client .transfer(1, &alice_keypair, &mallory_pubkey) .unwrap(); - assert_eq!(bank_client.get_balance(&alice_pubkey), 1); + assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1); let instruction = budget_instruction::apply_signature(&mallory_pubkey, &budget_pubkey, &bob_pubkey); @@ -375,9 +385,9 @@ mod tests { .send_instruction(&mallory_keypair, instruction) .unwrap(); // nothing should be changed because apply witness didn't finalize a payment - assert_eq!(bank_client.get_balance(&alice_pubkey), 1); - assert_eq!(bank_client.get_balance(&budget_pubkey), 1); - assert_eq!(bank_client.get_account_data(&bob_pubkey), None); + assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1); + assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 1); + assert_eq!(bank_client.get_account_data(&bob_pubkey).unwrap(), None); // Now, cancel the transaction. mint gets her funds back let instruction = @@ -385,8 +395,8 @@ mod tests { bank_client .send_instruction(&alice_keypair, instruction) .unwrap(); - assert_eq!(bank_client.get_balance(&alice_pubkey), 2); - assert_eq!(bank_client.get_account_data(&budget_pubkey), None); - assert_eq!(bank_client.get_account_data(&bob_pubkey), None); + assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 2); + assert_eq!(bank_client.get_account_data(&budget_pubkey).unwrap(), None); + assert_eq!(bank_client.get_account_data(&bob_pubkey).unwrap(), None); } } diff --git a/programs/config_api/src/config_processor.rs b/programs/config_api/src/config_processor.rs index c6d13beaf6..b20687e8e2 100644 --- a/programs/config_api/src/config_processor.rs +++ b/programs/config_api/src/config_processor.rs @@ -118,7 +118,10 @@ mod tests { .send_message(&[&from_keypair, &config_keypair], message) .unwrap(); - let config_account_data = bank_client.get_account_data(&config_pubkey).unwrap(); + let config_account_data = bank_client + .get_account_data(&config_pubkey) + .unwrap() + .unwrap(); assert_eq!( my_config, MyConfig::deserialize(&config_account_data).unwrap() diff --git a/programs/exchange_api/src/exchange_processor.rs b/programs/exchange_api/src/exchange_processor.rs index 71aeb5568f..7fdab85b72 100644 --- a/programs/exchange_api/src/exchange_processor.rs +++ b/programs/exchange_api/src/exchange_processor.rs @@ -652,7 +652,7 @@ mod test { let (client, owner) = create_client(&bank, mint_keypair); let new = create_token_account(&client, &owner); - let new_account_data = client.get_account_data(&new).unwrap(); + let new_account_data = client.get_account_data(&new).unwrap().unwrap(); // Check results @@ -691,7 +691,7 @@ mod test { .send_instruction(&owner, instruction) .expect(&format!("{}:{}", line!(), file!())); - let new_account_data = client.get_account_data(&new).unwrap(); + let new_account_data = client.get_account_data(&new).unwrap().unwrap(); // Check results @@ -720,9 +720,9 @@ mod test { 1000, ); - let trade_account_data = client.get_account_data(&trade).unwrap(); - let src_account_data = client.get_account_data(&src).unwrap(); - let dst_account_data = client.get_account_data(&dst).unwrap(); + let trade_account_data = client.get_account_data(&trade).unwrap().unwrap(); + let src_account_data = client.get_account_data(&src).unwrap().unwrap(); + let dst_account_data = client.get_account_data(&dst).unwrap().unwrap(); // check results @@ -794,14 +794,14 @@ mod test { .send_instruction(&owner, instruction) .expect(&format!("{}:{}", line!(), file!())); - let to_trade_account_data = client.get_account_data(&to_trade).unwrap(); - let to_src_account_data = client.get_account_data(&to_src).unwrap(); - let to_dst_account_data = client.get_account_data(&to_dst).unwrap(); - let from_trade_account_data = client.get_account_data(&from_trade).unwrap(); - let from_src_account_data = client.get_account_data(&from_src).unwrap(); - let from_dst_account_data = client.get_account_data(&from_dst).unwrap(); - let profit_account_data = client.get_account_data(&profit).unwrap(); - let swap_account_data = client.get_account_data(&swap).unwrap(); + let to_trade_account_data = client.get_account_data(&to_trade).unwrap().unwrap(); + let to_src_account_data = client.get_account_data(&to_src).unwrap().unwrap(); + let to_dst_account_data = client.get_account_data(&to_dst).unwrap().unwrap(); + let from_trade_account_data = client.get_account_data(&from_trade).unwrap().unwrap(); + let from_src_account_data = client.get_account_data(&from_src).unwrap().unwrap(); + let from_dst_account_data = client.get_account_data(&from_dst).unwrap().unwrap(); + let profit_account_data = client.get_account_data(&profit).unwrap().unwrap(); + let swap_account_data = client.get_account_data(&swap).unwrap().unwrap(); // check results diff --git a/programs/failure_program/tests/failure.rs b/programs/failure_program/tests/failure.rs index 3a0b61498b..a75f454599 100644 --- a/programs/failure_program/tests/failure.rs +++ b/programs/failure_program/tests/failure.rs @@ -20,10 +20,10 @@ fn test_program_native_failure() { // Call user program let instruction = create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8); assert_eq!( - bank_client.send_instruction(&alice_keypair, instruction), - Err(TransactionError::InstructionError( - 0, - InstructionError::GenericError - )) + bank_client + .send_instruction(&alice_keypair, instruction) + .unwrap_err() + .unwrap(), + TransactionError::InstructionError(0, InstructionError::GenericError) ); } diff --git a/programs/storage_api/src/storage_processor.rs b/programs/storage_api/src/storage_processor.rs index 67b268f7fc..badae36d65 100644 --- a/programs/storage_api/src/storage_processor.rs +++ b/programs/storage_api/src/storage_processor.rs @@ -557,7 +557,7 @@ mod tests { } fn get_storage_entry_height(client: &C, account: &Pubkey) -> u64 { - match client.get_account_data(&account) { + match client.get_account_data(&account).unwrap() { Some(storage_system_account_data) => { let contract = deserialize(&storage_system_account_data); if let Ok(contract) = contract { @@ -577,7 +577,7 @@ mod tests { } fn get_storage_blockhash(client: &C, account: &Pubkey) -> Hash { - if let Some(storage_system_account_data) = client.get_account_data(&account) { + if let Some(storage_system_account_data) = client.get_account_data(&account).unwrap() { let contract = deserialize(&storage_system_account_data); if let Ok(contract) = contract { match contract { diff --git a/programs/vote_api/src/vote_processor.rs b/programs/vote_api/src/vote_processor.rs index 8ce4c1829b..a72aa3e33e 100644 --- a/programs/vote_api/src/vote_processor.rs +++ b/programs/vote_api/src/vote_processor.rs @@ -73,7 +73,9 @@ mod tests { ) -> Result<()> { let ixs = vote_instruction::create_account(&from_keypair.pubkey(), vote_id, lamports); let message = Message::new(ixs); - bank_client.send_message(&[from_keypair], message)?; + bank_client + .send_message(&[from_keypair], message) + .map_err(|err| err.unwrap())?; Ok(()) } @@ -89,7 +91,9 @@ mod tests { let delegate_ix = vote_instruction::delegate_stake(&vote_id, delegate_id); ixs.push(delegate_ix); let message = Message::new(ixs); - bank_client.send_message(&[&from_keypair, vote_keypair], message)?; + bank_client + .send_message(&[from_keypair, vote_keypair], message) + .map_err(|err| err.unwrap())?; Ok(()) } @@ -99,7 +103,9 @@ mod tests { tick_height: u64, ) -> Result<()> { let vote_ix = vote_instruction::vote(&vote_keypair.pubkey(), Vote::new(tick_height)); - bank_client.send_instruction(&vote_keypair, vote_ix)?; + bank_client + .send_instruction(vote_keypair, vote_ix) + .map_err(|err| err.unwrap())?; Ok(()) } @@ -114,7 +120,7 @@ mod tests { create_vote_account(&bank_client, &from_keypair, &vote_id, 100).unwrap(); submit_vote(&bank_client, &vote_keypair, 0).unwrap(); - let vote_account_data = bank_client.get_account_data(&vote_id).unwrap(); + let vote_account_data = bank_client.get_account_data(&vote_id).unwrap().unwrap(); let vote_state = VoteState::deserialize(&vote_account_data).unwrap(); assert_eq!(vote_state.votes.len(), 1); } @@ -157,16 +163,13 @@ mod tests { let result = bank_client.send_message(&[&mallory_keypair], message); // And ensure there's no vote. - let vote_account_data = bank_client.get_account_data(&vote_id).unwrap(); + let vote_account_data = bank_client.get_account_data(&vote_id).unwrap().unwrap(); let vote_state = VoteState::deserialize(&vote_account_data).unwrap(); assert_eq!(vote_state.votes.len(), 0); assert_eq!( - result, - Err(TransactionError::InstructionError( - 1, - InstructionError::InvalidArgument - )) + result.unwrap_err().unwrap(), + TransactionError::InstructionError(1, InstructionError::InvalidArgument) ); } } diff --git a/runtime/src/bank_client.rs b/runtime/src/bank_client.rs index 9d3c999e7e..4607d9fb4f 100644 --- a/runtime/src/bank_client.rs +++ b/runtime/src/bank_client.rs @@ -6,18 +6,15 @@ use solana_sdk::signature::Signature; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::sync_client::SyncClient; use solana_sdk::system_instruction; -use solana_sdk::transaction::{Transaction, TransactionError}; +use solana_sdk::transaction::Transaction; +use solana_sdk::transport::Result; pub struct BankClient<'a> { bank: &'a Bank, } impl<'a> SyncClient for BankClient<'a> { - fn send_message( - &self, - keypairs: &[&Keypair], - message: Message, - ) -> Result { + fn send_message(&self, keypairs: &[&Keypair], message: Message) -> Result { let blockhash = self.bank.last_blockhash(); let transaction = Transaction::new(&keypairs, message, blockhash); self.bank.process_transaction(&transaction)?; @@ -25,33 +22,23 @@ impl<'a> SyncClient for BankClient<'a> { } /// Create and process a transaction from a single instruction. - fn send_instruction( - &self, - keypair: &Keypair, - instruction: Instruction, - ) -> Result { + fn send_instruction(&self, keypair: &Keypair, instruction: Instruction) -> Result { let message = Message::new(vec![instruction]); self.send_message(&[keypair], message) } /// Transfer `lamports` from `keypair` to `pubkey` - fn transfer( - &self, - lamports: u64, - keypair: &Keypair, - pubkey: &Pubkey, - ) -> Result { + fn transfer(&self, lamports: u64, keypair: &Keypair, pubkey: &Pubkey) -> Result { let move_instruction = system_instruction::transfer(&keypair.pubkey(), pubkey, lamports); self.send_instruction(keypair, move_instruction) } - fn get_account_data(&self, pubkey: &Pubkey) -> Option> { - let account = self.bank.get_account(pubkey)?; - Some(account.data) + fn get_account_data(&self, pubkey: &Pubkey) -> Result>> { + Ok(self.bank.get_account(pubkey).map(|account| account.data)) } - fn get_balance(&self, pubkey: &Pubkey) -> u64 { - self.bank.get_balance(pubkey) + fn get_balance(&self, pubkey: &Pubkey) -> Result { + Ok(self.bank.get_balance(pubkey)) } } @@ -86,6 +73,6 @@ mod tests { let message = Message::new(vec![move_instruction]); bank_client.send_message(&doe_keypairs, message).unwrap(); - assert_eq!(bank_client.get_balance(&bob_pubkey), 42); + assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 42); } } diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index d7e23bfbf5..d6b635c042 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -301,13 +301,13 @@ mod tests { account_metas, ); assert_eq!( - bank_client.send_instruction(&mallory_keypair, malicious_instruction), - Err(TransactionError::InstructionError( - 0, - InstructionError::MissingRequiredSignature - )) + bank_client + .send_instruction(&mallory_keypair, malicious_instruction) + .unwrap_err() + .unwrap(), + TransactionError::InstructionError(0, InstructionError::MissingRequiredSignature) ); - assert_eq!(bank_client.get_balance(&alice_pubkey), 50); - assert_eq!(bank_client.get_balance(&mallory_pubkey), 50); + assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 50); + assert_eq!(bank_client.get_balance(&mallory_pubkey).unwrap(), 50); } } diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 06db2cd920..d3185e3745 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -19,6 +19,7 @@ pub mod system_program; pub mod system_transaction; pub mod timing; pub mod transaction; +pub mod transport; #[macro_use] extern crate serde_derive; diff --git a/sdk/src/sync_client.rs b/sdk/src/sync_client.rs index 67fe9ffdfc..bb42791269 100644 --- a/sdk/src/sync_client.rs +++ b/sdk/src/sync_client.rs @@ -6,37 +6,24 @@ use crate::instruction::Instruction; use crate::message::Message; use crate::pubkey::Pubkey; use crate::signature::{Keypair, Signature}; -use crate::transaction::TransactionError; +use crate::transport::Result; pub trait SyncClient { /// Create a transaction from the given message, and send it to the /// server, retrying as-needed. - fn send_message( - &self, - keypairs: &[&Keypair], - message: Message, - ) -> Result; + fn send_message(&self, keypairs: &[&Keypair], message: Message) -> Result; /// Create a transaction from a single instruction that only requires /// a single signer. Then send it to the server, retrying as-needed. - fn send_instruction( - &self, - keypair: &Keypair, - instruction: Instruction, - ) -> Result; + fn send_instruction(&self, keypair: &Keypair, instruction: Instruction) -> Result; /// Transfer lamports from `keypair` to `pubkey`, retrying until the /// transfer completes or produces and error. - fn transfer( - &self, - lamports: u64, - keypair: &Keypair, - pubkey: &Pubkey, - ) -> Result; + fn transfer(&self, lamports: u64, keypair: &Keypair, pubkey: &Pubkey) -> Result; /// Get an account or None if not found. - fn get_account_data(&self, pubkey: &Pubkey) -> Option>; + fn get_account_data(&self, pubkey: &Pubkey) -> Result>>; /// Get account balance or 0 if not found. - fn get_balance(&self, pubkey: &Pubkey) -> u64; + fn get_balance(&self, pubkey: &Pubkey) -> Result; } diff --git a/sdk/src/transport.rs b/sdk/src/transport.rs new file mode 100644 index 0000000000..d03d1a50da --- /dev/null +++ b/sdk/src/transport.rs @@ -0,0 +1,32 @@ +use crate::transaction::TransactionError; +use std::io; + +#[derive(Debug)] +pub enum TransportError { + IoError(io::Error), + TransactionError(TransactionError), +} + +impl TransportError { + pub fn unwrap(&self) -> TransactionError { + if let TransportError::TransactionError(err) = self { + err.clone() + } else { + panic!("unexpected transport error") + } + } +} + +impl From for TransportError { + fn from(err: io::Error) -> TransportError { + TransportError::IoError(err) + } +} + +impl From for TransportError { + fn from(err: TransactionError) -> TransportError { + TransportError::TransactionError(err) + } +} + +pub type Result = std::result::Result;