difftreelog
Merge pull request #9 from usetech-llc/feature_limits_nft_78_85_105
in: master
Transfer rate limit + chain bounds
4 files changed
node/src/chain_spec.rsdiffbeforeafterboth--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -130,23 +130,35 @@
}),
sudo: Some(SudoConfig { key: root_key }),
nft: Some(NftConfig {
- collection: vec![(1, CollectionType {
- owner: get_account_id_from_seed::<sr25519::Public>("Alice"),
- mode: CollectionMode::NFT(50),
- access: AccessMode::Normal,
- decimal_points: 0,
- name: vec!(),
- description: vec!(),
- token_prefix: vec!(),
- custom_data_size: 50,
- mint_mode: false,
- offchain_schema: vec!(),
- sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),
- unconfirmed_sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),
- })],
- nft_item_id: vec!(),
- fungible_item_id: vec!(),
- refungible_item_id: vec!(),
+ collection: vec![(
+ 1,
+ CollectionType {
+ owner: get_account_id_from_seed::<sr25519::Public>("Alice"),
+ mode: CollectionMode::NFT(50),
+ access: AccessMode::Normal,
+ decimal_points: 0,
+ name: vec![],
+ description: vec![],
+ token_prefix: vec![],
+ custom_data_size: 50,
+ mint_mode: false,
+ offchain_schema: vec![],
+ sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),
+ unconfirmed_sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),
+ },
+ )],
+ nft_item_id: vec![],
+ fungible_item_id: vec![],
+ refungible_item_id: vec![],
+ chain_limit: 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,
+ },
}),
contracts: Some(ContractsConfig {
current_schedule: ContractsSchedule {
pallets/nft/src/lib.rsdiffbeforeafterboth1#![cfg_attr(not(feature = "std"), no_std)]1#![cfg_attr(not(feature = "std"), no_std)]223#[cfg(feature = "std")]3#[cfg(feature = "std")]4pub use std::*;56#[cfg(feature = "std")]4pub use serde::*;7pub use serde::*;586use codec::{Decode, Encode};9use codec::{Decode, Encode};20 IsSubType, StorageValue,23 IsSubType, StorageValue,21};24};222523use frame_system::{self as system, ensure_signed};26use frame_system::{self as system, ensure_signed, ensure_root};24use sp_runtime::sp_std::prelude::Vec;27use sp_runtime::sp_std::prelude::Vec;25use sp_runtime::{28use sp_runtime::{26 traits::{29 traits::{157 pub vesting_date: Moment,160 pub vesting_date: Moment,158}161}159162163#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]164#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]165pub struct BasketItem<AccountId, BlockNumber> {166 pub address: AccountId,167 pub start_block: BlockNumber,168}169170#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]171#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]172pub struct ChainLimits {173 pub collection_numbers_limit: u64,174 pub account_token_ownership_limit: u64,175 pub collections_admins_limit: u64,176 pub custom_data_limit: u32,177178 // Timeouts for item types in passed blocks179 pub nft_sponsor_transfer_timeout: u32,180 pub fungible_sponsor_transfer_timeout: u32,181 pub refungible_sponsor_transfer_timeout: u32,182}183160pub trait Trait: system::Trait {184pub trait Trait: system::Trait {161 type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;185 type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;162}186}172 ChainVersion: u64;196 ChainVersion: u64;173 ItemListIndex: map hasher(blake2_128_concat) u64 => u64;197 ItemListIndex: map hasher(blake2_128_concat) u64 => u64;174198199 // Chain limits struct200 pub ChainLimit get(fn chain_limit) config(): ChainLimits;201202 // Bound counters203 CollectionCount: u64;204 pub AccountItemCount get(fn account_item_count): map hasher(identity) T::AccountId => u64;205206 // Basic collections175 pub Collection get(fn collection) config(): map hasher(identity) u64 => CollectionType<T::AccountId>;207 pub Collection get(fn collection) config(): map hasher(identity) u64 => CollectionType<T::AccountId>;176 pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;208 pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;177 pub WhiteList get(fn white_list): map hasher(identity) u64 => Vec<T::AccountId>;209 pub WhiteList get(fn white_list): map hasher(identity) u64 => Vec<T::AccountId>;190 /// Index list222 /// Index list191 pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;223 pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;192224225 /// Tokens transfer baskets226 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;227 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => Vec<BasketItem<T::AccountId, T::BlockNumber>>;228 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;229193 // Sponsorship230 // Sponsorship194 pub ContractSponsor get(fn contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;231 pub ContractSponsor get(fn contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;195 pub UnconfirmedContractSponsor get(fn unconfirmed_contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;232 pub UnconfirmedContractSponsor get(fn unconfirmed_contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;196 }233 }197 add_extra_genesis {234 add_extra_genesis {198 build(|config: &GenesisConfig<T>| {235 build(|config: &GenesisConfig<T>| {199 // Modification of storage236 // Modification of storage200 for (_num, _c) in &config.collection {237 for (_num, _c) in &config.collection {201 <Module<T>>::init_collection(_c);238 <Module<T>>::init_collection(_c);202 }239 }212 for (_num, _q, _i) in &config.refungible_item_id {249 for (_num, _q, _i) in &config.refungible_item_id {213 <Module<T>>::init_refungible_token(_i);250 <Module<T>>::init_refungible_token(_i);214 }251 }215 })252 })216 }253 }217}254}218255295 // Anyone can create a collection332 // Anyone can create a collection296 let who = ensure_signed(origin)?;333 let who = ensure_signed(origin)?;297 let custom_data_size = match mode {334 let custom_data_size = match mode {298 CollectionMode::NFT(size) => size,335 CollectionMode::NFT(size) => {336337 // bound Custom data size338 ensure!(size < ChainLimit::get().custom_data_limit, "Custom data size bound exceeded");299 CollectionMode::ReFungible(size, _) => size,339 size340 },341 CollectionMode::ReFungible(size, _) => {342343 // bound Custom data size344 ensure!(size < ChainLimit::get().custom_data_limit, "Custom data size bound exceeded");345 size346 },300 _ => 0347 _ => 0301 };348 };302349306 _ => 0353 _ => 0307 };354 };308355356 // bound Total number of collections357 ensure!(CollectionCount::get() < ChainLimit::get().collection_numbers_limit, "Total collections bound exceeded");358309 // check params359 // check params310 ensure!(decimal_points <= 4, "decimal_points parameter must be lower than 4");360 ensure!(decimal_points <= 4, "decimal_points parameter must be lower than 4");311361326 .checked_add(1)376 .checked_add(1)327 .expect("collection id error");377 .expect("collection id error");328378379 // bound counter380 let total = CollectionCount::get()381 .checked_add(1)382 .expect("collection counter error");383329 CreatedCollectionCount::put(next_id);384 CreatedCollectionCount::put(next_id);385 CollectionCount::put(total);330386331 // Create new collection387 // Create new collection332 let new_collection = CollectionType {388 let new_collection = CollectionType {368 let sender = ensure_signed(origin)?;424 let sender = ensure_signed(origin)?;369 Self::check_owner_permissions(collection_id, sender)?;425 Self::check_owner_permissions(collection_id, sender)?;370426371 // TODO Items remove372 <AddressTokens<T>>::remove_prefix(collection_id);427 <AddressTokens<T>>::remove_prefix(collection_id);373 <ApprovedList<T>>::remove_prefix(collection_id);428 <ApprovedList<T>>::remove_prefix(collection_id);374 <Balance<T>>::remove_prefix(collection_id);429 <Balance<T>>::remove_prefix(collection_id);377 <Collection<T>>::remove(collection_id);432 <Collection<T>>::remove(collection_id);378 <WhiteList<T>>::remove(collection_id);433 <WhiteList<T>>::remove(collection_id);379434435 <NftItemList<T>>::remove_prefix(collection_id);436 <FungibleItemList<T>>::remove_prefix(collection_id);437 <ReFungibleItemList<T>>::remove_prefix(collection_id);438439 <NftTransferBasket<T>>::remove_prefix(collection_id);440 <FungibleTransferBasket<T>>::remove_prefix(collection_id);441 <ReFungibleTransferBasket<T>>::remove_prefix(collection_id);442443 if CollectionCount::get() > 0444 {445 // bound couter446 let total = CollectionCount::get()447 .checked_sub(1)448 .expect("collection counter error");449450 CollectionCount::put(total);451 }452380 Ok(())453 Ok(())381 }454 }382455544 ensure!(!admin_arr.contains(&new_admin_id), "Account already has admin role");617 ensure!(!admin_arr.contains(&new_admin_id), "Account already has admin role");545 }618 }546619620 // Number of collection admins621 ensure!((admin_arr.len() as u64) < ChainLimit::get().collections_admins_limit, "Number of collection admins bound exceeded");622547 admin_arr.push(new_admin_id);623 admin_arr.push(new_admin_id);548 <AdminList<T>>::insert(collection_id, admin_arr);624 <AdminList<T>>::insert(collection_id, admin_arr);549625758834759 // Transfer permissions check835 // Transfer permissions check760 let target_collection = <Collection<T>>::get(collection_id);836 let target_collection = <Collection<T>>::get(collection_id);761 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || 837 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||762 Self::is_owner_or_admin_permissions(collection_id, sender.clone()), 838 Self::is_owner_or_admin_permissions(collection_id, sender.clone()),763 "Only item owner, collection owner and admins can modify item");839 "Only item owner, collection owner and admins can modify item");764840765 if target_collection.access == AccessMode::WhiteList {841 if target_collection.access == AccessMode::WhiteList {810886811 // Transfer permissions check887 // Transfer permissions check812 let target_collection = <Collection<T>>::get(collection_id);888 let target_collection = <Collection<T>>::get(collection_id);813 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || 889 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||814 Self::is_owner_or_admin_permissions(collection_id, sender.clone()), 890 Self::is_owner_or_admin_permissions(collection_id, sender.clone()),815 "Only item owner, collection owner and admins can modify item");891 "Only item owner, collection owner and admins can modify item");816892817 if target_collection.access == AccessMode::WhiteList {893 if target_collection.access == AccessMode::WhiteList {852928853 // Transfer permissions check929 // Transfer permissions check854 let target_collection = <Collection<T>>::get(collection_id);930 let target_collection = <Collection<T>>::get(collection_id);855 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || 931 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||856 Self::is_owner_or_admin_permissions(collection_id, sender.clone()), 932 Self::is_owner_or_admin_permissions(collection_id, sender.clone()),857 "Only item owner, collection owner and admins can approve");933 "Only item owner, collection owner and admins can approve");858934859 if target_collection.access == AccessMode::WhiteList {935 if target_collection.access == AccessMode::WhiteList {919995920 // Transfer permissions check996 // Transfer permissions check921 let target_collection = <Collection<T>>::get(collection_id);997 let target_collection = <Collection<T>>::get(collection_id);922 ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()), 998 ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()),923 "Only item owner, collection owner and admins can modify items");999 "Only item owner, collection owner and admins can modify items");9241000925 if target_collection.access == AccessMode::WhiteList {1001 if target_collection.access == AccessMode::WhiteList {9871063988 Ok(())1064 Ok(())989 }1065 }10661067 // Sudo permissions function1068 #[weight = 0]1069 pub fn set_chain_limits(1070 origin,1071 limits: ChainLimits1072 ) -> DispatchResult {1073 ensure_root(origin)?;1074 <ChainLimit>::put(limits);1075 Ok(())1076 } 990 }1077 }991}1078}99210791004 <ItemListIndex>::insert(item.collection, current_index);1091 <ItemListIndex>::insert(item.collection, current_index);1005 <FungibleItemList<T>>::insert(item.collection, current_index, itemcopy);1092 <FungibleItemList<T>>::insert(item.collection, current_index, itemcopy);100610931094 // Add current block1095 let v: Vec<BasketItem<T::AccountId, T::BlockNumber>> = Vec::new();1096 <FungibleTransferBasket<T>>::insert(item.collection, current_index, v);1097 1007 // Update balance1098 // Update balance1008 let new_balance = <Balance<T>>::get(item.collection, owner.clone())1099 let new_balance = <Balance<T>>::get(item.collection, owner.clone())1009 .checked_add(value)1100 .checked_add(value)1027 <ItemListIndex>::insert(item.collection, current_index);1118 <ItemListIndex>::insert(item.collection, current_index);1028 <ReFungibleItemList<T>>::insert(item.collection, current_index, itemcopy);1119 <ReFungibleItemList<T>>::insert(item.collection, current_index, itemcopy);102911201121 // Add current block1122 let block_number: T::BlockNumber = 0.into();1123 <ReFungibleTransferBasket<T>>::insert(item.collection, current_index, block_number);11241030 // Update balance1125 // Update balance1031 let new_balance = <Balance<T>>::get(item.collection, owner.clone())1126 let new_balance = <Balance<T>>::get(item.collection, owner.clone())1032 .checked_add(value)1127 .checked_add(value)1048 <ItemListIndex>::insert(collection_id, current_index);1143 <ItemListIndex>::insert(collection_id, current_index);1049 <NftItemList<T>>::insert(collection_id, current_index, item);1144 <NftItemList<T>>::insert(collection_id, current_index, item);105011451146 // Add current block1147 let block_number: T::BlockNumber = 0.into();1148 <NftTransferBasket<T>>::insert(collection_id, current_index, block_number);11491051 // Update balance1150 // Update balance1052 let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())1151 let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())1053 .checked_add(1)1152 .checked_add(1)1057 Ok(())1156 Ok(())1058 }1157 }105911581060 fn burn_refungible_item(collection_id: u64, item_id: u64, owner: T::AccountId) -> DispatchResult {1159 fn burn_refungible_item(1160 collection_id: u64,1161 item_id: u64,1162 owner: T::AccountId,1163 ) -> DispatchResult {1061 ensure!(1164 ensure!(1062 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1165 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1063 "Item does not exists"1166 "Item does not exists"1149 }1252 }115012531151 fn is_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> bool {1254 fn is_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> bool {11521153 let target_collection = <Collection<T>>::get(collection_id);1255 let target_collection = <Collection<T>>::get(collection_id);1154 let mut result: bool = subject == target_collection.owner;1256 let mut result: bool = subject == target_collection.owner;1155 let exists = <AdminList<T>>::contains_key(collection_id);1257 let exists = <AdminList<T>>::contains_key(collection_id);1163 result1265 result1164 }1266 }116512671166 fn check_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> DispatchResult {1268 fn check_owner_or_admin_permissions(1167 1269 collection_id: u64,1270 subject: T::AccountId,1271 ) -> DispatchResult {1168 Self::collection_exists(collection_id)?;1272 Self::collection_exists(collection_id)?;1169 let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());1273 let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());117012741171 ensure!(result, "You do not have permissions to modify this collection");1275 ensure!(1276 result,1277 "You do not have permissions to modify this collection"1278 );1172 Ok(())1279 Ok(())1173 }1280 }117412811193 }1300 }119413011195 fn check_white_list(collection_id: u64, address: &T::AccountId) -> DispatchResult {1302 fn check_white_list(collection_id: u64, address: &T::AccountId) -> DispatchResult {11961197 let mes = "Address is not in white list";1303 let mes = "Address is not in white list";1198 ensure!(<WhiteList<T>>::contains_key(collection_id), mes);1304 ensure!(<WhiteList<T>>::contains_key(collection_id), mes);1199 let wl = <WhiteList<T>>::get(collection_id);1305 let wl = <WhiteList<T>>::get(collection_id);1209 owner: T::AccountId,1315 owner: T::AccountId,1210 new_owner: T::AccountId,1316 new_owner: T::AccountId,1211 ) -> DispatchResult {1317 ) -> DispatchResult {12121213 ensure!(1318 ensure!(1214 <FungibleItemList<T>>::contains_key(collection_id, item_id),1319 <FungibleItemList<T>>::contains_key(collection_id, item_id),1215 "Item not exists"1320 "Item not exists"1299 owner: T::AccountId,1404 owner: T::AccountId,1300 new_owner: T::AccountId,1405 new_owner: T::AccountId,1301 ) -> DispatchResult {1406 ) -> DispatchResult {13021303 ensure!(1407 ensure!(1304 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1408 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1305 "Item not exists"1409 "Item not exists"1385 sender: T::AccountId,1489 sender: T::AccountId,1386 new_owner: T::AccountId,1490 new_owner: T::AccountId,1387 ) -> DispatchResult {1491 ) -> DispatchResult {1388 1389 ensure!(1492 ensure!(1390 <NftItemList<T>>::contains_key(collection_id, item_id),1493 <NftItemList<T>>::contains_key(collection_id, item_id),1391 "Item not exists"1494 "Item not exists"1422 Ok(())1525 Ok(())1423 }1526 }142415271425 fn init_collection(item: &CollectionType<T::AccountId>){1528 fn init_collection(item: &CollectionType<T::AccountId>) {1529 // check params1530 assert!(1531 item.decimal_points <= 4,1532 "decimal_points parameter must be lower than 4"1533 );1534 assert!(1535 item.name.len() <= 64,1536 "Collection name can not be longer than 63 char"1537 );1538 assert!(1539 item.name.len() <= 256,1540 "Collection description can not be longer than 255 char"1541 );1542 assert!(1543 item.token_prefix.len() <= 16,1544 "Token prefix can not be longer than 15 char"1545 );142615461427 // check params1547 // Generate next collection ID1428 assert!(item.decimal_points <= 4, "decimal_points parameter must be lower than 4");1429 assert!(item.name.len() <= 64, "Collection name can not be longer than 63 char");1430 assert!(item.name.len() <= 256, "Collection description can not be longer than 255 char");1431 assert!(item.token_prefix.len() <= 16, "Token prefix can not be longer than 15 char");1432 1433 // Generate next collection ID1434 let next_id = CreatedCollectionCount::get()1548 let next_id = CreatedCollectionCount::get()1435 .checked_add(1)1549 .checked_add(1)1436 .expect("collection id error");1550 .expect("collection id error");1437 15511438 CreatedCollectionCount::put(next_id); 1552 CreatedCollectionCount::put(next_id);1439 }1553 }144015541441 fn init_nft_token(item: &NftItemType<T::AccountId>){1555 fn init_nft_token(item: &NftItemType<T::AccountId>) {14421443 let current_index = <ItemListIndex>::get(item.collection)1556 let current_index = <ItemListIndex>::get(item.collection)1444 .checked_add(1)1557 .checked_add(1)1457 <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);1570 <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);1458 }1571 }145915721460 fn init_fungible_token(item: &FungibleItemType<T::AccountId>){1573 fn init_fungible_token(item: &FungibleItemType<T::AccountId>) {14611462 let current_index = <ItemListIndex>::get(item.collection)1574 let current_index = <ItemListIndex>::get(item.collection)1463 .checked_add(1)1575 .checked_add(1)1476 <Balance<T>>::insert(item.collection, owner.clone(), new_balance);1588 <Balance<T>>::insert(item.collection, owner.clone(), new_balance);1477 }1589 }147815901479 fn init_refungible_token(item: &ReFungibleItemType<T::AccountId>){1591 fn init_refungible_token(item: &ReFungibleItemType<T::AccountId>) {14801481 let current_index = <ItemListIndex>::get(item.collection)1592 let current_index = <ItemListIndex>::get(item.collection)1482 .checked_add(1)1593 .checked_add(1)1497 }1608 }149816091499 fn add_token_index(collection_id: u64, item_index: u64, owner: T::AccountId) -> DispatchResult {1610 fn add_token_index(collection_id: u64, item_index: u64, owner: T::AccountId) -> DispatchResult {16111612 // add to account limit1613 if <AccountItemCount<T>>::contains_key(owner.clone()) {16141615 // bound Owned tokens by a single address1616 let count = <AccountItemCount<T>>::get(owner.clone());1617 ensure!(count < ChainLimit::get().account_token_ownership_limit, "Owned tokens by a single address bound exceeded");16181619 <AccountItemCount<T>>::insert(owner.clone(), 1620 count.checked_add(1).unwrap());1621 }1622 else {1623 <AccountItemCount<T>>::insert(owner.clone(), 1);1624 }16251500 let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.clone());1626 let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.clone());1501 if list_exists {1627 if list_exists {1502 let mut list = <AddressTokens<T>>::get(collection_id, owner.clone());1628 let mut list = <AddressTokens<T>>::get(collection_id, owner.clone());1511 let mut itm = Vec::new();1637 let mut itm = Vec::new();1512 itm.push(item_index.clone());1638 itm.push(item_index.clone());1513 <AddressTokens<T>>::insert(collection_id, owner, itm);1639 <AddressTokens<T>>::insert(collection_id, owner, itm);1640 1514 }1641 }151516421516 Ok(())1643 Ok(())1521 item_index: u64,1648 item_index: u64,1522 owner: T::AccountId,1649 owner: T::AccountId,1523 ) -> DispatchResult {1650 ) -> DispatchResult {16511652 // update counter1653 <AccountItemCount<T>>::insert(owner.clone(), 1654 <AccountItemCount<T>>::get(owner.clone()).checked_sub(1).unwrap());165516561524 let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.clone());1657 let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.clone());1525 if list_exists {1658 if list_exists {1526 let mut list = <AddressTokens<T>>::get(collection_id, owner.clone());1659 let mut list = <AddressTokens<T>>::get(collection_id, owner.clone());1628 <Collection<T>>::get(collection_id).sponsor1761 <Collection<T>>::get(collection_id).sponsor1629 }1762 }1630 Some(Call::transfer(_new_owner, collection_id, _item_id, _value)) => {1763 Some(Call::transfer(_new_owner, collection_id, _item_id, _value)) => {1631 <Collection<T>>::get(collection_id).sponsor1764 let _collection_mode = <Collection<T>>::get(collection_id).mode;17651766 // sponsor timeout1767 let sponsor_transfer = match _collection_mode {1768 CollectionMode::NFT(_) => {1769 let basket = <NftTransferBasket<T>>::get(collection_id, _item_id);1770 let block_number = <system::Module<T>>::block_number() as T::BlockNumber;1771 let limit_time = basket + ChainLimit::get().nft_sponsor_transfer_timeout.into();1772 if block_number >= limit_time {1773 <NftTransferBasket<T>>::insert(collection_id, _item_id, block_number);1774 true1775 }1776 else {1777 false1778 }1779 }1780 CollectionMode::Fungible(_) => {1781 let mut basket = <FungibleTransferBasket<T>>::get(collection_id, _item_id);1782 let block_number = <system::Module<T>>::block_number() as T::BlockNumber;1783 if basket.iter().any(|i| i.address == _new_owner.clone())1784 {1785 let item = basket.iter_mut().find(|i| i.address == _new_owner.clone()).unwrap().clone();1786 let limit_time = item.start_block + ChainLimit::get().fungible_sponsor_transfer_timeout.into();1787 if block_number >= limit_time {1788 basket.retain(|x| x.address == item.address);1789 basket.push(BasketItem { start_block: block_number, address: _new_owner.clone() });1790 <FungibleTransferBasket<T>>::insert(collection_id, _item_id, basket);1791 true1792 }1793 else {1794 false1795 }1796 }1797 else {1798 basket.push(BasketItem { start_block: block_number, address: _new_owner.clone()});1799 true1800 }1801 }1802 CollectionMode::ReFungible(_, _) => {1803 let basket = <ReFungibleTransferBasket<T>>::get(collection_id, _item_id);1804 let block_number = <system::Module<T>>::block_number() as T::BlockNumber;1805 let limit_time = basket + ChainLimit::get().nft_sponsor_transfer_timeout.into();1806 if block_number >= limit_time {1807 <ReFungibleTransferBasket<T>>::insert(collection_id, _item_id, block_number);1808 true1809 } else {1810 false1811 }1812 }1813 _ => {1814 false1815 },1816 };18171818 if !sponsor_transfer {1819 T::AccountId::default()1820 } else {1821 <Collection<T>>::get(collection_id).sponsor1822 }1632 }1823 }163318241634 _ => T::AccountId::default(),1825 _ => T::AccountId::default(),1745 Ok(())1936 Ok(())1746 }1937 }1747}1938}1748// #endregion1939// #endregion1940pallets/nft/src/mock.rsdiffbeforeafterboth--- a/pallets/nft/src/mock.rs
+++ b/pallets/nft/src/mock.rs
@@ -65,6 +65,7 @@
}
pub type TemplateModule = Module<Test>;
+
// This function basically just builds a genesis storage key/value store according to
// our desired mockup.
pub fn new_test_ext() -> sp_io::TestExternalities {
pallets/nft/src/tests.rsdiffbeforeafterboth--- a/pallets/nft/src/tests.rs
+++ b/pallets/nft/src/tests.rs
@@ -1,7 +1,8 @@
// Tests to be written here
use crate::mock::*;
-use crate::{ApprovePermissions, CollectionMode, AccessMode, Ownership};
+use crate::{AccessMode, ApprovePermissions, CollectionMode, Ownership, ChainLimits};
use frame_support::{assert_noop, assert_ok};
+use frame_system::{ RawOrigin };
// Use cases tests region
// #region
@@ -13,6 +14,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -41,6 +52,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -79,6 +100,16 @@
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
let mode: CollectionMode = CollectionMode::Fungible(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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -109,6 +140,16 @@
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
let mode: CollectionMode = CollectionMode::Fungible(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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -167,6 +208,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -264,6 +315,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -302,6 +363,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -323,8 +394,16 @@
assert_eq!(TemplateModule::balance_count(1, 1), 1);
assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ true
+ ));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));
@@ -362,6 +441,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -393,8 +482,16 @@
assert_eq!(TemplateModule::balance_count(1, 1), 1000);
assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ true
+ ));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));
@@ -444,6 +541,16 @@
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
let mode: CollectionMode = CollectionMode::Fungible(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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -465,8 +572,16 @@
assert_eq!(TemplateModule::balance_count(1, 1), 1000);
assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ true
+ ));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));
@@ -532,6 +647,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -557,6 +682,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -577,6 +712,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -617,6 +762,16 @@
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
let mode: CollectionMode = CollectionMode::Fungible(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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -655,6 +810,16 @@
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
let mode: CollectionMode = CollectionMode::ReFungible(200, 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -664,9 +829,17 @@
token_prefix1.clone(),
mode
));
-
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ true
+ ));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));
@@ -704,6 +877,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
let origin3 = Origin::signed(3);
@@ -754,6 +937,16 @@
let origin2 = Origin::signed(2);
let origin3 = Origin::signed(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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -809,6 +1002,16 @@
let origin1 = Origin::signed(1);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -881,6 +1084,16 @@
let nft_mode: CollectionMode = CollectionMode::NFT(2000);
let origin1 = Origin::signed(1);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -915,6 +1128,16 @@
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -937,8 +1160,16 @@
assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));
assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ true
+ ));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));
@@ -972,6 +1203,16 @@
let mode: CollectionMode = CollectionMode::NFT(2000);
let origin1 = Origin::signed(1);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -995,6 +1236,16 @@
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -1019,6 +1270,16 @@
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -1027,16 +1288,32 @@
mode
));
- assert_noop!(TemplateModule::add_to_white_list(origin2.clone(), 1, 3), "You do not have permissions to modify this collection");
+ assert_noop!(
+ TemplateModule::add_to_white_list(origin2.clone(), 1, 3),
+ "You do not have permissions to modify this collection"
+ );
});
}
#[test]
fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {
new_test_ext().execute_with(|| {
+ let origin1 = Origin::signed(1);
+
+ 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,
+ }));
- let origin1 = Origin::signed(1);
- assert_noop!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2), "This collection does not exist");
+ assert_noop!(
+ TemplateModule::add_to_white_list(origin1.clone(), 1, 2),
+ "This collection does not exist"
+ );
});
}
@@ -1049,6 +1326,16 @@
let mode: CollectionMode = CollectionMode::NFT(2000);
let origin1 = Origin::signed(1);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -1058,7 +1345,10 @@
));
assert_ok!(TemplateModule::destroy_collection(origin1.clone(), 1));
- assert_noop!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2), "This collection does not exist");
+ assert_noop!(
+ TemplateModule::add_to_white_list(origin1.clone(), 1, 2),
+ "This collection does not exist"
+ );
});
}
@@ -1066,13 +1356,22 @@
#[test]
fn address_is_already_added_to_white_list() {
new_test_ext().execute_with(|| {
-
let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
let mode: CollectionMode = CollectionMode::NFT(2000);
let origin1 = Origin::signed(1);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -1091,13 +1390,22 @@
#[test]
fn owner_can_remove_address_from_white_list() {
new_test_ext().execute_with(|| {
-
let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
let mode: CollectionMode = CollectionMode::NFT(2000);
let origin1 = Origin::signed(1);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -1107,7 +1415,11 @@
));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
- assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));
+ assert_ok!(TemplateModule::remove_from_white_list(
+ origin1.clone(),
+ 1,
+ 2
+ ));
assert_eq!(TemplateModule::white_list(1).len(), 0);
});
}
@@ -1115,7 +1427,6 @@
#[test]
fn admin_can_remove_address_from_white_list() {
new_test_ext().execute_with(|| {
-
let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
@@ -1123,6 +1434,16 @@
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -1134,7 +1455,11 @@
assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));
- assert_ok!(TemplateModule::remove_from_white_list(origin2.clone(), 1, 3));
+ assert_ok!(TemplateModule::remove_from_white_list(
+ origin2.clone(),
+ 1,
+ 3
+ ));
assert_eq!(TemplateModule::white_list(1).len(), 0);
});
}
@@ -1142,7 +1467,6 @@
#[test]
fn nonprivileged_user_cannot_remove_address_from_white_list() {
new_test_ext().execute_with(|| {
-
let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
@@ -1150,6 +1474,16 @@
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -1159,7 +1493,10 @@
));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
- assert_noop!(TemplateModule::remove_from_white_list(origin2.clone(), 1, 2), "You do not have permissions to modify this collection");
+ assert_noop!(
+ TemplateModule::remove_from_white_list(origin2.clone(), 1, 2),
+ "You do not have permissions to modify this collection"
+ );
assert_eq!(TemplateModule::white_list(1)[0], 2);
});
}
@@ -1167,16 +1504,28 @@
#[test]
fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {
new_test_ext().execute_with(|| {
+ let origin1 = Origin::signed(1);
+
+ 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,
+ }));
- let origin1 = Origin::signed(1);
- assert_noop!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2), "This collection does not exist");
+ assert_noop!(
+ TemplateModule::remove_from_white_list(origin1.clone(), 1, 2),
+ "This collection does not exist"
+ );
});
}
#[test]
fn nobody_can_remove_address_from_white_list_of_deleted_collection() {
new_test_ext().execute_with(|| {
-
let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
@@ -1184,6 +1533,16 @@
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -1194,7 +1553,10 @@
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
assert_ok!(TemplateModule::destroy_collection(origin1.clone(), 1));
- assert_noop!(TemplateModule::remove_from_white_list(origin2.clone(), 1, 2), "This collection does not exist");
+ assert_noop!(
+ TemplateModule::remove_from_white_list(origin2.clone(), 1, 2),
+ "This collection does not exist"
+ );
assert_eq!(TemplateModule::white_list(1).len(), 0);
});
}
@@ -1209,6 +1571,16 @@
let mode: CollectionMode = CollectionMode::NFT(2000);
let origin1 = Origin::signed(1);
+ 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,
+ }));
+
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
col_name1.clone(),
@@ -1218,8 +1590,16 @@
));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
- assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));
- assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));
+ assert_ok!(TemplateModule::remove_from_white_list(
+ origin1.clone(),
+ 1,
+ 2
+ ));
+ assert_ok!(TemplateModule::remove_from_white_list(
+ origin1.clone(),
+ 1,
+ 2
+ ));
assert_eq!(TemplateModule::white_list(1).len(), 0);
});
}
@@ -1233,6 +1613,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1250,16 +1640,17 @@
1
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
-
- assert_noop!(TemplateModule::transfer(
+ assert_ok!(TemplateModule::set_public_access_mode(
origin1.clone(),
- 3,
1,
- 1,
- 1
- ), "Address is not in white list");
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
+
+ assert_noop!(
+ TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),
+ "Address is not in white list"
+ );
});
}
@@ -1271,6 +1662,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1288,24 +1689,28 @@
1
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
// do approve
assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));
assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);
-
- assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 1));
- assert_noop!(TemplateModule::transfer_from(
+ assert_ok!(TemplateModule::remove_from_white_list(
origin1.clone(),
- 1,
- 3,
1,
- 1,
1
- ), "Address is not in white list");
+ ));
+
+ assert_noop!(
+ TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),
+ "Address is not in white list"
+ );
});
}
@@ -1318,6 +1723,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1335,16 +1750,17 @@
1
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
-
- assert_noop!(TemplateModule::transfer(
+ assert_ok!(TemplateModule::set_public_access_mode(
origin1.clone(),
- 3,
1,
- 1,
- 1
- ), "Address is not in white list");
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
+
+ assert_noop!(
+ TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),
+ "Address is not in white list"
+ );
});
}
@@ -1356,6 +1772,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1373,7 +1799,11 @@
1
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
@@ -1381,16 +1811,16 @@
assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));
assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);
- assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));
-
- assert_noop!(TemplateModule::transfer_from(
+ assert_ok!(TemplateModule::remove_from_white_list(
origin1.clone(),
- 1,
- 3,
1,
- 1,
- 1
- ), "Address is not in white list");
+ 2
+ ));
+
+ assert_noop!(
+ TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),
+ "Address is not in white list"
+ );
});
}
@@ -1403,6 +1833,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1420,8 +1860,15 @@
1
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_noop!(TemplateModule::burn_item(origin1.clone(), 1, 1), "Address is not in white list");
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
+ assert_noop!(
+ TemplateModule::burn_item(origin1.clone(), 1, 1),
+ "Address is not in white list"
+ );
});
}
@@ -1434,6 +1881,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1442,10 +1899,17 @@
token_prefix1.clone(),
mode
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
// do approve
- assert_noop!(TemplateModule::approve(origin1.clone(), 1, 1, 1), "Address is not in white list");
+ assert_noop!(
+ TemplateModule::approve(origin1.clone(), 1, 1, 1),
+ "Address is not in white list"
+ );
});
}
@@ -1459,6 +1923,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1476,17 +1950,15 @@
1
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
- assert_ok!(TemplateModule::transfer(
- origin1.clone(),
- 2,
- 1,
- 1,
- 1
- ));
+ assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1));
});
}
@@ -1498,6 +1970,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1515,7 +1997,11 @@
1
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
@@ -1543,6 +2029,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1552,8 +2048,16 @@
mode
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ false
+ ));
assert_ok!(TemplateModule::create_item(
origin1.clone(),
@@ -1573,6 +2077,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -1583,8 +2097,16 @@
mode
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ false
+ ));
assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));
@@ -1606,6 +2128,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -1616,16 +2148,22 @@
mode
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ false
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
- assert_noop!(TemplateModule::create_item(
- origin2.clone(),
- 1,
- [1, 2, 3].to_vec(),
- 2
- ), "Collection is not in mint mode");
+ assert_noop!(
+ TemplateModule::create_item(origin2.clone(), 1, [1, 2, 3].to_vec(), 2),
+ "Collection is not in mint mode"
+ );
});
}
@@ -1638,6 +2176,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -1648,15 +2196,21 @@
mode
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ false
+ ));
- assert_noop!(TemplateModule::create_item(
- origin2.clone(),
- 1,
- [1, 2, 3].to_vec(),
- 2
- ), "Collection is not in mint mode");
+ assert_noop!(
+ TemplateModule::create_item(origin2.clone(), 1, [1, 2, 3].to_vec(), 2),
+ "Collection is not in mint mode"
+ );
});
}
@@ -1669,6 +2223,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::create_collection(
origin1.clone(),
@@ -1678,8 +2242,16 @@
mode
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ true
+ ));
assert_ok!(TemplateModule::create_item(
origin1.clone(),
@@ -1699,6 +2271,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -1709,8 +2291,16 @@
mode
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ true
+ ));
assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));
@@ -1732,6 +2322,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -1742,15 +2342,21 @@
mode
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ true
+ ));
- assert_noop!(TemplateModule::create_item(
- origin2.clone(),
- 1,
- [1, 2, 3].to_vec(),
- 2
- ), "Address is not in white list");
+ assert_noop!(
+ TemplateModule::create_item(origin2.clone(), 1, [1, 2, 3].to_vec(), 2),
+ "Address is not in white list"
+ );
});
}
@@ -1763,6 +2369,16 @@
let token_prefix1: Vec<u8> = 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,
+ }));
+
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
assert_ok!(TemplateModule::create_collection(
@@ -1773,8 +2389,16 @@
mode
));
- assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));
- assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));
+ assert_ok!(TemplateModule::set_public_access_mode(
+ origin1.clone(),
+ 1,
+ AccessMode::WhiteList
+ ));
+ assert_ok!(TemplateModule::set_mint_permission(
+ origin1.clone(),
+ 1,
+ true
+ ));
assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));
assert_ok!(TemplateModule::create_item(
@@ -1786,4 +2410,290 @@
});
}
-// #endregion
\ No newline at end of file
+// Total number of collections. Positive test
+#[test]
+fn total_number_collections_bound() {
+ new_test_ext().execute_with(|| {
+ let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = 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,
+ }));
+
+ let origin1 = Origin::signed(1);
+ assert_ok!(TemplateModule::create_collection(
+ origin1.clone(),
+ col_name1.clone(),
+ col_desc1.clone(),
+ token_prefix1.clone(),
+ mode
+ ));
+ });
+}
+
+// Total number of collections. Negotive test
+#[test]
+fn total_number_collections_bound_neg() {
+ new_test_ext().execute_with(|| {
+ let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = 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,
+ }));
+
+ let origin1 = Origin::signed(1);
+
+ for _ in 0..10 {
+
+ assert_ok!(TemplateModule::create_collection(
+ origin1.clone(),
+ col_name1.clone(),
+ col_desc1.clone(),
+ token_prefix1.clone(),
+ mode.clone()
+ ));
+ }
+
+ // 11-th collection in chain. Expects error
+ assert_noop!(TemplateModule::create_collection(
+ origin1.clone(),
+ col_name1.clone(),
+ col_desc1.clone(),
+ token_prefix1.clone(),
+ mode.clone()
+ ), "Total collections bound exceeded");
+ });
+}
+
+// Owned tokens by a single address. Positive test
+#[test]
+fn owned_tokens_bound() {
+ new_test_ext().execute_with(|| {
+ let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = 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,
+ }));
+
+ let origin1 = Origin::signed(1);
+ assert_ok!(TemplateModule::create_collection(
+ origin1.clone(),
+ col_name1.clone(),
+ col_desc1.clone(),
+ token_prefix1.clone(),
+ mode
+ ));
+
+ assert_ok!(TemplateModule::create_item(
+ origin1.clone(),
+ 1,
+ [1, 2, 3].to_vec(),
+ 1
+ ));
+
+ assert_ok!(TemplateModule::create_item(
+ origin1.clone(),
+ 1,
+ [1, 2, 3].to_vec(),
+ 1
+ ));
+ });
+}
+
+// Owned tokens by a single address. Negotive test
+#[test]
+fn owned_tokens_bound_neg() {
+ new_test_ext().execute_with(|| {
+ let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = 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: 1,
+ collections_admins_limit: 5,
+ custom_data_limit: 2048,
+ nft_sponsor_transfer_timeout: 15,
+ fungible_sponsor_transfer_timeout: 15,
+ refungible_sponsor_transfer_timeout: 15,
+ }));
+
+ let origin1 = Origin::signed(1);
+ assert_ok!(TemplateModule::create_collection(
+ origin1.clone(),
+ col_name1.clone(),
+ col_desc1.clone(),
+ token_prefix1.clone(),
+ mode
+ ));
+
+ assert_ok!(TemplateModule::create_item(
+ origin1.clone(),
+ 1,
+ [1, 2, 3].to_vec(),
+ 1
+ ));
+
+ assert_noop!(TemplateModule::create_item(
+ origin1.clone(),
+ 1,
+ [1, 2, 3].to_vec(),
+ 1
+ ), "Owned tokens by a single address bound exceeded");
+ });
+}
+
+// Number of collection admins. Positive test
+#[test]
+fn collection_admins_bound() {
+ new_test_ext().execute_with(|| {
+ let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = 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: 2,
+ custom_data_limit: 2048,
+ nft_sponsor_transfer_timeout: 15,
+ fungible_sponsor_transfer_timeout: 15,
+ refungible_sponsor_transfer_timeout: 15,
+ }));
+
+ let origin1 = Origin::signed(1);
+ assert_ok!(TemplateModule::create_collection(
+ origin1.clone(),
+ col_name1.clone(),
+ col_desc1.clone(),
+ token_prefix1.clone(),
+ mode
+ ));
+
+ assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));
+ assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 3));
+ });
+}
+
+// Number of collection admins. Negotive test
+#[test]
+fn collection_admins_bound_neg() {
+ new_test_ext().execute_with(|| {
+ let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = 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: 1,
+ collections_admins_limit: 1,
+ custom_data_limit: 2048,
+ nft_sponsor_transfer_timeout: 15,
+ fungible_sponsor_transfer_timeout: 15,
+ refungible_sponsor_transfer_timeout: 15,
+ }));
+
+ let origin1 = Origin::signed(1);
+ assert_ok!(TemplateModule::create_collection(
+ origin1.clone(),
+ col_name1.clone(),
+ col_desc1.clone(),
+ token_prefix1.clone(),
+ mode
+ ));
+
+ assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));
+ assert_noop!(TemplateModule::add_collection_admin(origin1.clone(), 1, 3), "Number of collection admins bound exceeded");
+ });
+}
+
+// Custom data size. Positive test
+#[test]
+fn custom_data_size_bound() {
+ new_test_ext().execute_with(|| {
+ let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = 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,
+ }));
+
+ let origin1 = Origin::signed(1);
+ assert_ok!(TemplateModule::create_collection(
+ origin1.clone(),
+ col_name1.clone(),
+ col_desc1.clone(),
+ token_prefix1.clone(),
+ mode
+ ));
+ });
+}
+
+// Custom data size. Negotive test
+#[test]
+fn custom_data_size_bound_neg() {
+ new_test_ext().execute_with(|| {
+ let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = 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: 200,
+ nft_sponsor_transfer_timeout: 15,
+ fungible_sponsor_transfer_timeout: 15,
+ refungible_sponsor_transfer_timeout: 15,
+ }));
+
+ let origin1 = Origin::signed(1);
+ assert_noop!(TemplateModule::create_collection(
+ origin1.clone(),
+ col_name1.clone(),
+ col_desc1.clone(),
+ token_prefix1.clone(),
+ mode
+ ), "Custom data size bound exceeded");
+ });
+}
+// #endregion