difftreelog
feat implement collection nesting rules field
in: master
3 files changed
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -192,7 +192,10 @@
type CrossTokenAddressMapping: TokenAddressMapping<Self::CrossAccountId>;
}
+ const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
+
#[pallet::pallet]
+ #[pallet::storage_version(STORAGE_VERSION)]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
@@ -393,6 +396,22 @@
#[pallet::storage]
pub type DummyStorageValue<T> =
StorageValue<Value = (CollectionStats, CollectionId, TokenId), QueryKind = OptionQuery>;
+
+ #[pallet::hooks]
+ impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
+ fn on_runtime_upgrade() -> Weight {
+ let mut weight = 0;
+
+ if StorageVersion::get::<Pallet<T>>() < StorageVersion::new(1) {
+ use up_data_structs::{CollectionVersion1, CollectionVersion2};
+ <CollectionById<T>>::translate_values::<CollectionVersion1<T::AccountId>, _>(|v| {
+ Some(CollectionVersion2::from(v))
+ });
+ }
+
+ weight
+ }
+ }
}
impl<T: Config> Pallet<T> {
primitives/data-structs/Cargo.tomldiffbeforeafterboth24sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }24sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }25sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }25sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }26derivative = "2.2.0"26derivative = "2.2.0"27struct-versioning = { path = "../../crates/struct-versioning" }272828[features]29[features]29default = ["std"]30default = ["std"]primitives/data-structs/src/lib.rsdiffbeforeafterboth--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -248,6 +248,7 @@
}
}
+#[struct_versioning::versioned(version = 2, upper)]
#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct Collection<AccountId> {
@@ -265,7 +266,12 @@
pub offchain_schema: BoundedVec<u8, ConstU32<OFFCHAIN_SCHEMA_LIMIT>>,
pub schema_version: SchemaVersion,
pub sponsorship: SponsorshipState<AccountId>,
- pub limits: CollectionLimits, // Collection private restrictions
+
+ #[version(..2)]
+ pub limits: CollectionLimitsVersion1, // Collection private restrictions
+ #[version(2.., upper(limits.into()))]
+ pub limits: CollectionLimitsVersion2,
+
#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
pub variable_on_chain_schema: BoundedVec<u8, ConstU32<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>>,
#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
@@ -321,6 +327,7 @@
}
/// All fields are wrapped in `Option`s, where None means chain default
+#[struct_versioning::versioned(version = 2, upper)]
#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct CollectionLimits {
@@ -338,6 +345,9 @@
pub owner_can_transfer: Option<bool>,
pub owner_can_destroy: Option<bool>,
pub transfers_enabled: Option<bool>,
+
+ #[version(2.., upper(None))]
+ pub nesting_rule: Option<NestingRule>,
}
impl CollectionLimits {
@@ -384,6 +394,26 @@
SponsoringRateLimit::Blocks(v) => Some(v.min(MAX_SPONSOR_TIMEOUT)),
}
}
+ pub fn nesting_rule(&self) -> &NestingRule {
+ static DEFAULT: NestingRule = NestingRule::Owner;
+ self.nesting_rule.as_ref().unwrap_or(&DEFAULT)
+ }
+}
+
+#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen, Derivative)]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
+#[derivative(Debug)]
+pub enum NestingRule {
+ /// No one can nest tokens
+ Disabled,
+ /// Owner can nest any tokens
+ Owner,
+ /// Owner can nest tokens from specified collections
+ OwnerRestricted(
+ #[cfg_attr(feature = "serde1", serde(with = "bounded_set_serde"))]
+ #[derivative(Debug(format_with = "bounded_set_debug"))]
+ BoundedBTreeSet<CollectionId, ConstU32<16>>,
+ ),
}
#[derive(Encode, Decode, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]
@@ -482,6 +512,50 @@
(&v as &BTreeMap<K, V>).fmt(f)
}
+#[cfg(feature = "serde1")]
+#[allow(dead_code)]
+mod bounded_set_serde {
+ use core::convert::TryFrom;
+ use sp_std::collections::btree_set::BTreeSet;
+ use frame_support::{traits::Get, storage::bounded_btree_set::BoundedBTreeSet};
+ use serde::{
+ ser::{self, Serialize},
+ de::{self, Deserialize, Error},
+ };
+ pub fn serialize<D, K, S>(
+ value: &BoundedBTreeSet<K, S>,
+ serializer: D,
+ ) -> Result<D::Ok, D::Error>
+ where
+ D: ser::Serializer,
+ K: Serialize + Ord,
+ {
+ (value as &BTreeSet<_>).serialize(serializer)
+ }
+
+ pub fn deserialize<'de, D, K, S>(deserializer: D) -> Result<BoundedBTreeSet<K, S>, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ K: de::Deserialize<'de> + Ord,
+ S: Get<u32>,
+ {
+ let map = <BTreeSet<K>>::deserialize(deserializer)?;
+ let len = map.len();
+ TryFrom::try_from(map).map_err(|_| D::Error::invalid_length(len, &"lesser size"))
+ }
+}
+
+fn bounded_set_debug<K, S>(
+ v: &BoundedBTreeSet<K, S>,
+ f: &mut fmt::Formatter,
+) -> Result<(), fmt::Error>
+where
+ K: fmt::Debug + Ord,
+{
+ use core::fmt::Debug;
+ (&v as &BTreeSet<K>).fmt(f)
+}
+
#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
#[derivative(Debug)]