git.delta.rocks / unique-network / refs/commits / b69992369f0e

difftreelog

Add first draft of Properties

Daniel Shiposha2022-04-29parent: #c01b00c.patch.diff
in: master

14 files changed

modifiedpallets/common/src/lib.rsdiffbeforeafterboth
1818
19use 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 ),
292
293 CollectionPropertySet(CollectionId, Property),
294
295 TokenPropertySet(CollectionId, TokenId, Property),
291 }296 }
292297
293 #[pallet::error]298 #[pallet::error]
372 QueryKind = OptionQuery,376 QueryKind = OptionQuery,
373 >;377 >;
378
379 /// Collection properties
380 #[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 >;
388
389 #[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 >;
374397
375 /// Large variable-size collection fields are extracted here398 /// Large variable-size collection fields are extracted here
376 #[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 };
645
646 CollectionProperties::<T>::insert(
647 id,
648 Properties::from_collection_props_vec(data.properties)?,
649 );
650
651 let token_props_permissions: PropertiesPermissionMap = data
652 .token_property_permissions
653 .into_iter()
654 .map(|property| (property.key, property.permission))
655 .collect::<BTreeMap<_, _>>()
656 .try_into()
657 .map_err(|_| PropertiesError::PropertyLimitReached)?;
658
659 CollectionPropertyPermissions::<T>::insert(id, token_props_permissions);
619660
620 // Take a (non-refundable) deposit of collection creation661 // Take a (non-refundable) deposit of collection creation
621 {662 {
688 Ok(())729 Ok(())
689 }730 }
731
732 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)?;
738
739 CollectionProperties::<T>::get(collection.id).try_change_property(property)?;
740
741 Ok(())
742 }
743
744 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)?;
751
752 CollectionPropertyPermissions::<T>::try_mutate(collection.id, |permissions| {
753 permissions.try_insert(property_key, permission)
754 })
755 .map_err(|_| PropertiesError::PropertyLimitReached)?;
756
757 Ok(())
758 }
690759
691 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;
947
948 fn change_collection_property(
949 &self,
950 sender: T::CrossAccountId,
951 property: Property,
952 ) -> DispatchResultWithPostInfo;
953
954 fn change_token_property(
955 &self,
956 sender: T::CrossAccountId,
957 token_id: TokenId,
958 property: Property,
959 ) -> DispatchResultWithPostInfo;
877960
878 fn transfer(961 fn transfer(
879 &self,962 &self,
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
21use 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};
2525
26use 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 }
52
53 fn set_property() -> Weight {
54 <SelfWeightOf<T>>::set_property()
55 }
5256
53 fn transfer() -> Weight {57 fn transfer() -> Weight {
54 <SelfWeightOf<T>>::transfer()58 <SelfWeightOf<T>>::transfer()
225 )229 )
226 }230 }
231
232 fn change_collection_property(
233 &self,
234 _sender: T::CrossAccountId,
235 _property: Property,
236 ) -> DispatchResultWithPostInfo {
237 fail!(<Error<T>>::PropertiesNotAllowed)
238 }
239
240 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 }
227248
228 fn set_variable_metadata(249 fn set_variable_metadata(
229 &self,250 &self,
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
61 FungibleItemsDontHaveData,61 FungibleItemsDontHaveData,
62 /// Fungible token does not support nested62 /// Fungible token does not support nested
63 FungibleDisallowsNesting,63 FungibleDisallowsNesting,
64 /// Item properties are not allowed
65 PropertiesNotAllowed,
64 }66 }
6567
66 #[pallet::config]68 #[pallet::config]
modifiedpallets/fungible/src/weights.rsdiffbeforeafterboth
35 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 }
73
74 fn set_property() -> Weight {
75 // Error
76 0
77 }
78
72 // 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 }
136
137 fn set_property() -> Weight {
138 // Error
139 0
140 }
141
129 // Storage: Fungible Balance (r:2 w:2)142 // Storage: Fungible Balance (r:2 w:2)
130 fn transfer() -> Weight {143 fn transfer() -> Weight {
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
1818
19use 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 }
52
53 fn set_property() -> Weight {
54 <SelfWeightOf<T>>::set_property()
55 }
5056
51 fn transfer() -> Weight {57 fn transfer() -> Weight {
52 <SelfWeightOf<T>>::transfer()58 <SelfWeightOf<T>>::transfer()
235 }241 }
236 }242 }
243
244 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 }
256
257 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 }
237269
238 fn set_variable_metadata(270 fn set_variable_metadata(
239 &self,271 &self,
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
20use 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 >;
96
97 #[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 >;
96104
97 /// Used to enumerate tokens owned by account105 /// Used to enumerate tokens owned by account
98 #[pallet::storage]106 #[pallet::storage]
246 Ok(())254 Ok(())
247 }255 }
256
257 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);
267
268 let check_token_owner = || -> DispatchResult {
269 let token_data = <TokenData<T>>::get((collection.id, token_id))
270 .ok_or(<CommonError<T>>::TokenNotFound)?;
271
272 ensure!(&token_data.owner == sender, <CommonError<T>>::NoPermission);
273
274 Ok(())
275 };
276
277 let is_property_exists = TokenProperties::<T>::get((collection.id, token_id))
278 .get_property(&property.key)
279 .is_some();
280
281 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 }
293
294 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {
295 properties.try_change_property(property.clone())
296 })?;
297
298 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertySet(
299 collection.id,
300 token_id,
301 property,
302 ));
303
304 Ok(())
305 }
248306
249 pub fn transfer(307 pub fn transfer(
250 collection: &NonfungibleHandle<T>,308 collection: &NonfungibleHandle<T>,
modifiedpallets/nonfungible/src/weights.rsdiffbeforeafterboth
36 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 }
94
95 fn set_property() -> Weight {
96 // TODO calculate appropriate weight
97 50_000_000 as Weight
98 }
99
93 // 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 }
189
190 fn set_property() -> Weight {
191 // TODO calculate appropriate weight
192 50_000_000 as Weight
193 }
194
182 // 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)
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
20use 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 }
68
69 fn set_property() -> Weight {
70 <SelfWeightOf<T>>::set_property()
71 }
6872
69 fn transfer() -> Weight {73 fn transfer() -> Weight {
70 max_weight_of!(74 max_weight_of!(
244 )248 )
245 }249 }
250
251 fn change_collection_property(
252 &self,
253 _sender: T::CrossAccountId,
254 _property: Property,
255 ) -> DispatchResultWithPostInfo {
256 fail!(<Error<T>>::PropertiesNotAllowed)
257 }
258
259 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 }
246267
247 fn set_variable_metadata(268 fn set_variable_metadata(
248 &self,269 &self,
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
62 WrongRefungiblePieces,62 WrongRefungiblePieces,
63 /// Refungible token can't nest other tokens63 /// Refungible token can't nest other tokens
64 RefungibleDisallowsNesting,64 RefungibleDisallowsNesting,
65 /// Item properties are not allowed
66 PropertiesNotAllowed,
65 }67 }
6668
67 #[pallet::config]69 #[pallet::config]
modifiedpallets/refungible/src/weights.rsdiffbeforeafterboth
38 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 }
133
134 fn set_property() -> Weight {
135 // Error
136 0
137 }
138
132 // 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 }
307
308 fn set_property() -> Weight {
309 // Error
310 0
311 }
312
300 // 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 {
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
39 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::{
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
22};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};
2627
27#[cfg(feature = "serde")]28#[cfg(feature = "serde")]
28use serde::{Serialize, Deserialize};29use serde::{Serialize, Deserialize};
2930
30use 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;
88
89pub const MAX_PROPERTY_KEY_LENGTH: u32 = 256;
90pub const MAX_PROPERTY_VALUE_LENGTH: u32 = 32768;
91pub const MAX_PROPERTIES_PER_ITEM: u32 = 64;
92
93// 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;
96
97pub const MAX_COLLECTION_PROPERTIES_ENCODE_LEN: u32 =
98 MAX_PROPERTIES_PER_ITEM * MAX_PROPERTY_KEY_LENGTH + MAX_COLLECTION_PROPERTIES_SIZE;
99
100pub struct MaxPropertiesPermissionsEncodeLen;
101
102impl Get<u32> for MaxPropertiesPermissionsEncodeLen {
103 fn get() -> u32 {
104 MAX_PROPERTIES_PER_ITEM * MAX_PROPERTY_KEY_LENGTH
105 + <PropertyPermission as MaxEncodedLen>::max_encoded_len() as u32
106 }
107}
87108
88/// How much items can be created per single109/// How much items can be created per single
89/// create_many call110/// create_many call
310 OffchainSchema,331 OffchainSchema,
311}332}
312333
313#[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}
353
354pub type CollectionPropertiesPermissionsVec =
355 BoundedVec<PropertyKeyPermission, MaxPropertiesPermissionsEncodeLen>;
356
357pub type CollectionPropertiesVec =
358 BoundedVec<Property, ConstU32<MAX_COLLECTION_PROPERTIES_ENCODE_LEN>>;
337359
338#[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}
632
633pub type PropertyKey = BoundedVec<u8, ConstU32<MAX_PROPERTY_KEY_LENGTH>>;
634pub type PropertyValue = BoundedVec<u8, ConstU32<MAX_PROPERTY_VALUE_LENGTH>>;
635
636#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]
637pub enum PropertyPermission {
638 None,
639 AdminConst,
640 Admin,
641 ItemOwnerConst,
642 ItemOwner,
643 ItemOwnerOrAdmin,
644}
645
646#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, MaxEncodedLen)]
647pub struct Property {
648 pub key: PropertyKey,
649 pub value: PropertyValue,
650}
651
652#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]
653pub struct PropertyKeyPermission {
654 pub key: PropertyKey,
655 pub permission: PropertyPermission,
656}
657
658pub enum PropertiesError {
659 NoSpaceForProperty,
660 PropertyLimitReached,
661}
662
663impl 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}
673
674pub type PropertiesMap =
675 BoundedBTreeMap<PropertyKey, PropertyValue, ConstU32<MAX_PROPERTIES_PER_ITEM>>;
676pub type PropertiesPermissionMap =
677 BoundedBTreeMap<PropertyKey, PropertyPermission, ConstU32<MAX_PROPERTIES_PER_ITEM>>;
678
679#[derive(Encode, Decode, TypeInfo, Clone, PartialEq, MaxEncodedLen)]
680pub struct Properties {
681 map: PropertiesMap,
682 consumed_space: u32,
683 space_limit: u32,
684}
685
686impl Properties {
687 pub fn new(space_limit: u32) -> Self {
688 Self {
689 map: BoundedBTreeMap::new(),
690 consumed_space: 0,
691 space_limit,
692 }
693 }
694
695 pub fn from_collection_props_vec(
696 data: CollectionPropertiesVec,
697 ) -> Result<Self, PropertiesError> {
698 let mut props = Self::new(MAX_COLLECTION_PROPERTIES_SIZE);
699
700 for property in data.into_iter() {
701 props.try_change_property(property)?;
702 }
703
704 Ok(props)
705 }
706
707 pub fn try_change_property(&mut self, property: Property) -> Result<(), PropertiesError> {
708 let value_len = property.value.len();
709
710 if self.consumed_space as usize + value_len > self.space_limit as usize {
711 return Err(PropertiesError::NoSpaceForProperty);
712 }
713
714 self.map
715 .try_insert(property.key, property.value)
716 .map_err(|_| PropertiesError::PropertyLimitReached)?;
717
718 self.consumed_space += value_len as u32;
719
720 Ok(())
721 }
722
723 pub fn get_property(&self, key: &PropertyKey) -> Option<&PropertyValue> {
724 self.map.get(key)
725 }
726}
727
728pub struct CollectionProperties;
729
730impl Get<Properties> for CollectionProperties {
731 fn get() -> Properties {
732 Properties::new(MAX_COLLECTION_PROPERTIES_SIZE)
733 }
734}
735
736pub struct TokenProperties;
737
738impl Get<Properties> for TokenProperties {
739 fn get() -> Properties {
740 Properties::new(MAX_TOKEN_PROPERTIES_SIZE)
741 }
742}
743
744// #[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// }
748
749// #[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// }
610757
modifiedprimitives/rpc/src/lib.rsdiffbeforeafterboth
17#![cfg_attr(not(feature = "std"), no_std)]17#![cfg_attr(not(feature = "std"), no_std)]
1818
19use 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;
modifiedruntime/common/src/weights.rsdiffbeforeafterboth
54 dispatch_weight::<T>() + max_weight_of!(burn_item())54 dispatch_weight::<T>() + max_weight_of!(burn_item())
55 }55 }
56
57 fn set_property() -> Weight {
58 dispatch_weight::<T>() + max_weight_of!(set_property())
59 }
5660
57 fn transfer() -> Weight {61 fn transfer() -> Weight {
58 dispatch_weight::<T>() + max_weight_of!(transfer())62 dispatch_weight::<T>() + max_weight_of!(transfer())