feat: return bank/block info with block-related results (#6716)

This commit is contained in:
Sunny Gleason
2019-11-12 14:49:41 -05:00
committed by GitHub
parent 2688ae614c
commit 5903339c17
10 changed files with 262 additions and 134 deletions

View File

@ -1,3 +1,4 @@
use crate::rpc_request::{Response, RpcResponseContext};
use crate::{
client_error::ClientError, generic_rpc_client_request::GenericRpcClientRequest,
rpc_request::RpcRequest,
@ -48,12 +49,18 @@ impl GenericRpcClientRequest for MockRpcClientRequest {
}
RpcRequest::GetBalance => {
let n = if self.url == "airdrop" { 0 } else { 50 };
Value::Number(Number::from(n))
serde_json::to_value(Response {
context: RpcResponseContext { slot: 1 },
value: Value::Number(Number::from(n)),
})?
}
RpcRequest::GetRecentBlockhash => Value::Array(vec![
Value::String(PUBKEY.to_string()),
serde_json::to_value(FeeCalculator::default()).unwrap(),
]),
RpcRequest::GetRecentBlockhash => serde_json::to_value(Response {
context: RpcResponseContext { slot: 1 },
value: (
Value::String(PUBKEY.to_string()),
serde_json::to_value(FeeCalculator::default()).unwrap(),
),
})?,
RpcRequest::GetSignatureStatus => {
let response: Option<transaction::Result<()>> = if self.url == "account_in_use" {
Some(Err(TransactionError::AccountInUse))

View File

@ -1,3 +1,4 @@
use crate::rpc_request::{Response, RpcResponse};
use crate::{
client_error::ClientError,
generic_rpc_client_request::GenericRpcClientRequest,
@ -55,31 +56,39 @@ impl RpcClient {
}
}
pub fn confirm_transaction(&self, signature: &str) -> Result<bool, ClientError> {
self.confirm_transaction_with_commitment(signature, CommitmentConfig::default())
pub fn confirm_transaction(&self, signature: &str) -> io::Result<bool> {
Ok(self
.confirm_transaction_with_commitment(signature, CommitmentConfig::default())?
.value)
}
pub fn confirm_transaction_with_commitment(
&self,
signature: &str,
commitment_config: CommitmentConfig,
) -> Result<bool, ClientError> {
) -> RpcResponse<bool> {
let params = json!(signature);
let response = self.client.send(
&RpcRequest::ConfirmTransaction,
Some(params),
0,
Some(commitment_config),
)?;
if response.as_bool().is_none() {
Err(io::Error::new(
io::ErrorKind::Other,
"Received result of an unexpected type",
let response = self
.client
.send(
&RpcRequest::ConfirmTransaction,
Some(params),
0,
Some(commitment_config),
)
.into())
} else {
Ok(response.as_bool().unwrap())
}
.map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("ConfirmTransaction request failure {:?}", err),
)
})?;
serde_json::from_value::<Response<bool>>(response).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("Received result of an unexpected type {:?}", err),
)
})
}
pub fn send_transaction(&self, transaction: &Transaction) -> Result<String, ClientError> {
@ -378,46 +387,69 @@ impl RpcClient {
retries: usize,
) -> Result<Option<u64>, Box<dyn error::Error>> {
let params = json!(format!("{}", pubkey));
let res = self
let balance_json = self
.client
.send(&RpcRequest::GetBalance, Some(params), retries, None)?
.as_u64();
Ok(res)
.send(&RpcRequest::GetBalance, Some(params), retries, None)
.map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("RetryGetBalance request failure: {:?}", err),
)
})?;
Ok(Some(
serde_json::from_value::<Response<u64>>(balance_json)
.map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("RetryGetBalance parse failure: {:?}", err),
)
})?
.value,
))
}
pub fn get_account(&self, pubkey: &Pubkey) -> io::Result<Account> {
self.get_account_with_commitment(pubkey, CommitmentConfig::default())
Ok(self
.get_account_with_commitment(pubkey, CommitmentConfig::default())
.map(|x| x.value.unwrap())?)
}
pub fn get_account_with_commitment(
&self,
pubkey: &Pubkey,
commitment_config: CommitmentConfig,
) -> io::Result<Account> {
) -> RpcResponse<Option<Account>> {
let params = json!(format!("{}", pubkey));
let response = self.client.send(
&RpcRequest::GetAccountInfo,
Some(params),
0,
commitment_config.ok(),
Some(commitment_config),
);
response
.and_then(|account_json| {
let account: Account = serde_json::from_value(account_json)?;
trace!("Response account {:?} {:?}", pubkey, account);
Ok(account)
.map(|result_json| {
if result_json.is_null() {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("AccountNotFound: pubkey={}", pubkey),
));
}
let result = serde_json::from_value::<Response<Option<Account>>>(result_json)?;
trace!("Response account {:?} {:?}", pubkey, result);
Ok(result)
})
.map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("AccountNotFound: pubkey={}: {}", pubkey, err),
)
})
})?
}
pub fn get_account_data(&self, pubkey: &Pubkey) -> io::Result<Vec<u8>> {
self.get_account(pubkey).map(|account| account.data)
Ok(self.get_account(pubkey).unwrap().data)
}
pub fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> io::Result<u64> {
@ -456,14 +488,16 @@ impl RpcClient {
/// Request the balance of the account `pubkey`.
pub fn get_balance(&self, pubkey: &Pubkey) -> io::Result<u64> {
self.get_balance_with_commitment(pubkey, CommitmentConfig::default())
Ok(self
.get_balance_with_commitment(pubkey, CommitmentConfig::default())?
.value)
}
pub fn get_balance_with_commitment(
&self,
pubkey: &Pubkey,
commitment_config: CommitmentConfig,
) -> io::Result<u64> {
) -> RpcResponse<u64> {
let params = json!(pubkey.to_string());
let balance_json = self
.client
@ -479,7 +513,8 @@ impl RpcClient {
format!("GetBalance request failure: {:?}", err),
)
})?;
serde_json::from_value(balance_json).map_err(|err| {
serde_json::from_value::<Response<u64>>(balance_json).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("GetBalance parse failure: {:?}", err),
@ -553,13 +588,15 @@ impl RpcClient {
}
pub fn get_recent_blockhash(&self) -> io::Result<(Hash, FeeCalculator)> {
self.get_recent_blockhash_with_commitment(CommitmentConfig::default())
Ok(self
.get_recent_blockhash_with_commitment(CommitmentConfig::default())?
.value)
}
pub fn get_recent_blockhash_with_commitment(
&self,
commitment_config: CommitmentConfig,
) -> io::Result<(Hash, FeeCalculator)> {
) -> RpcResponse<(Hash, FeeCalculator)> {
let response = self
.client
.send(
@ -575,21 +612,27 @@ impl RpcClient {
)
})?;
let (blockhash, fee_calculator) =
serde_json::from_value::<(String, FeeCalculator)>(response).map_err(|err| {
let Response {
context,
value: (blockhash_str, fee_calculator),
} = serde_json::from_value::<Response<(String, FeeCalculator)>>(response).map_err(
|err| {
io::Error::new(
io::ErrorKind::Other,
format!("GetRecentBlockhash parse failure: {:?}", err),
)
})?;
let blockhash = blockhash.parse().map_err(|err| {
},
)?;
let blockhash = blockhash_str.parse().map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("GetRecentBlockhash hash parse failure: {:?}", err),
)
})?;
Ok((blockhash, fee_calculator))
Ok(Response {
context,
value: (blockhash, fee_calculator),
})
}
pub fn get_new_blockhash(&self, blockhash: &Hash) -> io::Result<(Hash, FeeCalculator)> {
@ -658,7 +701,7 @@ impl RpcClient {
loop {
match self.get_balance_with_commitment(&pubkey, commitment_config.clone()) {
Ok(bal) => {
return Ok(bal);
return Ok(bal.value);
}
Err(e) => {
sleep(*polling_frequency);

View File

@ -1,9 +1,24 @@
use jsonrpc_core::Result as JsonResult;
use serde_json::{json, Value};
use solana_sdk::{
clock::{Epoch, Slot},
commitment_config::CommitmentConfig,
};
use std::{error, fmt};
use std::{error, fmt, io};
pub type RpcResponseIn<T> = JsonResult<Response<T>>;
pub type RpcResponse<T> = io::Result<Response<T>>;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RpcResponseContext {
pub slot: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Response<T> {
pub context: RpcResponseContext,
pub value: T,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]

View File

@ -4,6 +4,7 @@
//! unstable and may change in future releases.
use crate::rpc_client::RpcClient;
use crate::rpc_request::Response;
use bincode::{serialize_into, serialized_size};
use log::*;
use solana_sdk::{
@ -383,7 +384,11 @@ impl SyncClient for ThinClient {
}
fn get_account(&self, pubkey: &Pubkey) -> TransportResult<Option<Account>> {
Ok(self.rpc_client().get_account(pubkey).ok())
let account = self.rpc_client().get_account(pubkey);
match account {
Ok(value) => Ok(Some(value)),
Err(_) => Ok(None),
}
}
fn get_account_with_commitment(
@ -393,13 +398,12 @@ impl SyncClient for ThinClient {
) -> TransportResult<Option<Account>> {
Ok(self
.rpc_client()
.get_account_with_commitment(pubkey, commitment_config)
.ok())
.get_account_with_commitment(pubkey, commitment_config)?
.value)
}
fn get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64> {
let balance = self.rpc_client().get_balance(pubkey)?;
Ok(balance)
Ok(self.rpc_client().get_balance(pubkey)?)
}
fn get_balance_with_commitment(
@ -410,7 +414,7 @@ impl SyncClient for ThinClient {
let balance = self
.rpc_client()
.get_balance_with_commitment(pubkey, commitment_config)?;
Ok(balance)
Ok(balance.value)
}
fn get_recent_blockhash(&self) -> TransportResult<(Hash, FeeCalculator)> {
@ -426,9 +430,9 @@ impl SyncClient for ThinClient {
let recent_blockhash =
self.rpc_clients[index].get_recent_blockhash_with_commitment(commitment_config);
match recent_blockhash {
Ok(recent_blockhash) => {
Ok(Response { value, .. }) => {
self.optimizer.report(index, duration_as_ms(&now.elapsed()));
Ok(recent_blockhash)
Ok(value)
}
Err(e) => {
self.optimizer.report(index, std::u64::MAX);