Prevent new RentPaying state created by paying fees (#23358)
* Add failing test * Check fee-payer rent-state change on load * Add more test cases * Review comments
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use {
|
||||
crate::{
|
||||
account_rent_state::{check_rent_state_with_account, RentState},
|
||||
accounts_db::{
|
||||
AccountShrinkThreshold, AccountsAddRootTiming, AccountsDb, AccountsDbConfig,
|
||||
BankHashInfo, ErrorCounters, LoadHint, LoadedAccount, ScanStorageResult,
|
||||
@@ -342,7 +343,7 @@ impl Accounts {
|
||||
if payer_index != 0 {
|
||||
warn!("Payer index should be 0! {:?}", tx);
|
||||
}
|
||||
let payer_account = &mut accounts[payer_index].1;
|
||||
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);
|
||||
@@ -363,10 +364,27 @@ impl Accounts {
|
||||
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 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?;
|
||||
}
|
||||
|
||||
let program_indices = message
|
||||
.instructions()
|
||||
.iter()
|
||||
|
Reference in New Issue
Block a user