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

Commit 125d904

Browse files
committed
Make pallet Assets instantiable
1 parent 3dc169d commit 125d904

File tree

6 files changed

+267
-199
lines changed

6 files changed

+267
-199
lines changed

frame/assets/src/extra_mutator.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,23 @@ use super::*;
2525
/// any uncommitted changes (see `commit` function) will be automatically committed to storage when
2626
/// dropped. Changes, even after committed, may be reverted to their original values with the
2727
/// `revert` function.
28-
pub struct ExtraMutator<T: Config> {
28+
pub struct ExtraMutator<T: Config<I>, I: 'static = ()> {
2929
id: T::AssetId,
3030
who: T::AccountId,
3131
original: T::Extra,
3232
pending: Option<T::Extra>,
3333
}
3434

35-
impl<T: Config> Drop for ExtraMutator<T> {
35+
impl<T: Config<I>, I: 'static> Drop for ExtraMutator<T, I> {
3636
fn drop(&mut self) {
37-
debug_assert!(self.commit().is_ok(), "attempt to write to non-existent asset account");
37+
debug_assert!(
38+
self.commit().is_ok(),
39+
"attempt to write to non-existent asset account"
40+
);
3841
}
3942
}
4043

41-
impl<T: Config> sp_std::ops::Deref for ExtraMutator<T> {
44+
impl<T: Config<I>, I: 'static> sp_std::ops::Deref for ExtraMutator<T, I> {
4245
type Target = T::Extra;
4346
fn deref(&self) -> &T::Extra {
4447
match self.pending {
@@ -48,7 +51,7 @@ impl<T: Config> sp_std::ops::Deref for ExtraMutator<T> {
4851
}
4952
}
5053

51-
impl<T: Config> sp_std::ops::DerefMut for ExtraMutator<T> {
54+
impl<T: Config<I>, I: 'static> sp_std::ops::DerefMut for ExtraMutator<T, I> {
5255
fn deref_mut(&mut self) -> &mut T::Extra {
5356
if self.pending.is_none() {
5457
self.pending = Some(self.original.clone());
@@ -57,34 +60,34 @@ impl<T: Config> sp_std::ops::DerefMut for ExtraMutator<T> {
5760
}
5861
}
5962

60-
impl<T: Config> ExtraMutator<T> {
61-
pub(super) fn maybe_new(id: T::AssetId, who: impl sp_std::borrow::Borrow<T::AccountId>)
62-
-> Option<ExtraMutator<T>>
63-
{
64-
if Account::<T>::contains_key(id, who.borrow()) {
65-
Some(ExtraMutator::<T> {
63+
impl<T: Config<I>, I: 'static> ExtraMutator<T, I> {
64+
pub(super) fn maybe_new(
65+
id: T::AssetId,
66+
who: impl sp_std::borrow::Borrow<T::AccountId>,
67+
) -> Option<ExtraMutator<T, I>> {
68+
if Account::<T, I>::contains_key(id, who.borrow()) {
69+
Some(ExtraMutator::<T, I> {
6670
id,
6771
who: who.borrow().clone(),
68-
original: Account::<T>::get(id, who.borrow()).extra,
72+
original: Account::<T, I>::get(id, who.borrow()).extra,
6973
pending: None,
7074
})
7175
} else {
7276
None
7377
}
7478
}
7579

76-
7780
/// Commit any changes to storage.
7881
pub fn commit(&mut self) -> Result<(), ()> {
7982
if let Some(extra) = self.pending.take() {
80-
Account::<T>::try_mutate_exists(self.id, self.who.borrow(), |maybe_account|
83+
Account::<T, I>::try_mutate_exists(self.id, self.who.borrow(), |maybe_account| {
8184
if let Some(ref mut account) = maybe_account {
8285
account.extra = extra;
8386
Ok(())
8487
} else {
8588
Err(())
8689
}
87-
)
90+
})
8891
} else {
8992
Ok(())
9093
}
@@ -93,13 +96,13 @@ impl<T: Config> ExtraMutator<T> {
9396
/// Revert any changes, even those already committed by `self` and drop self.
9497
pub fn revert(mut self) -> Result<(), ()> {
9598
self.pending = None;
96-
Account::<T>::try_mutate_exists(self.id, self.who.borrow(), |maybe_account|
99+
Account::<T, I>::try_mutate_exists(self.id, self.who.borrow(), |maybe_account| {
97100
if let Some(ref mut account) = maybe_account {
98101
account.extra = self.original.clone();
99102
Ok(())
100103
} else {
101104
Err(())
102105
}
103-
)
106+
})
104107
}
105108
}

frame/assets/src/functions.rs

+55-42
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,40 @@
2020
use super::*;
2121

2222
// The main implementation block for the module.
23-
impl<T: Config> Pallet<T> {
23+
impl<T: Config<I>, I: 'static> Pallet<T, I> {
2424
// Public immutables
2525

2626
/// Return the extra "sid-car" data for `id`/`who`, or `None` if the account doesn't exist.
27-
pub fn adjust_extra(id: T::AssetId, who: impl sp_std::borrow::Borrow<T::AccountId>)
28-
-> Option<ExtraMutator<T>>
29-
{
27+
pub fn adjust_extra(
28+
id: T::AssetId,
29+
who: impl sp_std::borrow::Borrow<T::AccountId>,
30+
) -> Option<ExtraMutator<T, I>> {
3031
ExtraMutator::maybe_new(id, who)
3132
}
3233

3334
/// Get the asset `id` balance of `who`.
3435
pub fn balance(id: T::AssetId, who: impl sp_std::borrow::Borrow<T::AccountId>) -> T::Balance {
35-
Account::<T>::get(id, who.borrow()).balance
36+
Account::<T, I>::get(id, who.borrow()).balance
3637
}
3738

3839
/// Get the total supply of an asset `id`.
3940
pub fn total_supply(id: T::AssetId) -> T::Balance {
40-
Asset::<T>::get(id).map(|x| x.supply).unwrap_or_else(Zero::zero)
41+
Asset::<T, I>::get(id)
42+
.map(|x| x.supply)
43+
.unwrap_or_else(Zero::zero)
4144
}
4245

4346
pub(super) fn new_account(
4447
who: &T::AccountId,
45-
d: &mut AssetDetails<T::Balance, T::AccountId, DepositBalanceOf<T>>,
48+
d: &mut AssetDetails<T::Balance, T::AccountId, DepositBalanceOf<T, I>>,
4649
) -> Result<bool, DispatchError> {
47-
let accounts = d.accounts.checked_add(1).ok_or(Error::<T>::Overflow)?;
50+
let accounts = d.accounts.checked_add(1).ok_or(Error::<T, I>::Overflow)?;
4851
let is_sufficient = if d.is_sufficient {
4952
frame_system::Pallet::<T>::inc_sufficients(who);
5053
d.sufficients += 1;
5154
true
5255
} else {
53-
frame_system::Pallet::<T>::inc_consumers(who).map_err(|_| Error::<T>::NoProvider)?;
56+
frame_system::Pallet::<T>::inc_consumers(who).map_err(|_| Error::<T, I>::NoProvider)?;
5457
false
5558
};
5659
d.accounts = accounts;
@@ -60,7 +63,7 @@ impl<T: Config> Pallet<T> {
6063
pub(super) fn dead_account(
6164
what: T::AssetId,
6265
who: &T::AccountId,
63-
d: &mut AssetDetails<T::Balance, T::AccountId, DepositBalanceOf<T>>,
66+
d: &mut AssetDetails<T::Balance, T::AccountId, DepositBalanceOf<T, I>>,
6467
sufficient: bool,
6568
) {
6669
if sufficient {
@@ -73,15 +76,19 @@ impl<T: Config> Pallet<T> {
7376
T::Freezer::died(what, who)
7477
}
7578

76-
pub(super) fn can_increase(id: T::AssetId, who: &T::AccountId, amount: T::Balance) -> DepositConsequence {
77-
let details = match Asset::<T>::get(id) {
79+
pub(super) fn can_increase(
80+
id: T::AssetId,
81+
who: &T::AccountId,
82+
amount: T::Balance,
83+
) -> DepositConsequence {
84+
let details = match Asset::<T, I>::get(id) {
7885
Some(details) => details,
7986
None => return DepositConsequence::UnknownAsset,
8087
};
8188
if details.supply.checked_add(&amount).is_none() {
8289
return DepositConsequence::Overflow
8390
}
84-
let account = Account::<T>::get(id, who);
91+
let account = Account::<T, I>::get(id, who);
8592
if account.balance.checked_add(&amount).is_none() {
8693
return DepositConsequence::Overflow
8794
}
@@ -108,7 +115,7 @@ impl<T: Config> Pallet<T> {
108115
keep_alive: bool,
109116
) -> WithdrawConsequence<T::Balance> {
110117
use WithdrawConsequence::*;
111-
let details = match Asset::<T>::get(id) {
118+
let details = match Asset::<T, I>::get(id) {
112119
Some(details) => details,
113120
None => return UnknownAsset,
114121
};
@@ -118,7 +125,7 @@ impl<T: Config> Pallet<T> {
118125
if details.is_frozen {
119126
return Frozen
120127
}
121-
let account = Account::<T>::get(id, who);
128+
let account = Account::<T, I>::get(id, who);
122129
if account.is_frozen {
123130
return Frozen
124131
}
@@ -155,19 +162,21 @@ impl<T: Config> Pallet<T> {
155162
id: T::AssetId,
156163
who: &T::AccountId,
157164
keep_alive: bool,
158-
) -> Result<T::Balance, Error<T>> {
159-
let details = match Asset::<T>::get(id) {
165+
) -> Result<T::Balance, Error<T, I>> {
166+
let details = match Asset::<T, I>::get(id) {
160167
Some(details) => details,
161-
None => return Err(Error::<T>::Unknown),
168+
None => return Err(Error::<T, I>::Unknown),
162169
};
163-
ensure!(!details.is_frozen, Error::<T>::Frozen);
170+
ensure!(!details.is_frozen, Error::<T, I>::Frozen);
164171

165-
let account = Account::<T>::get(id, who);
166-
ensure!(!account.is_frozen, Error::<T>::Frozen);
172+
let account = Account::<T, I>::get(id, who);
173+
ensure!(!account.is_frozen, Error::<T, I>::Frozen);
167174

168175
let amount = if let Some(frozen) = T::Freezer::frozen_balance(id, who) {
169176
// Frozen balance: account CANNOT be deleted
170-
let required = frozen.checked_add(&details.min_balance).ok_or(Error::<T>::Overflow)?;
177+
let required = frozen
178+
.checked_add(&details.min_balance)
179+
.ok_or(Error::<T, I>::Overflow)?;
171180
account.balance.saturating_sub(required)
172181
} else {
173182
let is_provider = false;
@@ -204,9 +213,8 @@ impl<T: Config> Pallet<T> {
204213
amount: T::Balance,
205214
f: DebitFlags,
206215
) -> Result<T::Balance, DispatchError> {
207-
let actual = Self::reducible_balance(id, target, f.keep_alive)?
208-
.min(amount);
209-
ensure!(f.best_effort || actual >= amount, Error::<T>::BalanceLow);
216+
let actual = Self::reducible_balance(id, target, f.keep_alive)?.min(amount);
217+
ensure!(f.best_effort || actual >= amount, Error::<T, I>::BalanceLow);
210218

211219
let conseq = Self::can_decrease(id, target, actual, f.keep_alive);
212220
let actual = match conseq.into_result() {
@@ -263,7 +271,10 @@ impl<T: Config> Pallet<T> {
263271
) -> DispatchResult {
264272
Self::increase_balance(id, beneficiary, amount, |details| -> DispatchResult {
265273
if let Some(check_issuer) = maybe_check_issuer {
266-
ensure!(&check_issuer == &details.issuer, Error::<T>::NoPermission);
274+
ensure!(
275+
&check_issuer == &details.issuer,
276+
Error::<T, I>::NoPermission
277+
);
267278
}
268279
debug_assert!(T::Balance::max_value() - details.supply >= amount, "checked in prep; qed");
269280
details.supply = details.supply.saturating_add(amount);
@@ -283,17 +294,19 @@ impl<T: Config> Pallet<T> {
283294
id: T::AssetId,
284295
beneficiary: &T::AccountId,
285296
amount: T::Balance,
286-
check: impl FnOnce(&mut AssetDetails<T::Balance, T::AccountId, DepositBalanceOf<T>>) -> DispatchResult,
297+
check: impl FnOnce(
298+
&mut AssetDetails<T::Balance, T::AccountId, DepositBalanceOf<T, I>>,
299+
) -> DispatchResult,
287300
) -> DispatchResult {
288301
if amount.is_zero() { return Ok(()) }
289302

290303
Self::can_increase(id, beneficiary, amount).into_result()?;
291-
Asset::<T>::try_mutate(id, |maybe_details| -> DispatchResult {
292-
let details = maybe_details.as_mut().ok_or(Error::<T>::Unknown)?;
304+
Asset::<T, I>::try_mutate(id, |maybe_details| -> DispatchResult {
305+
let details = maybe_details.as_mut().ok_or(Error::<T, I>::Unknown)?;
293306

294307
check(details)?;
295308

296-
Account::<T>::try_mutate(id, beneficiary, |t| -> DispatchResult {
309+
Account::<T, I>::try_mutate(id, beneficiary, |t| -> DispatchResult {
297310
let new_balance = t.balance.saturating_add(amount);
298311
ensure!(new_balance >= details.min_balance, TokenError::BelowMinimum);
299312
if t.balance.is_zero() {
@@ -324,7 +337,7 @@ impl<T: Config> Pallet<T> {
324337
let actual = Self::decrease_balance(id, target, amount, f, |actual, details| {
325338
// Check admin rights.
326339
if let Some(check_admin) = maybe_check_admin {
327-
ensure!(&check_admin == &details.admin, Error::<T>::NoPermission);
340+
ensure!(&check_admin == &details.admin, Error::<T, I>::NoPermission);
328341
}
329342

330343
debug_assert!(details.supply >= actual, "checked in prep; qed");
@@ -351,19 +364,19 @@ impl<T: Config> Pallet<T> {
351364
f: DebitFlags,
352365
check: impl FnOnce(
353366
T::Balance,
354-
&mut AssetDetails<T::Balance, T::AccountId, DepositBalanceOf<T>>,
367+
&mut AssetDetails<T::Balance, T::AccountId, DepositBalanceOf<T, I>>,
355368
) -> DispatchResult,
356369
) -> Result<T::Balance, DispatchError> {
357370
if amount.is_zero() { return Ok(amount) }
358371

359372
let actual = Self::prep_debit(id, target, amount, f)?;
360373

361-
Asset::<T>::try_mutate(id, |maybe_details| -> DispatchResult {
362-
let details = maybe_details.as_mut().ok_or(Error::<T>::Unknown)?;
374+
Asset::<T, I>::try_mutate(id, |maybe_details| -> DispatchResult {
375+
let details = maybe_details.as_mut().ok_or(Error::<T, I>::Unknown)?;
363376

364377
check(actual, details)?;
365378

366-
Account::<T>::try_mutate_exists(id, target, |maybe_account| -> DispatchResult {
379+
Account::<T, I>::try_mutate_exists(id, target, |maybe_account| -> DispatchResult {
367380
let mut account = maybe_account.take().unwrap_or_default();
368381
debug_assert!(account.balance >= actual, "checked in prep; qed");
369382

@@ -411,14 +424,14 @@ impl<T: Config> Pallet<T> {
411424
let debit = Self::prep_debit(id, &source, amount, f.into())?;
412425
let (credit, maybe_burn) = Self::prep_credit(id, &dest, amount, debit, f.burn_dust)?;
413426

414-
let mut source_account = Account::<T>::get(id, &source);
427+
let mut source_account = Account::<T, I>::get(id, &source);
415428

416-
Asset::<T>::try_mutate(id, |maybe_details| -> DispatchResult {
417-
let details = maybe_details.as_mut().ok_or(Error::<T>::Unknown)?;
429+
Asset::<T, I>::try_mutate(id, |maybe_details| -> DispatchResult {
430+
let details = maybe_details.as_mut().ok_or(Error::<T, I>::Unknown)?;
418431

419432
// Check admin rights.
420433
if let Some(need_admin) = maybe_need_admin {
421-
ensure!(&need_admin == &details.admin, Error::<T>::NoPermission);
434+
ensure!(&need_admin == &details.admin, Error::<T, I>::NoPermission);
422435
}
423436

424437
// Skip if source == dest
@@ -437,7 +450,7 @@ impl<T: Config> Pallet<T> {
437450
debug_assert!(source_account.balance >= debit, "checked in prep; qed");
438451
source_account.balance = source_account.balance.saturating_sub(debit);
439452

440-
Account::<T>::try_mutate(id, &dest, |a| -> DispatchResult {
453+
Account::<T, I>::try_mutate(id, &dest, |a| -> DispatchResult {
441454
// Calculate new balance; this will not saturate since it's already checked in prep.
442455
debug_assert!(a.balance.checked_add(&credit).is_some(), "checked in prep; qed");
443456
let new_balance = a.balance.saturating_add(credit);
@@ -455,9 +468,9 @@ impl<T: Config> Pallet<T> {
455468
if source_account.balance < details.min_balance {
456469
debug_assert!(source_account.balance.is_zero(), "checked in prep; qed");
457470
Self::dead_account(id, &source, details, source_account.sufficient);
458-
Account::<T>::remove(id, &source);
471+
Account::<T, I>::remove(id, &source);
459472
} else {
460-
Account::<T>::insert(id, &source, &source_account)
473+
Account::<T, I>::insert(id, &source, &source_account)
461474
}
462475

463476
Ok(())

0 commit comments

Comments
 (0)