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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 262 additions and 134 deletions

View File

@ -96,6 +96,13 @@ If commitment configuration is not provided, the node will default to `"commitme
Only methods that query bank state accept the commitment parameter. They are indicated in the API Reference below.
#### RpcResponse Structure
Many methods that take a commitment parameter return an RpcResponse JSON object comprised of two parts:
* `context` : An RpcResponseContext JSON structure including a `slot` field at which the operation was evaluated.
* `value` : The value returned by the operation itself.
## JSON RPC API Reference
### confirmTransaction
@ -109,7 +116,7 @@ Returns a transaction receipt
#### Results:
* `boolean` - Transaction status, true if Transaction is confirmed
* `RpcResponse<boolean>` - RpcResponse JSON object with `value` field set to Transaction status, boolean true if Transaction is confirmed
#### Example:
@ -118,7 +125,7 @@ Returns a transaction receipt
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"confirmTransaction", "params":["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW"]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":true,"id":1}
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":true},"id":1}
```
### getAccountInfo
@ -132,8 +139,9 @@ Returns all information associated with the account of provided Pubkey
#### Results:
The result field will be a JSON object with the following sub fields:
The result value will be an RpcResponse JSON object containing an AccountInfo JSON object.
* `RpcResponse<AccountInfo>`, RpcResponse JSON object with `value` field set to AccountInfo, a JSON object containing:
* `lamports`, number of lamports assigned to this account, as a signed 64-bit integer
* `owner`, array of 32 bytes representing the program this account has been assigned to
* `data`, array of bytes representing any data associated with the account
@ -146,7 +154,7 @@ The result field will be a JSON object with the following sub fields:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getAccountInfo", "params":["2gVkYWexTHR5Hb2aLeQN3tnngvWzisFKXDUPrgMHpdST"]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"executable":false,"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"data":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0.21.0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]},"id":1}
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"executable":false,"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"data":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0.21.0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]}},"id":1}
```
### getBalance
@ -160,7 +168,7 @@ Returns the balance of the account of provided Pubkey
#### Results:
* `integer` - quantity, as a signed 64-bit integer
* `RpcResponse<integer>` - RpcResponse JSON object with `value` field set to quantity, as a signed 64-bit integer
#### Example:
@ -169,7 +177,7 @@ Returns the balance of the account of provided Pubkey
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getBalance", "params":["83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri"]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":0,"id":1}
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":0},"id":1}
```
### getBlockCommitment
@ -410,8 +418,9 @@ Returns a recent block hash from the ledger, and a fee schedule that can be used
#### Results:
An array consisting of
An RpcResponse containing an array consisting of a string blockhash and FeeCalculator JSON object.
* `RpcResponse<array>` - RpcResponse JSON object with `value` field set to an array including:
* `string` - a Hash as base-58 encoded string
* `FeeCalculator object` - the fee schedule for this block hash
@ -422,7 +431,7 @@ An array consisting of
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getRecentBlockhash"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":["GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC",{"lamportsPerSignature": 0}],"id":1}
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":["GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC",{"lamportsPerSignature": 0}]},"id":1}
```
### getSignatureStatus

View File

@ -3,7 +3,7 @@ use solana_cli::cli::{process_command, CliCommand, CliConfig};
use solana_client::rpc_client::RpcClient;
use solana_core::validator::new_validator_for_tests;
use solana_drone::drone::run_local_drone;
use solana_sdk::{bpf_loader, commitment_config::CommitmentConfig, pubkey::Pubkey};
use solana_sdk::{bpf_loader, pubkey::Pubkey};
use std::{
fs::{remove_dir_all, File},
io::Read,
@ -59,10 +59,7 @@ fn test_cli_deploy_program() {
.as_str()
.unwrap();
let program_id = Pubkey::from_str(&program_id_str).unwrap();
let account = rpc_client
.get_account_with_commitment(&program_id, CommitmentConfig::recent())
.unwrap();
let account = rpc_client.get_account(&program_id).unwrap();
assert_eq!(account.lamports, minimum_balance_for_rent_exemption);
assert_eq!(account.owner, bpf_loader::id());
assert_eq!(account.executable, true);

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);

View File

@ -12,7 +12,9 @@ use crate::{
use bincode::serialize;
use jsonrpc_core::{Error, Metadata, Result};
use jsonrpc_derive::rpc;
use solana_client::rpc_request::{RpcEpochInfo, RpcVoteAccountInfo, RpcVoteAccountStatus};
use solana_client::rpc_request::{
Response, RpcEpochInfo, RpcResponseContext, RpcVoteAccountInfo, RpcVoteAccountStatus,
};
use solana_drone::drone::request_airdrop_transaction;
use solana_ledger::{
bank_forks::BankForks, blocktree::Blocktree, rooted_slot_iterator::RootedSlotIterator,
@ -40,6 +42,13 @@ use std::{
time::{Duration, Instant},
};
type RpcResponse<T> = Result<Response<T>>;
fn new_response<T>(bank: &Bank, value: T) -> RpcResponse<T> {
let context = RpcResponseContext { slot: bank.slot() };
Ok(Response { context, value })
}
#[derive(Debug, Clone)]
pub struct JsonRpcConfig {
pub enable_validator_exit: bool, // Enable the 'validatorExit' command
@ -100,12 +109,14 @@ impl JsonRpcRequestProcessor {
pub fn get_account_info(
&self,
pubkey: &Pubkey,
pubkey: Result<Pubkey>,
commitment: Option<CommitmentConfig>,
) -> Result<Account> {
self.bank(commitment)
.get_account(&pubkey)
.ok_or_else(Error::invalid_request)
) -> RpcResponse<Option<Account>> {
let bank = &*self.bank(commitment);
match pubkey {
Ok(key) => new_response(bank, bank.get_account(&key)),
Err(e) => Err(e),
}
}
pub fn get_minimum_balance_for_rent_exemption(
@ -141,16 +152,43 @@ impl JsonRpcRequestProcessor {
Ok(*self.bank(None).epoch_schedule())
}
pub fn get_balance(&self, pubkey: &Pubkey, commitment: Option<CommitmentConfig>) -> u64 {
self.bank(commitment).get_balance(&pubkey)
pub fn get_balance(
&self,
pubkey: Result<Pubkey>,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<u64> {
let bank = &*self.bank(commitment);
match pubkey {
Ok(key) => new_response(bank, bank.get_balance(&key)),
Err(e) => Err(e),
}
}
fn get_recent_blockhash(
&self,
commitment: Option<CommitmentConfig>,
) -> (String, FeeCalculator) {
let (blockhash, fee_calculator) = self.bank(commitment).confirmed_last_blockhash();
(blockhash.to_string(), fee_calculator)
) -> RpcResponse<(String, FeeCalculator)> {
let bank = &*self.bank(commitment);
let (blockhash, fee_calculator) = bank.confirmed_last_blockhash();
new_response(bank, (blockhash.to_string(), fee_calculator))
}
pub fn confirm_transaction(
&self,
signature: Result<Signature>,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<bool> {
let bank = &*self.bank(commitment);
match signature {
Err(e) => Err(e),
Ok(sig) => {
let status = bank.get_signature_confirmation_status(&sig);
match status {
Some((_, result)) => new_response(bank, result.is_ok()),
None => new_response(bank, false),
}
}
}
}
fn get_block_commitment(&self, block: Slot) -> (Option<BlockCommitment>, u64) {
@ -333,7 +371,7 @@ pub trait RpcSol {
meta: Self::Metadata,
signature_str: String,
commitment: Option<CommitmentConfig>,
) -> Result<bool>;
) -> RpcResponse<bool>;
#[rpc(meta, name = "getAccountInfo")]
fn get_account_info(
@ -341,7 +379,7 @@ pub trait RpcSol {
meta: Self::Metadata,
pubkey_str: String,
commitment: Option<CommitmentConfig>,
) -> Result<Account>;
) -> RpcResponse<Option<Account>>;
#[rpc(meta, name = "getProgramAccounts")]
fn get_program_accounts(
@ -375,7 +413,7 @@ pub trait RpcSol {
meta: Self::Metadata,
pubkey_str: String,
commitment: Option<CommitmentConfig>,
) -> Result<u64>;
) -> RpcResponse<u64>;
#[rpc(meta, name = "getClusterNodes")]
fn get_cluster_nodes(&self, meta: Self::Metadata) -> Result<Vec<RpcContactInfo>>;
@ -409,7 +447,7 @@ pub trait RpcSol {
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> Result<(String, FeeCalculator)>;
) -> RpcResponse<(String, FeeCalculator)>;
#[rpc(meta, name = "getSignatureStatus")]
fn get_signature_status(
@ -521,20 +559,15 @@ impl RpcSol for RpcSolImpl {
fn confirm_transaction(
&self,
meta: Self::Metadata,
signature_str: String,
id: String,
commitment: Option<CommitmentConfig>,
) -> Result<bool> {
debug!(
"confirm_transaction rpc request received: {:?}",
signature_str
);
self.get_signature_status(meta, signature_str, commitment)
.map(|status_option| {
if status_option.is_none() {
return false;
}
status_option.unwrap().is_ok()
})
) -> RpcResponse<bool> {
debug!("confirm_transaction rpc request received: {:?}", id);
let signature = verify_signature(&id);
meta.request_processor
.read()
.unwrap()
.confirm_transaction(signature, commitment)
}
fn get_account_info(
@ -542,13 +575,13 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata,
pubkey_str: String,
commitment: Option<CommitmentConfig>,
) -> Result<Account> {
) -> RpcResponse<Option<Account>> {
debug!("get_account_info rpc request received: {:?}", pubkey_str);
let pubkey = verify_pubkey(pubkey_str)?;
let pubkey = verify_pubkey(pubkey_str);
meta.request_processor
.read()
.unwrap()
.get_account_info(&pubkey, commitment)
.get_account_info(pubkey, commitment)
}
fn get_minimum_balance_for_rent_exemption(
@ -613,14 +646,13 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata,
pubkey_str: String,
commitment: Option<CommitmentConfig>,
) -> Result<u64> {
) -> RpcResponse<u64> {
debug!("get_balance rpc request received: {:?}", pubkey_str);
let pubkey = verify_pubkey(pubkey_str)?;
Ok(meta
.request_processor
let pubkey = verify_pubkey(pubkey_str);
meta.request_processor
.read()
.unwrap()
.get_balance(&pubkey, commitment))
.get_balance(pubkey, commitment)
}
fn get_cluster_nodes(&self, meta: Self::Metadata) -> Result<Vec<RpcContactInfo>> {
@ -707,13 +739,12 @@ impl RpcSol for RpcSolImpl {
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> Result<(String, FeeCalculator)> {
) -> RpcResponse<(String, FeeCalculator)> {
debug!("get_recent_blockhash rpc request received");
Ok(meta
.request_processor
meta.request_processor
.read()
.unwrap()
.get_recent_blockhash(commitment))
.get_recent_blockhash(commitment)
}
fn get_signature_status(
@ -1150,10 +1181,15 @@ pub mod tests {
bob_pubkey
);
let res = io.handle_request_sync(&req, meta);
let expected = format!(r#"{{"jsonrpc":"2.0","result":20,"id":1}}"#);
let expected: Response =
serde_json::from_str(&expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))
let expected = json!({
"jsonrpc": "2.0",
"result": {
"context":{"slot":0},
"value":20,
},
"id": 1,
});
let result = serde_json::from_str::<Value>(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(expected, result);
}
@ -1328,19 +1364,22 @@ pub mod tests {
bob_pubkey
);
let res = io.handle_request_sync(&req, meta);
let expected = r#"{
"jsonrpc":"2.0",
"result":{
let expected = json!({
"jsonrpc": "2.0",
"result": {
"context":{"slot":0},
"value":{
"owner": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
"lamports": 20,
"data": [],
"executable": false,
"rent_epoch": 0
},
"id":1}
"#;
},
"id": 1,
});
let expected: Response =
serde_json::from_str(&expected).expect("expected response deserialization");
serde_json::from_value(expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(expected, result);
@ -1404,9 +1443,16 @@ pub mod tests {
tx.signatures[0]
);
let res = io.handle_request_sync(&req, meta);
let expected = format!(r#"{{"jsonrpc":"2.0","result":true,"id":1}}"#);
let expected = json!({
"jsonrpc": "2.0",
"result": {
"context":{"slot":0},
"value":true,
},
"id": 1,
});
let expected: Response =
serde_json::from_str(&expected).expect("expected response deserialization");
serde_json::from_value(expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(expected, result);
@ -1496,14 +1542,16 @@ pub mod tests {
let res = io.handle_request_sync(&req, meta);
let expected = json!({
"jsonrpc": "2.0",
"result": [ blockhash.to_string(), {
"result": {
"context":{"slot":0},
"value":[ blockhash.to_string(), {
"burnPercent": DEFAULT_BURN_PERCENT,
"lamportsPerSignature": 0,
"maxLamportsPerSignature": 0,
"minLamportsPerSignature": 0,
"targetLamportsPerSignature": 0,
"targetSignaturesPerSlot": 0
}],
}]},
"id": 1
});
let expected: Response =

View File

@ -229,7 +229,9 @@ mod tests {
.request_processor
.read()
.unwrap()
.get_balance(&mint_keypair.pubkey(), None)
.get_balance(Ok(mint_keypair.pubkey()), None)
.unwrap()
.value
);
rpc_service.exit();
rpc_service.join().unwrap();

View File

@ -1,5 +1,6 @@
use solana_client::rpc_client::RpcClient;
use solana_core::validator::new_validator_for_tests;
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::KeypairUtil;
use solana_sdk::system_transaction;
@ -22,7 +23,6 @@ fn test_rpc_client() {
);
assert_eq!(client.get_balance(&bob_pubkey).unwrap(), 0);
assert_eq!(client.get_balance(&alice.pubkey()).unwrap(), 10000);
let (blockhash, _fee_calculator) = client.get_recent_blockhash().unwrap();
@ -34,14 +34,13 @@ fn test_rpc_client() {
let now = Instant::now();
while now.elapsed().as_secs() <= 20 {
let response = client.confirm_transaction(signature.as_str());
let response = client
.confirm_transaction_with_commitment(signature.as_str(), CommitmentConfig::default())
.unwrap();
match response {
Ok(true) => {
confirmed_tx = true;
break;
}
_ => (),
if response.value {
confirmed_tx = true;
break;
}
sleep(Duration::from_millis(500));

View File

@ -34,7 +34,11 @@ fn test_rpc_send_tx() {
.send()
.unwrap();
let json: Value = serde_json::from_str(&response.text().unwrap()).unwrap();
let blockhash: Hash = json["result"][0].as_str().unwrap().parse().unwrap();
let blockhash: Hash = json["result"]["value"][0]
.as_str()
.unwrap()
.parse()
.unwrap();
info!("blockhash: {:?}", blockhash);
let tx = system_transaction::transfer(&alice, &bob_pubkey, 20, blockhash);
@ -78,7 +82,7 @@ fn test_rpc_send_tx() {
let response_json_text = response.text().unwrap();
let json: Value = serde_json::from_str(&response_json_text).unwrap();
if true == json["result"] {
if true == json["result"]["value"] {
confirmed_tx = true;
break;
}