difftreelog
Merge branch 'develop' into feature/CORE-189
in: master
9 files changed
node/cli/src/chain_spec.rsdiffbeforeafterboth196 const_on_chain_schema: vec![],196 const_on_chain_schema: vec![],197 variable_on_chain_schema: vec![],197 variable_on_chain_schema: vec![],198 limits: CollectionLimits::default(),198 limits: CollectionLimits::default(),199 meta_update_permission: MetaUpdatePermission::ItemOwner,199 transfers_enabled: true,200 transfers_enabled: true,200 },201 },201 )],202 )],pallets/nft/src/lib.rsdiffbeforeafterboth43 OFFCHAIN_SCHEMA_LIMIT, MAX_TOKEN_PREFIX_LENGTH, MAX_COLLECTION_NAME_LENGTH,43 OFFCHAIN_SCHEMA_LIMIT, MAX_TOKEN_PREFIX_LENGTH, MAX_COLLECTION_NAME_LENGTH,44 MAX_COLLECTION_DESCRIPTION_LENGTH, AccessMode, Collection, CreateItemData, CollectionLimits,44 MAX_COLLECTION_DESCRIPTION_LENGTH, AccessMode, Collection, CreateItemData, CollectionLimits,45 CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, Ownership, NftItemType,45 CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, Ownership, NftItemType,46 FungibleItemType, ReFungibleItemType,46 MetaUpdatePermission, FungibleItemType, ReFungibleItemType,47};47};484849#[cfg(test)]49#[cfg(test)]145 BadCreateRefungibleCall,145 BadCreateRefungibleCall,146 /// Gas limit exceeded146 /// Gas limit exceeded147 OutOfGas,147 OutOfGas,148 /// Metadata update denied by collection settings149 MetadataUpdateDenied,150 /// Metadata update flag become unmutable with None option151 MetadataFlagFrozen,148 /// Collection settings not allowing items transferring152 /// Collection settings not allowing items transferring149 TransferNotAllowed,153 TransferNotAllowed,150 /// Can't transfer tokens to ethereum zero address154 /// Can't transfer tokens to ethereum zero address541 variable_on_chain_schema: Vec::new(),545 variable_on_chain_schema: Vec::new(),542 const_on_chain_schema: Vec::new(),546 const_on_chain_schema: Vec::new(),543 limits,547 limits,548 meta_update_permission: MetaUpdatePermission::default(),544 transfers_enabled: true,549 transfers_enabled: true,545 };550 };546551940 target_collection.save()945 target_collection.save()941 }946 }947948 // TODO! transaction weight949 /// Set meta_update_permission value for particular collection950 ///951 /// # Permissions952 ///953 /// * Collection Owner.954 ///955 /// # Arguments956 ///957 /// * collection_id: ID of the collection.958 ///959 /// * value: New flag value.960 #[weight = <T as Config>::WeightInfo::burn_item()]961 #[transactional]962 pub fn set_meta_update_permission_flag(origin, collection_id: CollectionId, value: MetaUpdatePermission) -> DispatchResult {963964 let sender = ensure_signed(origin)?;965 let mut target_collection = Self::get_collection(collection_id)?;966967 ensure!(968 target_collection.meta_update_permission != MetaUpdatePermission::None,969 Error::<T>::MetadataFlagFrozen970 );971 Self::check_owner_permissions(&target_collection, &sender)?;972973 target_collection.meta_update_permission = value;974975 target_collection.save()976 }942977943 /// Destroys a concrete instance of NFT.978 /// Destroys a concrete instance of NFT.944 ///979 ///1485 Error::<T>::TokenVariableDataLimitExceeded1520 Error::<T>::TokenVariableDataLimitExceeded1486 );1521 );148715221488 // Modify permissions check1489 ensure!(1523 ensure!(1490 Self::is_item_owner(sender, collection, item_id)?1524 (Self::is_item_owner(sender, collection, item_id)?1525 && collection.meta_update_permission == MetaUpdatePermission::ItemOwner)1491 || Self::is_owner_or_admin_permissions(collection, sender)?,1526 || (Self::is_owner_or_admin_permissions(collection, sender)?1527 && collection.meta_update_permission == MetaUpdatePermission::Admin),1492 Error::<T>::NoPermission1528 Error::<T>::NoPermission1493 );1529 );149415301504 Ok(())1540 Ok(())1505 }1541 }15421543 pub fn meta_update_check(1544 sender: &T::CrossAccountId,1545 collection: &CollectionHandle<T>,1546 item_id: TokenId,1547 ) -> DispatchResult {1548 match collection.meta_update_permission {1549 MetaUpdatePermission::ItemOwner => ensure!(1550 Self::is_item_owner(sender, collection, item_id)?,1551 Error::<T>::NoPermission1552 ),1553 MetaUpdatePermission::Admin => ensure!(1554 Self::is_owner_or_admin_permissions(collection, sender)?,1555 Error::<T>::NoPermission1556 ),1557 MetaUpdatePermission::None => fail!(Error::<T>::MetadataUpdateDenied),1558 }15591560 Ok(())1561 }150615621507 pub fn get_variable_metadata(1563 pub fn get_variable_metadata(1508 collection: &CollectionHandle<T>,1564 collection: &CollectionHandle<T>,pallets/nft/src/tests.rsdiffbeforeafterboth2004 });2004 });2005}2005}20062007#[test]2008fn set_variable_meta_data_on_nft_with_item_owner_permission_flag() {2009 new_test_ext().execute_with(|| {2010 //default_limits();20112012 let collection_id = create_test_collection(&CollectionMode::NFT, 1);20132014 let origin1 = Origin::signed(1);20152016 let data = default_nft_data();2017 create_test_item(1, &data.into());20182019 TemplateModule::set_meta_update_permission_flag(2020 origin1.clone(),2021 collection_id,2022 MetaUpdatePermission::ItemOwner,2023 );20242025 let variable_data = b"ten chars.".to_vec();2026 assert_ok!(TemplateModule::set_variable_meta_data(2027 origin1,2028 collection_id,2029 1,2030 variable_data.clone()2031 ));20322033 assert_eq!(2034 TemplateModule::nft_item_id(collection_id, 1)2035 .unwrap()2036 .variable_data,2037 variable_data2038 );2039 });2040}20412042#[test]2043fn set_variable_meta_data_on_nft_with_item_owner_permission_flag_neg() {2044 new_test_ext().execute_with(|| {2045 // default_limits();20462047 let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);20482049 let origin1 = Origin::signed(1);2050 let origin2 = Origin::signed(2);20512052 assert_ok!(TemplateModule::set_mint_permission(2053 origin2.clone(),2054 collection_id,2055 true2056 ));2057 assert_ok!(TemplateModule::add_to_white_list(2058 origin2.clone(),2059 collection_id,2060 account(1)2061 ));20622063 let data = default_nft_data();2064 create_test_item(1, &data.into());20652066 assert_ok!(TemplateModule::set_meta_update_permission_flag(2067 origin2.clone(),2068 collection_id,2069 MetaUpdatePermission::ItemOwner,2070 ));20712072 let variable_data = b"ten chars.++".to_vec();2073 assert_noop!(2074 TemplateModule::set_variable_meta_data(2075 origin2,2076 collection_id,2077 1,2078 variable_data.clone()2079 ),2080 Error::<Test>::TokenVariableDataLimitExceeded2081 );200620822007#[test]2083 #[test]2008fn collection_transfer_flag_works() {2084 fn collection_transfer_flag_works() {2029 });2105 });2030}2106 }21072108 #[test]2109 fn set_variable_meta_data_on_nft_with_admin_flag() {2110 new_test_ext().execute_with(|| {2111 // default_limits();21122113 let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);21142115 let origin1 = Origin::signed(1);2116 let origin2 = Origin::signed(2);21172118 assert_ok!(TemplateModule::set_mint_permission(2119 origin2.clone(),2120 collection_id,2121 true2122 ));2123 assert_ok!(TemplateModule::add_to_white_list(2124 origin2.clone(),2125 collection_id,2126 account(1)2127 ));21282129 assert_ok!(TemplateModule::add_collection_admin(2130 origin2.clone(),2131 collection_id,2132 account(1)2133 ));21342135 let data = default_nft_data();2136 create_test_item(1, &data.into());21372138 assert_ok!(TemplateModule::set_meta_update_permission_flag(2139 origin2.clone(),2140 collection_id,2141 MetaUpdatePermission::Admin,2142 ));21432144 let variable_data = b"test set_variable_meta_data method.".to_vec();2145 assert_ok!(TemplateModule::set_variable_meta_data(2146 origin1,2147 collection_id,2148 1,2149 variable_data.clone()2150 ));21512152 assert_eq!(2153 TemplateModule::nft_item_id(collection_id, 1)2154 .unwrap()2155 .variable_data,2156 variable_data2157 );2158 });2159 }21602161 #[test]2162 fn set_variable_meta_data_on_nft_with_admin_flag_neg() {2163 new_test_ext().execute_with(|| {2164 // default_limits();21652166 let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);21672168 let origin1 = Origin::signed(1);2169 let origin2 = Origin::signed(2);21702171 assert_ok!(TemplateModule::set_mint_permission(2172 origin2.clone(),2173 collection_id,2174 true2175 ));2176 assert_ok!(TemplateModule::add_to_white_list(2177 origin2.clone(),2178 collection_id,2179 account(1)2180 ));21812182 let data = default_nft_data();2183 create_test_item(1, &data.into());21842185 assert_ok!(TemplateModule::set_meta_update_permission_flag(2186 origin2.clone(),2187 collection_id,2188 MetaUpdatePermission::Admin,2189 ));21902191 let variable_data = b"test set_variable_meta_data method.".to_vec();2192 assert_noop!(2193 TemplateModule::set_variable_meta_data(2194 origin1,2195 collection_id,2196 1,2197 variable_data.clone()2198 ),2199 Error::<Test>::NoPermission2200 );2201 });2202 }22032204 #[test]2205 fn set_variable_meta_flag_after_freeze() {2206 new_test_ext().execute_with(|| {2207 // default_limits();22082209 let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);22102211 let origin2 = Origin::signed(2);22122213 assert_ok!(TemplateModule::set_meta_update_permission_flag(2214 origin2.clone(),2215 collection_id,2216 MetaUpdatePermission::None,2217 ));2218 assert_noop!(2219 TemplateModule::set_meta_update_permission_flag(2220 origin2.clone(),2221 collection_id,2222 MetaUpdatePermission::Admin2223 ),2224 Error::<Test>::MetadataFlagFrozen2225 );2226 });2227 }22282229 #[test]2230 fn set_variable_meta_data_on_nft_with_none_flag_neg() {2231 new_test_ext().execute_with(|| {2232 // default_limits();22332234 let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);2235 let origin1 = Origin::signed(1);22362237 let data = default_nft_data();2238 create_test_item(1, &data.into());22392240 assert_ok!(TemplateModule::set_meta_update_permission_flag(2241 origin1.clone(),2242 collection_id,2243 MetaUpdatePermission::None,2244 ));22452246 let variable_data = b"test set_variable_meta_data method.".to_vec();2247 assert_noop!(2248 TemplateModule::set_variable_meta_data(2249 origin1.clone(),2250 collection_id,2251 1,2252 variable_data.clone()2253 ),2254 Error::<Test>::MetadataUpdateDenied2255 );2256 });2257 }203122582032#[test]2259 #[test]2033fn collection_transfer_flag_works_neg() {2260 fn collection_transfer_flag_works_neg() {2058 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);2285 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);2059 });2286 });2060}2287 }2288 });2289}20612290primitives/nft/src/lib.rsdiffbeforeafterboth185 pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions185 pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions186 pub variable_on_chain_schema: Vec<u8>, //186 pub variable_on_chain_schema: Vec<u8>, //187 pub const_on_chain_schema: Vec<u8>, //187 pub const_on_chain_schema: Vec<u8>, //188 pub meta_update_permission: MetaUpdatePermission,188 pub transfers_enabled: bool,189 pub transfers_enabled: bool,189}190}190191305 pub pieces: u128,306 pub pieces: u128,306}307}308309#[derive(Encode, Decode, Debug, Clone, PartialEq)]310#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]311pub enum MetaUpdatePermission {312 ItemOwner,313 Admin,314 None,315}316317impl Default for MetaUpdatePermission {318 fn default() -> Self {319 Self::ItemOwner320 }321}307322308#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug)]323#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug)]309#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]324#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]runtime_types.jsondiffbeforeafterboth63 "Limits": "CollectionLimits",63 "Limits": "CollectionLimits",64 "VariableOnChainSchema": "Vec<u8>",64 "VariableOnChainSchema": "Vec<u8>",65 "ConstOnChainSchema": "Vec<u8>",65 "ConstOnChainSchema": "Vec<u8>",66 "MetaUpdatePermission": "MetaUpdatePermission",66 "TransfersEnabled": "bool"67 "TransfersEnabled": "bool"67 },68 },68 "RawData": "Vec<u8>",69 "RawData": "Vec<u8>",94 "Unique"95 "Unique"95 ]96 ]96 },97 },98 "MetaUpdatePermission": {99 "_enum": [100 "ItemOwner",101 "Admin",102 "None" 103 ]104 },97 "CollectionId": "u32",105 "CollectionId": "u32",98 "TokenId": "u32",106 "TokenId": "u32",99 "ChainLimits": {107 "ChainLimits": {tests/src/addCollectionAdmin.test.tsdiffbeforeafterboth4//4//556import { ApiPromise } from '@polkadot/api';6import { ApiPromise } from '@polkadot/api';7import BN from 'bn.js';8import chai from 'chai';7import chai from 'chai';9import chaiAsPromised from 'chai-as-promised';8import chaiAsPromised from 'chai-as-promised';10import privateKey from './substrate/privateKey';9import privateKey from './substrate/privateKey';tests/src/collision-tests/adminLimitsOff.test.tsdiffbeforeafterboth1import { IKeyringPair } from '@polkadot/types/types';1import { IKeyringPair } from '@polkadot/types/types';2import BN from 'bn.js';3import chai from 'chai';2import chai from 'chai';4import chaiAsPromised from 'chai-as-promised';3import chaiAsPromised from 'chai-as-promised';5import privateKey from '../substrate/privateKey';4import privateKey from '../substrate/privateKey';tests/src/metadataUpdate.test.tsdiffbeforeafterbothno changes
tests/src/util/helpers.tsdiffbeforeafterboth525 });525 });526}526}527528export async function setMetadataUpdatePermissionFlagExpectSuccess(sender: IKeyringPair, collectionId: number, flag: string) {529530 await usingApi(async (api) => {531 const tx = api.tx.nft.setMetaUpdatePermissionFlag(collectionId, flag); 532 const events = await submitTransactionAsync(sender, tx);533 const result = getGenericResult(events);534535 expect(result.success).to.be.true;536 }); 537}538539export async function setMetadataUpdatePermissionFlagExpectFailure(sender: IKeyringPair, collectionId: number, flag: string) {540541 await usingApi(async (api) => {542 const tx = api.tx.nft.setMetaUpdatePermissionFlag(collectionId, flag); 543 const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;544 const result = getGenericResult(events);545546 expect(result.success).to.be.false;547 }); 548}527549528export async function enableContractSponsoringExpectSuccess(sender: IKeyringPair, contractAddress: AccountId | string, enable: boolean) {550export async function enableContractSponsoringExpectSuccess(sender: IKeyringPair, contractAddress: AccountId | string, enable: boolean) {529 await usingApi(async (api) => {551 await usingApi(async (api) => {