Relieve the caller of having to care about the rpc request id

This commit is contained in:
Michael Vines
2019-03-15 23:49:28 -07:00
parent c2b1010f18
commit bcc34b906c
10 changed files with 51 additions and 55 deletions

View File

@ -27,20 +27,18 @@ impl MockRpcClient {
pub fn retry_get_balance( pub fn retry_get_balance(
&self, &self,
id: u64,
pubkey: &Pubkey, pubkey: &Pubkey,
retries: usize, retries: usize,
) -> Result<Option<u64>, Box<dyn error::Error>> { ) -> Result<Option<u64>, Box<dyn error::Error>> {
let params = json!([format!("{}", pubkey)]); let params = json!([format!("{}", pubkey)]);
let res = self let res = self
.retry_make_rpc_request(id, &RpcRequest::GetBalance, Some(params), retries)? .retry_make_rpc_request(&RpcRequest::GetBalance, Some(params), retries)?
.as_u64(); .as_u64();
Ok(res) Ok(res)
} }
pub fn retry_make_rpc_request( pub fn retry_make_rpc_request(
&self, &self,
_id: u64,
request: &RpcRequest, request: &RpcRequest,
params: Option<Value>, params: Option<Value>,
mut _retries: usize, mut _retries: usize,
@ -86,11 +84,10 @@ impl MockRpcClient {
impl RpcRequestHandler for MockRpcClient { impl RpcRequestHandler for MockRpcClient {
fn make_rpc_request( fn make_rpc_request(
&self, &self,
id: u64,
request: RpcRequest, request: RpcRequest,
params: Option<Value>, params: Option<Value>,
) -> Result<Value, Box<dyn error::Error>> { ) -> Result<Value, Box<dyn error::Error>> {
self.retry_make_rpc_request(id, &request, params, 0) self.retry_make_rpc_request(&request, params, 0)
} }
} }

View File

@ -39,25 +39,26 @@ impl RpcClient {
pub fn retry_get_balance( pub fn retry_get_balance(
&self, &self,
id: u64,
pubkey: &Pubkey, pubkey: &Pubkey,
retries: usize, retries: usize,
) -> Result<Option<u64>, Box<dyn error::Error>> { ) -> Result<Option<u64>, Box<dyn error::Error>> {
let params = json!([format!("{}", pubkey)]); let params = json!([format!("{}", pubkey)]);
let res = self let res = self
.retry_make_rpc_request(id, &RpcRequest::GetBalance, Some(params), retries)? .retry_make_rpc_request(&RpcRequest::GetBalance, Some(params), retries)?
.as_u64(); .as_u64();
Ok(res) Ok(res)
} }
pub fn retry_make_rpc_request( pub fn retry_make_rpc_request(
&self, &self,
id: u64,
request: &RpcRequest, request: &RpcRequest,
params: Option<Value>, params: Option<Value>,
mut retries: usize, mut retries: usize,
) -> Result<Value, Box<dyn error::Error>> { ) -> Result<Value, Box<dyn error::Error>> {
let request_json = request.build_request_json(id, params); // Concurrent requests are not supported so reuse the same request id for all requests
let request_id = 1;
let request_json = request.build_request_json(request_id, params);
loop { loop {
match self match self
@ -108,7 +109,6 @@ pub fn get_rpc_request_str(rpc_addr: SocketAddr, tls: bool) -> String {
pub trait RpcRequestHandler { pub trait RpcRequestHandler {
fn make_rpc_request( fn make_rpc_request(
&self, &self,
id: u64,
request: RpcRequest, request: RpcRequest,
params: Option<Value>, params: Option<Value>,
) -> Result<Value, Box<dyn error::Error>>; ) -> Result<Value, Box<dyn error::Error>>;
@ -117,11 +117,10 @@ pub trait RpcRequestHandler {
impl RpcRequestHandler for RpcClient { impl RpcRequestHandler for RpcClient {
fn make_rpc_request( fn make_rpc_request(
&self, &self,
id: u64,
request: RpcRequest, request: RpcRequest,
params: Option<Value>, params: Option<Value>,
) -> Result<Value, Box<dyn error::Error>> { ) -> Result<Value, Box<dyn error::Error>> {
self.retry_make_rpc_request(id, &request, params, 0) self.retry_make_rpc_request(&request, params, 0)
} }
} }
@ -272,13 +271,12 @@ mod tests {
let rpc_client = RpcClient::new_socket(rpc_addr); let rpc_client = RpcClient::new_socket(rpc_addr);
let balance = rpc_client.make_rpc_request( let balance = rpc_client.make_rpc_request(
1,
RpcRequest::GetBalance, RpcRequest::GetBalance,
Some(json!(["deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhx"])), Some(json!(["deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhx"])),
); );
assert_eq!(balance.unwrap().as_u64().unwrap(), 50); assert_eq!(balance.unwrap().as_u64().unwrap(), 50);
let blockhash = rpc_client.make_rpc_request(2, RpcRequest::GetRecentBlockhash, None); let blockhash = rpc_client.make_rpc_request(RpcRequest::GetRecentBlockhash, None);
assert_eq!( assert_eq!(
blockhash.unwrap().as_str().unwrap(), blockhash.unwrap().as_str().unwrap(),
"deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhx" "deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhx"
@ -286,7 +284,7 @@ mod tests {
// Send erroneous parameter // Send erroneous parameter
let blockhash = let blockhash =
rpc_client.make_rpc_request(3, RpcRequest::GetRecentBlockhash, Some(json!("paramter"))); rpc_client.make_rpc_request(RpcRequest::GetRecentBlockhash, Some(json!("paramter")));
assert_eq!(blockhash.is_err(), true); assert_eq!(blockhash.is_err(), true);
} }
@ -321,7 +319,6 @@ mod tests {
let rpc_client = RpcClient::new_socket(rpc_addr); let rpc_client = RpcClient::new_socket(rpc_addr);
let balance = rpc_client.retry_make_rpc_request( let balance = rpc_client.retry_make_rpc_request(
1,
&RpcRequest::GetBalance, &RpcRequest::GetBalance,
Some(json!(["deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhw"])), Some(json!(["deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhw"])),
10, 10,

View File

@ -144,9 +144,9 @@ impl ThinClient {
pub fn get_account_data(&mut self, pubkey: &Pubkey) -> io::Result<Option<Vec<u8>>> { pub fn get_account_data(&mut self, pubkey: &Pubkey) -> io::Result<Option<Vec<u8>>> {
let params = json!([format!("{}", pubkey)]); let params = json!([format!("{}", pubkey)]);
let response = let response = self
self.rpc_client .rpc_client
.make_rpc_request(1, RpcRequest::GetAccountInfo, Some(params)); .make_rpc_request(RpcRequest::GetAccountInfo, Some(params));
match response { match response {
Ok(account_json) => { Ok(account_json) => {
let account: Account = let account: Account =
@ -169,9 +169,9 @@ impl ThinClient {
pub fn get_balance(&mut self, pubkey: &Pubkey) -> io::Result<u64> { pub fn get_balance(&mut self, pubkey: &Pubkey) -> io::Result<u64> {
trace!("get_balance sending request to {}", self.rpc_addr); trace!("get_balance sending request to {}", self.rpc_addr);
let params = json!([format!("{}", pubkey)]); let params = json!([format!("{}", pubkey)]);
let response = let response = self
self.rpc_client .rpc_client
.make_rpc_request(1, RpcRequest::GetAccountInfo, Some(params)); .make_rpc_request(RpcRequest::GetAccountInfo, Some(params));
response response
.and_then(|account_json| { .and_then(|account_json| {
@ -192,9 +192,9 @@ impl ThinClient {
pub fn transaction_count(&mut self) -> u64 { pub fn transaction_count(&mut self) -> u64 {
debug!("transaction_count"); debug!("transaction_count");
for _tries in 0..5 { for _tries in 0..5 {
let response = let response = self
self.rpc_client .rpc_client
.make_rpc_request(1, RpcRequest::GetTransactionCount, None); .make_rpc_request(RpcRequest::GetTransactionCount, None);
match response { match response {
Ok(value) => { Ok(value) => {
@ -215,9 +215,9 @@ impl ThinClient {
pub fn try_get_recent_blockhash(&mut self, mut num_retries: u64) -> Option<Hash> { pub fn try_get_recent_blockhash(&mut self, mut num_retries: u64) -> Option<Hash> {
loop { loop {
trace!("try_get_recent_blockhash send_to {}", &self.rpc_addr); trace!("try_get_recent_blockhash send_to {}", &self.rpc_addr);
let response = let response = self
self.rpc_client .rpc_client
.make_rpc_request(1, RpcRequest::GetRecentBlockhash, None); .make_rpc_request(RpcRequest::GetRecentBlockhash, None);
match response { match response {
Ok(value) => { Ok(value) => {
@ -326,11 +326,9 @@ impl ThinClient {
let now = Instant::now(); let now = Instant::now();
loop { loop {
let response = self.rpc_client.make_rpc_request( let response = self
1, .rpc_client
RpcRequest::ConfirmTransaction, .make_rpc_request(RpcRequest::ConfirmTransaction, Some(params.clone()));
Some(params.clone()),
);
match response { match response {
Ok(confirmation) => { Ok(confirmation) => {
@ -363,7 +361,7 @@ impl ThinClient {
trace!("fullnode_exit sending request to {}", self.rpc_addr); trace!("fullnode_exit sending request to {}", self.rpc_addr);
let response = self let response = self
.rpc_client .rpc_client
.make_rpc_request(1, RpcRequest::FullnodeExit, None) .make_rpc_request(RpcRequest::FullnodeExit, None)
.map_err(|error| { .map_err(|error| {
debug!("Response from {} fullndoe_exit: {}", self.rpc_addr, error); debug!("Response from {} fullndoe_exit: {}", self.rpc_addr, error);
io::Error::new(io::ErrorKind::Other, "FullodeExit request failure") io::Error::new(io::ErrorKind::Other, "FullodeExit request failure")

View File

@ -357,11 +357,11 @@ impl Replicator {
RpcClient::new_socket(rpc_peers[node_idx].rpc) RpcClient::new_socket(rpc_peers[node_idx].rpc)
}; };
let storage_blockhash = rpc_client let storage_blockhash = rpc_client
.make_rpc_request(2, RpcRequest::GetStorageBlockhash, None) .make_rpc_request(RpcRequest::GetStorageBlockhash, None)
.expect("rpc request") .expect("rpc request")
.to_string(); .to_string();
let storage_entry_height = rpc_client let storage_entry_height = rpc_client
.make_rpc_request(2, RpcRequest::GetStorageEntryHeight, None) .make_rpc_request(RpcRequest::GetStorageEntryHeight, None)
.expect("rpc request") .expect("rpc request")
.as_u64() .as_u64()
.unwrap(); .unwrap();

View File

@ -30,7 +30,7 @@ impl VoteSigner for RemoteVoteSigner {
let params = json!([pubkey, sig, msg]); let params = json!([pubkey, sig, msg]);
let resp = self let resp = self
.rpc_client .rpc_client
.retry_make_rpc_request(1, &RpcRequest::RegisterNode, Some(params), 5) .retry_make_rpc_request(&RpcRequest::RegisterNode, Some(params), 5)
.unwrap(); .unwrap();
let vote_account: Pubkey = serde_json::from_value(resp).unwrap(); let vote_account: Pubkey = serde_json::from_value(resp).unwrap();
Ok(vote_account) Ok(vote_account)
@ -44,7 +44,7 @@ impl VoteSigner for RemoteVoteSigner {
let params = json!([pubkey, sig, msg]); let params = json!([pubkey, sig, msg]);
let resp = self let resp = self
.rpc_client .rpc_client
.retry_make_rpc_request(1, &RpcRequest::SignVote, Some(params), 0) .retry_make_rpc_request(&RpcRequest::SignVote, Some(params), 0)
.unwrap(); .unwrap();
let vote_signature: Signature = serde_json::from_value(resp).unwrap(); let vote_signature: Signature = serde_json::from_value(resp).unwrap();
Ok(vote_signature) Ok(vote_signature)
@ -53,7 +53,7 @@ impl VoteSigner for RemoteVoteSigner {
let params = json!([pubkey, sig, msg]); let params = json!([pubkey, sig, msg]);
let _resp = self let _resp = self
.rpc_client .rpc_client
.retry_make_rpc_request(1, &RpcRequest::DeregisterNode, Some(params), 5) .retry_make_rpc_request(&RpcRequest::DeregisterNode, Some(params), 5)
.unwrap(); .unwrap();
Ok(()) Ok(())
} }

View File

@ -139,8 +139,12 @@ fn test_transaction_count() {
solana_logger::setup(); solana_logger::setup();
let addr = "0.0.0.0:1234".parse().unwrap(); let addr = "0.0.0.0:1234".parse().unwrap();
let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap(); let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap();
let mut client = let mut client = ThinClient::new_socket_with_timeout(
ThinClient::new_socket_with_timeout(addr, addr, transactions_socket, Duration::from_secs(2)); addr,
addr,
transactions_socket,
Duration::from_secs(2),
);
assert_eq!(client.transaction_count(), 0); assert_eq!(client.transaction_count(), 0);
} }

View File

@ -375,7 +375,7 @@ fn process_airdrop(
"Requesting airdrop of {:?} lamports from {}", "Requesting airdrop of {:?} lamports from {}",
lamports, drone_addr lamports, drone_addr
); );
let previous_balance = match rpc_client.retry_get_balance(1, &config.id.pubkey(), 5)? { let previous_balance = match rpc_client.retry_get_balance(&config.id.pubkey(), 5)? {
Some(lamports) => lamports, Some(lamports) => lamports,
None => Err(WalletError::RpcRequestError( None => Err(WalletError::RpcRequestError(
"Received result of an unexpected type".to_string(), "Received result of an unexpected type".to_string(),
@ -385,7 +385,7 @@ fn process_airdrop(
request_and_confirm_airdrop(&rpc_client, &drone_addr, &config.id.pubkey(), lamports)?; request_and_confirm_airdrop(&rpc_client, &drone_addr, &config.id.pubkey(), lamports)?;
let current_balance = rpc_client let current_balance = rpc_client
.retry_get_balance(1, &config.id.pubkey(), 5)? .retry_get_balance(&config.id.pubkey(), 5)?
.unwrap_or(previous_balance); .unwrap_or(previous_balance);
if current_balance < previous_balance { if current_balance < previous_balance {
@ -405,7 +405,7 @@ fn process_airdrop(
} }
fn process_balance(config: &WalletConfig, rpc_client: &RpcClient) -> ProcessResult { fn process_balance(config: &WalletConfig, rpc_client: &RpcClient) -> ProcessResult {
let balance = rpc_client.retry_get_balance(1, &config.id.pubkey(), 5)?; let balance = rpc_client.retry_get_balance(&config.id.pubkey(), 5)?;
match balance { match balance {
Some(0) => Ok("No account found! Request an airdrop to get started.".to_string()), Some(0) => Ok("No account found! Request an airdrop to get started.".to_string()),
Some(lamports) => Ok(format!("Your balance is: {:?}", lamports)), Some(lamports) => Ok(format!("Your balance is: {:?}", lamports)),
@ -418,7 +418,7 @@ fn process_balance(config: &WalletConfig, rpc_client: &RpcClient) -> ProcessResu
fn process_confirm(rpc_client: &RpcClient, signature: Signature) -> ProcessResult { fn process_confirm(rpc_client: &RpcClient, signature: Signature) -> ProcessResult {
let params = json!([format!("{}", signature)]); let params = json!([format!("{}", signature)]);
let confirmation = rpc_client let confirmation = rpc_client
.retry_make_rpc_request(1, &RpcRequest::ConfirmTransaction, Some(params), 5)? .retry_make_rpc_request(&RpcRequest::ConfirmTransaction, Some(params), 5)?
.as_bool(); .as_bool();
match confirmation { match confirmation {
Some(b) => { Some(b) => {
@ -478,7 +478,7 @@ fn process_deploy(
config: &WalletConfig, config: &WalletConfig,
program_location: &str, program_location: &str,
) -> ProcessResult { ) -> ProcessResult {
let balance = rpc_client.retry_get_balance(1, &config.id.pubkey(), 5)?; let balance = rpc_client.retry_get_balance(&config.id.pubkey(), 5)?;
if let Some(lamports) = balance { if let Some(lamports) = balance {
if lamports < 1 { if lamports < 1 {
Err(WalletError::DynamicProgramError( Err(WalletError::DynamicProgramError(
@ -632,7 +632,7 @@ fn process_cancel(rpc_client: &RpcClient, config: &WalletConfig, pubkey: &Pubkey
fn process_get_transaction_count(rpc_client: &RpcClient) -> ProcessResult { fn process_get_transaction_count(rpc_client: &RpcClient) -> ProcessResult {
let transaction_count = rpc_client let transaction_count = rpc_client
.retry_make_rpc_request(1, &RpcRequest::GetTransactionCount, None, 5)? .retry_make_rpc_request(&RpcRequest::GetTransactionCount, None, 5)?
.as_u64(); .as_u64();
match transaction_count { match transaction_count {
Some(count) => Ok(count.to_string()), Some(count) => Ok(count.to_string()),
@ -650,7 +650,7 @@ fn process_time_elapsed(
pubkey: &Pubkey, pubkey: &Pubkey,
dt: DateTime<Utc>, dt: DateTime<Utc>,
) -> ProcessResult { ) -> ProcessResult {
let balance = rpc_client.retry_get_balance(1, &config.id.pubkey(), 5)?; let balance = rpc_client.retry_get_balance(&config.id.pubkey(), 5)?;
if let Some(0) = balance { if let Some(0) = balance {
request_and_confirm_airdrop(&rpc_client, &drone_addr, &config.id.pubkey(), 1)?; request_and_confirm_airdrop(&rpc_client, &drone_addr, &config.id.pubkey(), 1)?;
@ -671,7 +671,7 @@ fn process_witness(
to: &Pubkey, to: &Pubkey,
pubkey: &Pubkey, pubkey: &Pubkey,
) -> ProcessResult { ) -> ProcessResult {
let balance = rpc_client.retry_get_balance(1, &config.id.pubkey(), 5)?; let balance = rpc_client.retry_get_balance(&config.id.pubkey(), 5)?;
if let Some(0) = balance { if let Some(0) = balance {
request_and_confirm_airdrop(&rpc_client, &drone_addr, &config.id.pubkey(), 1)?; request_and_confirm_airdrop(&rpc_client, &drone_addr, &config.id.pubkey(), 1)?;
@ -771,7 +771,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
} }
fn get_recent_blockhash(rpc_client: &RpcClient) -> Result<Hash, Box<dyn error::Error>> { fn get_recent_blockhash(rpc_client: &RpcClient) -> Result<Hash, Box<dyn error::Error>> {
let result = rpc_client.retry_make_rpc_request(1, &RpcRequest::GetRecentBlockhash, None, 5)?; let result = rpc_client.retry_make_rpc_request(&RpcRequest::GetRecentBlockhash, None, 5)?;
if result.as_str().is_none() { if result.as_str().is_none() {
Err(WalletError::RpcRequestError( Err(WalletError::RpcRequestError(
"Received bad blockhash".to_string(), "Received bad blockhash".to_string(),
@ -823,7 +823,7 @@ fn send_transaction(
let serialized = serialize(transaction).unwrap(); let serialized = serialize(transaction).unwrap();
let params = json!([serialized]); let params = json!([serialized]);
let signature = let signature =
rpc_client.retry_make_rpc_request(2, &RpcRequest::SendTransaction, Some(params), 5)?; rpc_client.retry_make_rpc_request(&RpcRequest::SendTransaction, Some(params), 5)?;
if signature.as_str().is_none() { if signature.as_str().is_none() {
Err(WalletError::RpcRequestError( Err(WalletError::RpcRequestError(
"Received result of an unexpected type".to_string(), "Received result of an unexpected type".to_string(),
@ -838,7 +838,7 @@ fn confirm_transaction(
) -> Result<RpcSignatureStatus, Box<dyn error::Error>> { ) -> Result<RpcSignatureStatus, Box<dyn error::Error>> {
let params = json!([signature.to_string()]); let params = json!([signature.to_string()]);
let signature_status = let signature_status =
rpc_client.retry_make_rpc_request(1, &RpcRequest::GetSignatureStatus, Some(params), 5)?; rpc_client.retry_make_rpc_request(&RpcRequest::GetSignatureStatus, Some(params), 5)?;
if let Some(status) = signature_status.as_str() { if let Some(status) = signature_status.as_str() {
let rpc_status = RpcSignatureStatus::from_str(status).map_err(|_| { let rpc_status = RpcSignatureStatus::from_str(status).map_err(|_| {
WalletError::RpcRequestError("Unable to parse signature status".to_string()) WalletError::RpcRequestError("Unable to parse signature status".to_string())

View File

@ -47,7 +47,7 @@ fn test_wallet_deploy_program() {
let params = json!([program_id_str]); let params = json!([program_id_str]);
let account_info = rpc_client let account_info = rpc_client
.make_rpc_request(1, RpcRequest::GetAccountInfo, Some(params)) .make_rpc_request(RpcRequest::GetAccountInfo, Some(params))
.unwrap(); .unwrap();
let account_info_obj = account_info.as_object().unwrap(); let account_info_obj = account_info.as_object().unwrap();
assert_eq!( assert_eq!(

View File

@ -14,7 +14,7 @@ use std::sync::mpsc::channel;
use solana::fullnode::new_fullnode_for_tests; use solana::fullnode::new_fullnode_for_tests;
fn check_balance(expected_balance: u64, client: &RpcClient, pubkey: &Pubkey) { fn check_balance(expected_balance: u64, client: &RpcClient, pubkey: &Pubkey) {
let balance = client.retry_get_balance(1, pubkey, 1).unwrap().unwrap(); let balance = client.retry_get_balance(pubkey, 1).unwrap().unwrap();
assert_eq!(balance, expected_balance); assert_eq!(balance, expected_balance);
} }

View File

@ -24,7 +24,7 @@ fn test_wallet_request_airdrop() {
let rpc_client = RpcClient::new_socket(leader_data.rpc); let rpc_client = RpcClient::new_socket(leader_data.rpc);
let balance = rpc_client let balance = rpc_client
.retry_get_balance(1, &bob_config.id.pubkey(), 1) .retry_get_balance(&bob_config.id.pubkey(), 1)
.unwrap() .unwrap()
.unwrap(); .unwrap();
assert_eq!(balance, 50); assert_eq!(balance, 50);