Allow RpcClient users to inject custom "senders" (#10157)

automerge
This commit is contained in:
Greg Fitzgerald 2020-05-20 19:40:45 -06:00 committed by GitHub
parent ce17de7d25
commit 64cec764b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 35 deletions

View File

@ -2613,7 +2613,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
mod tests { mod tests {
use super::*; use super::*;
use serde_json::Value; use serde_json::Value;
use solana_client::mock_rpc_client_request::SIGNATURE; use solana_client::mock_sender::SIGNATURE;
use solana_sdk::{ use solana_sdk::{
pubkey::Pubkey, pubkey::Pubkey,
signature::{ signature::{

View File

@ -1,19 +1,19 @@
use crate::{ use crate::{
client_error::Result, client_error::Result,
generic_rpc_client_request::GenericRpcClientRequest,
rpc_request::{RpcError, RpcRequest}, rpc_request::{RpcError, RpcRequest},
rpc_sender::RpcSender,
}; };
use log::*; use log::*;
use reqwest::{self, header::CONTENT_TYPE}; use reqwest::{self, header::CONTENT_TYPE};
use solana_sdk::clock::{DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT}; use solana_sdk::clock::{DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT};
use std::{thread::sleep, time::Duration}; use std::{thread::sleep, time::Duration};
pub struct RpcClientRequest { pub struct HttpSender {
client: reqwest::blocking::Client, client: reqwest::blocking::Client,
url: String, url: String,
} }
impl RpcClientRequest { impl HttpSender {
pub fn new(url: String) -> Self { pub fn new(url: String) -> Self {
Self::new_with_timeout(url, Duration::from_secs(30)) Self::new_with_timeout(url, Duration::from_secs(30))
} }
@ -28,7 +28,7 @@ impl RpcClientRequest {
} }
} }
impl GenericRpcClientRequest for RpcClientRequest { impl RpcSender for HttpSender {
fn send( fn send(
&self, &self,
request: RpcRequest, request: RpcRequest,

View File

@ -2,13 +2,13 @@
extern crate serde_derive; extern crate serde_derive;
pub mod client_error; pub mod client_error;
mod generic_rpc_client_request; pub mod http_sender;
pub mod mock_rpc_client_request; pub mod mock_sender;
pub mod perf_utils; pub mod perf_utils;
pub mod pubsub_client; pub mod pubsub_client;
pub mod rpc_client; pub mod rpc_client;
pub mod rpc_client_request;
pub mod rpc_config; pub mod rpc_config;
pub mod rpc_request; pub mod rpc_request;
pub mod rpc_response; pub mod rpc_response;
pub mod rpc_sender;
pub mod thin_client; pub mod thin_client;

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
client_error::Result, client_error::Result,
generic_rpc_client_request::GenericRpcClientRequest,
rpc_request::RpcRequest, rpc_request::RpcRequest,
rpc_response::{Response, RpcResponseContext}, rpc_response::{Response, RpcResponseContext},
rpc_sender::RpcSender,
}; };
use serde_json::{Number, Value}; use serde_json::{Number, Value};
use solana_sdk::{ use solana_sdk::{
@ -19,12 +19,12 @@ pub const SIGNATURE: &str =
"43yNSFC6fYTuPgTNFFhF4axw7AfWxB2BPdurme8yrsWEYwm8299xh8n6TAHjGymiSub1XtyxTNyd9GBfY2hxoBw8"; "43yNSFC6fYTuPgTNFFhF4axw7AfWxB2BPdurme8yrsWEYwm8299xh8n6TAHjGymiSub1XtyxTNyd9GBfY2hxoBw8";
pub type Mocks = HashMap<RpcRequest, Value>; pub type Mocks = HashMap<RpcRequest, Value>;
pub struct MockRpcClientRequest { pub struct MockSender {
mocks: RwLock<Mocks>, mocks: RwLock<Mocks>,
url: String, url: String,
} }
impl MockRpcClientRequest { impl MockSender {
pub fn new(url: String) -> Self { pub fn new(url: String) -> Self {
Self::new_with_mocks(url, Mocks::default()) Self::new_with_mocks(url, Mocks::default())
} }
@ -37,7 +37,7 @@ impl MockRpcClientRequest {
} }
} }
impl GenericRpcClientRequest for MockRpcClientRequest { impl RpcSender for MockSender {
fn send( fn send(
&self, &self,
request: RpcRequest, request: RpcRequest,

View File

@ -1,11 +1,11 @@
use crate::{ use crate::{
client_error::{ClientError, ClientErrorKind, Result as ClientResult}, client_error::{ClientError, ClientErrorKind, Result as ClientResult},
generic_rpc_client_request::GenericRpcClientRequest, http_sender::HttpSender,
mock_rpc_client_request::{MockRpcClientRequest, Mocks}, mock_sender::{MockSender, Mocks},
rpc_client_request::RpcClientRequest,
rpc_config::RpcLargestAccountsConfig, rpc_config::RpcLargestAccountsConfig,
rpc_request::{RpcError, RpcRequest}, rpc_request::{RpcError, RpcRequest},
rpc_response::*, rpc_response::*,
rpc_sender::RpcSender,
}; };
use bincode::serialize; use bincode::serialize;
use indicatif::{ProgressBar, ProgressStyle}; use indicatif::{ProgressBar, ProgressStyle};
@ -40,26 +40,26 @@ use std::{
}; };
pub struct RpcClient { pub struct RpcClient {
client: Box<dyn GenericRpcClientRequest + Send + Sync>, sender: Box<dyn RpcSender + Send + Sync + 'static>,
} }
impl RpcClient { impl RpcClient {
pub fn new(url: String) -> Self { pub fn new_sender<T: RpcSender + Send + Sync + 'static>(sender: T) -> Self {
Self { Self {
client: Box::new(RpcClientRequest::new(url)), sender: Box::new(sender),
} }
} }
pub fn new(url: String) -> Self {
Self::new_sender(HttpSender::new(url))
}
pub fn new_mock(url: String) -> Self { pub fn new_mock(url: String) -> Self {
Self { Self::new_sender(MockSender::new(url))
client: Box::new(MockRpcClientRequest::new(url)),
}
} }
pub fn new_mock_with_mocks(url: String, mocks: Mocks) -> Self { pub fn new_mock_with_mocks(url: String, mocks: Mocks) -> Self {
Self { Self::new_sender(MockSender::new_with_mocks(url, mocks))
client: Box::new(MockRpcClientRequest::new_with_mocks(url, mocks)),
}
} }
pub fn new_socket(addr: SocketAddr) -> Self { pub fn new_socket(addr: SocketAddr) -> Self {
@ -68,9 +68,7 @@ impl RpcClient {
pub fn new_socket_with_timeout(addr: SocketAddr, timeout: Duration) -> Self { pub fn new_socket_with_timeout(addr: SocketAddr, timeout: Duration) -> Self {
let url = get_rpc_request_str(addr, false); let url = get_rpc_request_str(addr, false);
Self { Self::new_sender(HttpSender::new_with_timeout(url, timeout))
client: Box::new(RpcClientRequest::new_with_timeout(url, timeout)),
}
} }
pub fn confirm_transaction(&self, signature: &Signature) -> ClientResult<bool> { pub fn confirm_transaction(&self, signature: &Signature) -> ClientResult<bool> {
@ -295,7 +293,7 @@ impl RpcClient {
pub fn get_block_time(&self, slot: Slot) -> ClientResult<UnixTimestamp> { pub fn get_block_time(&self, slot: Slot) -> ClientResult<UnixTimestamp> {
let request = RpcRequest::GetBlockTime; let request = RpcRequest::GetBlockTime;
let response = self.client.send(request, json!([slot]), 0); let response = self.sender.send(request, json!([slot]), 0);
response response
.map(|result_json| { .map(|result_json| {
@ -524,7 +522,7 @@ impl RpcClient {
pubkey: &Pubkey, pubkey: &Pubkey,
commitment_config: CommitmentConfig, commitment_config: CommitmentConfig,
) -> RpcResult<Option<Account>> { ) -> RpcResult<Option<Account>> {
let response = self.client.send( let response = self.sender.send(
RpcRequest::GetAccountInfo, RpcRequest::GetAccountInfo,
json!([pubkey.to_string(), commitment_config]), json!([pubkey.to_string(), commitment_config]),
0, 0,
@ -563,7 +561,7 @@ impl RpcClient {
pub fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> ClientResult<u64> { pub fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> ClientResult<u64> {
let request = RpcRequest::GetMinimumBalanceForRentExemption; let request = RpcRequest::GetMinimumBalanceForRentExemption;
let minimum_balance_json = self let minimum_balance_json = self
.client .sender
.send(request, json!([data_len]), 0) .send(request, json!([data_len]), 0)
.map_err(|err| err.into_with_request(request))?; .map_err(|err| err.into_with_request(request))?;
@ -1039,7 +1037,7 @@ impl RpcClient {
{ {
assert!(params.is_array() || params.is_null()); assert!(params.is_array() || params.is_null());
let response = self let response = self
.client .sender
.send(request, params, retries) .send(request, params, retries)
.map_err(|err| err.into_with_request(request))?; .map_err(|err| err.into_with_request(request))?;
serde_json::from_value(response) serde_json::from_value(response)
@ -1066,7 +1064,7 @@ pub fn get_rpc_request_str(rpc_addr: SocketAddr, tls: bool) -> String {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::{client_error::ClientErrorKind, mock_rpc_client_request::PUBKEY}; use crate::{client_error::ClientErrorKind, mock_sender::PUBKEY};
use assert_matches::assert_matches; use assert_matches::assert_matches;
use jsonrpc_core::{Error, IoHandler, Params}; use jsonrpc_core::{Error, IoHandler, Params};
use jsonrpc_http_server::{AccessControlAllowOrigin, DomainsValidation, ServerBuilder}; use jsonrpc_http_server::{AccessControlAllowOrigin, DomainsValidation, ServerBuilder};
@ -1138,8 +1136,8 @@ mod tests {
let (sender, receiver) = channel(); let (sender, receiver) = channel();
thread::spawn(move || { thread::spawn(move || {
// 1. Pick a random port // 1. Pick a random port
// 2. Tell the client to start using it // 2. Tell the sender to start using it
// 3. Delay for 1.5 seconds before starting the server to ensure the client will fail // 3. Delay for 1.5 seconds before starting the server to ensure the sender will fail
// and need to retry // and need to retry
let rpc_addr: SocketAddr = "0.0.0.0:4242".parse().unwrap(); let rpc_addr: SocketAddr = "0.0.0.0:4242".parse().unwrap();
sender.send(rpc_addr.clone()).unwrap(); sender.send(rpc_addr.clone()).unwrap();

View File

@ -1,6 +1,6 @@
use crate::{client_error::Result, rpc_request::RpcRequest}; use crate::{client_error::Result, rpc_request::RpcRequest};
pub(crate) trait GenericRpcClientRequest { pub trait RpcSender {
fn send( fn send(
&self, &self,
request: RpcRequest, request: RpcRequest,