RpcClient now returns Signatures instead of Strings (#9129)
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(
|
||||||
|
@ -28,7 +28,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},
|
||||||
};
|
};
|
||||||
@ -67,7 +66,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)
|
||||||
@ -75,14 +74,14 @@ 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 = self
|
||||||
.client
|
.client
|
||||||
.send(
|
.send(
|
||||||
&RpcRequest::ConfirmTransaction,
|
&RpcRequest::ConfirmTransaction,
|
||||||
json!([signature, commitment_config]),
|
json!([signature.to_string(), commitment_config]),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.into_with_command("ConfirmTransaction"))?;
|
.map_err(|err| err.into_with_command("ConfirmTransaction"))?;
|
||||||
@ -91,28 +90,32 @@ impl RpcClient {
|
|||||||
.map_err(|err| ClientError::new_with_command(err.into(), "ConfirmTransaction"))
|
.map_err(|err| ClientError::new_with_command(err.into(), "ConfirmTransaction"))
|
||||||
}
|
}
|
||||||
|
|
||||||
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_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(
|
||||||
@ -346,13 +349,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 {
|
||||||
@ -368,7 +371,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)?;
|
||||||
@ -830,10 +833,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 {
|
||||||
@ -971,7 +973,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();
|
||||||
@ -982,23 +984,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)) {
|
||||||
@ -1023,7 +1023,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());
|
||||||
@ -1036,19 +1036,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",
|
||||||
@ -1210,7 +1204,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());
|
||||||
|
|
||||||
@ -1233,18 +1227,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)));
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
Reference in New Issue
Block a user