Fix solana CLI deploy (#11520)

* Refresh blockhash for program writes and finalize transactions

* Refactor to use current api, eliminating an rpc call

* Review comment
This commit is contained in:
Tyera Eulberg
2020-08-11 02:42:29 -06:00
committed by GitHub
parent 15d7619bdc
commit c0d6761f63

View File

@ -23,7 +23,7 @@ use solana_client::{
client_error::{ClientError, ClientErrorKind, Result as ClientResult}, client_error::{ClientError, ClientErrorKind, Result as ClientResult},
rpc_client::RpcClient, rpc_client::RpcClient,
rpc_config::{RpcLargestAccountsFilter, RpcSendTransactionConfig}, rpc_config::{RpcLargestAccountsFilter, RpcSendTransactionConfig},
rpc_response::RpcKeyedAccount, rpc_response::{Response, RpcKeyedAccount},
}; };
#[cfg(not(test))] #[cfg(not(test))]
use solana_faucet::faucet::request_airdrop_transaction; use solana_faucet::faucet::request_airdrop_transaction;
@ -1204,23 +1204,16 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
transactions_signatures = transactions_signatures transactions_signatures = transactions_signatures
.into_iter() .into_iter()
.filter(|(_transaction, signature)| { .filter(|(_transaction, signature)| {
if let Some(signature) = signature { signature
if let Ok(status) = rpc_client.get_signature_status(&signature) { .and_then(|signature| rpc_client.get_signature_statuses(&[signature]).ok())
if rpc_client .map(|Response { context: _, value }| match &value[0] {
.get_num_blocks_since_signature_confirmation(&signature)
.unwrap_or(0)
> 1
{
return false;
} else {
return match status {
None => true, None => true,
Some(result) => result.is_err(), Some(transaction_status) => {
}; !(transaction_status.confirmations.is_none()
|| transaction_status.confirmations.unwrap() > 1)
} }
} })
} .unwrap_or(true)
true
}) })
.collect(); .collect();
@ -1283,7 +1276,7 @@ fn process_deploy(
let signers = [config.signers[0], program_id]; let signers = [config.signers[0], program_id];
create_account_tx.try_sign(&signers, blockhash)?; create_account_tx.try_sign(&signers, blockhash)?;
messages.push(&create_account_tx.message); messages.push(&create_account_tx.message);
let mut write_transactions = vec![]; let mut write_messages = vec![];
for (chunk, i) in program_data.chunks(DATA_CHUNK_SIZE).zip(0..) { for (chunk, i) in program_data.chunks(DATA_CHUNK_SIZE).zip(0..) {
let instruction = loader_instruction::write( let instruction = loader_instruction::write(
&program_id.pubkey(), &program_id.pubkey(),
@ -1292,19 +1285,17 @@ fn process_deploy(
chunk.to_vec(), chunk.to_vec(),
); );
let message = Message::new(&[instruction], Some(&signers[0].pubkey())); let message = Message::new(&[instruction], Some(&signers[0].pubkey()));
let mut tx = Transaction::new_unsigned(message); write_messages.push(message);
tx.try_sign(&signers, blockhash)?;
write_transactions.push(tx);
} }
for transaction in write_transactions.iter() { let mut write_message_refs = vec![];
messages.push(&transaction.message); for message in write_messages.iter() {
write_message_refs.push(message);
} }
messages.append(&mut write_message_refs);
let instruction = loader_instruction::finalize(&program_id.pubkey(), &bpf_loader::id()); let instruction = loader_instruction::finalize(&program_id.pubkey(), &bpf_loader::id());
let message = Message::new(&[instruction], Some(&signers[0].pubkey())); let finalize_message = Message::new(&[instruction], Some(&signers[0].pubkey()));
let mut finalize_tx = Transaction::new_unsigned(message); messages.push(&finalize_message);
finalize_tx.try_sign(&signers, blockhash)?;
messages.push(&finalize_tx.message);
check_account_for_multiple_fees_with_commitment( check_account_for_multiple_fees_with_commitment(
rpc_client, rpc_client,
@ -1324,11 +1315,28 @@ fn process_deploy(
CliError::DynamicProgramError("Program account allocation failed".to_string()) CliError::DynamicProgramError("Program account allocation failed".to_string())
})?; })?;
let (blockhash, _, _) = rpc_client
.get_recent_blockhash_with_commitment(config.commitment)?
.value;
let mut write_transactions = vec![];
for message in write_messages.into_iter() {
let mut tx = Transaction::new_unsigned(message);
tx.try_sign(&signers, blockhash)?;
write_transactions.push(tx);
}
trace!("Writing program data"); trace!("Writing program data");
send_and_confirm_transactions_with_spinner(&rpc_client, write_transactions, &signers).map_err( send_and_confirm_transactions_with_spinner(&rpc_client, write_transactions, &signers).map_err(
|_| CliError::DynamicProgramError("Data writes to program account failed".to_string()), |_| CliError::DynamicProgramError("Data writes to program account failed".to_string()),
)?; )?;
let (blockhash, _, _) = rpc_client
.get_recent_blockhash_with_commitment(config.commitment)?
.value;
let mut finalize_tx = Transaction::new_unsigned(finalize_message);
finalize_tx.try_sign(&signers, blockhash)?;
trace!("Finalizing program account"); trace!("Finalizing program account");
rpc_client rpc_client
.send_and_confirm_transaction_with_spinner_and_config( .send_and_confirm_transaction_with_spinner_and_config(