--- a/pallets/nft/src/benchmarking.rs +++ b/pallets/nft/src/benchmarking.rs @@ -165,7 +165,7 @@ let token_prefix1: Vec = b"token_prefix1".to_vec(); let mode: CollectionMode = CollectionMode::NFT; let caller: T::AccountId = T::AccountId::from(whitelisted_caller()); - let nft_data = CreateNftData { + let mut nft_data = CreateNftData { const_data: vec![], variable_data: vec![] }; @@ -173,7 +173,7 @@ nft_data.const_data.push(10); nft_data.variable_data.push(10); } - let mut data = CreateItemData::NFT(nft_data); + let data = CreateItemData::NFT(nft_data); Nft::::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?; }: create_item(RawOrigin::Signed(caller.clone()), 2, caller.clone(), data) --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -837,8 +837,8 @@ let target_collection = >::get(collection_id); Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?; - Self::validate_create_item_args(&target_collection, &properties)?; - Self::create_item_no_validation(collection_id, &target_collection, &properties, &owner)?; + Self::validate_create_item_args(&target_collection, &data)?; + Self::create_item_no_validation(collection_id, &target_collection, owner, data)?; Ok(()) } @@ -858,13 +858,15 @@ /// /// * collection_id: ID of the collection. /// - /// * properties: Array items properties. Each property is an array of bytes itself, see [create_item]. + /// * itemsData: Array items properties. Each property is an array of bytes itself, see [create_item]. /// /// * owner: Address, initial owner of the NFT. - #[weight = 0] - pub fn create_multiple_items(origin, collection_id: u64, properties: Vec>, owner: T::AccountId) -> DispatchResult { + #[weight = T::WeightInfo::create_item(items_data.into_iter() + .map(|data| { data.len() }) + .sum())] + pub fn create_multiple_items(origin, collection_id: u64, owner: T::AccountId, items_data: Vec) -> DispatchResult { - ensure!(properties.len() > 0, "Length of items properties must be greater than 0."); + ensure!(items_data.len() > 0, "Length of items properties must be greater than 0."); let sender = ensure_signed(origin)?; Self::collection_exists(collection_id)?; @@ -872,11 +874,11 @@ Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?; - for prop in &properties { - Self::validate_create_item_args(&target_collection, prop)?; + for data in &items_data { + Self::validate_create_item_args(&target_collection, data)?; } - for prop in &properties { - Self::create_item_no_validation(collection_id, &target_collection, prop, &owner)?; + for data in &items_data { + Self::create_item_no_validation(collection_id, &target_collection, owner.clone(), data.clone())?; } Ok(()) @@ -1289,61 +1291,64 @@ Ok(()) } - - fn validate_create_item_args(collection: &CollectionType, properties: &Vec) -> DispatchResult { - match collection.mode + fn validate_create_item_args(target_collection: &CollectionType, data: &CreateItemData) -> DispatchResult { + match target_collection.mode { - CollectionMode::NFT(_) => { - - // check size - ensure!(collection.custom_data_size >= properties.len() as u32, "Size of item is too large") + CollectionMode::NFT => { + if let CreateItemData::NFT(data) = data { + // check sizes + ensure!(ChainLimit::get().custom_data_limit >= data.const_data.len() as u32, "const_data exceeded data limit."); + ensure!(ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32, "variable_data exceeded data limit."); + } else { + fail!("Not NFT item data used to mint in NFT collection."); + } }, CollectionMode::Fungible(_) => { - - // check size - ensure!(properties.len() as u32 == 0, "Size of item must be 0 with fungible type") + if let CreateItemData::Fungible(_) = data { + } else { + fail!("Not Fungible item data used to mint in Fungible collection."); + } }, - CollectionMode::ReFungible(_, _) => { + CollectionMode::ReFungible(_) => { + if let CreateItemData::ReFungible(data) = data { - // check size - ensure!(collection.custom_data_size >= properties.len() as u32, "Size of item is too large") + // check sizes + ensure!(ChainLimit::get().custom_data_limit >= data.const_data.len() as u32, "const_data exceeded data limit."); + ensure!(ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32, "variable_data exceeded data limit."); + } else { + fail!("Not Re Fungible item data used to mint in Re Fungible collection."); + } }, - _ => { - fail!("Unexpected collection mode") - } - } + _ => { fail!("Unexpected collection type."); } + }; Ok(()) } - fn create_item_no_validation(collection_id: u64, collection: &CollectionType, properties: &Vec, owner: &T::AccountId) -> DispatchResult { - match collection.mode + fn create_item_no_validation(collection_id: u64, collection: &CollectionType, owner: T::AccountId, data: CreateItemData) -> DispatchResult { + match data { - CollectionMode::NFT(_) => { - - // Create nft item + CreateItemData::NFT(data) => { let item = NftItemType { collection: collection_id, - owner: owner.clone(), - data: properties.clone(), + owner, + const_data: data.const_data, + variable_data: data.variable_data }; Self::add_nft_item(item)?; - }, - CollectionMode::Fungible(_) => { - + CreateItemData::Fungible(_) => { let item = FungibleItemType { collection: collection_id, - owner: owner.clone(), + owner, value: (10 as u128).pow(collection.decimal_points) }; Self::add_fungible_item(item)?; }, - CollectionMode::ReFungible(_, _) => { - + CreateItemData::ReFungible(data) => { let mut owner_list = Vec::new(); let value = (10 as u128).pow(collection.decimal_points); owner_list.push(Ownership {owner: owner.clone(), fraction: value}); @@ -1351,15 +1356,15 @@ let item = ReFungibleItemType { collection: collection_id, owner: owner_list, - data: properties.clone() + const_data: data.const_data, + variable_data: data.variable_data }; Self::add_refungible_item(item)?; - }, - _ => { ensure!(1 == 0,"just error"); } - + } }; + // call event Self::deposit_event(RawEvent::ItemCreated(collection_id, ::get(collection_id))); --- a/pallets/nft/src/tests.rs +++ b/pallets/nft/src/tests.rs @@ -92,41 +92,23 @@ #[test] fn create_nft_multiple_items() { new_test_ext().execute_with(|| { - let col_name1: Vec = "Test1\0".encode_utf16().collect::>(); - let col_desc1: Vec = "TestDescription1\0".encode_utf16().collect::>(); - let token_prefix1: Vec = b"token_prefix1\0".to_vec(); - let mode: CollectionMode = CollectionMode::NFT(2000); - - assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { - collection_numbers_limit: 10, - account_token_ownership_limit: 10, - collections_admins_limit: 5, - custom_data_limit: 2048, - nft_sponsor_transfer_timeout: 15, - fungible_sponsor_transfer_timeout: 15, - refungible_sponsor_transfer_timeout: 15, - })); + default_limits(); + + create_test_collection(&CollectionMode::NFT, 1); let origin1 = Origin::signed(1); - assert_ok!(TemplateModule::create_collection( - origin1.clone(), - col_name1.clone(), - col_desc1.clone(), - token_prefix1.clone(), - mode - )); - assert_eq!(TemplateModule::collection(1).owner, 1); - let properties = [[1, 2, 3].to_vec(), [3, 2, 1].to_vec(), [3, 3, 3].to_vec()].to_vec(); + let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()]; assert_ok!(TemplateModule::create_multiple_items( origin1.clone(), 1, - properties.clone(), - 1 + 1, + items_data.clone().into_iter().map(|d| { d.into() }).collect() )); - for (index, data) in properties.iter().enumerate() { - assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as u64).data, *data); + for (index, data) in items_data.iter().enumerate() { + assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as u64).const_data.to_vec(), data.const_data); + assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as u64).variable_data.to_vec(), data.variable_data); } }); } @@ -160,43 +142,25 @@ #[test] fn create_multiple_refungible_items() { new_test_ext().execute_with(|| { - let col_name1: Vec = "Test1\0".encode_utf16().collect::>(); - let col_desc1: Vec = "TestDescription1\0".encode_utf16().collect::>(); - let token_prefix1: Vec = b"token_prefix1\0".to_vec(); - let mode: CollectionMode = CollectionMode::ReFungible(2000, 3); - - assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { - collection_numbers_limit: 10, - account_token_ownership_limit: 10, - collections_admins_limit: 5, - custom_data_limit: 2048, - nft_sponsor_transfer_timeout: 15, - fungible_sponsor_transfer_timeout: 15, - refungible_sponsor_transfer_timeout: 15, - })); + default_limits(); + + create_test_collection(&CollectionMode::ReFungible(3), 1); let origin1 = Origin::signed(1); - assert_ok!(TemplateModule::create_collection( - origin1.clone(), - col_name1.clone(), - col_desc1.clone(), - token_prefix1.clone(), - mode - )); - assert_eq!(TemplateModule::collection(1).owner, 1); - let properties = [[1, 2, 3].to_vec(), [3, 2, 1].to_vec(), [3, 3, 3].to_vec()].to_vec(); + let items_data = vec![default_re_fungible_data(), default_re_fungible_data(), default_re_fungible_data()]; assert_ok!(TemplateModule::create_multiple_items( origin1.clone(), 1, - properties.clone(), - 1 + 1, + items_data.clone().into_iter().map(|d| { d.into() }).collect() )); - for (index, data) in properties.iter().enumerate() { + for (index, data) in items_data.iter().enumerate() { let item = TemplateModule::refungible_item_id(1, (index + 1) as u64); - assert_eq!(item.data, *data); + assert_eq!(item.const_data.to_vec(), data.const_data); + assert_eq!(item.variable_data.to_vec(), data.variable_data); assert_eq!( item.owner[0], Ownership { @@ -225,41 +189,22 @@ #[test] fn create_multiple_fungible_items() { new_test_ext().execute_with(|| { - let col_name1: Vec = "Test1\0".encode_utf16().collect::>(); - let col_desc1: Vec = "TestDescription1\0".encode_utf16().collect::>(); - let token_prefix1: Vec = b"token_prefix1\0".to_vec(); - let mode: CollectionMode = CollectionMode::Fungible(3); + default_limits(); - assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { - collection_numbers_limit: 10, - account_token_ownership_limit: 10, - collections_admins_limit: 5, - custom_data_limit: 2048, - nft_sponsor_transfer_timeout: 15, - fungible_sponsor_transfer_timeout: 15, - refungible_sponsor_transfer_timeout: 15, - })); + create_test_collection(&CollectionMode::Fungible(3), 1); let origin1 = Origin::signed(1); - assert_ok!(TemplateModule::create_collection( - origin1.clone(), - col_name1.clone(), - col_desc1.clone(), - token_prefix1.clone(), - mode - )); - assert_eq!(TemplateModule::collection(1).owner, 1); - let properties = [[].to_vec(), [].to_vec(), [].to_vec()].to_vec(); + let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()]; assert_ok!(TemplateModule::create_multiple_items( origin1.clone(), 1, - properties.clone(), - 1 + 1, + items_data.clone().into_iter().map(|d| { d.into() }).collect() )); - for (index, _) in properties.iter().enumerate() { + for (index, _) in items_data.iter().enumerate() { assert_eq!(TemplateModule::fungible_item_id(1, (index + 1) as u64).owner, 1); } assert_eq!(TemplateModule::balance_count(1, 1), 3000); @@ -1471,7 +1416,7 @@ assert_noop!( TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()), - "Public minting is not allowed for this collection." + "Public minting is not allowed for this collection" ); }); } @@ -1500,7 +1445,7 @@ assert_noop!( TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()), - "Public minting is not allowed for this collection." + "Public minting is not allowed for this collection" ); }); }