Skip to content

Commit

Permalink
Zero refund check for FungibleAdapter (#6506)
Browse files Browse the repository at this point in the history
`FungibleAdapter` will now check if the _refund amount_ is zero before
calling deposit & emitting an event.

Fixes #6469.

---------

Co-authored-by: GitHub Action <[email protected]>
  • Loading branch information
Dinonard and actions-user authored Nov 26, 2024
1 parent 1c0b610 commit f520adb
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 8 deletions.
10 changes: 10 additions & 0 deletions prdoc/pr_6506.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
title: Zero refund check for FungibleAdapter
doc:
- audience: Runtime User
description: |-
`FungibleAdapter` will now check if the _refund amount_ is zero before calling deposit & emitting an event.

Fixes https://github.com/paritytech/polkadot-sdk/issues/6469.
crates:
- name: pallet-transaction-payment
bump: patch
17 changes: 9 additions & 8 deletions substrate/frame/transaction-payment/src/payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,15 @@ where
if let Some(paid) = already_withdrawn {
// Calculate how much refund we should return
let refund_amount = paid.peek().saturating_sub(corrected_fee);
// refund to the the account that paid the fees if it exists. otherwise, don't refind
// anything.
let refund_imbalance = if F::total_balance(who) > F::Balance::zero() {
F::deposit(who, refund_amount, Precision::BestEffort)
.unwrap_or_else(|_| Debt::<T::AccountId, F>::zero())
} else {
Debt::<T::AccountId, F>::zero()
};
// Refund to the the account that paid the fees if it exists & refund is non-zero.
// Otherwise, don't refund anything.
let refund_imbalance =
if refund_amount > Zero::zero() && F::total_balance(who) > F::Balance::zero() {
F::deposit(who, refund_amount, Precision::BestEffort)
.unwrap_or_else(|_| Debt::<T::AccountId, F>::zero())
} else {
Debt::<T::AccountId, F>::zero()
};
// merge the imbalance caused by paying the fees and refunding parts of it again.
let adjusted_paid: Credit<T::AccountId, F> = paid
.offset(refund_imbalance)
Expand Down
37 changes: 37 additions & 0 deletions substrate/frame/transaction-payment/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -877,3 +877,40 @@ fn no_fee_and_no_weight_for_other_origins() {
assert_eq!(post_info.actual_weight, Some(info.call_weight));
})
}

#[test]
fn fungible_adapter_no_zero_refund_action() {
type FungibleAdapterT = payment::FungibleAdapter<Balances, DealWithFees>;

ExtBuilder::default().balance_factor(10).build().execute_with(|| {
System::set_block_number(10);

let dummy_acc = 1;
let (actual_fee, no_tip) = (10, 0);
let already_paid = <FungibleAdapterT as OnChargeTransaction<Runtime>>::withdraw_fee(
&dummy_acc,
CALL,
&CALL.get_dispatch_info(),
actual_fee,
no_tip,
).expect("Account must have enough funds.");

// Correction action with no expected side effect.
assert!(<FungibleAdapterT as OnChargeTransaction<Runtime>>::correct_and_deposit_fee(
&dummy_acc,
&CALL.get_dispatch_info(),
&default_post_info(),
actual_fee,
no_tip,
already_paid,
).is_ok());

// Ensure no zero amount deposit event is emitted.
let events = System::events();
assert!(!events
.iter()
.any(|record| matches!(record.event, RuntimeEvent::Balances(pallet_balances::Event::Deposit { amount, .. }) if amount.is_zero())),
"No zero amount deposit amount event should be emitted.",
);
});
}

0 comments on commit f520adb

Please sign in to comment.