Resend transactions a couple times before giving up

This commit is contained in:
Michael Vines 2019-01-15 13:01:55 -08:00
parent 4369c1a113
commit 3f9c2bc33b
2 changed files with 30 additions and 13 deletions

View File

@ -705,8 +705,8 @@ fn send_and_confirm_tx(
tx: &mut Transaction, tx: &mut Transaction,
signer: &Keypair, signer: &Keypair,
) -> Result<String, Box<dyn error::Error>> { ) -> Result<String, Box<dyn error::Error>> {
let mut send_retries = 3; let mut send_retries = 5;
while send_retries > 0 { loop {
let mut status_retries = 4; let mut status_retries = 4;
let signature_str = send_tx(rpc_client, tx)?; let signature_str = send_tx(rpc_client, tx)?;
let status = loop { let status = loop {
@ -720,11 +720,12 @@ fn send_and_confirm_tx(
break status; break status;
} }
if cfg!(not(test)) { if cfg!(not(test)) {
sleep(Duration::from_secs(1)); sleep(Duration::from_millis(500));
} }
}; };
match status { match status {
RpcSignatureStatus::AccountInUse => { RpcSignatureStatus::AccountInUse | RpcSignatureStatus::SignatureNotFound => {
// Fetch a new last_id and re-sign the transaction before sending it again
resign_tx(rpc_client, tx, signer)?; resign_tx(rpc_client, tx, signer)?;
send_retries -= 1; send_retries -= 1;
} }
@ -732,17 +733,16 @@ fn send_and_confirm_tx(
return Ok(signature_str); return Ok(signature_str);
} }
_ => { _ => {
return Err(WalletError::RpcRequestError(format!( send_retries = 0;
"Transaction {:?} failed: {:?}",
signature_str, status
)))?;
} }
} }
if send_retries == 0 {
Err(WalletError::RpcRequestError(format!(
"Transaction {:?} failed: {:?}",
signature_str, status
)))?;
}
} }
Err(WalletError::RpcRequestError(format!(
"AccountInUse after 3 retries: {:?}",
tx.account_keys[0]
)))?
} }
fn resign_tx( fn resign_tx(
@ -750,7 +750,23 @@ fn resign_tx(
tx: &mut Transaction, tx: &mut Transaction,
signer_key: &Keypair, signer_key: &Keypair,
) -> Result<(), Box<dyn error::Error>> { ) -> Result<(), Box<dyn error::Error>> {
let last_id = get_last_id(rpc_client)?; // Fetch a new last_id to prevent the retry from getting rejected as a
// DuplicateSignature
let mut next_last_id_retries = 3;
let last_id = loop {
let next_last_id = get_last_id(rpc_client)?;
if next_last_id != tx.last_id {
break next_last_id;
}
if next_last_id_retries == 0 {
Err(WalletError::RpcRequestError(
"Unable to fetch next last_id".to_string(),
))?;
}
next_last_id_retries -= 1;
sleep(Duration::from_secs(1));
};
tx.sign(&[signer_key], last_id); tx.sign(&[signer_key], last_id);
Ok(()) Ok(())
} }

View File

@ -277,6 +277,7 @@ fn test_wallet_cancel_tx() {
let mut config_witness = WalletConfig::default(); let mut config_witness = WalletConfig::default();
config_witness.network = leader_data.gossip; config_witness.network = leader_data.gossip;
config_witness.drone_port = Some(drone_addr.port()); config_witness.drone_port = Some(drone_addr.port());
config_witness.rpc_port = Some(leader_data.rpc.port());
assert_ne!(config_payer.id.pubkey(), config_witness.id.pubkey()); assert_ne!(config_payer.id.pubkey(), config_witness.id.pubkey());