[FRAME] Short-circuit fungible self transfer (#2118)

Changes:
- Change the fungible(s) logic to treat a self-transfer as No-OP (as
long as all pre-checks pass).

Note that the self-transfer case will not emit an event since no state
was changed.

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Oliver Tale-Yazdi
2023-11-01 22:11:28 +01:00
committed by GitHub
parent 4f05f9a686
commit c66ae375e6
10 changed files with 89 additions and 23 deletions
@@ -18,14 +18,18 @@
//! Tests regarding the functionality of the `Currency` trait set implementations.
use super::*;
use crate::NegativeImbalance;
use frame_support::traits::{
BalanceStatus::{Free, Reserved},
Currency,
ExistenceRequirement::{self, AllowDeath, KeepAlive},
Hooks, LockIdentifier, LockableCurrency, NamedReservableCurrency, ReservableCurrency,
WithdrawReasons,
use crate::{Event, NegativeImbalance};
use frame_support::{
traits::{
BalanceStatus::{Free, Reserved},
Currency,
ExistenceRequirement::{self, AllowDeath, KeepAlive},
Hooks, LockIdentifier, LockableCurrency, NamedReservableCurrency, ReservableCurrency,
WithdrawReasons,
},
StorageNoopGuard,
};
use frame_system::Event as SysEvent;
const ID_1: LockIdentifier = *b"1 ";
const ID_2: LockIdentifier = *b"2 ";
@@ -1363,3 +1367,39 @@ fn freezing_and_locking_should_work() {
assert_eq!(System::consumers(&1), 0);
});
}
#[test]
fn self_transfer_noop() {
ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| {
assert_eq!(Balances::total_issuance(), 0);
let _ = Balances::deposit_creating(&1, 100);
// The account is set up properly:
assert_eq!(
events(),
[
Event::Deposit { who: 1, amount: 100 }.into(),
SysEvent::NewAccount { account: 1 }.into(),
Event::Endowed { account: 1, free_balance: 100 }.into(),
]
);
assert_eq!(Balances::free_balance(1), 100);
assert_eq!(Balances::total_issuance(), 100);
// Transfers to self are No-OPs:
let _g = StorageNoopGuard::new();
for i in 0..200 {
let r = Balances::transfer_allow_death(Some(1).into(), 1, i);
if i <= 100 {
assert_ok!(r);
} else {
assert!(r.is_err());
}
assert!(events().is_empty());
assert_eq!(Balances::free_balance(1), 100, "Balance unchanged by self transfer");
assert_eq!(Balances::total_issuance(), 100, "TI unchanged by self transfers");
}
});
}