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

Minor Uniques pallet improvements and XCM v3 preparations #10896

Merged
merged 14 commits into from
Mar 7, 2022
2 changes: 2 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,8 @@ impl pallet_uniques::Config for Runtime {
type KeyLimit = KeyLimit;
type ValueLimit = ValueLimit;
type WeightInfo = pallet_uniques::weights::SubstrateWeight<Runtime>;
#[cfg(feature = "runtime-benchmarks")]
type Helper = ();
}

impl pallet_transaction_storage::Config for Runtime {
Expand Down
4 changes: 2 additions & 2 deletions frame/support/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ mod members;
#[allow(deprecated)]
pub use members::{AllowAll, DenyAll, Filter};
pub use members::{
AsContains, ChangeMembers, Contains, ContainsLengthBound, Everything, InitializeMembers,
IsInVec, Nothing, SortedMembers,
AsContains, ChangeMembers, Contains, ContainsLengthBound, ContainsPair, Everything,
FromContainsPair, InitializeMembers, IsInVec, Nothing, SortedMembers,
};

mod validation;
Expand Down
113 changes: 88 additions & 25 deletions frame/support/src/traits/members.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,52 @@ pub trait Contains<T> {
fn contains(t: &T) -> bool;
}

#[impl_trait_for_tuples::impl_for_tuples(1, 30)]
impl<T> Contains<T> for Tuple {
fn contains(t: &T) -> bool {
for_tuples!( #(
if Tuple::contains(t) { return true }
)* );
false
}
}

/// A trait for querying whether a type can be said to "contain" a pair-value.
pub trait ContainsPair<A, B> {
/// Return `true` if this "contains" the pair-value `(a, b)`.
fn contains(a: &A, b: &B) -> bool;
}

#[impl_trait_for_tuples::impl_for_tuples(0, 30)]
impl<A, B> ContainsPair<A, B> for Tuple {
fn contains(a: &A, b: &B) -> bool {
for_tuples!( #(
if Tuple::contains(a, b) { return true }
)* );
false
}
}

/// Converter `struct` to use a `ContainsPair` implementation for a `Contains` bound.
pub struct FromContainsPair<CP>(PhantomData<CP>);
impl<A, B, CP: ContainsPair<A, B>> Contains<(A, B)> for FromContainsPair<CP> {
fn contains((ref a, ref b): &(A, B)) -> bool {
CP::contains(a, b)
}
}

/// A [`Contains`] implementation that contains every value.
pub enum Everything {}
impl<T> Contains<T> for Everything {
fn contains(_: &T) -> bool {
true
}
}
impl<A, B> ContainsPair<A, B> for Everything {
fn contains(_: &A, _: &B) -> bool {
true
}
}

/// A [`Contains`] implementation that contains no value.
pub enum Nothing {}
Expand All @@ -40,56 +79,80 @@ impl<T> Contains<T> for Nothing {
false
}
}

#[deprecated = "Use `Everything` instead"]
pub type AllowAll = Everything;
#[deprecated = "Use `Nothing` instead"]
pub type DenyAll = Nothing;
#[deprecated = "Use `Contains` instead"]
pub trait Filter<T> {
fn filter(t: &T) -> bool;
}
#[allow(deprecated)]
impl<T, C: Contains<T>> Filter<T> for C {
fn filter(t: &T) -> bool {
Self::contains(t)
}
}

#[impl_trait_for_tuples::impl_for_tuples(1, 30)]
impl<T> Contains<T> for Tuple {
fn contains(t: &T) -> bool {
for_tuples!( #(
if Tuple::contains(t) { return true }
)* );
impl<A, B> ContainsPair<A, B> for Nothing {
fn contains(_: &A, _: &B) -> bool {
false
}
}

/// Create a type which implements the `Contains` trait for a particular type with syntax similar
/// to `matches!`.
#[macro_export]
#[deprecated = "Use `match_types!` instead"]
macro_rules! match_type {
( pub type $n:ident: impl Contains<$t:ty> = { $phead:pat_param $( | $ptail:pat )* } ; ) => {
($( $x:tt )*) => { match_types!( $( $x )* ); }
}

/// Create a type which implements the `Contains` trait for a particular type with syntax similar
/// to `matches!`.
#[macro_export]
macro_rules! match_types {
(
pub type $n:ident: impl Contains<$t:ty> = {
$phead:pat_param $( | $ptail:pat )*
};
$( $rest:tt )*
) => {
pub struct $n;
impl $crate::traits::Contains<$t> for $n {
fn contains(l: &$t) -> bool {
matches!(l, $phead $( | $ptail )* )
}
}
$crate::match_types!( $( $rest )* );
};
(
pub type $n:ident: impl ContainsPair<$a:ty, $b:ty> = {
$phead:pat_param $( | $ptail:pat )*
};
$( $rest:tt )*
) => {
pub struct $n;
impl $crate::traits::ContainsPair<$a, $b> for $n {
fn contains(a: &$a, b: &$b) -> bool {
matches!((a, b), $phead $( | $ptail )* )
}
}
$crate::match_types!( $( $rest )* );
};
() => {}
}

#[deprecated = "Use `Everything` instead"]
pub type AllowAll = Everything;
#[deprecated = "Use `Nothing` instead"]
pub type DenyAll = Nothing;
#[deprecated = "Use `Contains` instead"]
pub trait Filter<T> {
fn filter(t: &T) -> bool;
}
#[allow(deprecated)]
impl<T, C: Contains<T>> Filter<T> for C {
fn filter(t: &T) -> bool {
Self::contains(t)
}
}

#[cfg(test)]
mod tests {
use super::*;

match_type! {
match_types! {
pub type OneOrTenToTwenty: impl Contains<u8> = { 1 | 10..=20 };
}

#[test]
fn match_type_works() {
fn match_types_works() {
for i in 0..=255 {
assert_eq!(OneOrTenToTwenty::contains(&i), i == 1 || i >= 10 && i <= 20);
}
Expand Down
46 changes: 23 additions & 23 deletions frame/uniques/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn create_class<T: Config<I>, I: 'static>(
) -> (T::ClassId, T::AccountId, <T::Lookup as StaticLookup>::Source) {
let caller: T::AccountId = whitelisted_caller();
let caller_lookup = T::Lookup::unlookup(caller.clone());
let class = Default::default();
let class = T::Helper::class(0);
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
assert!(Uniques::<T, I>::create(
SystemOrigin::Signed(caller.clone()).into(),
Expand All @@ -53,14 +53,14 @@ fn create_class<T: Config<I>, I: 'static>(

fn add_class_metadata<T: Config<I>, I: 'static>(
) -> (T::AccountId, <T::Lookup as StaticLookup>::Source) {
let caller = Class::<T, I>::get(T::ClassId::default()).unwrap().owner;
let caller = Class::<T, I>::get(T::Helper::class(0)).unwrap().owner;
if caller != whitelisted_caller() {
whitelist_account!(caller);
}
let caller_lookup = T::Lookup::unlookup(caller.clone());
assert!(Uniques::<T, I>::set_class_metadata(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
T::Helper::class(0),
vec![0; T::StringLimit::get() as usize].try_into().unwrap(),
false,
)
Expand All @@ -71,15 +71,15 @@ fn add_class_metadata<T: Config<I>, I: 'static>(
fn mint_instance<T: Config<I>, I: 'static>(
index: u16,
) -> (T::InstanceId, T::AccountId, <T::Lookup as StaticLookup>::Source) {
let caller = Class::<T, I>::get(T::ClassId::default()).unwrap().admin;
let caller = Class::<T, I>::get(T::Helper::class(0)).unwrap().admin;
if caller != whitelisted_caller() {
whitelist_account!(caller);
}
let caller_lookup = T::Lookup::unlookup(caller.clone());
let instance = index.into();
let instance = T::Helper::instance(index);
assert!(Uniques::<T, I>::mint(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
T::Helper::class(0),
instance,
caller_lookup.clone(),
)
Expand All @@ -90,14 +90,14 @@ fn mint_instance<T: Config<I>, I: 'static>(
fn add_instance_metadata<T: Config<I>, I: 'static>(
instance: T::InstanceId,
) -> (T::AccountId, <T::Lookup as StaticLookup>::Source) {
let caller = Class::<T, I>::get(T::ClassId::default()).unwrap().owner;
let caller = Class::<T, I>::get(T::Helper::class(0)).unwrap().owner;
if caller != whitelisted_caller() {
whitelist_account!(caller);
}
let caller_lookup = T::Lookup::unlookup(caller.clone());
assert!(Uniques::<T, I>::set_metadata(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
T::Helper::class(0),
instance,
vec![0; T::StringLimit::get() as usize].try_into().unwrap(),
false,
Expand All @@ -109,15 +109,15 @@ fn add_instance_metadata<T: Config<I>, I: 'static>(
fn add_instance_attribute<T: Config<I>, I: 'static>(
instance: T::InstanceId,
) -> (BoundedVec<u8, T::KeyLimit>, T::AccountId, <T::Lookup as StaticLookup>::Source) {
let caller = Class::<T, I>::get(T::ClassId::default()).unwrap().owner;
let caller = Class::<T, I>::get(T::Helper::class(0)).unwrap().owner;
if caller != whitelisted_caller() {
whitelist_account!(caller);
}
let caller_lookup = T::Lookup::unlookup(caller.clone());
let key: BoundedVec<_, _> = vec![0; T::KeyLimit::get() as usize].try_into().unwrap();
assert!(Uniques::<T, I>::set_attribute(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
T::Helper::class(0),
Some(instance),
key.clone(),
vec![0; T::ValueLimit::get() as usize].try_into().unwrap(),
Expand All @@ -139,17 +139,17 @@ benchmarks_instance_pallet! {
let caller: T::AccountId = whitelisted_caller();
let caller_lookup = T::Lookup::unlookup(caller.clone());
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup)
}: _(SystemOrigin::Signed(caller.clone()), T::Helper::class(0), caller_lookup)
verify {
assert_last_event::<T, I>(Event::Created { class: Default::default(), creator: caller.clone(), owner: caller }.into());
assert_last_event::<T, I>(Event::Created { class: T::Helper::class(0), creator: caller.clone(), owner: caller }.into());
}

force_create {
let caller: T::AccountId = whitelisted_caller();
let caller_lookup = T::Lookup::unlookup(caller.clone());
}: _(SystemOrigin::Root, Default::default(), caller_lookup, true)
}: _(SystemOrigin::Root, T::Helper::class(0), caller_lookup, true)
verify {
assert_last_event::<T, I>(Event::ForceCreated { class: Default::default(), owner: caller }.into());
assert_last_event::<T, I>(Event::ForceCreated { class: T::Helper::class(0), owner: caller }.into());
}

destroy {
Expand All @@ -163,10 +163,10 @@ benchmarks_instance_pallet! {
mint_instance::<T, I>(i as u16);
}
for i in 0..m {
add_instance_metadata::<T, I>((i as u16).into());
add_instance_metadata::<T, I>(T::Helper::instance(i as u16));
}
for i in 0..a {
add_instance_attribute::<T, I>((i as u16).into());
add_instance_attribute::<T, I>(T::Helper::instance(i as u16));
}
let witness = Class::<T, I>::get(class).unwrap().destroy_witness();
}: _(SystemOrigin::Signed(caller), class, witness)
Expand All @@ -176,7 +176,7 @@ benchmarks_instance_pallet! {

mint {
let (class, caller, caller_lookup) = create_class::<T, I>();
let instance = Default::default();
let instance = T::Helper::instance(0);
}: _(SystemOrigin::Signed(caller.clone()), class, instance, caller_lookup)
verify {
assert_last_event::<T, I>(Event::Issued { class, instance, owner: caller }.into());
Expand All @@ -192,7 +192,7 @@ benchmarks_instance_pallet! {

transfer {
let (class, caller, caller_lookup) = create_class::<T, I>();
let (instance, ..) = mint_instance::<T, I>(Default::default());
let (instance, ..) = mint_instance::<T, I>(0);

let target: T::AccountId = account("target", 0, SEED);
let target_lookup = T::Lookup::unlookup(target.clone());
Expand Down Expand Up @@ -222,15 +222,15 @@ benchmarks_instance_pallet! {

freeze {
let (class, caller, caller_lookup) = create_class::<T, I>();
let (instance, ..) = mint_instance::<T, I>(Default::default());
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), Default::default())
let (instance, ..) = mint_instance::<T, I>(0);
}: _(SystemOrigin::Signed(caller.clone()), T::Helper::class(0), T::Helper::instance(0))
verify {
assert_last_event::<T, I>(Event::Frozen { class: Default::default(), instance: Default::default() }.into());
assert_last_event::<T, I>(Event::Frozen { class: T::Helper::class(0), instance: T::Helper::instance(0) }.into());
}

thaw {
let (class, caller, caller_lookup) = create_class::<T, I>();
let (instance, ..) = mint_instance::<T, I>(Default::default());
let (instance, ..) = mint_instance::<T, I>(0);
Uniques::<T, I>::freeze(
SystemOrigin::Signed(caller.clone()).into(),
class,
Expand Down Expand Up @@ -272,7 +272,7 @@ benchmarks_instance_pallet! {
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.clone(), target1.clone(), target2.clone())
}: _(SystemOrigin::Signed(caller), class, target0.clone(), target1.clone(), target2.clone())
verify {
assert_last_event::<T, I>(Event::TeamChanged{
class,
Expand Down
Loading