difftreelog
Add first draft of Properties
in: master
14 files changed
pallets/common/src/lib.rsdiffbeforeafterboth181819use core::ops::{Deref, DerefMut};19use core::ops::{Deref, DerefMut};20use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};20use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};21use sp_std::vec::Vec;21use sp_std::{vec::Vec, collections::btree_map::BTreeMap};22use pallet_evm::account::CrossAccountId;22use pallet_evm::account::CrossAccountId;23use frame_support::{23use frame_support::{24 dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Weight, PostDispatchInfo},24 dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Weight, PostDispatchInfo},35 FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MAX_SPONSOR_TIMEOUT,35 FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MAX_SPONSOR_TIMEOUT,36 CUSTOM_DATA_LIMIT, CollectionLimits, CustomDataLimit, CreateCollectionData, SponsorshipState,36 CUSTOM_DATA_LIMIT, CollectionLimits, CustomDataLimit, CreateCollectionData, SponsorshipState,37 CreateItemExData, SponsoringRateLimit, budget::Budget, COLLECTION_FIELD_LIMIT, CollectionField,37 CreateItemExData, SponsoringRateLimit, budget::Budget, COLLECTION_FIELD_LIMIT, CollectionField,38 PhantomType,38 PhantomType, Property, Properties, PropertiesPermissionMap, PropertyKey, PropertyPermission,39 PropertiesError,39};40};40pub use pallet::*;41pub use pallet::*;41use sp_core::H160;42use sp_core::H160;289 u128,290 u128,290 ),291 ),292293 CollectionPropertySet(CollectionId, Property),294295 TokenPropertySet(CollectionId, TokenId, Property),291 }296 }292297293 #[pallet::error]298 #[pallet::error]372 QueryKind = OptionQuery,376 QueryKind = OptionQuery,373 >;377 >;378379 /// Collection properties380 #[pallet::storage]381 pub type CollectionProperties<T> = StorageMap<382 Hasher = Blake2_128Concat,383 Key = CollectionId,384 Value = Properties,385 QueryKind = ValueQuery,386 OnEmpty = up_data_structs::CollectionProperties,387 >;388389 #[pallet::storage]390 #[pallet::getter(fn property_permission)]391 pub type CollectionPropertyPermissions<T> = StorageMap<392 Hasher = Blake2_128Concat,393 Key = CollectionId,394 Value = PropertiesPermissionMap,395 QueryKind = ValueQuery,396 >;374397375 /// Large variable-size collection fields are extracted here398 /// Large variable-size collection fields are extracted here376 #[pallet::storage]399 #[pallet::storage]538 sponsorship,561 sponsorship,539 limits,562 limits,540 meta_update_permission,563 meta_update_permission,564 ..541 } = <CollectionById<T>>::get(collection)?;565 } = <CollectionById<T>>::get(collection)?;542 Some(RpcCollection {566 Some(RpcCollection {543 name: name.into_inner(),567 name: name.into_inner(),615 .map(|limits| Self::clamp_limits(data.mode.clone(), &Default::default(), limits))639 .map(|limits| Self::clamp_limits(data.mode.clone(), &Default::default(), limits))616 .unwrap_or_else(|| Ok(CollectionLimits::default()))?,640 .unwrap_or_else(|| Ok(CollectionLimits::default()))?,617 meta_update_permission: data.meta_update_permission.unwrap_or_default(),641 meta_update_permission: data.meta_update_permission.unwrap_or_default(),642 // token_property_permissions: data.token_property_permissions.unwrap_or_default(),643 // properties: Properties::from_collection_props_vec(data.properties)?618 };644 };645646 CollectionProperties::<T>::insert(647 id,648 Properties::from_collection_props_vec(data.properties)?,649 );650651 let token_props_permissions: PropertiesPermissionMap = data652 .token_property_permissions653 .into_iter()654 .map(|property| (property.key, property.permission))655 .collect::<BTreeMap<_, _>>()656 .try_into()657 .map_err(|_| PropertiesError::PropertyLimitReached)?;658659 CollectionPropertyPermissions::<T>::insert(id, token_props_permissions);619660620 // Take a (non-refundable) deposit of collection creation661 // Take a (non-refundable) deposit of collection creation621 {662 {688 Ok(())729 Ok(())689 }730 }731732 pub fn change_collection_property(733 collection: &CollectionHandle<T>,734 sender: &T::CrossAccountId,735 property: Property,736 ) -> DispatchResult {737 collection.check_is_owner_or_admin(sender)?;738739 CollectionProperties::<T>::get(collection.id).try_change_property(property)?;740741 Ok(())742 }743744 pub fn change_property_permission(745 collection: &CollectionHandle<T>,746 sender: &T::CrossAccountId,747 property_key: PropertyKey,748 permission: PropertyPermission,749 ) -> DispatchResult {750 collection.check_is_owner_or_admin(sender)?;751752 CollectionPropertyPermissions::<T>::try_mutate(collection.id, |permissions| {753 permissions.try_insert(property_key, permission)754 })755 .map_err(|_| PropertiesError::PropertyLimitReached)?;756757 Ok(())758 }690759691 fn set_field_raw(760 fn set_field_raw(692 collection_id: CollectionId,761 collection_id: CollectionId,840 fn create_multiple_items(amount: u32) -> Weight;909 fn create_multiple_items(amount: u32) -> Weight;841 fn create_multiple_items_ex(cost: &CreateItemExData<CrossAccountId>) -> Weight;910 fn create_multiple_items_ex(cost: &CreateItemExData<CrossAccountId>) -> Weight;842 fn burn_item() -> Weight;911 fn burn_item() -> Weight;912 fn set_property() -> Weight;843 fn transfer() -> Weight;913 fn transfer() -> Weight;844 fn approve() -> Weight;914 fn approve() -> Weight;845 fn transfer_from() -> Weight;915 fn transfer_from() -> Weight;875 amount: u128,945 amount: u128,876 ) -> DispatchResultWithPostInfo;946 ) -> DispatchResultWithPostInfo;947948 fn change_collection_property(949 &self,950 sender: T::CrossAccountId,951 property: Property,952 ) -> DispatchResultWithPostInfo;953954 fn change_token_property(955 &self,956 sender: T::CrossAccountId,957 token_id: TokenId,958 property: Property,959 ) -> DispatchResultWithPostInfo;877960878 fn transfer(961 fn transfer(879 &self,962 &self,pallets/fungible/src/common.rsdiffbeforeafterboth21use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};21use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};22use sp_runtime::ArithmeticError;22use sp_runtime::ArithmeticError;23use sp_std::{vec::Vec, vec};23use sp_std::{vec::Vec, vec};24use up_data_structs::CustomDataLimit;24use up_data_structs::{CustomDataLimit, Property};252526use crate::{26use crate::{27 Allowance, Balance, Config, Error, FungibleHandle, Pallet, SelfWeightOf, weights::WeightInfo,27 Allowance, Balance, Config, Error, FungibleHandle, Pallet, SelfWeightOf, weights::WeightInfo,50 <SelfWeightOf<T>>::burn_item()50 <SelfWeightOf<T>>::burn_item()51 }51 }5253 fn set_property() -> Weight {54 <SelfWeightOf<T>>::set_property()55 }525653 fn transfer() -> Weight {57 fn transfer() -> Weight {54 <SelfWeightOf<T>>::transfer()58 <SelfWeightOf<T>>::transfer()225 )229 )226 }230 }231232 fn change_collection_property(233 &self,234 _sender: T::CrossAccountId,235 _property: Property,236 ) -> DispatchResultWithPostInfo {237 fail!(<Error<T>>::PropertiesNotAllowed)238 }239240 fn change_token_property(241 &self,242 _sender: T::CrossAccountId,243 _token_id: TokenId,244 _property: Property,245 ) -> DispatchResultWithPostInfo {246 fail!(<Error<T>>::PropertiesNotAllowed)247 }227248228 fn set_variable_metadata(249 fn set_variable_metadata(229 &self,250 &self,pallets/fungible/src/lib.rsdiffbeforeafterboth61 FungibleItemsDontHaveData,61 FungibleItemsDontHaveData,62 /// Fungible token does not support nested62 /// Fungible token does not support nested63 FungibleDisallowsNesting,63 FungibleDisallowsNesting,64 /// Item properties are not allowed65 PropertiesNotAllowed,64 }66 }656766 #[pallet::config]68 #[pallet::config]pallets/fungible/src/weights.rsdiffbeforeafterboth35 fn create_item() -> Weight;35 fn create_item() -> Weight;36 fn create_multiple_items_ex(b: u32, ) -> Weight;36 fn create_multiple_items_ex(b: u32, ) -> Weight;37 fn burn_item() -> Weight;37 fn burn_item() -> Weight;38 fn set_property() -> Weight;38 fn transfer() -> Weight;39 fn transfer() -> Weight;39 fn approve() -> Weight;40 fn approve() -> Weight;40 fn transfer_from() -> Weight;41 fn transfer_from() -> Weight;70 .saturating_add(T::DbWeight::get().writes(2 as Weight))71 .saturating_add(T::DbWeight::get().writes(2 as Weight))71 }72 }7374 fn set_property() -> Weight {75 // Error76 077 }7872 // Storage: Fungible Balance (r:2 w:2)79 // Storage: Fungible Balance (r:2 w:2)73 fn transfer() -> Weight {80 fn transfer() -> Weight {127 .saturating_add(RocksDbWeight::get().writes(2 as Weight))134 .saturating_add(RocksDbWeight::get().writes(2 as Weight))128 }135 }136137 fn set_property() -> Weight {138 // Error139 0140 }141129 // Storage: Fungible Balance (r:2 w:2)142 // Storage: Fungible Balance (r:2 w:2)130 fn transfer() -> Weight {143 fn transfer() -> Weight {pallets/nonfungible/src/common.rsdiffbeforeafterboth181819use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};19use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};20use up_data_structs::{TokenId, CustomDataLimit, CreateItemExData, CollectionId, budget::Budget};20use up_data_structs::{21 TokenId, CustomDataLimit, CreateItemExData, CollectionId, budget::Budget, Property,22};21use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};23use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};22use sp_runtime::DispatchError;24use sp_runtime::DispatchError;48 <SelfWeightOf<T>>::burn_item()50 <SelfWeightOf<T>>::burn_item()49 }51 }5253 fn set_property() -> Weight {54 <SelfWeightOf<T>>::set_property()55 }505651 fn transfer() -> Weight {57 fn transfer() -> Weight {52 <SelfWeightOf<T>>::transfer()58 <SelfWeightOf<T>>::transfer()235 }241 }236 }242 }243244 fn change_collection_property(245 &self,246 sender: T::CrossAccountId,247 property: Property,248 ) -> DispatchResultWithPostInfo {249 // let token_id = None;250 with_weight(251 // <Pallet<T>>::change_property(self, &sender, token_id, property),252 Ok(()),253 <CommonWeights<T>>::set_property(),254 )255 }256257 fn change_token_property(258 &self,259 sender: T::CrossAccountId,260 token_id: TokenId,261 property: Property,262 ) -> DispatchResultWithPostInfo {263 with_weight(264 // <Pallet<T>>::change_property(self, &sender, Some(token_id), property),265 Ok(()),266 <CommonWeights<T>>::set_property(),267 )268 }237269238 fn set_variable_metadata(270 fn set_variable_metadata(239 &self,271 &self,pallets/nonfungible/src/lib.rsdiffbeforeafterboth20use frame_support::{BoundedVec, ensure, fail};20use frame_support::{BoundedVec, ensure, fail};21use up_data_structs::{21use up_data_structs::{22 AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData, CreateNftExData,22 AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData, CreateNftExData,23 mapping::TokenAddressMapping, NestingRule, budget::Budget,23 mapping::TokenAddressMapping, NestingRule, budget::Budget, Property, PropertyPermission,24};24};25use pallet_evm::account::CrossAccountId;25use pallet_evm::account::CrossAccountId;26use pallet_common::{26use pallet_common::{94 QueryKind = OptionQuery,94 QueryKind = OptionQuery,95 >;95 >;9697 #[pallet::storage]98 pub type TokenProperties<T: Config> = StorageNMap<99 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),100 Value = up_data_structs::Properties,101 QueryKind = ValueQuery,102 OnEmpty = up_data_structs::TokenProperties,103 >;9610497 /// Used to enumerate tokens owned by account105 /// Used to enumerate tokens owned by account98 #[pallet::storage]106 #[pallet::storage]246 Ok(())254 Ok(())247 }255 }256257 pub fn change_token_property(258 collection: &NonfungibleHandle<T>,259 sender: &T::CrossAccountId,260 token_id: TokenId,261 property: Property,262 ) -> DispatchResult {263 let permission = <PalletCommon<T>>::property_permission(collection.id)264 .get(&property.key)265 .map(|p| p.clone())266 .unwrap_or(PropertyPermission::None);267268 let check_token_owner = || -> DispatchResult {269 let token_data = <TokenData<T>>::get((collection.id, token_id))270 .ok_or(<CommonError<T>>::TokenNotFound)?;271272 ensure!(&token_data.owner == sender, <CommonError<T>>::NoPermission);273274 Ok(())275 };276277 let is_property_exists = TokenProperties::<T>::get((collection.id, token_id))278 .get_property(&property.key)279 .is_some();280281 match (permission, is_property_exists) {282 (PropertyPermission::AdminConst, false) => {283 collection.check_is_owner_or_admin(sender)?284 }285 (PropertyPermission::Admin, _) => collection.check_is_owner_or_admin(sender)?,286 (PropertyPermission::ItemOwnerConst, false) => check_token_owner()?,287 (PropertyPermission::ItemOwner, _) => check_token_owner()?,288 (PropertyPermission::ItemOwnerOrAdmin, _) => {289 check_token_owner().or(collection.check_is_owner_or_admin(sender))?;290 }291 _ => return Err(<CommonError<T>>::NoPermission.into()),292 }293294 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {295 properties.try_change_property(property.clone())296 })?;297298 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertySet(299 collection.id,300 token_id,301 property,302 ));303304 Ok(())305 }248306249 pub fn transfer(307 pub fn transfer(250 collection: &NonfungibleHandle<T>,308 collection: &NonfungibleHandle<T>,pallets/nonfungible/src/weights.rsdiffbeforeafterboth36 fn create_multiple_items(b: u32, ) -> Weight;36 fn create_multiple_items(b: u32, ) -> Weight;37 fn create_multiple_items_ex(b: u32, ) -> Weight;37 fn create_multiple_items_ex(b: u32, ) -> Weight;38 fn burn_item() -> Weight;38 fn burn_item() -> Weight;39 fn set_property() -> Weight;39 fn transfer() -> Weight;40 fn transfer() -> Weight;40 fn approve() -> Weight;41 fn approve() -> Weight;41 fn transfer_from() -> Weight;42 fn transfer_from() -> Weight;91 .saturating_add(T::DbWeight::get().writes(4 as Weight))92 .saturating_add(T::DbWeight::get().writes(4 as Weight))92 }93 }9495 fn set_property() -> Weight {96 // TODO calculate appropriate weight97 50_000_000 as Weight98 }9993 // Storage: Nonfungible TokenData (r:1 w:1)100 // Storage: Nonfungible TokenData (r:1 w:1)94 // Storage: Nonfungible AccountBalance (r:2 w:2)101 // Storage: Nonfungible AccountBalance (r:2 w:2)180 .saturating_add(RocksDbWeight::get().writes(4 as Weight))187 .saturating_add(RocksDbWeight::get().writes(4 as Weight))181 }188 }189190 fn set_property() -> Weight {191 // TODO calculate appropriate weight192 50_000_000 as Weight193 }194182 // Storage: Nonfungible TokenData (r:1 w:1)195 // Storage: Nonfungible TokenData (r:1 w:1)183 // Storage: Nonfungible AccountBalance (r:2 w:2)196 // Storage: Nonfungible AccountBalance (r:2 w:2)pallets/refungible/src/common.rsdiffbeforeafterboth20use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};20use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};21use up_data_structs::{21use up_data_structs::{22 CollectionId, TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData,22 CollectionId, TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData,23 budget::Budget,23 budget::Budget, Property,24};24};25use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};25use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};26use sp_runtime::DispatchError;26use sp_runtime::DispatchError;66 max_weight_of!(burn_item_partial(), burn_item_fully())66 max_weight_of!(burn_item_partial(), burn_item_fully())67 }67 }6869 fn set_property() -> Weight {70 <SelfWeightOf<T>>::set_property()71 }687269 fn transfer() -> Weight {73 fn transfer() -> Weight {70 max_weight_of!(74 max_weight_of!(244 )248 )245 }249 }250251 fn change_collection_property(252 &self,253 _sender: T::CrossAccountId,254 _property: Property,255 ) -> DispatchResultWithPostInfo {256 fail!(<Error<T>>::PropertiesNotAllowed)257 }258259 fn change_token_property(260 &self,261 _sender: T::CrossAccountId,262 _token_id: TokenId,263 _property: Property,264 ) -> DispatchResultWithPostInfo {265 fail!(<Error<T>>::PropertiesNotAllowed)266 }246267247 fn set_variable_metadata(268 fn set_variable_metadata(248 &self,269 &self,pallets/refungible/src/lib.rsdiffbeforeafterboth62 WrongRefungiblePieces,62 WrongRefungiblePieces,63 /// Refungible token can't nest other tokens63 /// Refungible token can't nest other tokens64 RefungibleDisallowsNesting,64 RefungibleDisallowsNesting,65 /// Item properties are not allowed66 PropertiesNotAllowed,65 }67 }666867 #[pallet::config]69 #[pallet::config]pallets/refungible/src/weights.rsdiffbeforeafterboth38 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight;38 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight;39 fn burn_item_partial() -> Weight;39 fn burn_item_partial() -> Weight;40 fn burn_item_fully() -> Weight;40 fn burn_item_fully() -> Weight;41 fn set_property() -> Weight;41 fn transfer_normal() -> Weight;42 fn transfer_normal() -> Weight;42 fn transfer_creating() -> Weight;43 fn transfer_creating() -> Weight;43 fn transfer_removing() -> Weight;44 fn transfer_removing() -> Weight;130 .saturating_add(T::DbWeight::get().writes(6 as Weight))131 .saturating_add(T::DbWeight::get().writes(6 as Weight))131 }132 }133134 fn set_property() -> Weight {135 // Error136 0137 }138132 // Storage: Refungible Balance (r:2 w:2)139 // Storage: Refungible Balance (r:2 w:2)133 fn transfer_normal() -> Weight {140 fn transfer_normal() -> Weight {298 .saturating_add(RocksDbWeight::get().writes(6 as Weight))305 .saturating_add(RocksDbWeight::get().writes(6 as Weight))299 }306 }307308 fn set_property() -> Weight {309 // Error310 0311 }312300 // Storage: Refungible Balance (r:2 w:2)313 // Storage: Refungible Balance (r:2 w:2)301 fn transfer_normal() -> Weight {314 fn transfer_normal() -> Weight {pallets/unique/src/lib.rsdiffbeforeafterboth39 MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,39 MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,40 AccessMode, CreateItemData, CollectionLimits, CollectionId, CollectionMode, TokenId,40 AccessMode, CreateItemData, CollectionLimits, CollectionId, CollectionMode, TokenId,41 SchemaVersion, SponsorshipState, MetaUpdatePermission, CreateCollectionData, CustomDataLimit,41 SchemaVersion, SponsorshipState, MetaUpdatePermission, CreateCollectionData, CustomDataLimit,42 CreateItemExData, budget, CollectionField,42 CreateItemExData, budget, CollectionField, Property,43};43};44use pallet_evm::account::CrossAccountId;44use pallet_evm::account::CrossAccountId;45use pallet_common::{45use pallet_common::{primitives/data-structs/src/lib.rsdiffbeforeafterboth22};22};23use frame_support::{23use frame_support::{24 storage::{bounded_btree_map::BoundedBTreeMap, bounded_btree_set::BoundedBTreeSet},24 storage::{bounded_btree_map::BoundedBTreeMap, bounded_btree_set::BoundedBTreeSet},25 traits::Get,25};26};262727#[cfg(feature = "serde")]28#[cfg(feature = "serde")]28use serde::{Serialize, Deserialize};29use serde::{Serialize, Deserialize};293030use sp_core::U256;31use sp_core::U256;31use sp_runtime::{ArithmeticError, sp_std::prelude::Vec};32use sp_runtime::{ArithmeticError, sp_std::prelude::Vec, DispatchError};32use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};33use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};33use frame_support::{BoundedVec, traits::ConstU32};34use frame_support::{BoundedVec, traits::ConstU32};34use derivative::Derivative;35use derivative::Derivative;85pub const MAX_COLLECTION_DESCRIPTION_LENGTH: u32 = 256;86pub const MAX_COLLECTION_DESCRIPTION_LENGTH: u32 = 256;86pub const MAX_TOKEN_PREFIX_LENGTH: u32 = 16;87pub const MAX_TOKEN_PREFIX_LENGTH: u32 = 16;8889pub const MAX_PROPERTY_KEY_LENGTH: u32 = 256;90pub const MAX_PROPERTY_VALUE_LENGTH: u32 = 32768;91pub const MAX_PROPERTIES_PER_ITEM: u32 = 64;9293// pub const MAX_PROPERTY_KEYS_OVERALL_LENGTH: u32 = MAX_PROPERTY_KEY_LENGTH * MAX_PROPERTIES_PER_ITEM;94pub const MAX_COLLECTION_PROPERTIES_SIZE: u32 = 40960;95pub const MAX_TOKEN_PROPERTIES_SIZE: u32 = 32768;9697pub const MAX_COLLECTION_PROPERTIES_ENCODE_LEN: u32 =98 MAX_PROPERTIES_PER_ITEM * MAX_PROPERTY_KEY_LENGTH + MAX_COLLECTION_PROPERTIES_SIZE;99100pub struct MaxPropertiesPermissionsEncodeLen;101102impl Get<u32> for MaxPropertiesPermissionsEncodeLen {103 fn get() -> u32 {104 MAX_PROPERTIES_PER_ITEM * MAX_PROPERTY_KEY_LENGTH105 + <PropertyPermission as MaxEncodedLen>::max_encoded_len() as u32106 }107}8710888/// How much items can be created per single109/// How much items can be created per single89/// create_many call110/// create_many call310 OffchainSchema,331 OffchainSchema,311}332}312333313#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, Debug, Derivative, MaxEncodedLen)]334#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, Derivative, MaxEncodedLen)]314#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]315#[derivative(Default(bound = ""))]335#[derivative(Debug, Default(bound = ""))]316pub struct CreateCollectionData<AccountId> {336pub struct CreateCollectionData<AccountId> {317 #[derivative(Default(value = "CollectionMode::NFT"))]337 #[derivative(Default(value = "CollectionMode::NFT"))]318 pub mode: CollectionMode,338 pub mode: CollectionMode,319 pub access: Option<AccessMode>,339 pub access: Option<AccessMode>,320 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]321 pub name: BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>,340 pub name: BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>,322 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]323 pub description: BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>,341 pub description: BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>,324 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]325 pub token_prefix: BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>,342 pub token_prefix: BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>,326 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]327 pub offchain_schema: BoundedVec<u8, ConstU32<OFFCHAIN_SCHEMA_LIMIT>>,343 pub offchain_schema: BoundedVec<u8, ConstU32<OFFCHAIN_SCHEMA_LIMIT>>,328 pub schema_version: Option<SchemaVersion>,344 pub schema_version: Option<SchemaVersion>,329 pub pending_sponsor: Option<AccountId>,345 pub pending_sponsor: Option<AccountId>,330 pub limits: Option<CollectionLimits>,346 pub limits: Option<CollectionLimits>,331 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]332 pub variable_on_chain_schema: BoundedVec<u8, ConstU32<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>>,347 pub variable_on_chain_schema: BoundedVec<u8, ConstU32<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>>,333 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]334 pub const_on_chain_schema: BoundedVec<u8, ConstU32<CONST_ON_CHAIN_SCHEMA_LIMIT>>,348 pub const_on_chain_schema: BoundedVec<u8, ConstU32<CONST_ON_CHAIN_SCHEMA_LIMIT>>,335 pub meta_update_permission: Option<MetaUpdatePermission>,349 pub meta_update_permission: Option<MetaUpdatePermission>,350 pub token_property_permissions: CollectionPropertiesPermissionsVec,351 pub properties: CollectionPropertiesVec,336}352}353354pub type CollectionPropertiesPermissionsVec =355 BoundedVec<PropertyKeyPermission, MaxPropertiesPermissionsEncodeLen>;356357pub type CollectionPropertiesVec =358 BoundedVec<Property, ConstU32<MAX_COLLECTION_PROPERTIES_ENCODE_LEN>>;337359338#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]360#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]339#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]361#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]608 }630 }609}631}632633pub type PropertyKey = BoundedVec<u8, ConstU32<MAX_PROPERTY_KEY_LENGTH>>;634pub type PropertyValue = BoundedVec<u8, ConstU32<MAX_PROPERTY_VALUE_LENGTH>>;635636#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]637pub enum PropertyPermission {638 None,639 AdminConst,640 Admin,641 ItemOwnerConst,642 ItemOwner,643 ItemOwnerOrAdmin,644}645646#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, MaxEncodedLen)]647pub struct Property {648 pub key: PropertyKey,649 pub value: PropertyValue,650}651652#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]653pub struct PropertyKeyPermission {654 pub key: PropertyKey,655 pub permission: PropertyPermission,656}657658pub enum PropertiesError {659 NoSpaceForProperty,660 PropertyLimitReached,661}662663impl From<PropertiesError> for DispatchError {664 fn from(error: PropertiesError) -> Self {665 match error {666 PropertiesError::NoSpaceForProperty => DispatchError::Other("no space for property"),667 PropertiesError::PropertyLimitReached => {668 DispatchError::Other("property key limit reached")669 }670 }671 }672}673674pub type PropertiesMap =675 BoundedBTreeMap<PropertyKey, PropertyValue, ConstU32<MAX_PROPERTIES_PER_ITEM>>;676pub type PropertiesPermissionMap =677 BoundedBTreeMap<PropertyKey, PropertyPermission, ConstU32<MAX_PROPERTIES_PER_ITEM>>;678679#[derive(Encode, Decode, TypeInfo, Clone, PartialEq, MaxEncodedLen)]680pub struct Properties {681 map: PropertiesMap,682 consumed_space: u32,683 space_limit: u32,684}685686impl Properties {687 pub fn new(space_limit: u32) -> Self {688 Self {689 map: BoundedBTreeMap::new(),690 consumed_space: 0,691 space_limit,692 }693 }694695 pub fn from_collection_props_vec(696 data: CollectionPropertiesVec,697 ) -> Result<Self, PropertiesError> {698 let mut props = Self::new(MAX_COLLECTION_PROPERTIES_SIZE);699700 for property in data.into_iter() {701 props.try_change_property(property)?;702 }703704 Ok(props)705 }706707 pub fn try_change_property(&mut self, property: Property) -> Result<(), PropertiesError> {708 let value_len = property.value.len();709710 if self.consumed_space as usize + value_len > self.space_limit as usize {711 return Err(PropertiesError::NoSpaceForProperty);712 }713714 self.map715 .try_insert(property.key, property.value)716 .map_err(|_| PropertiesError::PropertyLimitReached)?;717718 self.consumed_space += value_len as u32;719720 Ok(())721 }722723 pub fn get_property(&self, key: &PropertyKey) -> Option<&PropertyValue> {724 self.map.get(key)725 }726}727728pub struct CollectionProperties;729730impl Get<Properties> for CollectionProperties {731 fn get() -> Properties {732 Properties::new(MAX_COLLECTION_PROPERTIES_SIZE)733 }734}735736pub struct TokenProperties;737738impl Get<Properties> for TokenProperties {739 fn get() -> Properties {740 Properties::new(MAX_TOKEN_PROPERTIES_SIZE)741 }742}743744// #[cfg(not(feature = "std"))]745// fn properties_map_debug(_properties: &PropertiesMap, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {746// write!(f, "<properties>")747// }748749// #[cfg(not(feature = "std"))]750// fn opt_properties_permissions_map_debug(properties: &Option<PropertiesPermissionMap>, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {751// if properties.is_some() {752// write!(f, "Some(<properties permissions>)")753// } else {754// write!(f, "None")755// }756// }610757primitives/rpc/src/lib.rsdiffbeforeafterboth17#![cfg_attr(not(feature = "std"), no_std)]17#![cfg_attr(not(feature = "std"), no_std)]181819use up_data_structs::{CollectionId, TokenId, RpcCollection, CollectionStats, CollectionLimits};19use up_data_structs::{20 CollectionId, TokenId, RpcCollection, CollectionStats, CollectionLimits, Property,21};20use sp_std::vec::Vec;22use sp_std::vec::Vec;21use codec::Decode;23use codec::Decode;runtime/common/src/weights.rsdiffbeforeafterboth54 dispatch_weight::<T>() + max_weight_of!(burn_item())54 dispatch_weight::<T>() + max_weight_of!(burn_item())55 }55 }5657 fn set_property() -> Weight {58 dispatch_weight::<T>() + max_weight_of!(set_property())59 }566057 fn transfer() -> Weight {61 fn transfer() -> Weight {58 dispatch_weight::<T>() + max_weight_of!(transfer())62 dispatch_weight::<T>() + max_weight_of!(transfer())