Remove Default, HasCompact, and TypeInfo trait bounds on AssetId (#12740)

* Remove Default, HasCompact, and TypeInfo trait bounds on AssetId

* don't use default in benchmarking

* add helper trait

* add helper to assets tx payment test

* docs fixes

* i'm confused

* aha, cargo

* move affected dispatchable calls into new indices

* Helper -> BenchmarkHelper

* benchmark use of helper

* actually, don't break every call interface

* use into on AssetIdParameter

* Remove From from AssetIdParameter and use it in BenchmarkHelper

* include from

Co-authored-by: parity-processbot <>
This commit is contained in:
joe petrowski
2022-11-28 19:51:59 +01:00
committed by GitHub
parent 2d4126d239
commit d56214c21f
7 changed files with 256 additions and 202 deletions
+1
View File
@@ -5007,6 +5007,7 @@ dependencies = [
name = "pallet-asset-tx-payment"
version = "4.0.0-dev"
dependencies = [
"frame-benchmarking",
"frame-support",
"frame-system",
"pallet-assets",
+3
View File
@@ -1440,6 +1440,7 @@ impl pallet_assets::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = u128;
type AssetId = u32;
type AssetIdParameter = codec::Compact<u32>;
type Currency = Balances;
type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
type ForceOrigin = EnsureRoot<AccountId>;
@@ -1453,6 +1454,8 @@ impl pallet_assets::Config for Runtime {
type Extra = ();
type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
type RemoveItemsLimit = ConstU32<1000>;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}
parameter_types! {
+113 -115
View File
@@ -35,43 +35,49 @@ use crate::Pallet as Assets;
const SEED: u32 = 0;
fn default_asset_id<T: Config<I>, I: 'static>() -> T::AssetIdParameter {
T::BenchmarkHelper::create_asset_id_parameter(0)
}
fn create_default_asset<T: Config<I>, I: 'static>(
is_sufficient: bool,
) -> (T::AccountId, AccountIdLookupOf<T>) {
) -> (T::AssetIdParameter, T::AccountId, AccountIdLookupOf<T>) {
let asset_id = default_asset_id::<T, I>();
let caller: T::AccountId = whitelisted_caller();
let caller_lookup = T::Lookup::unlookup(caller.clone());
let root = SystemOrigin::Root.into();
assert!(Assets::<T, I>::force_create(
root,
Default::default(),
asset_id,
caller_lookup.clone(),
is_sufficient,
1u32.into(),
)
.is_ok());
(caller, caller_lookup)
(asset_id, caller, caller_lookup)
}
fn create_default_minted_asset<T: Config<I>, I: 'static>(
is_sufficient: bool,
amount: T::Balance,
) -> (T::AccountId, AccountIdLookupOf<T>) {
let (caller, caller_lookup) = create_default_asset::<T, I>(is_sufficient);
) -> (T::AssetIdParameter, T::AccountId, AccountIdLookupOf<T>) {
let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(is_sufficient);
if !is_sufficient {
T::Currency::make_free_balance_be(&caller, T::Currency::minimum_balance());
}
assert!(Assets::<T, I>::mint(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
asset_id,
caller_lookup.clone(),
amount,
)
.is_ok());
(caller, caller_lookup)
(asset_id, caller, caller_lookup)
}
fn swap_is_sufficient<T: Config<I>, I: 'static>(s: &mut bool) {
Asset::<T, I>::mutate(&T::AssetId::default(), |maybe_a| {
let asset_id = default_asset_id::<T, I>();
Asset::<T, I>::mutate(&asset_id.into(), |maybe_a| {
if let Some(ref mut a) = maybe_a {
sp_std::mem::swap(s, &mut a.is_sufficient)
}
@@ -79,6 +85,7 @@ fn swap_is_sufficient<T: Config<I>, I: 'static>(s: &mut bool) {
}
fn add_sufficients<T: Config<I>, I: 'static>(minter: T::AccountId, n: u32) {
let asset_id = default_asset_id::<T, I>();
let origin = SystemOrigin::Signed(minter);
let mut s = true;
swap_is_sufficient::<T, I>(&mut s);
@@ -87,7 +94,7 @@ fn add_sufficients<T: Config<I>, I: 'static>(minter: T::AccountId, n: u32) {
let target_lookup = T::Lookup::unlookup(target);
assert!(Assets::<T, I>::mint(
origin.clone().into(),
Default::default(),
asset_id,
target_lookup,
100u32.into()
)
@@ -97,23 +104,19 @@ fn add_sufficients<T: Config<I>, I: 'static>(minter: T::AccountId, n: u32) {
}
fn add_approvals<T: Config<I>, I: 'static>(minter: T::AccountId, n: u32) {
let asset_id = default_asset_id::<T, I>();
T::Currency::deposit_creating(&minter, T::ApprovalDeposit::get() * n.into());
let minter_lookup = T::Lookup::unlookup(minter.clone());
let origin = SystemOrigin::Signed(minter);
Assets::<T, I>::mint(
origin.clone().into(),
Default::default(),
minter_lookup,
(100 * (n + 1)).into(),
)
.unwrap();
Assets::<T, I>::mint(origin.clone().into(), asset_id, minter_lookup, (100 * (n + 1)).into())
.unwrap();
for i in 0..n {
let target = account("approval", i, SEED);
T::Currency::make_free_balance_be(&target, T::Currency::minimum_balance());
let target_lookup = T::Lookup::unlookup(target);
Assets::<T, I>::approve_transfer(
origin.clone().into(),
Default::default(),
asset_id,
target_lookup,
100u32.into(),
)
@@ -131,48 +134,49 @@ fn assert_event<T: Config<I>, I: 'static>(generic_event: <T as Config<I>>::Runti
benchmarks_instance_pallet! {
create {
let asset_id = Default::default();
let origin = T::CreateOrigin::successful_origin(&asset_id);
let caller = T::CreateOrigin::ensure_origin(origin, &asset_id).unwrap();
let asset_id = default_asset_id::<T, I>();
let origin = T::CreateOrigin::successful_origin(&asset_id.into());
let caller = T::CreateOrigin::ensure_origin(origin, &asset_id.into()).unwrap();
let caller_lookup = T::Lookup::unlookup(caller.clone());
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
}: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, 1u32.into())
verify {
assert_last_event::<T, I>(Event::Created { asset_id, creator: caller.clone(), owner: caller }.into());
assert_last_event::<T, I>(Event::Created { asset_id: asset_id.into(), creator: caller.clone(), owner: caller }.into());
}
force_create {
let asset_id = default_asset_id::<T, I>();
let caller: T::AccountId = whitelisted_caller();
let caller_lookup = T::Lookup::unlookup(caller.clone());
}: _(SystemOrigin::Root, Default::default(), caller_lookup, true, 1u32.into())
}: _(SystemOrigin::Root, asset_id, caller_lookup, true, 1u32.into())
verify {
assert_last_event::<T, I>(Event::ForceCreated { asset_id: Default::default(), owner: caller }.into());
assert_last_event::<T, I>(Event::ForceCreated { asset_id: asset_id.into(), owner: caller }.into());
}
start_destroy {
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
Assets::<T, I>::freeze_asset(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
asset_id,
)?;
}:_(SystemOrigin::Signed(caller), Default::default())
}:_(SystemOrigin::Signed(caller), asset_id)
verify {
assert_last_event::<T, I>(Event::DestructionStarted { asset_id: Default::default() }.into());
assert_last_event::<T, I>(Event::DestructionStarted { asset_id: asset_id.into() }.into());
}
destroy_accounts {
let c in 0 .. T::RemoveItemsLimit::get();
let (caller, _) = create_default_asset::<T, I>(true);
let (asset_id, caller, _) = create_default_asset::<T, I>(true);
add_sufficients::<T, I>(caller.clone(), c);
Assets::<T, I>::freeze_asset(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
asset_id,
)?;
Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), Default::default())?;
}:_(SystemOrigin::Signed(caller), Default::default())
Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?;
}:_(SystemOrigin::Signed(caller), asset_id)
verify {
assert_last_event::<T, I>(Event::AccountsDestroyed {
asset_id: Default::default() ,
asset_id: asset_id.into(),
accounts_destroyed: c,
accounts_remaining: 0,
}.into());
@@ -180,142 +184,142 @@ benchmarks_instance_pallet! {
destroy_approvals {
let a in 0 .. T::RemoveItemsLimit::get();
let (caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
add_approvals::<T, I>(caller.clone(), a);
Assets::<T, I>::freeze_asset(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
asset_id,
)?;
Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), Default::default())?;
}:_(SystemOrigin::Signed(caller), Default::default())
Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?;
}:_(SystemOrigin::Signed(caller), asset_id)
verify {
assert_last_event::<T, I>(Event::ApprovalsDestroyed {
asset_id: Default::default() ,
asset_id: asset_id.into(),
approvals_destroyed: a,
approvals_remaining: 0,
}.into());
}
finish_destroy {
let (caller, caller_lookup) = create_default_asset::<T, I>(true);
let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
Assets::<T, I>::freeze_asset(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
asset_id,
)?;
Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), Default::default())?;
}:_(SystemOrigin::Signed(caller), Default::default())
Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?;
}:_(SystemOrigin::Signed(caller), asset_id)
verify {
assert_last_event::<T, I>(Event::Destroyed {
asset_id: Default::default() ,
asset_id: asset_id.into(),
}.into()
);
}
mint {
let (caller, caller_lookup) = create_default_asset::<T, I>(true);
let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
let amount = T::Balance::from(100u32);
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup, amount)
}: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, amount)
verify {
assert_last_event::<T, I>(Event::Issued { asset_id: Default::default(), owner: caller, total_supply: amount }.into());
assert_last_event::<T, I>(Event::Issued { asset_id: asset_id.into(), owner: caller, total_supply: amount }.into());
}
burn {
let amount = T::Balance::from(100u32);
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup, amount)
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
}: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, amount)
verify {
assert_last_event::<T, I>(Event::Burned { asset_id: Default::default(), owner: caller, balance: amount }.into());
assert_last_event::<T, I>(Event::Burned { asset_id: asset_id.into(), owner: caller, balance: amount }.into());
}
transfer {
let amount = T::Balance::from(100u32);
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
let target: T::AccountId = account("target", 0, SEED);
let target_lookup = T::Lookup::unlookup(target.clone());
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), target_lookup, amount)
}: _(SystemOrigin::Signed(caller.clone()), asset_id, target_lookup, amount)
verify {
assert_last_event::<T, I>(Event::Transferred { asset_id: Default::default(), from: caller, to: target, amount }.into());
assert_last_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into());
}
transfer_keep_alive {
let mint_amount = T::Balance::from(200u32);
let amount = T::Balance::from(100u32);
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, mint_amount);
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, mint_amount);
let target: T::AccountId = account("target", 0, SEED);
let target_lookup = T::Lookup::unlookup(target.clone());
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), target_lookup, amount)
}: _(SystemOrigin::Signed(caller.clone()), asset_id, target_lookup, amount)
verify {
assert!(frame_system::Pallet::<T>::account_exists(&caller));
assert_last_event::<T, I>(Event::Transferred { asset_id: Default::default(), from: caller, to: target, amount }.into());
assert_last_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into());
}
force_transfer {
let amount = T::Balance::from(100u32);
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
let target: T::AccountId = account("target", 0, SEED);
let target_lookup = T::Lookup::unlookup(target.clone());
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup, target_lookup, amount)
}: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, target_lookup, amount)
verify {
assert_last_event::<T, I>(
Event::Transferred { asset_id: Default::default(), from: caller, to: target, amount }.into()
Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into()
);
}
freeze {
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup)
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
}: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup)
verify {
assert_last_event::<T, I>(Event::Frozen { asset_id: Default::default(), who: caller }.into());
assert_last_event::<T, I>(Event::Frozen { asset_id: asset_id.into(), who: caller }.into());
}
thaw {
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
Assets::<T, I>::freeze(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
asset_id,
caller_lookup.clone(),
)?;
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup)
}: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup)
verify {
assert_last_event::<T, I>(Event::Thawed { asset_id: Default::default(), who: caller }.into());
assert_last_event::<T, I>(Event::Thawed { asset_id: asset_id.into(), who: caller }.into());
}
freeze_asset {
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
}: _(SystemOrigin::Signed(caller.clone()), Default::default())
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
}: _(SystemOrigin::Signed(caller.clone()), asset_id)
verify {
assert_last_event::<T, I>(Event::AssetFrozen { asset_id: Default::default() }.into());
assert_last_event::<T, I>(Event::AssetFrozen { asset_id: asset_id.into() }.into());
}
thaw_asset {
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
Assets::<T, I>::freeze_asset(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
asset_id,
)?;
}: _(SystemOrigin::Signed(caller.clone()), Default::default())
}: _(SystemOrigin::Signed(caller.clone()), asset_id)
verify {
assert_last_event::<T, I>(Event::AssetThawed { asset_id: Default::default() }.into());
assert_last_event::<T, I>(Event::AssetThawed { asset_id: asset_id.into() }.into());
}
transfer_ownership {
let (caller, _) = create_default_asset::<T, I>(true);
let (asset_id, caller, _) = create_default_asset::<T, I>(true);
let target: T::AccountId = account("target", 0, SEED);
let target_lookup = T::Lookup::unlookup(target.clone());
}: _(SystemOrigin::Signed(caller), Default::default(), target_lookup)
}: _(SystemOrigin::Signed(caller), asset_id, target_lookup)
verify {
assert_last_event::<T, I>(Event::OwnerChanged { asset_id: Default::default(), owner: target }.into());
assert_last_event::<T, I>(Event::OwnerChanged { asset_id: asset_id.into(), owner: target }.into());
}
set_team {
let (caller, _) = create_default_asset::<T, I>(true);
let (asset_id, caller, _) = create_default_asset::<T, I>(true);
let target0 = T::Lookup::unlookup(account("target", 0, SEED));
let target1 = T::Lookup::unlookup(account("target", 1, SEED));
let target2 = T::Lookup::unlookup(account("target", 2, SEED));
}: _(SystemOrigin::Signed(caller), Default::default(), target0, target1, target2)
}: _(SystemOrigin::Signed(caller), asset_id, target0, target1, target2)
verify {
assert_last_event::<T, I>(Event::TeamChanged {
asset_id: Default::default(),
asset_id: asset_id.into(),
issuer: account("target", 0, SEED),
admin: account("target", 1, SEED),
freezer: account("target", 2, SEED),
@@ -330,23 +334,22 @@ benchmarks_instance_pallet! {
let symbol = vec![0u8; s as usize];
let decimals = 12;
let (caller, _) = create_default_asset::<T, I>(true);
let (asset_id, caller, _) = create_default_asset::<T, I>(true);
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
}: _(SystemOrigin::Signed(caller), Default::default(), name.clone(), symbol.clone(), decimals)
}: _(SystemOrigin::Signed(caller), asset_id, name.clone(), symbol.clone(), decimals)
verify {
let id = Default::default();
assert_last_event::<T, I>(Event::MetadataSet { asset_id: id, name, symbol, decimals, is_frozen: false }.into());
assert_last_event::<T, I>(Event::MetadataSet { asset_id: asset_id.into(), name, symbol, decimals, is_frozen: false }.into());
}
clear_metadata {
let (caller, _) = create_default_asset::<T, I>(true);
let (asset_id, caller, _) = create_default_asset::<T, I>(true);
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
let dummy = vec![0u8; T::StringLimit::get() as usize];
let origin = SystemOrigin::Signed(caller.clone()).into();
Assets::<T, I>::set_metadata(origin, Default::default(), dummy.clone(), dummy, 12)?;
}: _(SystemOrigin::Signed(caller), Default::default())
Assets::<T, I>::set_metadata(origin, asset_id, dummy.clone(), dummy, 12)?;
}: _(SystemOrigin::Signed(caller), asset_id)
verify {
assert_last_event::<T, I>(Event::MetadataCleared { asset_id: Default::default() }.into());
assert_last_event::<T, I>(Event::MetadataCleared { asset_id: asset_id.into() }.into());
}
force_set_metadata {
@@ -357,11 +360,11 @@ benchmarks_instance_pallet! {
let symbol = vec![0u8; s as usize];
let decimals = 12;
create_default_asset::<T, I>(true);
let (asset_id, _, _) = create_default_asset::<T, I>(true);
let origin = T::ForceOrigin::successful_origin();
let call = Call::<T, I>::force_set_metadata {
id: Default::default(),
id: asset_id,
name: name.clone(),
symbol: symbol.clone(),
decimals,
@@ -369,30 +372,29 @@ benchmarks_instance_pallet! {
};
}: { call.dispatch_bypass_filter(origin)? }
verify {
let id = Default::default();
assert_last_event::<T, I>(Event::MetadataSet { asset_id: id, name, symbol, decimals, is_frozen: false }.into());
assert_last_event::<T, I>(Event::MetadataSet { asset_id: asset_id.into(), name, symbol, decimals, is_frozen: false }.into());
}
force_clear_metadata {
let (caller, _) = create_default_asset::<T, I>(true);
let (asset_id, caller, _) = create_default_asset::<T, I>(true);
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
let dummy = vec![0u8; T::StringLimit::get() as usize];
let origin = SystemOrigin::Signed(caller).into();
Assets::<T, I>::set_metadata(origin, Default::default(), dummy.clone(), dummy, 12)?;
Assets::<T, I>::set_metadata(origin, asset_id, dummy.clone(), dummy, 12)?;
let origin = T::ForceOrigin::successful_origin();
let call = Call::<T, I>::force_clear_metadata { id: Default::default() };
let call = Call::<T, I>::force_clear_metadata { id: asset_id };
}: { call.dispatch_bypass_filter(origin)? }
verify {
assert_last_event::<T, I>(Event::MetadataCleared { asset_id: Default::default() }.into());
assert_last_event::<T, I>(Event::MetadataCleared { asset_id: asset_id.into() }.into());
}
force_asset_status {
let (caller, caller_lookup) = create_default_asset::<T, I>(true);
let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
let origin = T::ForceOrigin::successful_origin();
let call = Call::<T, I>::force_asset_status {
id: Default::default(),
id: asset_id,
owner: caller_lookup.clone(),
issuer: caller_lookup.clone(),
admin: caller_lookup.clone(),
@@ -403,70 +405,66 @@ benchmarks_instance_pallet! {
};
}: { call.dispatch_bypass_filter(origin)? }
verify {
assert_last_event::<T, I>(Event::AssetStatusChanged { asset_id: Default::default() }.into());
assert_last_event::<T, I>(Event::AssetStatusChanged { asset_id: asset_id.into() }.into());
}
approve_transfer {
let (caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
let id = Default::default();
let delegate: T::AccountId = account("delegate", 0, SEED);
let delegate_lookup = T::Lookup::unlookup(delegate.clone());
let amount = 100u32.into();
}: _(SystemOrigin::Signed(caller.clone()), id, delegate_lookup, amount)
}: _(SystemOrigin::Signed(caller.clone()), asset_id, delegate_lookup, amount)
verify {
assert_last_event::<T, I>(Event::ApprovedTransfer { asset_id: id, source: caller, delegate, amount }.into());
assert_last_event::<T, I>(Event::ApprovedTransfer { asset_id: asset_id.into(), source: caller, delegate, amount }.into());
}
transfer_approved {
let (owner, owner_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
let (asset_id, owner, owner_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
T::Currency::make_free_balance_be(&owner, DepositBalanceOf::<T, I>::max_value());
let id = Default::default();
let delegate: T::AccountId = account("delegate", 0, SEED);
whitelist_account!(delegate);
let delegate_lookup = T::Lookup::unlookup(delegate.clone());
let amount = 100u32.into();
let origin = SystemOrigin::Signed(owner.clone()).into();
Assets::<T, I>::approve_transfer(origin, id, delegate_lookup, amount)?;
Assets::<T, I>::approve_transfer(origin, asset_id, delegate_lookup, amount)?;
let dest: T::AccountId = account("dest", 0, SEED);
let dest_lookup = T::Lookup::unlookup(dest.clone());
}: _(SystemOrigin::Signed(delegate.clone()), id, owner_lookup, dest_lookup, amount)
}: _(SystemOrigin::Signed(delegate.clone()), asset_id, owner_lookup, dest_lookup, amount)
verify {
assert!(T::Currency::reserved_balance(&owner).is_zero());
assert_event::<T, I>(Event::Transferred { asset_id: id, from: owner, to: dest, amount }.into());
assert_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: owner, to: dest, amount }.into());
}
cancel_approval {
let (caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
let id = Default::default();
let delegate: T::AccountId = account("delegate", 0, SEED);
let delegate_lookup = T::Lookup::unlookup(delegate.clone());
let amount = 100u32.into();
let origin = SystemOrigin::Signed(caller.clone()).into();
Assets::<T, I>::approve_transfer(origin, id, delegate_lookup.clone(), amount)?;
}: _(SystemOrigin::Signed(caller.clone()), id, delegate_lookup)
Assets::<T, I>::approve_transfer(origin, asset_id, delegate_lookup.clone(), amount)?;
}: _(SystemOrigin::Signed(caller.clone()), asset_id, delegate_lookup)
verify {
assert_last_event::<T, I>(Event::ApprovalCancelled { asset_id: id, owner: caller, delegate }.into());
assert_last_event::<T, I>(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into());
}
force_cancel_approval {
let (caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
let id = Default::default();
let delegate: T::AccountId = account("delegate", 0, SEED);
let delegate_lookup = T::Lookup::unlookup(delegate.clone());
let amount = 100u32.into();
let origin = SystemOrigin::Signed(caller.clone()).into();
Assets::<T, I>::approve_transfer(origin, id, delegate_lookup.clone(), amount)?;
}: _(SystemOrigin::Signed(caller.clone()), id, caller_lookup, delegate_lookup)
Assets::<T, I>::approve_transfer(origin, asset_id, delegate_lookup.clone(), amount)?;
}: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, delegate_lookup)
verify {
assert_last_event::<T, I>(Event::ApprovalCancelled { asset_id: id, owner: caller, delegate }.into());
assert_last_event::<T, I>(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into());
}
impl_benchmark_test_suite!(Assets, crate::mock::new_test_ext(), crate::mock::Test)
+106 -71
View File
@@ -144,7 +144,6 @@ mod impl_stored_map;
mod types;
pub use types::*;
use codec::HasCompact;
use scale_info::TypeInfo;
use sp_runtime::{
traits::{
@@ -186,6 +185,17 @@ pub mod pallet {
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T, I = ()>(_);
#[cfg(feature = "runtime-benchmarks")]
pub trait BenchmarkHelper<AssetIdParameter> {
fn create_asset_id_parameter(id: u32) -> AssetIdParameter;
}
#[cfg(feature = "runtime-benchmarks")]
impl<AssetIdParameter: From<u32>> BenchmarkHelper<AssetIdParameter> for () {
fn create_asset_id_parameter(id: u32) -> AssetIdParameter {
id.into()
}
}
#[pallet::config]
/// The module configuration trait.
pub trait Config<I: 'static = ()>: frame_system::Config {
@@ -210,14 +220,20 @@ pub mod pallet {
type RemoveItemsLimit: Get<u32>;
/// Identifier for the class of asset.
type AssetId: Member
+ Parameter
+ Default
type AssetId: Member + Parameter + Copy + MaybeSerializeDeserialize + MaxEncodedLen;
/// Wrapper around `Self::AssetId` to use in dispatchable call signatures. Allows the use
/// of compact encoding in instances of the pallet, which will prevent breaking changes
/// resulting from the removal of `HasCompact` from `Self::AssetId`.
///
/// This type includes the `From<Self::AssetId>` bound, since tightly coupled pallets may
/// want to convert an `AssetId` into a parameter for calling dispatchable functions
/// directly.
type AssetIdParameter: Parameter
+ Copy
+ HasCompact
+ MaybeSerializeDeserialize
+ MaxEncodedLen
+ TypeInfo;
+ From<Self::AssetId>
+ Into<Self::AssetId>
+ MaxEncodedLen;
/// The currency mechanism.
type Currency: ReservableCurrency<Self::AccountId>;
@@ -269,6 +285,10 @@ pub mod pallet {
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
/// Helper trait for benchmarks.
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper: BenchmarkHelper<Self::AssetIdParameter>;
}
#[pallet::storage]
@@ -546,10 +566,11 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::create())]
pub fn create(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
admin: AccountIdLookupOf<T>,
min_balance: T::Balance,
) -> DispatchResult {
let id: T::AssetId = id.into();
let owner = T::CreateOrigin::ensure_origin(origin, &id)?;
let admin = T::Lookup::lookup(admin)?;
@@ -602,84 +623,86 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_create())]
pub fn force_create(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
owner: AccountIdLookupOf<T>,
is_sufficient: bool,
#[pallet::compact] min_balance: T::Balance,
) -> DispatchResult {
T::ForceOrigin::ensure_origin(origin)?;
let owner = T::Lookup::lookup(owner)?;
let id: T::AssetId = id.into();
Self::do_force_create(id, owner, is_sufficient, min_balance)
}
/// Start the process of destroying a class of fungible asset
/// start_destroy is the first in a series of extrinsics that should be called, to allow
/// destroying an asset.
/// Start the process of destroying a fungible asset class.
///
/// The origin must conform to `ForceOrigin` or must be Signed and the sender must be the
/// owner of the asset `id`.
/// `start_destroy` is the first in a series of extrinsics that should be called, to allow
/// destruction of an asset class.
///
/// The origin must conform to `ForceOrigin` or must be `Signed` by the asset's `owner`.
///
/// - `id`: The identifier of the asset to be destroyed. This must identify an existing
/// asset.
///
/// Assets must be freezed before calling start_destroy.
/// The asset class must be frozen before calling `start_destroy`.
#[pallet::weight(T::WeightInfo::start_destroy())]
pub fn start_destroy(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
) -> DispatchResult {
pub fn start_destroy(origin: OriginFor<T>, id: T::AssetIdParameter) -> DispatchResult {
let maybe_check_owner = match T::ForceOrigin::try_origin(origin) {
Ok(_) => None,
Err(origin) => Some(ensure_signed(origin)?),
};
let id: T::AssetId = id.into();
Self::do_start_destroy(id, maybe_check_owner)
}
/// Destroy all accounts associated with a given asset.
/// `destroy_accounts` should only be called after `start_destroy` has been called, and the
/// asset is in a `Destroying` state
///
/// Due to weight restrictions, this function may need to be called multiple
/// times to fully destroy all accounts. It will destroy `RemoveItemsLimit` accounts at a
/// time.
/// `destroy_accounts` should only be called after `start_destroy` has been called, and the
/// asset is in a `Destroying` state.
///
/// Due to weight restrictions, this function may need to be called multiple times to fully
/// destroy all accounts. It will destroy `RemoveItemsLimit` accounts at a time.
///
/// - `id`: The identifier of the asset to be destroyed. This must identify an existing
/// asset.
///
/// Each call Emits the `Event::DestroyedAccounts` event.
/// Each call emits the `Event::DestroyedAccounts` event.
#[pallet::weight(T::WeightInfo::destroy_accounts(T::RemoveItemsLimit::get()))]
pub fn destroy_accounts(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
) -> DispatchResultWithPostInfo {
let _ = ensure_signed(origin)?;
let id: T::AssetId = id.into();
let removed_accounts = Self::do_destroy_accounts(id, T::RemoveItemsLimit::get())?;
Ok(Some(T::WeightInfo::destroy_accounts(removed_accounts)).into())
}
/// Destroy all approvals associated with a given asset up to the max (T::RemoveItemsLimit),
/// `destroy_approvals` should only be called after `start_destroy` has been called, and the
/// asset is in a `Destroying` state
/// Destroy all approvals associated with a given asset up to the max (T::RemoveItemsLimit).
///
/// Due to weight restrictions, this function may need to be called multiple
/// times to fully destroy all approvals. It will destroy `RemoveItemsLimit` approvals at a
/// time.
/// `destroy_approvals` should only be called after `start_destroy` has been called, and the
/// asset is in a `Destroying` state.
///
/// Due to weight restrictions, this function may need to be called multiple times to fully
/// destroy all approvals. It will destroy `RemoveItemsLimit` approvals at a time.
///
/// - `id`: The identifier of the asset to be destroyed. This must identify an existing
/// asset.
///
/// Each call Emits the `Event::DestroyedApprovals` event.
/// Each call emits the `Event::DestroyedApprovals` event.
#[pallet::weight(T::WeightInfo::destroy_approvals(T::RemoveItemsLimit::get()))]
pub fn destroy_approvals(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
) -> DispatchResultWithPostInfo {
let _ = ensure_signed(origin)?;
let id: T::AssetId = id.into();
let removed_approvals = Self::do_destroy_approvals(id, T::RemoveItemsLimit::get())?;
Ok(Some(T::WeightInfo::destroy_approvals(removed_approvals)).into())
}
/// Complete destroying asset and unreserve currency.
///
/// `finish_destroy` should only be called after `start_destroy` has been called, and the
/// asset is in a `Destroying` state. All accounts or approvals should be destroyed before
/// hand.
@@ -687,13 +710,11 @@ pub mod pallet {
/// - `id`: The identifier of the asset to be destroyed. This must identify an existing
/// asset.
///
/// Each successful call Emits the `Event::Destroyed` event.
/// Each successful call emits the `Event::Destroyed` event.
#[pallet::weight(T::WeightInfo::finish_destroy())]
pub fn finish_destroy(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
) -> DispatchResult {
pub fn finish_destroy(origin: OriginFor<T>, id: T::AssetIdParameter) -> DispatchResult {
let _ = ensure_signed(origin)?;
let id: T::AssetId = id.into();
Self::do_finish_destroy(id)
}
@@ -712,12 +733,13 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::mint())]
pub fn mint(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
beneficiary: AccountIdLookupOf<T>,
#[pallet::compact] amount: T::Balance,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let beneficiary = T::Lookup::lookup(beneficiary)?;
let id: T::AssetId = id.into();
Self::do_mint(id, &beneficiary, amount, Some(origin))?;
Ok(())
}
@@ -740,12 +762,13 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::burn())]
pub fn burn(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
who: AccountIdLookupOf<T>,
#[pallet::compact] amount: T::Balance,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let who = T::Lookup::lookup(who)?;
let id: T::AssetId = id.into();
let f = DebitFlags { keep_alive: false, best_effort: true };
let _ = Self::do_burn(id, &who, amount, Some(origin), f)?;
@@ -773,12 +796,13 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::transfer())]
pub fn transfer(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
target: AccountIdLookupOf<T>,
#[pallet::compact] amount: T::Balance,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let dest = T::Lookup::lookup(target)?;
let id: T::AssetId = id.into();
let f = TransferFlags { keep_alive: false, best_effort: false, burn_dust: false };
Self::do_transfer(id, &origin, &dest, amount, None, f).map(|_| ())
@@ -805,12 +829,13 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::transfer_keep_alive())]
pub fn transfer_keep_alive(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
target: AccountIdLookupOf<T>,
#[pallet::compact] amount: T::Balance,
) -> DispatchResult {
let source = ensure_signed(origin)?;
let dest = T::Lookup::lookup(target)?;
let id: T::AssetId = id.into();
let f = TransferFlags { keep_alive: true, best_effort: false, burn_dust: false };
Self::do_transfer(id, &source, &dest, amount, None, f).map(|_| ())
@@ -838,7 +863,7 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_transfer())]
pub fn force_transfer(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
source: AccountIdLookupOf<T>,
dest: AccountIdLookupOf<T>,
#[pallet::compact] amount: T::Balance,
@@ -846,6 +871,7 @@ pub mod pallet {
let origin = ensure_signed(origin)?;
let source = T::Lookup::lookup(source)?;
let dest = T::Lookup::lookup(dest)?;
let id: T::AssetId = id.into();
let f = TransferFlags { keep_alive: false, best_effort: false, burn_dust: false };
Self::do_transfer(id, &source, &dest, amount, Some(origin), f).map(|_| ())
@@ -864,10 +890,11 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::freeze())]
pub fn freeze(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
who: AccountIdLookupOf<T>,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let id: T::AssetId = id.into();
let d = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
ensure!(
@@ -899,10 +926,11 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::thaw())]
pub fn thaw(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
who: AccountIdLookupOf<T>,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let id: T::AssetId = id.into();
let details = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
ensure!(
@@ -931,11 +959,9 @@ pub mod pallet {
///
/// Weight: `O(1)`
#[pallet::weight(T::WeightInfo::freeze_asset())]
pub fn freeze_asset(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
) -> DispatchResult {
pub fn freeze_asset(origin: OriginFor<T>, id: T::AssetIdParameter) -> DispatchResult {
let origin = ensure_signed(origin)?;
let id: T::AssetId = id.into();
Asset::<T, I>::try_mutate(id, |maybe_details| {
let d = maybe_details.as_mut().ok_or(Error::<T, I>::Unknown)?;
@@ -959,11 +985,9 @@ pub mod pallet {
///
/// Weight: `O(1)`
#[pallet::weight(T::WeightInfo::thaw_asset())]
pub fn thaw_asset(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
) -> DispatchResult {
pub fn thaw_asset(origin: OriginFor<T>, id: T::AssetIdParameter) -> DispatchResult {
let origin = ensure_signed(origin)?;
let id: T::AssetId = id.into();
Asset::<T, I>::try_mutate(id, |maybe_details| {
let d = maybe_details.as_mut().ok_or(Error::<T, I>::Unknown)?;
@@ -990,11 +1014,12 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::transfer_ownership())]
pub fn transfer_ownership(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
owner: AccountIdLookupOf<T>,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let owner = T::Lookup::lookup(owner)?;
let id: T::AssetId = id.into();
Asset::<T, I>::try_mutate(id, |maybe_details| {
let details = maybe_details.as_mut().ok_or(Error::<T, I>::Unknown)?;
@@ -1032,7 +1057,7 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::set_team())]
pub fn set_team(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
issuer: AccountIdLookupOf<T>,
admin: AccountIdLookupOf<T>,
freezer: AccountIdLookupOf<T>,
@@ -1041,6 +1066,7 @@ pub mod pallet {
let issuer = T::Lookup::lookup(issuer)?;
let admin = T::Lookup::lookup(admin)?;
let freezer = T::Lookup::lookup(freezer)?;
let id: T::AssetId = id.into();
Asset::<T, I>::try_mutate(id, |maybe_details| {
let details = maybe_details.as_mut().ok_or(Error::<T, I>::Unknown)?;
@@ -1075,12 +1101,13 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::set_metadata(name.len() as u32, symbol.len() as u32))]
pub fn set_metadata(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
name: Vec<u8>,
symbol: Vec<u8>,
decimals: u8,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let id: T::AssetId = id.into();
Self::do_set_metadata(id, &origin, name, symbol, decimals)
}
@@ -1096,11 +1123,9 @@ pub mod pallet {
///
/// Weight: `O(1)`
#[pallet::weight(T::WeightInfo::clear_metadata())]
pub fn clear_metadata(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
) -> DispatchResult {
pub fn clear_metadata(origin: OriginFor<T>, id: T::AssetIdParameter) -> DispatchResult {
let origin = ensure_signed(origin)?;
let id: T::AssetId = id.into();
let d = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
ensure!(d.status == AssetStatus::Live, Error::<T, I>::AssetNotLive);
@@ -1131,13 +1156,14 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_set_metadata(name.len() as u32, symbol.len() as u32))]
pub fn force_set_metadata(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
name: Vec<u8>,
symbol: Vec<u8>,
decimals: u8,
is_frozen: bool,
) -> DispatchResult {
T::ForceOrigin::ensure_origin(origin)?;
let id: T::AssetId = id.into();
let bounded_name: BoundedVec<u8, T::StringLimit> =
name.clone().try_into().map_err(|_| Error::<T, I>::BadMetadata)?;
@@ -1181,9 +1207,10 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_clear_metadata())]
pub fn force_clear_metadata(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
) -> DispatchResult {
T::ForceOrigin::ensure_origin(origin)?;
let id: T::AssetId = id.into();
let d = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
Metadata::<T, I>::try_mutate_exists(id, |metadata| {
@@ -1219,7 +1246,7 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_asset_status())]
pub fn force_asset_status(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
owner: AccountIdLookupOf<T>,
issuer: AccountIdLookupOf<T>,
admin: AccountIdLookupOf<T>,
@@ -1229,6 +1256,7 @@ pub mod pallet {
is_frozen: bool,
) -> DispatchResult {
T::ForceOrigin::ensure_origin(origin)?;
let id: T::AssetId = id.into();
Asset::<T, I>::try_mutate(id, |maybe_asset| {
let mut asset = maybe_asset.take().ok_or(Error::<T, I>::Unknown)?;
@@ -1274,12 +1302,13 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::approve_transfer())]
pub fn approve_transfer(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
delegate: AccountIdLookupOf<T>,
#[pallet::compact] amount: T::Balance,
) -> DispatchResult {
let owner = ensure_signed(origin)?;
let delegate = T::Lookup::lookup(delegate)?;
let id: T::AssetId = id.into();
Self::do_approve_transfer(id, &owner, &delegate, amount)
}
@@ -1299,13 +1328,15 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::cancel_approval())]
pub fn cancel_approval(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
delegate: AccountIdLookupOf<T>,
) -> DispatchResult {
let owner = ensure_signed(origin)?;
let delegate = T::Lookup::lookup(delegate)?;
let id: T::AssetId = id.into();
let mut d = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
ensure!(d.status == AssetStatus::Live, Error::<T, I>::AssetNotLive);
let approval =
Approvals::<T, I>::take((id, &owner, &delegate)).ok_or(Error::<T, I>::Unknown)?;
T::Currency::unreserve(&owner, approval.deposit);
@@ -1333,10 +1364,11 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_cancel_approval())]
pub fn force_cancel_approval(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
owner: AccountIdLookupOf<T>,
delegate: AccountIdLookupOf<T>,
) -> DispatchResult {
let id: T::AssetId = id.into();
let mut d = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
ensure!(d.status == AssetStatus::Live, Error::<T, I>::AssetNotLive);
T::ForceOrigin::try_origin(origin)
@@ -1381,7 +1413,7 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::transfer_approved())]
pub fn transfer_approved(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
owner: AccountIdLookupOf<T>,
destination: AccountIdLookupOf<T>,
#[pallet::compact] amount: T::Balance,
@@ -1389,6 +1421,7 @@ pub mod pallet {
let delegate = ensure_signed(origin)?;
let owner = T::Lookup::lookup(owner)?;
let destination = T::Lookup::lookup(destination)?;
let id: T::AssetId = id.into();
Self::do_transfer_approved(id, &owner, &delegate, &destination, amount)
}
@@ -1402,7 +1435,8 @@ pub mod pallet {
///
/// Emits `Touched` event when successful.
#[pallet::weight(T::WeightInfo::mint())]
pub fn touch(origin: OriginFor<T>, #[pallet::compact] id: T::AssetId) -> DispatchResult {
pub fn touch(origin: OriginFor<T>, id: T::AssetIdParameter) -> DispatchResult {
let id: T::AssetId = id.into();
Self::do_touch(id, ensure_signed(origin)?)
}
@@ -1417,9 +1451,10 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::mint())]
pub fn refund(
origin: OriginFor<T>,
#[pallet::compact] id: T::AssetId,
id: T::AssetIdParameter,
allow_burn: bool,
) -> DispatchResult {
let id: T::AssetId = id.into();
Self::do_refund(id, ensure_signed(origin)?, allow_burn)
}
}
+3
View File
@@ -88,6 +88,7 @@ impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type Balance = u64;
type AssetId = u32;
type AssetIdParameter = u32;
type Currency = Balances;
type CreateOrigin = AsEnsureOriginWithArg<frame_system::EnsureSigned<u64>>;
type ForceOrigin = frame_system::EnsureRoot<u64>;
@@ -101,6 +102,8 @@ impl Config for Test {
type WeightInfo = ();
type Extra = ();
type RemoveItemsLimit = ConstU32<5>;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}
use std::collections::HashMap;
@@ -22,6 +22,7 @@ sp-std = { version = "5.0.0", default-features = false, path = "../../../primiti
frame-support = { version = "4.0.0-dev", default-features = false, path = "../../support" }
frame-system = { version = "4.0.0-dev", default-features = false, path = "../../system" }
pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, path = ".." }
frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../../benchmarking", optional = true }
# Other dependencies
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
@@ -51,5 +52,12 @@ std = [
"sp-io/std",
"sp-core/std",
"pallet-transaction-payment/std",
"frame-benchmarking?/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
]
try-runtime = ["frame-support/try-runtime"]
@@ -16,6 +16,7 @@
use super::*;
use crate as pallet_asset_tx_payment;
use codec;
use frame_support::{
assert_ok,
dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo},
@@ -152,10 +153,13 @@ impl pallet_transaction_payment::Config for Runtime {
type OperationalFeeMultiplier = ConstU8<5>;
}
type AssetId = u32;
impl pallet_assets::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = Balance;
type AssetId = u32;
type AssetId = AssetId;
type AssetIdParameter = codec::Compact<AssetId>;
type Currency = Balances;
type CreateOrigin = AsEnsureOriginWithArg<frame_system::EnsureSigned<AccountId>>;
type ForceOrigin = EnsureRoot<AccountId>;
@@ -169,6 +173,8 @@ impl pallet_assets::Config for Runtime {
type Extra = ();
type WeightInfo = ();
type RemoveItemsLimit = ConstU32<1000>;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}
pub struct HardcodedAuthor;
@@ -341,7 +347,7 @@ fn transaction_payment_in_asset_possible() {
let min_balance = 2;
assert_ok!(Assets::force_create(
RuntimeOrigin::root(),
asset_id,
asset_id.into(),
42, /* owner */
true, /* is_sufficient */
min_balance
@@ -351,7 +357,7 @@ fn transaction_payment_in_asset_possible() {
let caller = 1;
let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
let balance = 100;
assert_ok!(Assets::mint_into(asset_id, &beneficiary, balance));
assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
assert_eq!(Assets::balance(asset_id, caller), balance);
let weight = 5;
let len = 10;
@@ -394,7 +400,7 @@ fn transaction_payment_without_fee() {
let min_balance = 2;
assert_ok!(Assets::force_create(
RuntimeOrigin::root(),
asset_id,
asset_id.into(),
42, /* owner */
true, /* is_sufficient */
min_balance
@@ -404,7 +410,7 @@ fn transaction_payment_without_fee() {
let caller = 1;
let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
let balance = 100;
assert_ok!(Assets::mint_into(asset_id, &beneficiary, balance));
assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
assert_eq!(Assets::balance(asset_id, caller), balance);
let weight = 5;
let len = 10;
@@ -447,7 +453,7 @@ fn asset_transaction_payment_with_tip_and_refund() {
let min_balance = 2;
assert_ok!(Assets::force_create(
RuntimeOrigin::root(),
asset_id,
asset_id.into(),
42, /* owner */
true, /* is_sufficient */
min_balance
@@ -457,7 +463,7 @@ fn asset_transaction_payment_with_tip_and_refund() {
let caller = 2;
let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
let balance = 1000;
assert_ok!(Assets::mint_into(asset_id, &beneficiary, balance));
assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
assert_eq!(Assets::balance(asset_id, caller), balance);
let weight = 100;
let tip = 5;
@@ -499,7 +505,7 @@ fn payment_from_account_with_only_assets() {
let min_balance = 2;
assert_ok!(Assets::force_create(
RuntimeOrigin::root(),
asset_id,
asset_id.into(),
42, /* owner */
true, /* is_sufficient */
min_balance
@@ -509,7 +515,7 @@ fn payment_from_account_with_only_assets() {
let caller = 333;
let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
let balance = 100;
assert_ok!(Assets::mint_into(asset_id, &beneficiary, balance));
assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
assert_eq!(Assets::balance(asset_id, caller), balance);
// assert that native balance is not necessary
assert_eq!(Balances::free_balance(caller), 0);
@@ -558,7 +564,7 @@ fn payment_only_with_existing_sufficient_asset() {
let min_balance = 2;
assert_ok!(Assets::force_create(
RuntimeOrigin::root(),
asset_id,
asset_id.into(),
42, /* owner */
false, /* is_sufficient */
min_balance
@@ -583,7 +589,7 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() {
let min_balance = 1;
assert_ok!(Assets::force_create(
RuntimeOrigin::root(),
asset_id,
asset_id.into(),
42, /* owner */
true, /* is_sufficient */
min_balance
@@ -593,7 +599,7 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() {
let caller = 333;
let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
let balance = 100;
assert_ok!(Assets::mint_into(asset_id, &beneficiary, balance));
assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
assert_eq!(Assets::balance(asset_id, caller), balance);
let weight = 1;
let len = 1;
@@ -648,7 +654,7 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() {
let min_balance = 100;
assert_ok!(Assets::force_create(
RuntimeOrigin::root(),
asset_id,
asset_id.into(),
42, /* owner */
true, /* is_sufficient */
min_balance
@@ -658,7 +664,7 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() {
let caller = 333;
let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
let balance = 100;
assert_ok!(Assets::mint_into(asset_id, &beneficiary, balance));
assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
assert_eq!(Assets::balance(asset_id, caller), balance);
let weight = 1;
let len = 1;
@@ -705,7 +711,7 @@ fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() {
let min_balance = 100;
assert_ok!(Assets::force_create(
RuntimeOrigin::root(),
asset_id,
asset_id.into(),
42, /* owner */
true, /* is_sufficient */
min_balance
@@ -715,7 +721,7 @@ fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() {
let caller = 333;
let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
let balance = 100;
assert_ok!(Assets::mint_into(asset_id, &beneficiary, balance));
assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
assert_eq!(Assets::balance(asset_id, caller), balance);
let weight = 1;
let len = 1;