automerge
This commit is contained in:
@ -1153,7 +1153,7 @@ fn process_balance(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn process_confirm(rpc_client: &RpcClient, signature: &Signature) -> ProcessResult {
|
fn process_confirm(rpc_client: &RpcClient, signature: &Signature) -> ProcessResult {
|
||||||
match rpc_client.get_signature_status(&signature.to_string()) {
|
match rpc_client.get_signature_status(&signature) {
|
||||||
Ok(status) => {
|
Ok(status) => {
|
||||||
if let Some(result) = status {
|
if let Some(result) = status {
|
||||||
match result {
|
match result {
|
||||||
@ -2165,7 +2165,7 @@ pub fn request_and_confirm_airdrop(
|
|||||||
log_instruction_custom_error::<SystemError>(result)
|
log_instruction_custom_error::<SystemError>(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_instruction_custom_error<E>(result: ClientResult<String>) -> ProcessResult
|
pub fn log_instruction_custom_error<E>(result: ClientResult<Signature>) -> ProcessResult
|
||||||
where
|
where
|
||||||
E: 'static + std::error::Error + DecodeError<E> + FromPrimitive,
|
E: 'static + std::error::Error + DecodeError<E> + FromPrimitive,
|
||||||
{
|
{
|
||||||
@ -2182,7 +2182,7 @@ where
|
|||||||
}
|
}
|
||||||
Err(err.into())
|
Err(err.into())
|
||||||
}
|
}
|
||||||
Ok(sig) => Ok(sig),
|
Ok(sig) => Ok(sig.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,8 +266,8 @@ pub fn process_claim_storage_reward(
|
|||||||
&fee_calculator,
|
&fee_calculator,
|
||||||
&tx.message,
|
&tx.message,
|
||||||
)?;
|
)?;
|
||||||
let signature_str = rpc_client.send_and_confirm_transaction_with_spinner(&mut tx, &signers)?;
|
let signature = rpc_client.send_and_confirm_transaction_with_spinner(&mut tx, &signers)?;
|
||||||
Ok(signature_str)
|
Ok(signature.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_show_storage_account(
|
pub fn process_show_storage_account(
|
||||||
|
@ -40,7 +40,7 @@ impl GenericRpcClientRequest for MockRpcClientRequest {
|
|||||||
fn send(
|
fn send(
|
||||||
&self,
|
&self,
|
||||||
request: &RpcRequest,
|
request: &RpcRequest,
|
||||||
params: serde_json::Value,
|
_params: serde_json::Value,
|
||||||
_retries: usize,
|
_retries: usize,
|
||||||
) -> Result<serde_json::Value> {
|
) -> Result<serde_json::Value> {
|
||||||
if let Some(value) = self.mocks.write().unwrap().remove(request) {
|
if let Some(value) = self.mocks.write().unwrap().remove(request) {
|
||||||
@ -50,17 +50,6 @@ impl GenericRpcClientRequest for MockRpcClientRequest {
|
|||||||
return Ok(Value::Null);
|
return Ok(Value::Null);
|
||||||
}
|
}
|
||||||
let val = match request {
|
let val = match request {
|
||||||
RpcRequest::ConfirmTransaction => {
|
|
||||||
if let Some(params_array) = params.as_array() {
|
|
||||||
if let Value::String(param_string) = ¶ms_array[0] {
|
|
||||||
Value::Bool(param_string == SIGNATURE)
|
|
||||||
} else {
|
|
||||||
Value::Null
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Value::Null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RpcRequest::GetBalance => serde_json::to_value(Response {
|
RpcRequest::GetBalance => serde_json::to_value(Response {
|
||||||
context: RpcResponseContext { slot: 1 },
|
context: RpcResponseContext { slot: 1 },
|
||||||
value: Value::Number(Number::from(50)),
|
value: Value::Number(Number::from(50)),
|
||||||
@ -87,21 +76,6 @@ impl GenericRpcClientRequest for MockRpcClientRequest {
|
|||||||
context: RpcResponseContext { slot: 1 },
|
context: RpcResponseContext { slot: 1 },
|
||||||
value: serde_json::to_value(FeeRateGovernor::default()).unwrap(),
|
value: serde_json::to_value(FeeRateGovernor::default()).unwrap(),
|
||||||
})?,
|
})?,
|
||||||
RpcRequest::GetSignatureStatus => {
|
|
||||||
let response: Option<transaction::Result<()>> = if self.url == "account_in_use" {
|
|
||||||
Some(Err(TransactionError::AccountInUse))
|
|
||||||
} else if self.url == "instruction_error" {
|
|
||||||
Some(Err(TransactionError::InstructionError(
|
|
||||||
0,
|
|
||||||
InstructionError::UninitializedAccount,
|
|
||||||
)))
|
|
||||||
} else if self.url == "sig_not_found" {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Ok(()))
|
|
||||||
};
|
|
||||||
serde_json::to_value(response).unwrap()
|
|
||||||
}
|
|
||||||
RpcRequest::GetSignatureStatuses => {
|
RpcRequest::GetSignatureStatuses => {
|
||||||
let status: transaction::Result<()> = if self.url == "account_in_use" {
|
let status: transaction::Result<()> = if self.url == "account_in_use" {
|
||||||
Err(TransactionError::AccountInUse)
|
Err(TransactionError::AccountInUse)
|
||||||
|
@ -32,7 +32,6 @@ use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
|
|||||||
use std::{
|
use std::{
|
||||||
error,
|
error,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
str::FromStr,
|
|
||||||
thread::sleep,
|
thread::sleep,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
@ -71,7 +70,7 @@ impl RpcClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn confirm_transaction(&self, signature: &str) -> ClientResult<bool> {
|
pub fn confirm_transaction(&self, signature: &Signature) -> ClientResult<bool> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.confirm_transaction_with_commitment(signature, CommitmentConfig::default())?
|
.confirm_transaction_with_commitment(signature, CommitmentConfig::default())?
|
||||||
.value)
|
.value)
|
||||||
@ -79,44 +78,62 @@ impl RpcClient {
|
|||||||
|
|
||||||
pub fn confirm_transaction_with_commitment(
|
pub fn confirm_transaction_with_commitment(
|
||||||
&self,
|
&self,
|
||||||
signature: &str,
|
signature: &Signature,
|
||||||
commitment_config: CommitmentConfig,
|
commitment_config: CommitmentConfig,
|
||||||
) -> RpcResult<bool> {
|
) -> RpcResult<bool> {
|
||||||
let response = self
|
let Response { context, value } =
|
||||||
.client
|
self.get_signature_statuses_with_commitment(&[*signature], commitment_config)?;
|
||||||
.send(
|
|
||||||
&RpcRequest::ConfirmTransaction,
|
|
||||||
json!([signature, commitment_config]),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
.map_err(|err| err.into_with_command("ConfirmTransaction"))?;
|
|
||||||
|
|
||||||
serde_json::from_value::<Response<bool>>(response)
|
Ok(Response {
|
||||||
.map_err(|err| ClientError::new_with_command(err.into(), "ConfirmTransaction"))
|
context,
|
||||||
|
value: value[0]
|
||||||
|
.as_ref()
|
||||||
|
.map(|result| result.status.is_ok())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_transaction(&self, transaction: &Transaction) -> ClientResult<String> {
|
pub fn send_transaction(&self, transaction: &Transaction) -> ClientResult<Signature> {
|
||||||
let serialized_encoded = bs58::encode(serialize(transaction).unwrap()).into_string();
|
let serialized_encoded = bs58::encode(serialize(transaction).unwrap()).into_string();
|
||||||
let signature =
|
let response =
|
||||||
self.client
|
self.client
|
||||||
.send(&RpcRequest::SendTransaction, json!([serialized_encoded]), 5)?;
|
.send(&RpcRequest::SendTransaction, json!([serialized_encoded]), 5)?;
|
||||||
if signature.as_str().is_none() {
|
|
||||||
Err(RpcError::ForUser("Received result of an unexpected type".to_string()).into())
|
match response.as_str() {
|
||||||
} else {
|
None => {
|
||||||
Ok(signature.as_str().unwrap().to_string())
|
Err(RpcError::ForUser("Received result of an unexpected type".to_string()).into())
|
||||||
|
}
|
||||||
|
Some(signature_base58_str) => signature_base58_str
|
||||||
|
.parse::<Signature>()
|
||||||
|
.map_err(|err| RpcError::ParseError(err.to_string()).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_signature_status(
|
pub fn get_signature_status(
|
||||||
&self,
|
&self,
|
||||||
signature: &str,
|
signature: &Signature,
|
||||||
) -> ClientResult<Option<transaction::Result<()>>> {
|
) -> ClientResult<Option<transaction::Result<()>>> {
|
||||||
self.get_signature_status_with_commitment(signature, CommitmentConfig::default())
|
self.get_signature_status_with_commitment(signature, CommitmentConfig::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_signature_statuses_with_commitment(
|
||||||
|
&self,
|
||||||
|
signatures: &[Signature],
|
||||||
|
commitment_config: CommitmentConfig,
|
||||||
|
) -> RpcResult<Vec<Option<TransactionStatus>>> {
|
||||||
|
let signatures: Vec<_> = signatures.iter().map(|s| s.to_string()).collect();
|
||||||
|
let signature_status = self.client.send(
|
||||||
|
&RpcRequest::GetSignatureStatuses,
|
||||||
|
json!([&signatures, commitment_config]),
|
||||||
|
5,
|
||||||
|
)?;
|
||||||
|
Ok(serde_json::from_value(signature_status)
|
||||||
|
.map_err(|err| ClientError::new_with_command(err.into(), "GetSignatureStatuses"))?)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_signature_status_with_commitment(
|
pub fn get_signature_status_with_commitment(
|
||||||
&self,
|
&self,
|
||||||
signature: &str,
|
signature: &Signature,
|
||||||
commitment_config: CommitmentConfig,
|
commitment_config: CommitmentConfig,
|
||||||
) -> ClientResult<Option<transaction::Result<()>>> {
|
) -> ClientResult<Option<transaction::Result<()>>> {
|
||||||
let signature_status = self.client.send(
|
let signature_status = self.client.send(
|
||||||
@ -334,13 +351,13 @@ impl RpcClient {
|
|||||||
&self,
|
&self,
|
||||||
transaction: &mut Transaction,
|
transaction: &mut Transaction,
|
||||||
signer_keys: &T,
|
signer_keys: &T,
|
||||||
) -> ClientResult<String> {
|
) -> ClientResult<Signature> {
|
||||||
let mut send_retries = 20;
|
let mut send_retries = 20;
|
||||||
loop {
|
loop {
|
||||||
let mut status_retries = 15;
|
let mut status_retries = 15;
|
||||||
let signature_str = self.send_transaction(transaction)?;
|
let signature = self.send_transaction(transaction)?;
|
||||||
let status = loop {
|
let status = loop {
|
||||||
let status = self.get_signature_status(&signature_str)?;
|
let status = self.get_signature_status(&signature)?;
|
||||||
if status.is_none() {
|
if status.is_none() {
|
||||||
status_retries -= 1;
|
status_retries -= 1;
|
||||||
if status_retries == 0 {
|
if status_retries == 0 {
|
||||||
@ -356,7 +373,7 @@ impl RpcClient {
|
|||||||
};
|
};
|
||||||
send_retries = if let Some(result) = status.clone() {
|
send_retries = if let Some(result) = status.clone() {
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => return Ok(signature_str),
|
Ok(_) => return Ok(signature),
|
||||||
Err(TransactionError::AccountInUse) => {
|
Err(TransactionError::AccountInUse) => {
|
||||||
// Fetch a new blockhash and re-sign the transaction before sending it again
|
// Fetch a new blockhash and re-sign the transaction before sending it again
|
||||||
self.resign_transaction(transaction, signer_keys)?;
|
self.resign_transaction(transaction, signer_keys)?;
|
||||||
@ -818,10 +835,9 @@ impl RpcClient {
|
|||||||
) -> ClientResult<()> {
|
) -> ClientResult<()> {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
loop {
|
loop {
|
||||||
if let Ok(Some(_)) = self.get_signature_status_with_commitment(
|
if let Ok(Some(_)) =
|
||||||
&signature.to_string(),
|
self.get_signature_status_with_commitment(&signature, commitment_config.clone())
|
||||||
commitment_config.clone(),
|
{
|
||||||
) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if now.elapsed().as_secs() > 15 {
|
if now.elapsed().as_secs() > 15 {
|
||||||
@ -841,14 +857,13 @@ impl RpcClient {
|
|||||||
trace!("check_signature: {:?}", signature);
|
trace!("check_signature: {:?}", signature);
|
||||||
|
|
||||||
for _ in 0..30 {
|
for _ in 0..30 {
|
||||||
let response = self.client.send(
|
let response =
|
||||||
&RpcRequest::ConfirmTransaction,
|
self.confirm_transaction_with_commitment(signature, CommitmentConfig::recent());
|
||||||
json!([signature.to_string(), CommitmentConfig::recent()]),
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
|
|
||||||
match response {
|
match response {
|
||||||
Ok(Value::Bool(signature_status)) => {
|
Ok(Response {
|
||||||
|
value: signature_status,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
if signature_status {
|
if signature_status {
|
||||||
trace!("Response found signature");
|
trace!("Response found signature");
|
||||||
} else {
|
} else {
|
||||||
@ -857,12 +872,6 @@ impl RpcClient {
|
|||||||
|
|
||||||
return signature_status;
|
return signature_status;
|
||||||
}
|
}
|
||||||
Ok(other) => {
|
|
||||||
debug!(
|
|
||||||
"check_signature request failed, expected bool, got: {:?}",
|
|
||||||
other
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
debug!("check_signature request failed: {:?}", err);
|
debug!("check_signature request failed: {:?}", err);
|
||||||
}
|
}
|
||||||
@ -959,7 +968,7 @@ impl RpcClient {
|
|||||||
&self,
|
&self,
|
||||||
transaction: &mut Transaction,
|
transaction: &mut Transaction,
|
||||||
signer_keys: &T,
|
signer_keys: &T,
|
||||||
) -> ClientResult<String> {
|
) -> ClientResult<Signature> {
|
||||||
let mut confirmations = 0;
|
let mut confirmations = 0;
|
||||||
|
|
||||||
let progress_bar = new_spinner_progress_bar();
|
let progress_bar = new_spinner_progress_bar();
|
||||||
@ -970,23 +979,21 @@ impl RpcClient {
|
|||||||
));
|
));
|
||||||
|
|
||||||
let mut send_retries = 20;
|
let mut send_retries = 20;
|
||||||
let signature_str = loop {
|
let signature = loop {
|
||||||
let mut status_retries = 15;
|
let mut status_retries = 15;
|
||||||
let (signature_str, status) = loop {
|
let (signature, status) = loop {
|
||||||
let signature_str = self.send_transaction(transaction)?;
|
let signature = self.send_transaction(transaction)?;
|
||||||
|
|
||||||
// Get recent commitment in order to count confirmations for successful transactions
|
// Get recent commitment in order to count confirmations for successful transactions
|
||||||
let status = self.get_signature_status_with_commitment(
|
let status = self
|
||||||
&signature_str,
|
.get_signature_status_with_commitment(&signature, CommitmentConfig::recent())?;
|
||||||
CommitmentConfig::recent(),
|
|
||||||
)?;
|
|
||||||
if status.is_none() {
|
if status.is_none() {
|
||||||
status_retries -= 1;
|
status_retries -= 1;
|
||||||
if status_retries == 0 {
|
if status_retries == 0 {
|
||||||
break (signature_str, status);
|
break (signature, status);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break (signature_str, status);
|
break (signature, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg!(not(test)) {
|
if cfg!(not(test)) {
|
||||||
@ -1011,7 +1018,7 @@ impl RpcClient {
|
|||||||
if let Some(result) = status {
|
if let Some(result) = status {
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
break signature_str;
|
break signature;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(err.into());
|
return Err(err.into());
|
||||||
@ -1024,19 +1031,13 @@ impl RpcClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let signature = Signature::from_str(&signature_str).map_err(|_| {
|
|
||||||
ClientError::from(ClientErrorKind::Custom(format!(
|
|
||||||
"Returned string {} cannot be parsed as a signature",
|
|
||||||
signature_str
|
|
||||||
)))
|
|
||||||
})?;
|
|
||||||
loop {
|
loop {
|
||||||
// Return when default (max) commitment is reached
|
// Return when default (max) commitment is reached
|
||||||
// Failed transactions have already been eliminated, `is_some` check is sufficient
|
// Failed transactions have already been eliminated, `is_some` check is sufficient
|
||||||
if self.get_signature_status(&signature_str)?.is_some() {
|
if self.get_signature_status(&signature)?.is_some() {
|
||||||
progress_bar.set_message("Transaction confirmed");
|
progress_bar.set_message("Transaction confirmed");
|
||||||
progress_bar.finish_and_clear();
|
progress_bar.finish_and_clear();
|
||||||
return Ok(signature_str);
|
return Ok(signature);
|
||||||
}
|
}
|
||||||
progress_bar.set_message(&format!(
|
progress_bar.set_message(&format!(
|
||||||
"[{}/{}] Waiting for confirmations",
|
"[{}/{}] Waiting for confirmations",
|
||||||
@ -1198,7 +1199,7 @@ mod tests {
|
|||||||
let tx = system_transaction::transfer(&key, &to, 50, blockhash);
|
let tx = system_transaction::transfer(&key, &to, 50, blockhash);
|
||||||
|
|
||||||
let signature = rpc_client.send_transaction(&tx);
|
let signature = rpc_client.send_transaction(&tx);
|
||||||
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
assert_eq!(signature.unwrap(), SIGNATURE.parse().unwrap());
|
||||||
|
|
||||||
let rpc_client = RpcClient::new_mock("fails".to_string());
|
let rpc_client = RpcClient::new_mock("fails".to_string());
|
||||||
|
|
||||||
@ -1221,18 +1222,17 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_signature_status() {
|
fn test_get_signature_status() {
|
||||||
|
let signature = Signature::default();
|
||||||
|
|
||||||
let rpc_client = RpcClient::new_mock("succeeds".to_string());
|
let rpc_client = RpcClient::new_mock("succeeds".to_string());
|
||||||
let signature = "good_signature";
|
|
||||||
let status = rpc_client.get_signature_status(&signature).unwrap();
|
let status = rpc_client.get_signature_status(&signature).unwrap();
|
||||||
assert_eq!(status, Some(Ok(())));
|
assert_eq!(status, Some(Ok(())));
|
||||||
|
|
||||||
let rpc_client = RpcClient::new_mock("sig_not_found".to_string());
|
let rpc_client = RpcClient::new_mock("sig_not_found".to_string());
|
||||||
let signature = "sig_not_found";
|
|
||||||
let status = rpc_client.get_signature_status(&signature).unwrap();
|
let status = rpc_client.get_signature_status(&signature).unwrap();
|
||||||
assert_eq!(status, None);
|
assert_eq!(status, None);
|
||||||
|
|
||||||
let rpc_client = RpcClient::new_mock("account_in_use".to_string());
|
let rpc_client = RpcClient::new_mock("account_in_use".to_string());
|
||||||
let signature = "account_in_use";
|
|
||||||
let status = rpc_client.get_signature_status(&signature).unwrap();
|
let status = rpc_client.get_signature_status(&signature).unwrap();
|
||||||
assert_eq!(status, Some(Err(TransactionError::AccountInUse)));
|
assert_eq!(status, Some(Err(TransactionError::AccountInUse)));
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ use thiserror::Error;
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum RpcRequest {
|
pub enum RpcRequest {
|
||||||
ConfirmTransaction,
|
|
||||||
DeregisterNode,
|
DeregisterNode,
|
||||||
ValidatorExit,
|
ValidatorExit,
|
||||||
GetAccountInfo,
|
GetAccountInfo,
|
||||||
@ -22,7 +21,6 @@ pub enum RpcRequest {
|
|||||||
GetRecentBlockhash,
|
GetRecentBlockhash,
|
||||||
GetFeeCalculatorForBlockhash,
|
GetFeeCalculatorForBlockhash,
|
||||||
GetFeeRateGovernor,
|
GetFeeRateGovernor,
|
||||||
GetSignatureStatus,
|
|
||||||
GetSignatureStatuses,
|
GetSignatureStatuses,
|
||||||
GetSlot,
|
GetSlot,
|
||||||
GetSlotLeader,
|
GetSlotLeader,
|
||||||
@ -45,7 +43,6 @@ impl RpcRequest {
|
|||||||
pub(crate) fn build_request_json(&self, id: u64, params: Value) -> Value {
|
pub(crate) fn build_request_json(&self, id: u64, params: Value) -> Value {
|
||||||
let jsonrpc = "2.0";
|
let jsonrpc = "2.0";
|
||||||
let method = match self {
|
let method = match self {
|
||||||
RpcRequest::ConfirmTransaction => "confirmTransaction",
|
|
||||||
RpcRequest::DeregisterNode => "deregisterNode",
|
RpcRequest::DeregisterNode => "deregisterNode",
|
||||||
RpcRequest::ValidatorExit => "validatorExit",
|
RpcRequest::ValidatorExit => "validatorExit",
|
||||||
RpcRequest::GetAccountInfo => "getAccountInfo",
|
RpcRequest::GetAccountInfo => "getAccountInfo",
|
||||||
@ -64,7 +61,6 @@ impl RpcRequest {
|
|||||||
RpcRequest::GetRecentBlockhash => "getRecentBlockhash",
|
RpcRequest::GetRecentBlockhash => "getRecentBlockhash",
|
||||||
RpcRequest::GetFeeCalculatorForBlockhash => "getFeeCalculatorForBlockhash",
|
RpcRequest::GetFeeCalculatorForBlockhash => "getFeeCalculatorForBlockhash",
|
||||||
RpcRequest::GetFeeRateGovernor => "getFeeRateGovernor",
|
RpcRequest::GetFeeRateGovernor => "getFeeRateGovernor",
|
||||||
RpcRequest::GetSignatureStatus => "getSignatureStatus",
|
|
||||||
RpcRequest::GetSignatureStatuses => "getSignatureStatuses",
|
RpcRequest::GetSignatureStatuses => "getSignatureStatuses",
|
||||||
RpcRequest::GetSlot => "getSlot",
|
RpcRequest::GetSlot => "getSlot",
|
||||||
RpcRequest::GetSlotLeader => "getSlotLeader",
|
RpcRequest::GetSlotLeader => "getSlotLeader",
|
||||||
|
@ -471,7 +471,7 @@ impl SyncClient for ThinClient {
|
|||||||
) -> TransportResult<Option<transaction::Result<()>>> {
|
) -> TransportResult<Option<transaction::Result<()>>> {
|
||||||
let status = self
|
let status = self
|
||||||
.rpc_client()
|
.rpc_client()
|
||||||
.get_signature_status(&signature.to_string())
|
.get_signature_status(&signature)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
io::Error::new(
|
io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
@ -488,7 +488,7 @@ impl SyncClient for ThinClient {
|
|||||||
) -> TransportResult<Option<transaction::Result<()>>> {
|
) -> TransportResult<Option<transaction::Result<()>>> {
|
||||||
let status = self
|
let status = self
|
||||||
.rpc_client()
|
.rpc_client()
|
||||||
.get_signature_status_with_commitment(&signature.to_string(), commitment_config)
|
.get_signature_status_with_commitment(&signature, commitment_config)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
io::Error::new(
|
io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
|
@ -422,7 +422,7 @@ impl JsonRpcRequestProcessor {
|
|||||||
self.bank(commitment).get_signature_status(&signature)
|
self.bank(commitment).get_signature_status(&signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_signature_statuses(
|
pub fn get_signature_statuses_with_commitment(
|
||||||
&self,
|
&self,
|
||||||
signatures: Vec<Signature>,
|
signatures: Vec<Signature>,
|
||||||
commitment: Option<CommitmentConfig>,
|
commitment: Option<CommitmentConfig>,
|
||||||
@ -493,6 +493,7 @@ impl Metadata for Meta {}
|
|||||||
pub trait RpcSol {
|
pub trait RpcSol {
|
||||||
type Metadata;
|
type Metadata;
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
#[rpc(meta, name = "confirmTransaction")]
|
#[rpc(meta, name = "confirmTransaction")]
|
||||||
fn confirm_transaction(
|
fn confirm_transaction(
|
||||||
&self,
|
&self,
|
||||||
@ -501,6 +502,24 @@ pub trait RpcSol {
|
|||||||
commitment: Option<CommitmentConfig>,
|
commitment: Option<CommitmentConfig>,
|
||||||
) -> RpcResponse<bool>;
|
) -> RpcResponse<bool>;
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
|
#[rpc(meta, name = "getSignatureStatus")]
|
||||||
|
fn get_signature_status(
|
||||||
|
&self,
|
||||||
|
meta: Self::Metadata,
|
||||||
|
signature_str: String,
|
||||||
|
commitment: Option<CommitmentConfig>,
|
||||||
|
) -> Result<Option<transaction::Result<()>>>;
|
||||||
|
|
||||||
|
// DEPRECATED (used by Trust Wallet)
|
||||||
|
#[rpc(meta, name = "getSignatureConfirmation")]
|
||||||
|
fn get_signature_confirmation(
|
||||||
|
&self,
|
||||||
|
meta: Self::Metadata,
|
||||||
|
signature_str: String,
|
||||||
|
commitment: Option<CommitmentConfig>,
|
||||||
|
) -> Result<Option<RpcSignatureConfirmation>>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getAccountInfo")]
|
#[rpc(meta, name = "getAccountInfo")]
|
||||||
fn get_account_info(
|
fn get_account_info(
|
||||||
&self,
|
&self,
|
||||||
@ -588,24 +607,8 @@ pub trait RpcSol {
|
|||||||
#[rpc(meta, name = "getFeeRateGovernor")]
|
#[rpc(meta, name = "getFeeRateGovernor")]
|
||||||
fn get_fee_rate_governor(&self, meta: Self::Metadata) -> RpcResponse<RpcFeeRateGovernor>;
|
fn get_fee_rate_governor(&self, meta: Self::Metadata) -> RpcResponse<RpcFeeRateGovernor>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getSignatureConfirmation")]
|
|
||||||
fn get_signature_confirmation(
|
|
||||||
&self,
|
|
||||||
meta: Self::Metadata,
|
|
||||||
signature_str: String,
|
|
||||||
commitment: Option<CommitmentConfig>,
|
|
||||||
) -> Result<Option<RpcSignatureConfirmation>>;
|
|
||||||
|
|
||||||
#[rpc(meta, name = "getSignatureStatus")]
|
|
||||||
fn get_signature_status(
|
|
||||||
&self,
|
|
||||||
meta: Self::Metadata,
|
|
||||||
signature_str: String,
|
|
||||||
commitment: Option<CommitmentConfig>,
|
|
||||||
) -> Result<Option<transaction::Result<()>>>;
|
|
||||||
|
|
||||||
#[rpc(meta, name = "getSignatureStatuses")]
|
#[rpc(meta, name = "getSignatureStatuses")]
|
||||||
fn get_signature_statuses(
|
fn get_signature_statuses_with_commitment(
|
||||||
&self,
|
&self,
|
||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
signature_strs: Vec<String>,
|
signature_strs: Vec<String>,
|
||||||
@ -967,7 +970,7 @@ impl RpcSol for RpcSolImpl {
|
|||||||
.get_signature_status(signature, commitment))
|
.get_signature_status(signature, commitment))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_signature_statuses(
|
fn get_signature_statuses_with_commitment(
|
||||||
&self,
|
&self,
|
||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
signature_strs: Vec<String>,
|
signature_strs: Vec<String>,
|
||||||
@ -980,7 +983,7 @@ impl RpcSol for RpcSolImpl {
|
|||||||
meta.request_processor
|
meta.request_processor
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get_signature_statuses(signatures, commitment)
|
.get_signature_statuses_with_commitment(signatures, commitment)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64> {
|
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64> {
|
||||||
@ -1073,7 +1076,7 @@ impl RpcSol for RpcSolImpl {
|
|||||||
.request_processor
|
.request_processor
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get_signature_statuses(vec![signature], commitment.clone())?
|
.get_signature_statuses_with_commitment(vec![signature], commitment.clone())?
|
||||||
.value[0]
|
.value[0]
|
||||||
.clone()
|
.clone()
|
||||||
.map(|x| x.status);
|
.map(|x| x.status);
|
||||||
|
@ -58,7 +58,7 @@ fn test_rpc_client() {
|
|||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
while now.elapsed().as_secs() <= 20 {
|
while now.elapsed().as_secs() <= 20 {
|
||||||
let response = client
|
let response = client
|
||||||
.confirm_transaction_with_commitment(signature.as_str(), CommitmentConfig::default())
|
.confirm_transaction_with_commitment(&signature, CommitmentConfig::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if response.value {
|
if response.value {
|
||||||
|
@ -14,7 +14,6 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
|
|||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
* [confirmTransaction](jsonrpc-api.md#confirmtransaction)
|
|
||||||
* [getAccountInfo](jsonrpc-api.md#getaccountinfo)
|
* [getAccountInfo](jsonrpc-api.md#getaccountinfo)
|
||||||
* [getBalance](jsonrpc-api.md#getbalance)
|
* [getBalance](jsonrpc-api.md#getbalance)
|
||||||
* [getBlockCommitment](jsonrpc-api.md#getblockcommitment)
|
* [getBlockCommitment](jsonrpc-api.md#getblockcommitment)
|
||||||
@ -33,7 +32,6 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
|
|||||||
* [getMinimumBalanceForRentExemption](jsonrpc-api.md#getminimumbalanceforrentexemption)
|
* [getMinimumBalanceForRentExemption](jsonrpc-api.md#getminimumbalanceforrentexemption)
|
||||||
* [getProgramAccounts](jsonrpc-api.md#getprogramaccounts)
|
* [getProgramAccounts](jsonrpc-api.md#getprogramaccounts)
|
||||||
* [getRecentBlockhash](jsonrpc-api.md#getrecentblockhash)
|
* [getRecentBlockhash](jsonrpc-api.md#getrecentblockhash)
|
||||||
* [getSignatureStatus](jsonrpc-api.md#getsignaturestatus)
|
|
||||||
* [getSignatureStatuses](jsonrpc-api.md#getsignaturestatuses)
|
* [getSignatureStatuses](jsonrpc-api.md#getsignaturestatuses)
|
||||||
* [getSlot](jsonrpc-api.md#getslot)
|
* [getSlot](jsonrpc-api.md#getslot)
|
||||||
* [getSlotLeader](jsonrpc-api.md#getslotleader)
|
* [getSlotLeader](jsonrpc-api.md#getslotleader)
|
||||||
@ -117,29 +115,6 @@ Many methods that take a commitment parameter return an RpcResponse JSON object
|
|||||||
|
|
||||||
## JSON RPC API Reference
|
## JSON RPC API Reference
|
||||||
|
|
||||||
### confirmTransaction
|
|
||||||
|
|
||||||
Returns a transaction receipt. This method only searches the recent status cache of signatures, which retains all active slots plus `MAX_RECENT_BLOCKHASHES` rooted slots.
|
|
||||||
|
|
||||||
#### Parameters:
|
|
||||||
|
|
||||||
* `<string>` - Signature of Transaction to confirm, as base-58 encoded string
|
|
||||||
* `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
|
||||||
|
|
||||||
#### Results:
|
|
||||||
|
|
||||||
* `RpcResponse<bool>` - RpcResponse JSON object with `value` field set to Transaction status, boolean true if Transaction is confirmed
|
|
||||||
|
|
||||||
#### Example:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
// Request
|
|
||||||
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":{"context":{"slot":1},"value":true},"id":1}
|
|
||||||
```
|
|
||||||
|
|
||||||
### getAccountInfo
|
### getAccountInfo
|
||||||
|
|
||||||
Returns all information associated with the account of provided Pubkey
|
Returns all information associated with the account of provided Pubkey
|
||||||
@ -656,35 +631,9 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
|
|||||||
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"blockhash":"CSymwgTNX1j3E4qhKfJAUE41nBWEwXufoYryPbkde5RR","feeCalculator":{"burnPercent":50,"lamportsPerSignature":5000,"maxLamportsPerSignature":10000,"minLamportsPerSignature":5000,"targetLamportsPerSignature":1000,"targetSignaturesPerSlot":20000}}},"id":1}
|
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"blockhash":"CSymwgTNX1j3E4qhKfJAUE41nBWEwXufoYryPbkde5RR","feeCalculator":{"burnPercent":50,"lamportsPerSignature":5000,"maxLamportsPerSignature":10000,"minLamportsPerSignature":5000,"targetLamportsPerSignature":1000,"targetSignaturesPerSlot":20000}}},"id":1}
|
||||||
```
|
```
|
||||||
|
|
||||||
### getSignatureStatus
|
|
||||||
|
|
||||||
Returns the status of a given signature. This method is similar to [confirmTransaction](jsonrpc-api.md#confirmtransaction) but provides more resolution for error events. This method only searches the recent status cache of signatures, which retains all active slots plus `MAX_RECENT_BLOCKHASHES` rooted slots.
|
|
||||||
|
|
||||||
#### Parameters:
|
|
||||||
|
|
||||||
* `<string>` - Signature of Transaction to confirm, as base-58 encoded string
|
|
||||||
* `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
|
||||||
|
|
||||||
#### Results:
|
|
||||||
|
|
||||||
* `<null>` - Unknown transaction
|
|
||||||
* `<object>` - Transaction status:
|
|
||||||
* `"Ok": <null>` - Transaction was successful
|
|
||||||
* `"Err": <ERR>` - Transaction failed with TransactionError [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
|
|
||||||
|
|
||||||
#### Example:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
// Request
|
|
||||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getSignatureStatus", "params":["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW"]}' http://localhost:8899
|
|
||||||
|
|
||||||
// Result
|
|
||||||
{"jsonrpc":"2.0","result":{"Ok": null},"id":1}
|
|
||||||
```
|
|
||||||
|
|
||||||
### getSignatureStatuses
|
### getSignatureStatuses
|
||||||
|
|
||||||
Returns the statuses of a list of signatures. This method is similar to [confirmTransaction](jsonrpc-api.md#confirmtransaction) but provides more resolution for error events. This method only searches the recent status cache of signatures, which retains all active slots plus `MAX_RECENT_BLOCKHASHES` rooted slots.
|
Returns the statuses of a list of signatures. This method only searches the recent status cache of signatures, which retains statuses for all active slots plus `MAX_RECENT_BLOCKHASHES` rooted slots.
|
||||||
|
|
||||||
#### Parameters:
|
#### Parameters:
|
||||||
|
|
||||||
@ -713,7 +662,7 @@ An array of:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
// Request
|
// Request
|
||||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getSignatureStatus", "params":[["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW", "5j7s6NiJS3JAkvgkoc18WVAsiSaci2pxB2A6ueCJP4tprA2TFg9wSyTLeYouxPBJEMzJinENTkpA52YStRW5Dia7"]]]}' http://localhost:8899
|
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getSignatureStatuses", "params":[["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW", "5j7s6NiJS3JAkvgkoc18WVAsiSaci2pxB2A6ueCJP4tprA2TFg9wSyTLeYouxPBJEMzJinENTkpA52YStRW5Dia7"]]]}' http://localhost:8899
|
||||||
|
|
||||||
// Result
|
// Result
|
||||||
{"jsonrpc":"2.0","result":{"context":{"slot":82},"value":[{"slot": 72, "confirmations": 10, "err": null, "status": {"Ok": null}}, null]},"id":1}
|
{"jsonrpc":"2.0","result":{"context":{"slot":82},"value":[{"slot": 72, "confirmations": 10, "err": null, "status": {"Ok": null}}, null]},"id":1}
|
||||||
|
Reference in New Issue
Block a user