Wait for at least one confirmation when uploading program data (#9850)

automerge
This commit is contained in:
Jack May
2020-05-02 20:11:50 -07:00
committed by GitHub
parent ffbbdd46e8
commit a8394317c7
2 changed files with 35 additions and 8 deletions

View File

@ -1340,17 +1340,22 @@ fn process_deploy(
trace!("Creating program account"); trace!("Creating program account");
let result = let result =
rpc_client.send_and_confirm_transaction_with_spinner(&mut create_account_tx, &signers); rpc_client.send_and_confirm_transaction_with_spinner(&mut create_account_tx, &signers);
log_instruction_custom_error::<SystemError>(result) log_instruction_custom_error::<SystemError>(result).map_err(|_| {
.map_err(|_| CliError::DynamicProgramError("Program allocate space failed".to_string()))?; CliError::DynamicProgramError("Program account allocation failed".to_string())
})?;
trace!("Writing program data"); trace!("Writing program data");
rpc_client.send_and_confirm_transactions(write_transactions, &signers)?; rpc_client
.send_and_confirm_transactions_with_spinner(write_transactions, &signers)
.map_err(|_| {
CliError::DynamicProgramError("Data writes to program account failed".to_string())
})?;
trace!("Finalizing program account"); trace!("Finalizing program account");
rpc_client rpc_client
.send_and_confirm_transaction_with_spinner(&mut finalize_tx, &signers) .send_and_confirm_transaction_with_spinner(&mut finalize_tx, &signers)
.map_err(|e| { .map_err(|e| {
CliError::DynamicProgramError(format!("Program finalize transaction failed: {}", e)) CliError::DynamicProgramError(format!("Finalizing program account failed: {}", e))
})?; })?;
Ok(json!({ Ok(json!({

View File

@ -498,17 +498,19 @@ impl RpcClient {
} }
} }
pub fn send_and_confirm_transactions<T: Signers>( pub fn send_and_confirm_transactions_with_spinner<T: Signers>(
&self, &self,
mut transactions: Vec<Transaction>, mut transactions: Vec<Transaction>,
signer_keys: &T, signer_keys: &T,
) -> Result<(), Box<dyn error::Error>> { ) -> Result<(), Box<dyn error::Error>> {
let progress_bar = new_spinner_progress_bar();
let mut send_retries = 5; let mut send_retries = 5;
loop { loop {
let mut status_retries = 15; let mut status_retries = 15;
// Send all transactions // Send all transactions
let mut transactions_signatures = vec![]; let mut transactions_signatures = vec![];
let num_transactions = transactions.len();
for transaction in transactions { for transaction in transactions {
if cfg!(not(test)) { if cfg!(not(test)) {
// Delay ~1 tick between write transactions in an attempt to reduce AccountInUse errors // Delay ~1 tick between write transactions in an attempt to reduce AccountInUse errors
@ -518,13 +520,25 @@ impl RpcClient {
} }
let signature = self.send_transaction(&transaction).ok(); let signature = self.send_transaction(&transaction).ok();
transactions_signatures.push((transaction, signature)) transactions_signatures.push((transaction, signature));
progress_bar.set_message(&format!(
"[{}/{}] Transactions sent",
transactions_signatures.len(),
num_transactions
));
} }
// Collect statuses for all the transactions, drop those that are confirmed // Collect statuses for all the transactions, drop those that are confirmed
while status_retries > 0 { while status_retries > 0 {
status_retries -= 1; status_retries -= 1;
progress_bar.set_message(&format!(
"[{}/{}] Transactions confirmed",
num_transactions - transactions_signatures.len(),
num_transactions
));
if cfg!(not(test)) { if cfg!(not(test)) {
// Retry twice a second // Retry twice a second
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
@ -535,10 +549,18 @@ impl RpcClient {
.filter(|(_transaction, signature)| { .filter(|(_transaction, signature)| {
if let Some(signature) = signature { if let Some(signature) = signature {
if let Ok(status) = self.get_signature_status(&signature) { if let Ok(status) = self.get_signature_status(&signature) {
if status.is_none() { if self
.get_num_blocks_since_signature_confirmation(&signature)
.unwrap_or(0)
> 1
{
return false; return false;
} else {
return match status {
None => true,
Some(result) => result.is_err(),
};
} }
return status.unwrap().is_err();
} }
} }
true true