Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Token hook refactoring; Posthooks for deposit and transfer #834

Merged
merged 5 commits into from
Nov 10, 2022
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
7 changes: 1 addition & 6 deletions asset-registry/src/mock/para.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,11 @@ impl orml_tokens::Config for Runtime {
type CurrencyId = CurrencyId;
type WeightInfo = ();
type ExistentialDeposits = ExistentialDeposits;
type OnDust = ();
type OnSlash = ();
type OnDeposit = ();
type OnTransfer = ();
type CurrencyHooks = ();
type ReserveIdentifier = [u8; 8];
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
24 changes: 17 additions & 7 deletions currencies/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use frame_support::{
traits::{ConstU32, ConstU64, Everything, Nothing},
PalletId,
};
use orml_traits::parameter_type_with_key;
use orml_traits::{currency::MutationHooks, parameter_type_with_key};
use sp_core::H256;
use sp_runtime::{
testing::Header,
Expand Down Expand Up @@ -73,23 +73,33 @@ parameter_types! {
pub DustAccount: AccountId = PalletId(*b"orml/dst").into_account_truncating();
}

pub struct CurrencyHooks<T>(marker::PhantomData<T>);
impl<T: orml_tokens::Config> MutationHooks<T::AccountId, T::CurrencyId, T::Balance> for CurrencyHooks<T>
where
T::AccountId: From<AccountId32>,
{
type OnDust = orml_tokens::TransferDust<T, DustAccount>;
type OnSlash = ();
type PreDeposit = ();
type PostDeposit = ();
type PreTransfer = ();
type PostTransfer = ();
type OnNewTokenAccount = ();
type OnKilledTokenAccount = ();
}

impl orml_tokens::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = Balance;
type Amount = i64;
type CurrencyId = CurrencyId;
type WeightInfo = ();
type ExistentialDeposits = ExistentialDeposits;
type OnDust = orml_tokens::TransferDust<Runtime, DustAccount>;
type OnSlash = ();
type OnDeposit = ();
type OnTransfer = ();
type CurrencyHooks = CurrencyHooks<Runtime>;
type MaxLocks = ConstU32<100_000>;
type MaxReserves = ConstU32<100_000>;
type ReserveIdentifier = ReserveIdentifier;
type DustRemovalWhitelist = Nothing;
type OnNewTokenAccount = ();
type OnKilledTokenAccount = ();
}

pub const NATIVE_CURRENCY_ID: CurrencyId = 1;
Expand Down
7 changes: 1 addition & 6 deletions payments/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,12 @@ impl orml_tokens::Config for Test {
type CurrencyId = u32;
type RuntimeEvent = RuntimeEvent;
type ExistentialDeposits = ExistentialDeposits;
type OnDust = ();
type OnSlash = ();
type OnDeposit = ();
type OnTransfer = ();
type CurrencyHooks = ();
type WeightInfo = ();
type MaxLocks = MaxLocks;
type DustRemovalWhitelist = MockDustRemovalWhitelist;
type MaxReserves = ConstU32<2>;
type ReserveIdentifier = ReserveIdentifier;
type OnNewTokenAccount = ();
type OnKilledTokenAccount = ();
}

pub struct MockDisputeResolver;
Expand Down
68 changes: 41 additions & 27 deletions tokens/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ use sp_std::{cmp, convert::Infallible, marker, prelude::*, vec::Vec};

use orml_traits::{
arithmetic::{self, Signed},
currency::{OnDeposit, OnSlash, OnTransfer, TransferAll},
currency::{MutationHooks, OnDeposit, OnDust, OnSlash, OnTransfer, TransferAll},
BalanceStatus, GetByKey, Happened, LockIdentifier, MultiCurrency, MultiCurrencyExtended, MultiLockableCurrency,
MultiReservableCurrency, NamedMultiReservableCurrency, OnDust,
MultiReservableCurrency, NamedMultiReservableCurrency,
};

mod imbalances;
Expand Down Expand Up @@ -173,7 +173,7 @@ pub use module::*;

#[frame_support::pallet]
pub mod module {
use orml_traits::currency::{OnDeposit, OnSlash, OnTransfer};
use orml_traits::currency::MutationHooks;

use super::*;

Expand Down Expand Up @@ -216,23 +216,9 @@ pub mod module {
/// System::AccountInfo, zero ED may cause some problems.
type ExistentialDeposits: GetByKey<Self::CurrencyId, Self::Balance>;

/// Handler to burn or transfer account's dust
type OnDust: OnDust<Self::AccountId, Self::CurrencyId, Self::Balance>;

/// Hook to run before slashing an account.
type OnSlash: OnSlash<Self::AccountId, Self::CurrencyId, Self::Balance>;

/// Hook to run before depositing into an account.
type OnDeposit: OnDeposit<Self::AccountId, Self::CurrencyId, Self::Balance>;

/// Hook to run before transferring from an account to another.
type OnTransfer: OnTransfer<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)>;
/// Hooks are actions that are executed on certain events.
/// For example: OnDust, OnNewTokenAccount
type CurrencyHooks: MutationHooks<Self::AccountId, Self::CurrencyId, Self::Balance>;

#[pallet::constant]
type MaxLocks: Get<u32>;
Expand Down Expand Up @@ -765,11 +751,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));
<T::CurrencyHooks as MutationHooks<T::AccountId, T::CurrencyId, T::Balance>>::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));
<T::CurrencyHooks as MutationHooks<T::AccountId, T::CurrencyId, T::Balance>>::OnNewTokenAccount::happened(&(who.clone(), currency_id));
}

if let Some(endowed) = maybe_endowed {
Expand All @@ -783,7 +769,7 @@ impl<T: Config> Pallet<T> {
if let Some(dust_amount) = maybe_dust {
// `OnDust` maybe get/set storage `Accounts` of `who`, trigger handler here
// to avoid some unexpected errors.
T::OnDust::on_dust(who, currency_id, dust_amount);
<T::CurrencyHooks as MutationHooks<T::AccountId, T::CurrencyId, T::Balance>>::OnDust::on_dust(who, currency_id, dust_amount);

Self::deposit_event(Event::DustLost {
currency_id,
Expand Down Expand Up @@ -906,7 +892,12 @@ impl<T: Config> Pallet<T> {
return Ok(());
}

T::OnTransfer::on_transfer(currency_id, from, to, amount)?;
<T::CurrencyHooks as MutationHooks<T::AccountId, T::CurrencyId, T::Balance>>::PreTransfer::on_transfer(
currency_id,
from,
to,
amount,
)?;
Self::try_mutate_account(to, currency_id, |to_account, _existed| -> DispatchResult {
Self::try_mutate_account(from, currency_id, |from_account, _existed| -> DispatchResult {
from_account.free = from_account
Expand Down Expand Up @@ -946,6 +937,12 @@ impl<T: Config> Pallet<T> {
Ok(())
})?;

<T::CurrencyHooks as MutationHooks<T::AccountId, T::CurrencyId, T::Balance>>::PostTransfer::on_transfer(
currency_id,
from,
to,
amount,
)?;
Self::deposit_event(Event::Transfer {
currency_id,
from: from.clone(),
Expand Down Expand Up @@ -1032,7 +1029,11 @@ impl<T: Config> Pallet<T> {
return Ok(());
}

T::OnDeposit::on_deposit(currency_id, who, amount)?;
<T::CurrencyHooks as MutationHooks<T::AccountId, T::CurrencyId, T::Balance>>::PreDeposit::on_deposit(
currency_id,
who,
amount,
)?;
Self::try_mutate_account(who, currency_id, |account, existed| -> DispatchResult {
if require_existed {
ensure!(existed, Error::<T>::DeadAccount);
Expand All @@ -1054,6 +1055,11 @@ impl<T: Config> Pallet<T> {
}
account.free = account.free.defensive_saturating_add(amount);

<T::CurrencyHooks as MutationHooks<T::AccountId, T::CurrencyId, T::Balance>>::PostDeposit::on_deposit(
currency_id,
who,
amount,
)?;
Self::deposit_event(Event::Deposited {
currency_id,
who: who.clone(),
Expand Down Expand Up @@ -1128,7 +1134,11 @@ impl<T: Config> MultiCurrency<T::AccountId> for Pallet<T> {
return amount;
}

T::OnSlash::on_slash(currency_id, who, amount);
<T::CurrencyHooks as MutationHooks<T::AccountId, T::CurrencyId, T::Balance>>::OnSlash::on_slash(
currency_id,
who,
amount,
);
let account = Self::accounts(who, currency_id);
let free_slashed_amount = account.free.min(amount);
// Cannot underflow because free_slashed_amount can never be greater than amount
Expand Down Expand Up @@ -1306,7 +1316,11 @@ impl<T: Config> MultiReservableCurrency<T::AccountId> for Pallet<T> {
return value;
}

T::OnSlash::on_slash(currency_id, who, value);
<T::CurrencyHooks as MutationHooks<T::AccountId, T::CurrencyId, T::Balance>>::OnSlash::on_slash(
currency_id,
who,
value,
);
let reserved_balance = Self::reserved_balance(currency_id, who);
let actual = reserved_balance.min(value);
Self::mutate_account(who, currency_id, |account, _| {
Expand Down
Loading