Check payer balance for program account rent as needed (#12952)

This commit is contained in:
Tyera Eulberg 2020-10-16 12:03:50 -06:00 committed by GitHub
parent 71264bef67
commit b6bfed64cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 13 deletions

View File

@ -54,12 +54,42 @@ pub fn check_account_for_multiple_fees_with_commitment(
fee_calculator: &FeeCalculator, fee_calculator: &FeeCalculator,
messages: &[&Message], messages: &[&Message],
commitment: CommitmentConfig, commitment: CommitmentConfig,
) -> Result<(), CliError> {
check_account_for_spend_multiple_fees_with_commitment(
rpc_client,
account_pubkey,
0,
fee_calculator,
messages,
commitment,
)
}
pub fn check_account_for_spend_multiple_fees_with_commitment(
rpc_client: &RpcClient,
account_pubkey: &Pubkey,
balance: u64,
fee_calculator: &FeeCalculator,
messages: &[&Message],
commitment: CommitmentConfig,
) -> Result<(), CliError> { ) -> Result<(), CliError> {
let fee = calculate_fee(fee_calculator, messages); let fee = calculate_fee(fee_calculator, messages);
if !check_account_for_balance_with_commitment(rpc_client, account_pubkey, fee, commitment) if !check_account_for_balance_with_commitment(
.map_err(Into::<ClientError>::into)? rpc_client,
account_pubkey,
balance + fee,
commitment,
)
.map_err(Into::<ClientError>::into)?
{ {
return Err(CliError::InsufficientFundsForFee(lamports_to_sol(fee))); if balance > 0 {
return Err(CliError::InsufficientFundsForSpendAndFee(
lamports_to_sol(balance),
lamports_to_sol(fee),
));
} else {
return Err(CliError::InsufficientFundsForFee(lamports_to_sol(fee)));
}
} }
Ok(()) Ok(())
} }

View File

@ -1166,11 +1166,12 @@ fn process_deploy(
let signers = [config.signers[0], program_id]; let signers = [config.signers[0], program_id];
// Check program account to see if partial initialization has occurred // Check program account to see if partial initialization has occurred
let initial_instructions = if let Some(account) = rpc_client let (initial_instructions, balance_needed) = if let Some(account) = rpc_client
.get_account_with_commitment(&program_id.pubkey(), config.commitment)? .get_account_with_commitment(&program_id.pubkey(), config.commitment)?
.value .value
{ {
let mut instructions: Vec<Instruction> = vec![]; let mut instructions: Vec<Instruction> = vec![];
let mut balance_needed = 0;
if account.executable { if account.executable {
return Err(CliError::DynamicProgramError( return Err(CliError::DynamicProgramError(
"Program account is already executable".to_string(), "Program account is already executable".to_string(),
@ -1194,21 +1195,26 @@ fn process_deploy(
} }
} }
if account.lamports < minimum_balance { if account.lamports < minimum_balance {
let balance = minimum_balance - account.lamports;
instructions.push(system_instruction::transfer( instructions.push(system_instruction::transfer(
&config.signers[0].pubkey(), &config.signers[0].pubkey(),
&program_id.pubkey(), &program_id.pubkey(),
minimum_balance - account.lamports, balance,
)); ));
balance_needed = balance;
} }
instructions (instructions, balance_needed)
} else { } else {
vec![system_instruction::create_account( (
&config.signers[0].pubkey(), vec![system_instruction::create_account(
&program_id.pubkey(), &config.signers[0].pubkey(),
&program_id.pubkey(),
minimum_balance,
program_data.len() as u64,
&loader_id,
)],
minimum_balance, minimum_balance,
program_data.len() as u64, )
&loader_id,
)]
}; };
let initial_message = if !initial_instructions.is_empty() { let initial_message = if !initial_instructions.is_empty() {
Some(Message::new( Some(Message::new(
@ -1251,9 +1257,10 @@ fn process_deploy(
.get_recent_blockhash_with_commitment(config.commitment)? .get_recent_blockhash_with_commitment(config.commitment)?
.value; .value;
check_account_for_multiple_fees_with_commitment( check_account_for_spend_multiple_fees_with_commitment(
rpc_client, rpc_client,
&config.signers[0].pubkey(), &config.signers[0].pubkey(),
balance_needed,
&fee_calculator, &fee_calculator,
&messages, &messages,
config.commitment, config.commitment,