From eb8648fca8343a1b355660d989f057fbef30003d Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Thu, 26 Jan 2023 15:23:40 +0100 Subject: [PATCH 1/5] Implement lock events in update_locks(...) --- tokens/src/lib.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tokens/src/lib.rs b/tokens/src/lib.rs index 18333052a..319d260af 100644 --- a/tokens/src/lib.rs +++ b/tokens/src/lib.rs @@ -343,6 +343,18 @@ pub mod module { currency_id: T::CurrencyId, who: T::AccountId, }, + /// Some free balance was locked. + Locked { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + /// Some locked balance was freed. + Unlocked { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, } /// The total issuance of a token type. @@ -843,12 +855,18 @@ impl Pallet { who: &T::AccountId, locks: &[BalanceLock], ) -> DispatchResult { + // track lock delta + let mut total_frozen_prev = Zero::zero(); + let mut total_frozen_after = Zero::zero(); + // update account data Self::mutate_account(who, currency_id, |account, _| { + total_frozen_prev = account.frozen; account.frozen = Zero::zero(); for lock in locks.iter() { account.frozen = account.frozen.max(lock.amount); } + total_frozen_after = account.frozen; }); // update locks @@ -877,6 +895,22 @@ impl Pallet { } } + if total_frozen_prev < total_frozen_after { + let amount = total_frozen_after.saturating_sub(total_frozen_prev); + Self::deposit_event(Event::Locked { + currency_id, + who: who.clone(), + amount, + }); + } else if total_frozen_prev > total_frozen_after { + let amount = total_frozen_prev.saturating_sub(total_frozen_after); + Self::deposit_event(Event::Unlocked { + currency_id, + who: who.clone(), + amount, + }); + } + Ok(()) } From 4f08604334c73e82245a4b908f38c75ba93aabb0 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Thu, 26 Jan 2023 15:23:48 +0100 Subject: [PATCH 2/5] Implement lock tests --- tokens/src/tests.rs | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/tokens/src/tests.rs b/tokens/src/tests.rs index e1c51c8a3..c0f3f2fbb 100644 --- a/tokens/src/tests.rs +++ b/tokens/src/tests.rs @@ -8,6 +8,12 @@ use frame_system::RawOrigin; use mock::*; use sp_runtime::{traits::BadOrigin, TokenError}; +fn events() -> Vec { + let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); + System::reset_events(); + evt +} + // ************************************************* // tests for genesis // ************************************************* @@ -990,6 +996,101 @@ fn do_deposit_report_existential_deposit_error() { }); } +#[test] +fn emit_events_when_changing_locks() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Tokens::do_deposit(DOT, &ALICE, 100, false, false)); + assert_ok!(Tokens::do_deposit(BTC, &ALICE, 100, false, false)); + System::reset_events(); + + // Locks: [10/DOT] + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); + assert!(events().contains(&Event::Tokens(crate::Event::Locked { + currency_id: DOT, + who: ALICE, + amount: 10 + }))); + + // Locks: [15/DOT] + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 15)); + assert!(events().contains(&Event::Tokens(crate::Event::Locked { + currency_id: DOT, + who: ALICE, + amount: 5 + }))); + + // Locks: [15/DOT, 20/BTC] + assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 20)); + assert!(events().contains(&Event::Tokens(crate::Event::Locked { + currency_id: BTC, + who: ALICE, + amount: 20 + }))); + + // Locks: [15/DOT, 20/BTC, 10/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); + for event in events() { + match event { + Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + _ => continue, + } + } + + // Locks: [15/DOT, 20/BTC, 12/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 12)); + for event in events() { + match event { + Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + _ => continue, + } + } + + // Locks: [15/DOT, 20/BTC, 10/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); + for event in events() { + match event { + Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + _ => continue, + } + } + + // Locks: [15/DOT, 20/BTC, 20/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 20)); + assert!(events().contains(&Event::Tokens(crate::Event::Locked { + currency_id: DOT, + who: ALICE, + amount: 5 + }))); + + // Locks: [15/DOT, 20/BTC, 16/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 16)); + assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { + currency_id: DOT, + who: ALICE, + amount: 4 + }))); + + // Locks: [15/DOT, 12/BTC, 16/DOT] + assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 12)); + assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { + currency_id: BTC, + who: ALICE, + amount: 8 + }))); + + // Locks: [15/DOT, 12/BTC] + assert_ok!(Tokens::remove_lock(ID_2, DOT, &ALICE)); + assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { + currency_id: DOT, + who: ALICE, + amount: 1 + }))); + }); +} + // ************************************************* // tests for endowed account and remove account // ************************************************* From e0dcbe30da35a54d89496efea2dcc668e4c26c67 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Thu, 26 Jan 2023 15:24:04 +0100 Subject: [PATCH 3/5] Replace depracted clippy rule name --- scripts/run-clippy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run-clippy.sh b/scripts/run-clippy.sh index a172ae411..e11fed87a 100755 --- a/scripts/run-clippy.sh +++ b/scripts/run-clippy.sh @@ -6,7 +6,7 @@ COMMAND=$1 ALLOW_CLIPPY_RULES=( "clippy::identity_op" # this helps the code to be consistant - "clippy::blacklisted-name" # TODO: allow them in test only + "clippy::disallowed_names" # TODO: allow them in test only "clippy::ptr-arg" # TODO: decide if we want to fix those "clippy::match_single_binding" # TODO: fix those ) From 94a59639f1d46dff5cfd97e92d528dbb7044773f Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Thu, 26 Jan 2023 15:54:22 +0100 Subject: [PATCH 4/5] Move tests into correct test file --- tokens/src/tests.rs | 101 ------------------------------------- tokens/src/tests_events.rs | 101 +++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 101 deletions(-) diff --git a/tokens/src/tests.rs b/tokens/src/tests.rs index c0f3f2fbb..e1c51c8a3 100644 --- a/tokens/src/tests.rs +++ b/tokens/src/tests.rs @@ -8,12 +8,6 @@ use frame_system::RawOrigin; use mock::*; use sp_runtime::{traits::BadOrigin, TokenError}; -fn events() -> Vec { - let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); - System::reset_events(); - evt -} - // ************************************************* // tests for genesis // ************************************************* @@ -996,101 +990,6 @@ fn do_deposit_report_existential_deposit_error() { }); } -#[test] -fn emit_events_when_changing_locks() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Tokens::do_deposit(DOT, &ALICE, 100, false, false)); - assert_ok!(Tokens::do_deposit(BTC, &ALICE, 100, false, false)); - System::reset_events(); - - // Locks: [10/DOT] - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); - assert!(events().contains(&Event::Tokens(crate::Event::Locked { - currency_id: DOT, - who: ALICE, - amount: 10 - }))); - - // Locks: [15/DOT] - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 15)); - assert!(events().contains(&Event::Tokens(crate::Event::Locked { - currency_id: DOT, - who: ALICE, - amount: 5 - }))); - - // Locks: [15/DOT, 20/BTC] - assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 20)); - assert!(events().contains(&Event::Tokens(crate::Event::Locked { - currency_id: BTC, - who: ALICE, - amount: 20 - }))); - - // Locks: [15/DOT, 20/BTC, 10/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); - for event in events() { - match event { - Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), - Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), - _ => continue, - } - } - - // Locks: [15/DOT, 20/BTC, 12/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 12)); - for event in events() { - match event { - Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), - Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), - _ => continue, - } - } - - // Locks: [15/DOT, 20/BTC, 10/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); - for event in events() { - match event { - Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), - Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), - _ => continue, - } - } - - // Locks: [15/DOT, 20/BTC, 20/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 20)); - assert!(events().contains(&Event::Tokens(crate::Event::Locked { - currency_id: DOT, - who: ALICE, - amount: 5 - }))); - - // Locks: [15/DOT, 20/BTC, 16/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 16)); - assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { - currency_id: DOT, - who: ALICE, - amount: 4 - }))); - - // Locks: [15/DOT, 12/BTC, 16/DOT] - assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 12)); - assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { - currency_id: BTC, - who: ALICE, - amount: 8 - }))); - - // Locks: [15/DOT, 12/BTC] - assert_ok!(Tokens::remove_lock(ID_2, DOT, &ALICE)); - assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { - currency_id: DOT, - who: ALICE, - amount: 1 - }))); - }); -} - // ************************************************* // tests for endowed account and remove account // ************************************************* diff --git a/tokens/src/tests_events.rs b/tokens/src/tests_events.rs index 07896f866..f7000c849 100644 --- a/tokens/src/tests_events.rs +++ b/tokens/src/tests_events.rs @@ -6,6 +6,12 @@ use super::*; use frame_support::assert_ok; use mock::*; +fn events() -> Vec { + let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); + System::reset_events(); + evt +} + #[test] fn pallet_multicurrency_deposit_events() { ExtBuilder::default() @@ -300,3 +306,98 @@ fn currency_adapter_pallet_currency_deposit_events() { })); }); } + +#[test] +fn pallet_change_locks_events() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Tokens::do_deposit(DOT, &ALICE, 100, false, false)); + assert_ok!(Tokens::do_deposit(BTC, &ALICE, 100, false, false)); + System::reset_events(); + + // Locks: [10/DOT] + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); + assert!(events().contains(&Event::Tokens(crate::Event::Locked { + currency_id: DOT, + who: ALICE, + amount: 10 + }))); + + // Locks: [15/DOT] + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 15)); + assert!(events().contains(&Event::Tokens(crate::Event::Locked { + currency_id: DOT, + who: ALICE, + amount: 5 + }))); + + // Locks: [15/DOT, 20/BTC] + assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 20)); + assert!(events().contains(&Event::Tokens(crate::Event::Locked { + currency_id: BTC, + who: ALICE, + amount: 20 + }))); + + // Locks: [15/DOT, 20/BTC, 10/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); + for event in events() { + match event { + Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + _ => continue, + } + } + + // Locks: [15/DOT, 20/BTC, 12/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 12)); + for event in events() { + match event { + Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + _ => continue, + } + } + + // Locks: [15/DOT, 20/BTC, 10/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); + for event in events() { + match event { + Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + _ => continue, + } + } + + // Locks: [15/DOT, 20/BTC, 20/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 20)); + assert!(events().contains(&Event::Tokens(crate::Event::Locked { + currency_id: DOT, + who: ALICE, + amount: 5 + }))); + + // Locks: [15/DOT, 20/BTC, 16/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 16)); + assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { + currency_id: DOT, + who: ALICE, + amount: 4 + }))); + + // Locks: [15/DOT, 12/BTC, 16/DOT] + assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 12)); + assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { + currency_id: BTC, + who: ALICE, + amount: 8 + }))); + + // Locks: [15/DOT, 12/BTC] + assert_ok!(Tokens::remove_lock(ID_2, DOT, &ALICE)); + assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { + currency_id: DOT, + who: ALICE, + amount: 1 + }))); + }); +} From 26634165c6c20c825e6c2eddafc253ca37afb6c4 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 27 Jan 2023 10:55:09 +0100 Subject: [PATCH 5/5] Use correct Event type --- tokens/src/tests_events.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tokens/src/tests_events.rs b/tokens/src/tests_events.rs index f7000c849..eca7e4c22 100644 --- a/tokens/src/tests_events.rs +++ b/tokens/src/tests_events.rs @@ -6,7 +6,7 @@ use super::*; use frame_support::assert_ok; use mock::*; -fn events() -> Vec { +fn events() -> Vec { let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); System::reset_events(); evt @@ -316,7 +316,7 @@ fn pallet_change_locks_events() { // Locks: [10/DOT] assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); - assert!(events().contains(&Event::Tokens(crate::Event::Locked { + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { currency_id: DOT, who: ALICE, amount: 10 @@ -324,7 +324,7 @@ fn pallet_change_locks_events() { // Locks: [15/DOT] assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 15)); - assert!(events().contains(&Event::Tokens(crate::Event::Locked { + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { currency_id: DOT, who: ALICE, amount: 5 @@ -332,7 +332,7 @@ fn pallet_change_locks_events() { // Locks: [15/DOT, 20/BTC] assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 20)); - assert!(events().contains(&Event::Tokens(crate::Event::Locked { + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { currency_id: BTC, who: ALICE, amount: 20 @@ -342,8 +342,8 @@ fn pallet_change_locks_events() { assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); for event in events() { match event { - Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), - Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + RuntimeEvent::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + RuntimeEvent::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), _ => continue, } } @@ -352,8 +352,8 @@ fn pallet_change_locks_events() { assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 12)); for event in events() { match event { - Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), - Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + RuntimeEvent::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + RuntimeEvent::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), _ => continue, } } @@ -362,15 +362,15 @@ fn pallet_change_locks_events() { assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); for event in events() { match event { - Event::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), - Event::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + RuntimeEvent::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + RuntimeEvent::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), _ => continue, } } // Locks: [15/DOT, 20/BTC, 20/DOT] assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 20)); - assert!(events().contains(&Event::Tokens(crate::Event::Locked { + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { currency_id: DOT, who: ALICE, amount: 5 @@ -378,7 +378,7 @@ fn pallet_change_locks_events() { // Locks: [15/DOT, 20/BTC, 16/DOT] assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 16)); - assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Unlocked { currency_id: DOT, who: ALICE, amount: 4 @@ -386,7 +386,7 @@ fn pallet_change_locks_events() { // Locks: [15/DOT, 12/BTC, 16/DOT] assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 12)); - assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Unlocked { currency_id: BTC, who: ALICE, amount: 8 @@ -394,7 +394,7 @@ fn pallet_change_locks_events() { // Locks: [15/DOT, 12/BTC] assert_ok!(Tokens::remove_lock(ID_2, DOT, &ALICE)); - assert!(events().contains(&Event::Tokens(crate::Event::Unlocked { + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Unlocked { currency_id: DOT, who: ALICE, amount: 1