HoldReason: Improve usage (#13869)

* HoldReason: Improve usage

`HoldReason` was switched recently to use the `composite_enum` attribute that will merge the enums
from all pallets in the runtime to `RuntimeHoldReason`. `pallet-nis` was still requiring that the
variant was passed as constant to call `hold`. The proper implementation is to use the `HoldReason`
from inside the pallet directly when calling `hold`. This is done by adding a `RuntimeHoldReason` as
type to the `Config` trait and requiring that `Currency` is using the same reason. Besides that the
pr changes the name `HoldIdentifier` in `pallet_balances::Config` to `RuntimeHoldReason`.

* Update frame/nis/src/lib.rs

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Review comment

* Fixes

---------

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Bastian Köcher
2023-05-24 23:59:34 +02:00
committed by GitHub
parent 5bf4ff56bc
commit 05da6d8e84
60 changed files with 97 additions and 127 deletions
@@ -63,8 +63,8 @@ pub mod pallet {
sp_runtime::traits::{AccountIdConversion, StaticLookup},
traits::{
fungible::{
hold::{Inspect as HoldInspectFungible, Mutate as HoldMutateFungible},
Inspect as InspectFungible, Mutate as MutateFungible,
hold::Mutate as HoldMutateFungible, Inspect as InspectFungible,
Mutate as MutateFungible,
},
fungibles::{
metadata::{MetadataDeposit, Mutate as MutateMetadata},
@@ -96,11 +96,10 @@ pub mod pallet {
/// The currency mechanism, used for paying for deposits.
type Currency: InspectFungible<Self::AccountId>
+ MutateFungible<Self::AccountId>
+ HoldInspectFungible<Self::AccountId>
+ HoldMutateFungible<Self::AccountId>;
+ HoldMutateFungible<Self::AccountId, Reason = Self::RuntimeHoldReason>;
#[pallet::constant]
type HoldReason: Get<<Self::Currency as HoldInspectFungible<Self::AccountId>>::Reason>;
/// Overarching hold reason.
type RuntimeHoldReason: From<HoldReason>;
/// The deposit paid by the user locking an NFT. The deposit is returned to the original NFT
/// owner when the asset is unified and the NFT is unlocked.
@@ -201,6 +200,14 @@ pub mod pallet {
NftNotFractionalized,
}
/// A reason for the pallet placing a hold on funds.
#[pallet::composite_enum]
pub enum HoldReason {
/// Reserved for a fractionalized NFT.
#[codec(index = 0)]
Fractionalized,
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Lock the NFT and mint a new fungible asset.
@@ -239,7 +246,7 @@ pub mod pallet {
let pallet_account = Self::get_pallet_account();
let deposit = T::Deposit::get();
T::Currency::hold(&T::HoldReason::get(), &nft_owner, deposit)?;
T::Currency::hold(&HoldReason::Fractionalized.into(), &nft_owner, deposit)?;
Self::do_lock_nft(nft_collection_id, nft_id)?;
Self::do_create_asset(asset_id.clone(), pallet_account.clone())?;
Self::do_mint_asset(asset_id.clone(), &beneficiary, fractions)?;
@@ -303,7 +310,12 @@ pub mod pallet {
let asset_creator = details.asset_creator;
Self::do_burn_asset(asset_id.clone(), &who, details.fractions)?;
Self::do_unlock_nft(nft_collection_id, nft_id, &beneficiary)?;
T::Currency::release(&T::HoldReason::get(), &asset_creator, deposit, BestEffort)?;
T::Currency::release(
&HoldReason::Fractionalized.into(),
&asset_creator,
deposit,
BestEffort,
)?;
Self::deposit_event(Event::NftUnified {
nft_collection: nft_collection_id,
@@ -20,7 +20,6 @@
use super::*;
use crate as pallet_nft_fractionalization;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
construct_runtime, parameter_types,
traits::{AsEnsureOriginWithArg, ConstU32, ConstU64},
@@ -28,7 +27,6 @@ use frame_support::{
};
use frame_system::EnsureSigned;
use pallet_nfts::PalletFeatures;
use scale_info::TypeInfo;
use sp_core::H256;
use sp_runtime::{
testing::Header,
@@ -83,13 +81,6 @@ impl frame_system::Config for Test {
type MaxConsumers = ConstU32<16>;
}
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, Debug, TypeInfo,
)]
pub enum HoldIdentifier {
NftFractionalization,
}
impl pallet_balances::Config for Test {
type Balance = u64;
type DustRemoval = ();
@@ -100,7 +91,7 @@ impl pallet_balances::Config for Test {
type MaxLocks = ();
type MaxReserves = ConstU32<50>;
type ReserveIdentifier = [u8; 8];
type HoldIdentifier = HoldIdentifier;
type RuntimeHoldReason = RuntimeHoldReason;
type MaxHolds = ConstU32<1>;
type FreezeIdentifier = ();
type MaxFreezes = ();
@@ -169,7 +160,6 @@ parameter_types! {
pub const NftFractionalizationPalletId: PalletId = PalletId(*b"fraction");
pub NewAssetSymbol: BoundedVec<u8, StringLimit> = (*b"FRAC").to_vec().try_into().unwrap();
pub NewAssetName: BoundedVec<u8, StringLimit> = (*b"Frac").to_vec().try_into().unwrap();
pub const HoldReason: HoldIdentifier = HoldIdentifier::NftFractionalization;
}
impl Config for Test {
@@ -189,7 +179,7 @@ impl Config for Test {
type StringLimit = StringLimit;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
type HoldReason = HoldReason;
type RuntimeHoldReason = RuntimeHoldReason;
}
// Build genesis storage according to the mock runtime.