Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions asset-registry/src/mock/para.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ impl orml_tokens::Config for Runtime {
type MaxReserves = ();
type MaxLocks = ConstU32<50>;
type DustRemovalWhitelist = Nothing;
type OnNewTokenAccount = ();
type OnKilledTokenAccount = ();
}

#[derive(scale_info::TypeInfo, Encode, Decode, Clone, Eq, PartialEq, Debug)]
Expand Down
2 changes: 2 additions & 0 deletions currencies/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ impl orml_tokens::Config for Runtime {
type MaxReserves = ConstU32<100_000>;
type ReserveIdentifier = ReserveIdentifier;
type DustRemovalWhitelist = Nothing;
type OnNewTokenAccount = ();
type OnKilledTokenAccount = ();
}

pub const NATIVE_CURRENCY_ID: CurrencyId = 1;
Expand Down
2 changes: 2 additions & 0 deletions payments/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ impl orml_tokens::Config for Test {
type DustRemovalWhitelist = MockDustRemovalWhitelist;
type MaxReserves = ConstU32<2>;
type ReserveIdentifier = ReserveIdentifier;
type OnNewTokenAccount = ();
type OnKilledTokenAccount = ();
}

pub struct MockDisputeResolver;
Expand Down
10 changes: 9 additions & 1 deletion tokens/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ use sp_std::{cmp, convert::Infallible, marker, prelude::*, vec::Vec};
use orml_traits::{
arithmetic::{self, Signed},
currency::TransferAll,
BalanceStatus, GetByKey, LockIdentifier, MultiCurrency, MultiCurrencyExtended, MultiLockableCurrency,
BalanceStatus, GetByKey, Happened, LockIdentifier, MultiCurrency, MultiCurrencyExtended, MultiLockableCurrency,
MultiReservableCurrency, NamedMultiReservableCurrency, OnDust,
};

Expand Down Expand Up @@ -216,6 +216,12 @@ pub mod module {
/// Handler to burn or transfer account's dust
type OnDust: OnDust<Self::AccountId, Self::CurrencyId, Self::Balance>;

/// Handler for when an account was created
type OnNewTokenAccount: Happened<(Self::AccountId, Self::CurrencyId)>;

/// Handler for when an account was created
type OnKilledTokenAccount: Happened<(Self::AccountId, Self::CurrencyId)>;

#[pallet::constant]
type MaxLocks: Get<u32>;

Expand Down Expand Up @@ -747,9 +753,11 @@ impl<T: Config> Pallet<T> {
// Ignore the result, because if it failed then there are remaining consumers,
// and the account storage in frame_system shouldn't be reaped.
let _ = frame_system::Pallet::<T>::dec_providers(who);
T::OnKilledTokenAccount::happened(&(who.clone(), currency_id));
} else if !existed && exists {
// if new, increase account provider
frame_system::Pallet::<T>::inc_providers(who);
T::OnNewTokenAccount::happened(&(who.clone(), currency_id));
}

if let Some(endowed) = maybe_endowed {
Expand Down
50 changes: 50 additions & 0 deletions tokens/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,51 @@ parameter_type_with_key! {
};
}

thread_local! {
pub static CREATED: RefCell<Vec<(AccountId, CurrencyId)>> = RefCell::new(vec![]);
pub static KILLED: RefCell<Vec<(AccountId, CurrencyId)>> = RefCell::new(vec![]);
}

pub struct TrackCreatedAccounts;
impl TrackCreatedAccounts {
pub fn accounts() -> Vec<(AccountId, CurrencyId)> {
CREATED.with(|accounts| accounts.borrow().clone())
}

pub fn reset() {
CREATED.with(|accounts| {
accounts.replace(vec![]);
});
}
}
impl Happened<(AccountId, CurrencyId)> for TrackCreatedAccounts {
fn happened((who, currency): &(AccountId, CurrencyId)) {
CREATED.with(|accounts| {
accounts.borrow_mut().push((who.clone(), *currency));
});
}
}

pub struct TrackKilledAccounts;
impl TrackKilledAccounts {
pub fn accounts() -> Vec<(AccountId, CurrencyId)> {
KILLED.with(|accounts| accounts.borrow().clone())
}

pub fn reset() {
KILLED.with(|accounts| {
accounts.replace(vec![]);
});
}
}
impl Happened<(AccountId, CurrencyId)> for TrackKilledAccounts {
fn happened((who, currency): &(AccountId, CurrencyId)) {
KILLED.with(|accounts| {
accounts.borrow_mut().push((who.clone(), *currency));
});
}
}

parameter_types! {
pub DustReceiver: AccountId = PalletId(*b"orml/dst").into_account();
}
Expand All @@ -232,6 +277,8 @@ impl Config for Runtime {
type WeightInfo = ();
type ExistentialDeposits = ExistentialDeposits;
type OnDust = TransferDust<Runtime, DustReceiver>;
type OnNewTokenAccount = TrackCreatedAccounts;
type OnKilledTokenAccount = TrackKilledAccounts;
type MaxLocks = ConstU32<2>;
type MaxReserves = ConstU32<2>;
type ReserveIdentifier = ReserveIdentifier;
Expand Down Expand Up @@ -296,6 +343,9 @@ impl ExtBuilder {
.unwrap();
}

TrackCreatedAccounts::reset();
TrackKilledAccounts::reset();

let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(1));
ext
Expand Down
22 changes: 22 additions & 0 deletions tokens/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ fn transfer_should_work() {
Error::<Runtime>::ExistentialDeposit,
);
assert_ok!(Tokens::transfer(Some(ALICE).into(), CHARLIE, DOT, 2));
assert_eq!(TrackCreatedAccounts::accounts(), vec![(CHARLIE, DOT)]);

// imply AllowDeath
assert!(Accounts::<Runtime>::contains_key(ALICE, DOT));
Expand Down Expand Up @@ -131,6 +132,7 @@ fn transfer_all_allow_death_should_work() {
assert!(Accounts::<Runtime>::contains_key(ALICE, DOT));
assert_eq!(Tokens::free_balance(DOT, &ALICE), 100);
assert_ok!(Tokens::transfer_all(Some(ALICE).into(), CHARLIE, DOT, false));
assert_eq!(TrackCreatedAccounts::accounts(), vec![(CHARLIE, DOT)]);
System::assert_last_event(Event::Tokens(crate::Event::Transfer {
currency_id: DOT,
from: ALICE,
Expand All @@ -139,6 +141,7 @@ fn transfer_all_allow_death_should_work() {
}));
assert!(!Accounts::<Runtime>::contains_key(ALICE, DOT));
assert_eq!(Tokens::free_balance(DOT, &ALICE), 0);
assert_eq!(TrackKilledAccounts::accounts(), vec![(ALICE, DOT)]);

assert_ok!(Tokens::set_lock(ID_1, DOT, &BOB, 50));
assert_eq!(Tokens::accounts(&BOB, DOT).frozen, 50);
Expand Down Expand Up @@ -176,6 +179,7 @@ fn force_transfer_should_work() {
amount: 100,
}));
assert!(!Accounts::<Runtime>::contains_key(ALICE, DOT));
assert_eq!(TrackKilledAccounts::accounts(), vec![(ALICE, DOT)]);
assert_eq!(Tokens::free_balance(DOT, &ALICE), 0);
assert_eq!(Tokens::free_balance(DOT, &BOB), 200);
});
Expand Down Expand Up @@ -1145,3 +1149,21 @@ fn exceeding_max_reserves_should_fail() {
);
});
}

#[test]
fn lifecycle_callbacks_are_activated() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, 200, 0));
assert_eq!(TrackCreatedAccounts::accounts(), vec![(ALICE, DOT)]);

assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), ALICE, BTC, 200, 0));
assert_eq!(TrackCreatedAccounts::accounts(), vec![(ALICE, DOT), (ALICE, BTC)]);

assert_ok!(Tokens::transfer_all(Some(ALICE).into(), CHARLIE, BTC, false));
assert_eq!(
TrackCreatedAccounts::accounts(),
vec![(ALICE, DOT), (ALICE, BTC), (CHARLIE, BTC)]
);
assert_eq!(TrackKilledAccounts::accounts(), vec![(ALICE, BTC)]);
})
}
2 changes: 2 additions & 0 deletions xtokens/src/mock/para.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ impl orml_tokens::Config for Runtime {
type MaxReserves = ConstU32<50>;
type ReserveIdentifier = [u8; 8];
type DustRemovalWhitelist = Everything;
type OnNewTokenAccount = ();
type OnKilledTokenAccount = ();
}

parameter_types! {
Expand Down
2 changes: 2 additions & 0 deletions xtokens/src/mock/para_relative_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ impl orml_tokens::Config for Runtime {
type MaxReserves = ConstU32<50>;
type ReserveIdentifier = [u8; 8];
type DustRemovalWhitelist = Everything;
type OnNewTokenAccount = ();
type OnKilledTokenAccount = ();
}

parameter_types! {
Expand Down