Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit ea72382

Browse files
sea212kianenigma
andauthored
Emit event when changing total locked value in pallet-balances (#12287)
* Emit Locked/Unlocked events * Implement lock event tests * Adhere to style guide * Use saturating math Co-authored-by: Kian Paimani <[email protected]> * Fix typo * Emit event on change locks and add tests * Adjust event docstring --------- Co-authored-by: Kian Paimani <[email protected]> Co-authored-by: parity-processbot <>
1 parent 5766265 commit ea72382

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

frame/balances/src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,10 @@ pub mod pallet {
330330
Issued { amount: T::Balance },
331331
/// Total issuance was decreased by `amount`, creating a debt to be balanced.
332332
Rescinded { amount: T::Balance },
333+
/// Some balance was locked.
334+
Locked { who: T::AccountId, amount: T::Balance },
335+
/// Some balance was unlocked.
336+
Unlocked { who: T::AccountId, amount: T::Balance },
333337
}
334338

335339
#[pallet::error]
@@ -1016,16 +1020,20 @@ pub mod pallet {
10161020
);
10171021
}
10181022
let freezes = Freezes::<T, I>::get(who);
1023+
let mut prev_frozen = Zero::zero();
1024+
let mut after_frozen = Zero::zero();
10191025
// TODO: Revisit this assumption. We no manipulate consumer/provider refs.
10201026
// No way this can fail since we do not alter the existential balances.
10211027
let res = Self::mutate_account(who, |b| {
1028+
prev_frozen = b.frozen;
10221029
b.frozen = Zero::zero();
10231030
for l in locks.iter() {
10241031
b.frozen = b.frozen.max(l.amount);
10251032
}
10261033
for l in freezes.iter() {
10271034
b.frozen = b.frozen.max(l.amount);
10281035
}
1036+
after_frozen = b.frozen;
10291037
});
10301038
debug_assert!(res.is_ok());
10311039
if let Ok((_, maybe_dust)) = res {
@@ -1053,6 +1061,14 @@ pub mod pallet {
10531061
);
10541062
}
10551063
}
1064+
1065+
if prev_frozen > after_frozen {
1066+
let amount = prev_frozen.saturating_sub(after_frozen);
1067+
Self::deposit_event(Event::Unlocked { who: who.clone(), amount });
1068+
} else if after_frozen > prev_frozen {
1069+
let amount = after_frozen.saturating_sub(prev_frozen);
1070+
Self::deposit_event(Event::Locked { who: who.clone(), amount });
1071+
}
10561072
}
10571073

10581074
/// Update the account entry for `who`, given the locks.

frame/balances/src/tests/currency_tests.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,61 @@ fn emit_events_with_reserve_and_unreserve() {
754754
});
755755
}
756756

757+
#[test]
758+
fn emit_events_with_changing_locks() {
759+
ExtBuilder::default().build_and_execute_with(|| {
760+
let _ = Balances::deposit_creating(&1, 100);
761+
System::reset_events();
762+
763+
// Locks = [] --> [10]
764+
Balances::set_lock(*b"LOCK_000", &1, 10, WithdrawReasons::TRANSFER);
765+
assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Locked { who: 1, amount: 10 })]);
766+
767+
// Locks = [10] --> [15]
768+
Balances::set_lock(*b"LOCK_000", &1, 15, WithdrawReasons::TRANSFER);
769+
assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Locked { who: 1, amount: 5 })]);
770+
771+
// Locks = [15] --> [15, 20]
772+
Balances::set_lock(*b"LOCK_001", &1, 20, WithdrawReasons::TRANSACTION_PAYMENT);
773+
assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Locked { who: 1, amount: 5 })]);
774+
775+
// Locks = [15, 20] --> [17, 20]
776+
Balances::set_lock(*b"LOCK_000", &1, 17, WithdrawReasons::TRANSACTION_PAYMENT);
777+
for event in events() {
778+
match event {
779+
RuntimeEvent::Balances(crate::Event::Locked { .. }) => {
780+
assert!(false, "unexpected lock event")
781+
},
782+
RuntimeEvent::Balances(crate::Event::Unlocked { .. }) => {
783+
assert!(false, "unexpected unlock event")
784+
},
785+
_ => continue,
786+
}
787+
}
788+
789+
// Locks = [17, 20] --> [17, 15]
790+
Balances::set_lock(*b"LOCK_001", &1, 15, WithdrawReasons::TRANSFER);
791+
assert_eq!(
792+
events(),
793+
[RuntimeEvent::Balances(crate::Event::Unlocked { who: 1, amount: 3 })]
794+
);
795+
796+
// Locks = [17, 15] --> [15]
797+
Balances::remove_lock(*b"LOCK_000", &1);
798+
assert_eq!(
799+
events(),
800+
[RuntimeEvent::Balances(crate::Event::Unlocked { who: 1, amount: 2 })]
801+
);
802+
803+
// Locks = [15] --> []
804+
Balances::remove_lock(*b"LOCK_001", &1);
805+
assert_eq!(
806+
events(),
807+
[RuntimeEvent::Balances(crate::Event::Unlocked { who: 1, amount: 15 })]
808+
);
809+
});
810+
}
811+
757812
#[test]
758813
fn emit_events_with_existential_deposit() {
759814
ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| {

0 commit comments

Comments
 (0)