Refactor: pull out fee payer balance check (#25519)
This commit is contained in:
parent
b7149f7f54
commit
7b98ff1929
|
@ -350,51 +350,15 @@ impl Accounts {
|
|||
if payer_index != 0 {
|
||||
warn!("Payer index should be 0! {:?}", tx);
|
||||
}
|
||||
let (ref payer_address, ref mut payer_account) = accounts[payer_index];
|
||||
if payer_account.lamports() == 0 {
|
||||
error_counters.account_not_found += 1;
|
||||
return Err(TransactionError::AccountNotFound);
|
||||
}
|
||||
let min_balance = match get_system_account_kind(payer_account).ok_or_else(|| {
|
||||
error_counters.invalid_account_for_fee += 1;
|
||||
TransactionError::InvalidAccountForFee
|
||||
})? {
|
||||
SystemAccountKind::System => 0,
|
||||
SystemAccountKind::Nonce => {
|
||||
// Should we ever allow a fees charge to zero a nonce account's
|
||||
// balance. The state MUST be set to uninitialized in that case
|
||||
rent_collector.rent.minimum_balance(NonceState::size())
|
||||
}
|
||||
};
|
||||
|
||||
if payer_account.lamports() < fee + min_balance {
|
||||
error_counters.insufficient_funds += 1;
|
||||
return Err(TransactionError::InsufficientFundsForFee);
|
||||
}
|
||||
let payer_pre_rent_state =
|
||||
RentState::from_account(payer_account, &rent_collector.rent);
|
||||
payer_account
|
||||
.checked_sub_lamports(fee)
|
||||
.map_err(|_| TransactionError::InsufficientFundsForFee)?;
|
||||
|
||||
let payer_post_rent_state =
|
||||
RentState::from_account(payer_account, &rent_collector.rent);
|
||||
let rent_state_result = check_rent_state_with_account(
|
||||
&payer_pre_rent_state,
|
||||
&payer_post_rent_state,
|
||||
payer_address,
|
||||
payer_account,
|
||||
feature_set.is_active(&feature_set::do_support_realloc::id()),
|
||||
feature_set
|
||||
.is_active(&feature_set::include_account_index_in_rent_error::ID)
|
||||
.then(|| payer_index),
|
||||
);
|
||||
// Feature gate only wraps the actual error return so that the metrics and debug
|
||||
// logging generated by `check_rent_state_with_account()` can be examined before
|
||||
// feature activation
|
||||
if feature_set.is_active(&feature_set::require_rent_exempt_accounts::id()) {
|
||||
rent_state_result?;
|
||||
}
|
||||
Self::check_fee_payer_balance(
|
||||
&mut accounts,
|
||||
payer_index,
|
||||
error_counters,
|
||||
rent_collector,
|
||||
feature_set,
|
||||
fee,
|
||||
)?;
|
||||
|
||||
let program_indices = message
|
||||
.instructions()
|
||||
|
@ -408,6 +372,7 @@ impl Accounts {
|
|||
)
|
||||
})
|
||||
.collect::<Result<Vec<Vec<usize>>>>()?;
|
||||
|
||||
Ok(LoadedTransaction {
|
||||
accounts,
|
||||
program_indices,
|
||||
|
@ -421,6 +386,60 @@ impl Accounts {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_fee_payer_balance(
|
||||
accounts: &mut [(Pubkey, AccountSharedData)],
|
||||
payer_index: usize,
|
||||
error_counters: &mut TransactionErrorMetrics,
|
||||
rent_collector: &RentCollector,
|
||||
feature_set: &FeatureSet,
|
||||
fee: u64,
|
||||
) -> Result<()> {
|
||||
let (ref payer_address, ref mut payer_account) = accounts[payer_index];
|
||||
if payer_account.lamports() == 0 {
|
||||
error_counters.account_not_found += 1;
|
||||
return Err(TransactionError::AccountNotFound);
|
||||
}
|
||||
let min_balance = match get_system_account_kind(payer_account).ok_or_else(|| {
|
||||
error_counters.invalid_account_for_fee += 1;
|
||||
TransactionError::InvalidAccountForFee
|
||||
})? {
|
||||
SystemAccountKind::System => 0,
|
||||
SystemAccountKind::Nonce => {
|
||||
// Should we ever allow a fees charge to zero a nonce account's
|
||||
// balance. The state MUST be set to uninitialized in that case
|
||||
rent_collector.rent.minimum_balance(NonceState::size())
|
||||
}
|
||||
};
|
||||
|
||||
if payer_account.lamports() < fee + min_balance {
|
||||
error_counters.insufficient_funds += 1;
|
||||
return Err(TransactionError::InsufficientFundsForFee);
|
||||
}
|
||||
let payer_pre_rent_state = RentState::from_account(payer_account, &rent_collector.rent);
|
||||
payer_account
|
||||
.checked_sub_lamports(fee)
|
||||
.map_err(|_| TransactionError::InsufficientFundsForFee)?;
|
||||
|
||||
let payer_post_rent_state = RentState::from_account(payer_account, &rent_collector.rent);
|
||||
let rent_state_result = check_rent_state_with_account(
|
||||
&payer_pre_rent_state,
|
||||
&payer_post_rent_state,
|
||||
payer_address,
|
||||
payer_account,
|
||||
feature_set.is_active(&feature_set::do_support_realloc::id()),
|
||||
feature_set
|
||||
.is_active(&feature_set::include_account_index_in_rent_error::ID)
|
||||
.then(|| payer_index),
|
||||
);
|
||||
// Feature gate only wraps the actual error return so that the metrics and debug
|
||||
// logging generated by `check_rent_state_with_account()` can be examined before
|
||||
// feature activation
|
||||
if feature_set.is_active(&feature_set::require_rent_exempt_accounts::id()) {
|
||||
rent_state_result?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_executable_accounts(
|
||||
&self,
|
||||
ancestors: &Ancestors,
|
||||
|
|
Loading…
Reference in New Issue