Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
9 changes: 4 additions & 5 deletions tokens/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ where
}
}

fn can_deposit(asset: Self::AssetId, who: &AccountId, amount: Self::Balance, mint: bool) -> DepositConsequence {
fn can_deposit(asset: Self::AssetId, who: &AccountId, amount: Self::Balance) -> DepositConsequence {
if TestKey::contains(&asset) {
A::can_deposit(who, amount, mint)
A::can_deposit(who, amount)
} else {
B::can_deposit(asset, who, amount, mint)
B::can_deposit(asset, who, amount)
}
}

Expand Down Expand Up @@ -156,12 +156,11 @@ where
)
}

fn can_deposit(who: &AccountId, amount: Self::Balance, mint: bool) -> DepositConsequence {
fn can_deposit(who: &AccountId, amount: Self::Balance) -> DepositConsequence {
T::can_deposit(
GetCurrencyId::get(),
who,
C::convert_balance_back(amount, GetCurrencyId::get()),
mint,
)
}

Expand Down
15 changes: 11 additions & 4 deletions tokens/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ use orml_traits::{
arithmetic::{self, Signed},
currency::TransferAll,
BalanceStatus, GetByKey, LockIdentifier, MultiCurrency, MultiCurrencyExtended, MultiLockableCurrency,
MultiReservableCurrency, NamedMultiReservableCurrency, OnDust,
MultiReservableCurrency, NamedMultiReservableCurrency, OnDust, OnNewTokenAccount, OnKilledTokenAccount,
};

mod imbalances;
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: OnNewTokenAccount<Self::AccountId, Self::CurrencyId>;

/// Handler for when an account was created
type OnKilledTokenAccount: OnKilledTokenAccount<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::on_killed_account_for(&who, currency_id);
} else if !existed && exists {
// if new, increase account provider
frame_system::Pallet::<T>::inc_providers(who);
T::OnNewTokenAccount::on_new_account_for(&who, currency_id);
}

if let Some(endowed) = maybe_endowed {
Expand Down Expand Up @@ -1669,7 +1677,6 @@ impl<T: Config> fungibles::Inspect<T::AccountId> for Pallet<T> {
asset_id: Self::AssetId,
who: &T::AccountId,
amount: Self::Balance,
_mint: bool,
) -> DepositConsequence {
Self::deposit_consequence(who, asset_id, amount, &Self::accounts(who, asset_id))
}
Expand Down Expand Up @@ -2161,8 +2168,8 @@ where
fn reducible_balance(who: &T::AccountId, keep_alive: bool) -> Self::Balance {
<Pallet<T> as fungibles::Inspect<_>>::reducible_balance(GetCurrencyId::get(), who, keep_alive)
}
fn can_deposit(who: &T::AccountId, amount: Self::Balance, mint: bool) -> DepositConsequence {
<Pallet<T> as fungibles::Inspect<_>>::can_deposit(GetCurrencyId::get(), who, amount, mint)
fn can_deposit(who: &T::AccountId, amount: Self::Balance) -> DepositConsequence {
<Pallet<T> as fungibles::Inspect<_>>::can_deposit(GetCurrencyId::get(), who, amount)
}
fn can_withdraw(who: &T::AccountId, amount: Self::Balance) -> WithdrawConsequence<Self::Balance> {
<Pallet<T> as fungibles::Inspect<_>>::can_withdraw(GetCurrencyId::get(), who, amount)
Expand Down
42 changes: 42 additions & 0 deletions tokens/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,43 @@ 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 OnNewTokenAccount<AccountId, CurrencyId> for TrackCreatedAccounts {
fn on_new_account_for(who: &AccountId, currency: 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 OnKilledTokenAccount<AccountId, CurrencyId> for TrackKilledAccounts {
fn on_killed_account_for(who: &AccountId, currency: 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 +269,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 +335,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
23 changes: 23 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,22 @@ 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: 1 addition & 1 deletion tokens/src/tests_fungibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fn fungibles_inspect_trait_should_work() {
<Tokens as fungibles::Inspect<_>>::reducible_balance(DOT, &ALICE, true),
98
);
assert_ok!(<Tokens as fungibles::Inspect<_>>::can_deposit(DOT, &ALICE, 1, false).into_result());
assert_ok!(<Tokens as fungibles::Inspect<_>>::can_deposit(DOT, &ALICE, 1).into_result());
assert_ok!(<Tokens as fungibles::Inspect<_>>::can_withdraw(DOT, &ALICE, 1).into_result());
});
}
Expand Down
18 changes: 18 additions & 0 deletions traits/src/currency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,24 @@ impl<AccountId, CurrencyId, Balance> OnDust<AccountId, CurrencyId, Balance> for
fn on_dust(_: &AccountId, _: CurrencyId, _: Balance) {}
}

/// Handler for a newly created account
pub trait OnNewTokenAccount<AccountId, CurrencyId> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like the idea of bunch different traits for each individual purposes.

I think we can just reuse Happened<(&AccountId, CurrencyId)> instead.

Otherwise we can have trait OnAccountUpdated { fn updated }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a look. Not sure how I would get around the who.clone() induced by the change to Happened

fn on_new_account_for(who: &AccountId, currency_id: CurrencyId);
}

impl<AccountId, CurrencyId> OnNewTokenAccount<AccountId, CurrencyId> for () {
fn on_new_account_for(_: &AccountId, _: CurrencyId) {}
}

/// Handler for an account that was removed
pub trait OnKilledTokenAccount<AccountId, CurrencyId> {
fn on_killed_account_for(who: &AccountId, currency_id: CurrencyId);
}

impl<AccountId, CurrencyId> OnKilledTokenAccount<AccountId, CurrencyId> for () {
fn on_killed_account_for(_: &AccountId, _: CurrencyId) {}
}

pub trait TransferAll<AccountId> {
fn transfer_all(source: &AccountId, dest: &AccountId) -> DispatchResult;
}
Expand Down
2 changes: 1 addition & 1 deletion traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub use auction::{Auction, AuctionHandler, AuctionInfo, OnNewBidResult};
pub use currency::{
BalanceStatus, BasicCurrency, BasicCurrencyExtended, BasicLockableCurrency, BasicReservableCurrency,
LockIdentifier, MultiCurrency, MultiCurrencyExtended, MultiLockableCurrency, MultiReservableCurrency,
NamedBasicReservableCurrency, NamedMultiReservableCurrency, OnDust,
NamedBasicReservableCurrency, NamedMultiReservableCurrency, OnDust, OnNewTokenAccount, OnKilledTokenAccount,
};
pub use data_provider::{DataFeeder, DataProvider, DataProviderExtended};
pub use get_by_key::GetByKey;
Expand Down