From e7df3cfe22c9f5e8f1dbf7014fd374910028ef63 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 7 Feb 2019 19:23:12 -0800 Subject: [PATCH] thin_client grooming: remove dead code, improve var names and error reporting --- src/thin_client.rs | 229 +++++++++++++++++++++++---------------------- 1 file changed, 116 insertions(+), 113 deletions(-) diff --git a/src/thin_client.rs b/src/thin_client.rs index c255b99005..6b809ec9f3 100644 --- a/src/thin_client.rs +++ b/src/thin_client.rs @@ -3,7 +3,6 @@ //! messages to the network directly. The binary encoding of its messages are //! unstable and may change in future releases. -use crate::bank::Bank; use crate::cluster_info::{ClusterInfo, ClusterInfoError, NodeInfo}; use crate::fullnode::{Fullnode, FullnodeConfig}; use crate::gossip_service::GossipService; @@ -12,7 +11,6 @@ use crate::result::{Error, Result}; use crate::rpc_request::{RpcClient, RpcRequest, RpcRequestHandler}; use bincode::serialize_into; use bs58; -use hashbrown::HashMap; use log::Level; use serde_json; use solana_metrics; @@ -38,10 +36,6 @@ pub struct ThinClient { rpc_addr: SocketAddr, transactions_addr: SocketAddr, transactions_socket: UdpSocket, - transaction_count: u64, - balances: HashMap, - signature_status: bool, - confirmation: Option, rpc_client: RpcClient, } @@ -82,41 +76,39 @@ impl ThinClient { rpc_addr, transactions_addr, transactions_socket, - transaction_count: 0, - balances: HashMap::new(), - signature_status: false, - confirmation: None, } } /// Send a signed Transaction to the server for processing. This method /// does not wait for a response. - pub fn transfer_signed(&self, tx: &Transaction) -> io::Result { - let mut buf = vec![0; tx.serialized_size().unwrap() as usize]; + pub fn transfer_signed(&self, transaction: &Transaction) -> io::Result { + let mut buf = vec![0; transaction.serialized_size().unwrap() as usize]; let mut wr = std::io::Cursor::new(&mut buf[..]); - serialize_into(&mut wr, &tx).expect("serialize Transaction in pub fn transfer_signed"); + serialize_into(&mut wr, &transaction) + .expect("serialize Transaction in pub fn transfer_signed"); assert!(buf.len() < PACKET_DATA_SIZE); self.transactions_socket .send_to(&buf[..], &self.transactions_addr)?; - Ok(tx.signatures[0]) + Ok(transaction.signatures[0]) } /// Retry a sending a signed Transaction to the server for processing. pub fn retry_transfer( &mut self, keypair: &Keypair, - tx: &mut Transaction, + transaction: &mut Transaction, tries: usize, ) -> io::Result { for x in 0..tries { - tx.sign(&[keypair], self.get_last_id()); - let mut buf = vec![0; tx.serialized_size().unwrap() as usize]; + transaction.sign(&[keypair], self.get_last_id()); + let mut buf = vec![0; transaction.serialized_size().unwrap() as usize]; let mut wr = std::io::Cursor::new(&mut buf[..]); - serialize_into(&mut wr, &tx).expect("serialize Transaction in pub fn transfer_signed"); + serialize_into(&mut wr, &transaction) + .expect("serialize Transaction in pub fn transfer_signed"); self.transactions_socket .send_to(&buf[..], &self.transactions_addr)?; - if self.poll_for_signature(&tx.signatures[0]).is_ok() { - return Ok(tx.signatures[0]); + if self.poll_for_signature(&transaction.signatures[0]).is_ok() { + return Ok(transaction.signatures[0]); } info!("{} tries failed transfer to {}", x, self.transactions_addr); } @@ -129,21 +121,21 @@ impl ThinClient { /// Creates, signs, and processes a Transaction. Useful for writing unit-tests. pub fn transfer( &self, - n: u64, + tokens: u64, keypair: &Keypair, to: Pubkey, last_id: &Hash, ) -> io::Result { debug!( - "transfer: n={} from={:?} to={:?} last_id={:?}", - n, + "transfer: tokens={} from={:?} to={:?} last_id={:?}", + tokens, keypair.pubkey(), to, last_id ); let now = Instant::now(); - let tx = SystemTransaction::new_account(keypair, to, n, *last_id, 0); - let result = self.transfer_signed(&tx); + let transaction = SystemTransaction::new_account(keypair, to, tokens, *last_id, 0); + let result = self.transfer_signed(&transaction); solana_metrics::submit( influxdb::Point::new("thinclient") .add_tag("op", influxdb::Value::String("transfer".to_string())) @@ -158,18 +150,23 @@ impl ThinClient { pub fn get_account_userdata(&mut self, pubkey: &Pubkey) -> io::Result>> { let params = json!([format!("{}", pubkey)]); - let resp = self - .rpc_client - .make_rpc_request(1, RpcRequest::GetAccountInfo, Some(params)); - if let Ok(account_json) = resp { - let account: Account = - serde_json::from_value(account_json).expect("deserialize account"); - return Ok(Some(account.userdata)); + let response = + self.rpc_client + .make_rpc_request(1, RpcRequest::GetAccountInfo, Some(params)); + match response { + Ok(account_json) => { + let account: Account = + serde_json::from_value(account_json).expect("deserialize account"); + Ok(Some(account.userdata)) + } + Err(error) => { + debug!("get_account_userdata failed: {:?}", error); + Err(io::Error::new( + io::ErrorKind::Other, + "get_account_userdata failed", + )) + } } - Err(io::Error::new( - io::ErrorKind::Other, - "get_account_userdata failed", - )) } /// Request the balance of the user holding `pubkey`. This method blocks @@ -178,69 +175,67 @@ impl ThinClient { pub fn get_balance(&mut self, pubkey: &Pubkey) -> io::Result { trace!("get_balance sending request to {}", self.rpc_addr); let params = json!([format!("{}", pubkey)]); - let resp = self - .rpc_client - .make_rpc_request(1, RpcRequest::GetAccountInfo, Some(params)); - if let Ok(account_json) = resp { - let account: Account = - serde_json::from_value(account_json).expect("deserialize account"); - trace!("Response account {:?} {:?}", pubkey, account); - self.balances.insert(*pubkey, account.clone()); - } else { - debug!("Response account {}: None ", pubkey); - self.balances.remove(&pubkey); - } - trace!("get_balance {:?}", self.balances.get(pubkey)); + let response = + self.rpc_client + .make_rpc_request(1, RpcRequest::GetAccountInfo, Some(params)); - // TODO: This is a hard coded call to introspect the balance of a budget_dsl contract - // In the future custom contracts would need their own introspection - self.balances - .get(pubkey) - .map(Bank::read_balance) - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "AccountNotFound")) + response + .and_then(|account_json| { + let account: Account = + serde_json::from_value(account_json).expect("deserialize account"); + trace!("Response account {:?} {:?}", pubkey, account); + trace!("get_balance {:?}", account.tokens); + Ok(account.tokens) + }) + .map_err(|error| { + debug!("Response account {}: None (error: {:?})", pubkey, error); + io::Error::new(io::ErrorKind::Other, "AccountNotFound") + }) } /// Request the confirmation time from the leader node pub fn get_confirmation_time(&mut self) -> usize { trace!("get_confirmation_time"); - let mut done = false; - while !done { + loop { debug!("get_confirmation_time send_to {}", &self.rpc_addr); - let resp = self - .rpc_client - .make_rpc_request(1, RpcRequest::GetConfirmationTime, None); - if let Ok(value) = resp { - done = true; - let confirmation = value.as_u64().unwrap() as usize; - self.confirmation = Some(confirmation); - } else { - debug!("thin_client get_confirmation_time error: {:?}", resp); - } + let response = + self.rpc_client + .make_rpc_request(1, RpcRequest::GetConfirmationTime, None); + + match response { + Ok(value) => { + let confirmation = value.as_u64().unwrap() as usize; + return confirmation; + } + Err(error) => { + debug!("thin_client get_confirmation_time error: {:?}", error); + } + }; } - self.confirmation.expect("some confirmation") } /// Request the transaction count. If the response packet is dropped by the network, /// this method will try again 5 times. pub fn transaction_count(&mut self) -> u64 { debug!("transaction_count"); - let mut tries_left = 5; - while tries_left > 0 { - let resp = self - .rpc_client - .make_rpc_request(1, RpcRequest::GetTransactionCount, None); + for _tries in 0..5 { + let response = + self.rpc_client + .make_rpc_request(1, RpcRequest::GetTransactionCount, None); - if let Ok(value) = resp { - debug!("transaction_count recv_response: {:?}", value); - tries_left = 0; - let transaction_count = value.as_u64().unwrap(); - self.transaction_count = transaction_count; - } else { - tries_left -= 1; - } + match response { + Ok(value) => { + debug!("transaction_count response: {:?}", value); + let transaction_count = value.as_u64().unwrap(); + return transaction_count; + } + Err(error) => { + debug!("transaction_count failed: {:?}", error); + } + }; } - self.transaction_count + 0 } /// Request the last Entry ID from the server. This method blocks @@ -248,17 +243,20 @@ impl ThinClient { pub fn get_last_id(&mut self) -> Hash { loop { trace!("get_last_id send_to {}", &self.rpc_addr); - let resp = self + let response = self .rpc_client .make_rpc_request(1, RpcRequest::GetLastId, None); - if let Ok(value) = resp { - let last_id_str = value.as_str().unwrap(); - let last_id_vec = bs58::decode(last_id_str).into_vec().unwrap(); - return Hash::new(&last_id_vec); - } else { - debug!("thin_client get_last_id error: {:?}", resp); - } + match response { + Ok(value) => { + let last_id_str = value.as_str().unwrap(); + let last_id_vec = bs58::decode(last_id_str).into_vec().unwrap(); + return Hash::new(&last_id_vec); + } + Err(error) => { + debug!("thin_client get_last_id error: {:?}", error); + } + }; } } @@ -331,37 +329,43 @@ impl ThinClient { /// Check a signature in the bank. This method blocks /// until the server sends a response. pub fn check_signature(&mut self, signature: &Signature) -> bool { - trace!("check_signature"); + trace!("check_signature: {:?}", signature); let params = json!([format!("{}", signature)]); let now = Instant::now(); - let mut done = false; - while !done { - let resp = self.rpc_client.make_rpc_request( + + loop { + let response = self.rpc_client.make_rpc_request( 1, RpcRequest::ConfirmTransaction, Some(params.clone()), ); - if let Ok(confirmation) = resp { - done = true; - self.signature_status = confirmation.as_bool().unwrap(); - if self.signature_status { - trace!("Response found signature"); - } else { - trace!("Response signature not found"); + match response { + Ok(confirmation) => { + let signature_status = confirmation.as_bool().unwrap(); + if signature_status { + trace!("Response found signature"); + } else { + trace!("Response signature not found"); + } + solana_metrics::submit( + influxdb::Point::new("thinclient") + .add_tag("op", influxdb::Value::String("check_signature".to_string())) + .add_field( + "duration_ms", + influxdb::Value::Integer( + timing::duration_as_ms(&now.elapsed()) as i64 + ), + ) + .to_owned(), + ); + return signature_status; } - } + Err(err) => { + debug!("check_signature request failed: {:?}", err); + } + }; } - solana_metrics::submit( - influxdb::Point::new("thinclient") - .add_tag("op", influxdb::Value::String("check_signature".to_string())) - .add_field( - "duration_ms", - influxdb::Value::Integer(timing::duration_as_ms(&now.elapsed()) as i64), - ) - .to_owned(), - ); - self.signature_status } } @@ -482,7 +486,6 @@ mod tests { use super::*; use crate::client::mk_client; use bincode::{deserialize, serialize}; - use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::vote_program::VoteState; use solana_sdk::vote_transaction::VoteTransaction;