mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-10 05:17:59 +00:00
Use StorageNMap for Approvals in assets pallet (#8816)
* Use StorageNMap for Approvals in assets pallet * Use EncodeLike on HashKeyPrefix trait bounds * Add comments clarifying AccountId roles * Properly document the keys in the Approvals storage * Fix line width
This commit is contained in:
@@ -237,12 +237,14 @@ pub mod pallet {
|
||||
#[pallet::storage]
|
||||
/// Approved balance transfers. First balance is the amount approved for transfer. Second
|
||||
/// is the amount of `T::Currency` reserved for storing this.
|
||||
pub(super) type Approvals<T: Config<I>, I: 'static = ()> = StorageDoubleMap<
|
||||
/// First key is the asset ID, second key is the owner and third key is the delegate.
|
||||
pub(super) type Approvals<T: Config<I>, I: 'static = ()> = StorageNMap<
|
||||
_,
|
||||
Blake2_128Concat,
|
||||
T::AssetId,
|
||||
Blake2_128Concat,
|
||||
ApprovalKey<T::AccountId>,
|
||||
(
|
||||
NMapKey<Blake2_128Concat, T::AssetId>,
|
||||
NMapKey<Blake2_128Concat, T::AccountId>, // owner
|
||||
NMapKey<Blake2_128Concat, T::AccountId>, // delegate
|
||||
),
|
||||
Approval<T::Balance, DepositBalanceOf<T, I>>,
|
||||
OptionQuery,
|
||||
>;
|
||||
@@ -502,7 +504,7 @@ pub mod pallet {
|
||||
details.deposit.saturating_add(metadata.deposit),
|
||||
);
|
||||
|
||||
Approvals::<T, I>::remove_prefix(&id);
|
||||
Approvals::<T, I>::remove_prefix((&id,));
|
||||
Self::deposit_event(Event::Destroyed(id));
|
||||
|
||||
// NOTE: could use postinfo to reflect the actual number of accounts/sufficient/approvals
|
||||
@@ -1118,19 +1120,18 @@ pub mod pallet {
|
||||
let owner = ensure_signed(origin)?;
|
||||
let delegate = T::Lookup::lookup(delegate)?;
|
||||
|
||||
let key = ApprovalKey { owner, delegate };
|
||||
Approvals::<T, I>::try_mutate(id, &key, |maybe_approved| -> DispatchResult {
|
||||
Approvals::<T, I>::try_mutate((id, &owner, &delegate), |maybe_approved| -> DispatchResult {
|
||||
let mut approved = maybe_approved.take().unwrap_or_default();
|
||||
let deposit_required = T::ApprovalDeposit::get();
|
||||
if approved.deposit < deposit_required {
|
||||
T::Currency::reserve(&key.owner, deposit_required - approved.deposit)?;
|
||||
T::Currency::reserve(&owner, deposit_required - approved.deposit)?;
|
||||
approved.deposit = deposit_required;
|
||||
}
|
||||
approved.amount = approved.amount.saturating_add(amount);
|
||||
*maybe_approved = Some(approved);
|
||||
Ok(())
|
||||
})?;
|
||||
Self::deposit_event(Event::ApprovedTransfer(id, key.owner, key.delegate, amount));
|
||||
Self::deposit_event(Event::ApprovedTransfer(id, owner, delegate, amount));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1156,11 +1157,10 @@ pub mod pallet {
|
||||
) -> DispatchResult {
|
||||
let owner = ensure_signed(origin)?;
|
||||
let delegate = T::Lookup::lookup(delegate)?;
|
||||
let key = ApprovalKey { owner, delegate };
|
||||
let approval = Approvals::<T, I>::take(id, &key).ok_or(Error::<T, I>::Unknown)?;
|
||||
T::Currency::unreserve(&key.owner, approval.deposit);
|
||||
let approval = Approvals::<T, I>::take((id, &owner, &delegate)).ok_or(Error::<T, I>::Unknown)?;
|
||||
T::Currency::unreserve(&owner, approval.deposit);
|
||||
|
||||
Self::deposit_event(Event::ApprovalCancelled(id, key.owner, key.delegate));
|
||||
Self::deposit_event(Event::ApprovalCancelled(id, owner, delegate));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1196,11 +1196,10 @@ pub mod pallet {
|
||||
let owner = T::Lookup::lookup(owner)?;
|
||||
let delegate = T::Lookup::lookup(delegate)?;
|
||||
|
||||
let key = ApprovalKey { owner, delegate };
|
||||
let approval = Approvals::<T, I>::take(id, &key).ok_or(Error::<T, I>::Unknown)?;
|
||||
T::Currency::unreserve(&key.owner, approval.deposit);
|
||||
let approval = Approvals::<T, I>::take((id, &owner, &delegate)).ok_or(Error::<T, I>::Unknown)?;
|
||||
T::Currency::unreserve(&owner, approval.deposit);
|
||||
|
||||
Self::deposit_event(Event::ApprovalCancelled(id, key.owner, key.delegate));
|
||||
Self::deposit_event(Event::ApprovalCancelled(id, owner, delegate));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1234,8 +1233,7 @@ pub mod pallet {
|
||||
let owner = T::Lookup::lookup(owner)?;
|
||||
let destination = T::Lookup::lookup(destination)?;
|
||||
|
||||
let key = ApprovalKey { owner, delegate };
|
||||
Approvals::<T, I>::try_mutate_exists(id, &key, |maybe_approved| -> DispatchResult {
|
||||
Approvals::<T, I>::try_mutate_exists((id, &owner, delegate), |maybe_approved| -> DispatchResult {
|
||||
let mut approved = maybe_approved.take().ok_or(Error::<T, I>::Unapproved)?;
|
||||
let remaining = approved
|
||||
.amount
|
||||
@@ -1247,10 +1245,10 @@ pub mod pallet {
|
||||
best_effort: false,
|
||||
burn_dust: false
|
||||
};
|
||||
Self::do_transfer(id, &key.owner, &destination, amount, None, f)?;
|
||||
Self::do_transfer(id, &owner, &destination, amount, None, f)?;
|
||||
|
||||
if remaining.is_zero() {
|
||||
T::Currency::unreserve(&key.owner, approved.deposit);
|
||||
T::Currency::unreserve(&owner, approved.deposit);
|
||||
} else {
|
||||
approved.amount = remaining;
|
||||
*maybe_approved = Some(approved);
|
||||
|
||||
@@ -65,15 +65,6 @@ impl<Balance, AccountId, DepositBalance> AssetDetails<Balance, AccountId, Deposi
|
||||
}
|
||||
}
|
||||
|
||||
/// A pair to act as a key for the approval storage map.
|
||||
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug)]
|
||||
pub struct ApprovalKey<AccountId> {
|
||||
/// The owner of the funds that are being approved.
|
||||
pub(super) owner: AccountId,
|
||||
/// The party to whom transfer of the funds is being delegated.
|
||||
pub(super) delegate: AccountId,
|
||||
}
|
||||
|
||||
/// Data concerning an approval.
|
||||
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default)]
|
||||
pub struct Approval<Balance, DepositBalance> {
|
||||
|
||||
@@ -248,19 +248,23 @@ pub trait HasReversibleKeyPrefix<P>: ReversibleKeyGenerator + HasKeyPrefix<P> {
|
||||
macro_rules! impl_key_prefix_for {
|
||||
(($($keygen:ident),+), ($($prefix:ident),+), ($($suffix:ident),+)) => {
|
||||
paste! {
|
||||
impl<$($keygen: FullCodec,)+ $( [<$keygen $keygen>]: StorageHasher),+>
|
||||
HasKeyPrefix<($($prefix),+)> for
|
||||
($(Key<[<$keygen $keygen>], $keygen>),+)
|
||||
{
|
||||
impl<
|
||||
$($keygen: FullCodec,)+
|
||||
$( [<$keygen $keygen>]: StorageHasher,)+
|
||||
$( [<KArg $prefix>]: EncodeLike<$prefix> ),+
|
||||
> HasKeyPrefix<($( [<KArg $prefix>] ),+)> for ($(Key<[<$keygen $keygen>], $keygen>),+) {
|
||||
type Suffix = ($($suffix),+);
|
||||
|
||||
fn partial_key(prefix: ($($prefix),+)) -> Vec<u8> {
|
||||
fn partial_key(prefix: ($( [<KArg $prefix>] ),+)) -> Vec<u8> {
|
||||
<($(Key<[<$prefix $prefix>], $prefix>),+)>::final_key(prefix)
|
||||
}
|
||||
}
|
||||
|
||||
impl<$($keygen: FullCodec,)+ $( [<$keygen $keygen>]: ReversibleStorageHasher),+>
|
||||
HasReversibleKeyPrefix<($($prefix),+)> for
|
||||
impl<
|
||||
$($keygen: FullCodec,)+
|
||||
$( [<$keygen $keygen>]: ReversibleStorageHasher,)+
|
||||
$( [<KArg $prefix>]: EncodeLike<$prefix> ),+
|
||||
> HasReversibleKeyPrefix<($( [<KArg $prefix>] ),+)> for
|
||||
($(Key<[<$keygen $keygen>], $keygen>),+)
|
||||
{
|
||||
fn decode_partial_key(key_material: &[u8]) -> Result<Self::Suffix, codec::Error> {
|
||||
@@ -271,19 +275,23 @@ macro_rules! impl_key_prefix_for {
|
||||
};
|
||||
(($($keygen:ident),+), $prefix:ident, ($($suffix:ident),+)) => {
|
||||
paste! {
|
||||
impl<$($keygen: FullCodec,)+ $( [<$keygen $keygen>]: StorageHasher),+>
|
||||
HasKeyPrefix<($prefix,)> for
|
||||
($(Key<[<$keygen $keygen>], $keygen>),+)
|
||||
{
|
||||
impl<
|
||||
$($keygen: FullCodec,)+
|
||||
$( [<$keygen $keygen>]: StorageHasher,)+
|
||||
[<KArg $prefix>]: EncodeLike<$prefix>
|
||||
> HasKeyPrefix<( [<KArg $prefix>] ,)> for ($(Key<[<$keygen $keygen>], $keygen>),+) {
|
||||
type Suffix = ($($suffix),+);
|
||||
|
||||
fn partial_key(prefix: ($prefix,)) -> Vec<u8> {
|
||||
fn partial_key(prefix: ( [<KArg $prefix>] ,)) -> Vec<u8> {
|
||||
<Key<[<$prefix $prefix>], $prefix>>::final_key(prefix)
|
||||
}
|
||||
}
|
||||
|
||||
impl<$($keygen: FullCodec,)+ $( [<$keygen $keygen>]: ReversibleStorageHasher),+>
|
||||
HasReversibleKeyPrefix<($prefix,)> for
|
||||
impl<
|
||||
$($keygen: FullCodec,)+
|
||||
$( [<$keygen $keygen>]: ReversibleStorageHasher,)+
|
||||
[<KArg $prefix>]: EncodeLike<$prefix>
|
||||
> HasReversibleKeyPrefix<( [<KArg $prefix>] ,)> for
|
||||
($(Key<[<$keygen $keygen>], $keygen>),+)
|
||||
{
|
||||
fn decode_partial_key(key_material: &[u8]) -> Result<Self::Suffix, codec::Error> {
|
||||
@@ -294,19 +302,23 @@ macro_rules! impl_key_prefix_for {
|
||||
};
|
||||
(($($keygen:ident),+), ($($prefix:ident),+), $suffix:ident) => {
|
||||
paste! {
|
||||
impl<$($keygen: FullCodec,)+ $( [<$keygen $keygen>]: StorageHasher),+>
|
||||
HasKeyPrefix<($($prefix),+)> for
|
||||
($(Key<[<$keygen $keygen>], $keygen>),+)
|
||||
{
|
||||
impl<
|
||||
$($keygen: FullCodec,)+
|
||||
$( [<$keygen $keygen>]: StorageHasher,)+
|
||||
$( [<KArg $prefix>]: EncodeLike<$prefix>),+
|
||||
> HasKeyPrefix<($( [<KArg $prefix>] ),+)> for ($(Key<[<$keygen $keygen>], $keygen>),+) {
|
||||
type Suffix = $suffix;
|
||||
|
||||
fn partial_key(prefix: ($($prefix),+)) -> Vec<u8> {
|
||||
fn partial_key(prefix: ($( [<KArg $prefix>] ),+)) -> Vec<u8> {
|
||||
<($(Key<[<$prefix $prefix>], $prefix>),+)>::final_key(prefix)
|
||||
}
|
||||
}
|
||||
|
||||
impl<$($keygen: FullCodec,)+ $( [<$keygen $keygen>]: ReversibleStorageHasher),+>
|
||||
HasReversibleKeyPrefix<($($prefix),+)> for
|
||||
impl<
|
||||
$($keygen: FullCodec,)+
|
||||
$( [<$keygen $keygen>]: ReversibleStorageHasher,)+
|
||||
$( [<KArg $prefix>]: EncodeLike<$prefix> ),+
|
||||
> HasReversibleKeyPrefix<($( [<KArg $prefix>] ),+)> for
|
||||
($(Key<[<$keygen $keygen>], $keygen>),+)
|
||||
{
|
||||
fn decode_partial_key(key_material: &[u8]) -> Result<Self::Suffix, codec::Error> {
|
||||
@@ -317,18 +329,28 @@ macro_rules! impl_key_prefix_for {
|
||||
};
|
||||
}
|
||||
|
||||
impl<A: FullCodec, B: FullCodec, X: StorageHasher, Y: StorageHasher> HasKeyPrefix<(A,)>
|
||||
for (Key<X, A>, Key<Y, B>)
|
||||
impl<A, B, X, Y, KArg> HasKeyPrefix<(KArg,)> for (Key<X, A>, Key<Y, B>)
|
||||
where
|
||||
A: FullCodec,
|
||||
B: FullCodec,
|
||||
X: StorageHasher,
|
||||
Y: StorageHasher,
|
||||
KArg: EncodeLike<A>,
|
||||
{
|
||||
type Suffix = B;
|
||||
|
||||
fn partial_key(prefix: (A,)) -> Vec<u8> {
|
||||
fn partial_key(prefix: (KArg,)) -> Vec<u8> {
|
||||
<Key<X, A>>::final_key(prefix)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: FullCodec, B: FullCodec, X: ReversibleStorageHasher, Y: ReversibleStorageHasher>
|
||||
HasReversibleKeyPrefix<(A,)> for (Key<X, A>, Key<Y, B>)
|
||||
impl<A, B, X, Y, KArg> HasReversibleKeyPrefix<(KArg,)> for (Key<X, A>, Key<Y, B>)
|
||||
where
|
||||
A: FullCodec,
|
||||
B: FullCodec,
|
||||
X: ReversibleStorageHasher,
|
||||
Y: ReversibleStorageHasher,
|
||||
KArg: EncodeLike<A>,
|
||||
{
|
||||
fn decode_partial_key(key_material: &[u8]) -> Result<B, codec::Error> {
|
||||
<Key<Y, B>>::decode_final_key(key_material).map(|k| k.0)
|
||||
|
||||
Reference in New Issue
Block a user