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.rsdiffbeforeafterboth135 mode: CollectionMode::NFT(50),137 mode: CollectionMode::NFT(50),136 access: AccessMode::Normal,138 access: AccessMode::Normal,137 decimal_points: 0,139 decimal_points: 0,138 name: vec!(),140 name: vec![],139 description: vec!(),141 description: vec![],140 token_prefix: vec!(),142 token_prefix: vec![],141 custom_data_size: 50,143 custom_data_size: 50,142 mint_mode: false,144 mint_mode: false,143 offchain_schema: vec!(),145 offchain_schema: vec![],144 sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),146 sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),145 unconfirmed_sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),147 unconfirmed_sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),146 })],148 },149 )],147 nft_item_id: vec!(),150 nft_item_id: vec![],148 fungible_item_id: vec!(),151 fungible_item_id: vec![],149 refungible_item_id: vec!(),152 refungible_item_id: vec![],153 chain_limit: ChainLimits {154 collection_numbers_limit: 10,155 account_token_ownership_limit: 10,156 collections_admins_limit: 5,157 custom_data_limit: 2048,158 nft_sponsor_transfer_timeout: 15,159 fungible_sponsor_transfer_timeout: 15,160 refungible_sponsor_transfer_timeout: 15,161 },150 }),162 }),151 contracts: Some(ContractsConfig {163 contracts: Some(ContractsConfig {152 current_schedule: ContractsSchedule {164 current_schedule: ContractsSchedule {pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -1,6 +1,9 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
+pub use std::*;
+
+#[cfg(feature = "std")]
pub use serde::*;
use codec::{Decode, Encode};
@@ -20,7 +23,7 @@
IsSubType, StorageValue,
};
-use frame_system::{self as system, ensure_signed};
+use frame_system::{self as system, ensure_signed, ensure_root};
use sp_runtime::sp_std::prelude::Vec;
use sp_runtime::{
traits::{
@@ -157,6 +160,27 @@
pub vesting_date: Moment,
}
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+pub struct BasketItem<AccountId, BlockNumber> {
+ pub address: AccountId,
+ pub start_block: BlockNumber,
+}
+
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+pub struct ChainLimits {
+ pub collection_numbers_limit: u64,
+ pub account_token_ownership_limit: u64,
+ pub collections_admins_limit: u64,
+ pub custom_data_limit: u32,
+
+ // Timeouts for item types in passed blocks
+ pub nft_sponsor_transfer_timeout: u32,
+ pub fungible_sponsor_transfer_timeout: u32,
+ pub refungible_sponsor_transfer_timeout: u32,
+}
+
pub trait Trait: system::Trait {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
@@ -172,6 +196,14 @@
ChainVersion: u64;
ItemListIndex: map hasher(blake2_128_concat) u64 => u64;
+ // Chain limits struct
+ pub ChainLimit get(fn chain_limit) config(): ChainLimits;
+
+ // Bound counters
+ CollectionCount: u64;
+ pub AccountItemCount get(fn account_item_count): map hasher(identity) T::AccountId => u64;
+
+ // Basic collections
pub Collection get(fn collection) config(): map hasher(identity) u64 => CollectionType<T::AccountId>;
pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;
pub WhiteList get(fn white_list): map hasher(identity) u64 => Vec<T::AccountId>;
@@ -190,13 +222,18 @@
/// Index list
pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;
+ /// Tokens transfer baskets
+ pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;
+ 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>>;
+ pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;
+
// Sponsorship
pub ContractSponsor get(fn contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;
pub UnconfirmedContractSponsor get(fn unconfirmed_contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;
}
add_extra_genesis {
build(|config: &GenesisConfig<T>| {
- // Modification of storage
+ // Modification of storage
for (_num, _c) in &config.collection {
<Module<T>>::init_collection(_c);
}
@@ -212,7 +249,7 @@
for (_num, _q, _i) in &config.refungible_item_id {
<Module<T>>::init_refungible_token(_i);
}
- })
+ })
}
}
@@ -295,8 +332,18 @@
// Anyone can create a collection
let who = ensure_signed(origin)?;
let custom_data_size = match mode {
- CollectionMode::NFT(size) => size,
- CollectionMode::ReFungible(size, _) => size,
+ CollectionMode::NFT(size) => {
+
+ // bound Custom data size
+ ensure!(size < ChainLimit::get().custom_data_limit, "Custom data size bound exceeded");
+ size
+ },
+ CollectionMode::ReFungible(size, _) => {
+
+ // bound Custom data size
+ ensure!(size < ChainLimit::get().custom_data_limit, "Custom data size bound exceeded");
+ size
+ },
_ => 0
};
@@ -306,6 +353,9 @@
_ => 0
};
+ // bound Total number of collections
+ ensure!(CollectionCount::get() < ChainLimit::get().collection_numbers_limit, "Total collections bound exceeded");
+
// check params
ensure!(decimal_points <= 4, "decimal_points parameter must be lower than 4");
@@ -326,7 +376,13 @@
.checked_add(1)
.expect("collection id error");
+ // bound counter
+ let total = CollectionCount::get()
+ .checked_add(1)
+ .expect("collection counter error");
+
CreatedCollectionCount::put(next_id);
+ CollectionCount::put(total);
// Create new collection
let new_collection = CollectionType {
@@ -368,7 +424,6 @@
let sender = ensure_signed(origin)?;
Self::check_owner_permissions(collection_id, sender)?;
- // TODO Items remove
<AddressTokens<T>>::remove_prefix(collection_id);
<ApprovedList<T>>::remove_prefix(collection_id);
<Balance<T>>::remove_prefix(collection_id);
@@ -377,6 +432,24 @@
<Collection<T>>::remove(collection_id);
<WhiteList<T>>::remove(collection_id);
+ <NftItemList<T>>::remove_prefix(collection_id);
+ <FungibleItemList<T>>::remove_prefix(collection_id);
+ <ReFungibleItemList<T>>::remove_prefix(collection_id);
+
+ <NftTransferBasket<T>>::remove_prefix(collection_id);
+ <FungibleTransferBasket<T>>::remove_prefix(collection_id);
+ <ReFungibleTransferBasket<T>>::remove_prefix(collection_id);
+
+ if CollectionCount::get() > 0
+ {
+ // bound couter
+ let total = CollectionCount::get()
+ .checked_sub(1)
+ .expect("collection counter error");
+
+ CollectionCount::put(total);
+ }
+
Ok(())
}
@@ -544,6 +617,9 @@
ensure!(!admin_arr.contains(&new_admin_id), "Account already has admin role");
}
+ // Number of collection admins
+ ensure!((admin_arr.len() as u64) < ChainLimit::get().collections_admins_limit, "Number of collection admins bound exceeded");
+
admin_arr.push(new_admin_id);
<AdminList<T>>::insert(collection_id, admin_arr);
@@ -758,8 +834,8 @@
// Transfer permissions check
let target_collection = <Collection<T>>::get(collection_id);
- ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
- Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
+ Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
"Only item owner, collection owner and admins can modify item");
if target_collection.access == AccessMode::WhiteList {
@@ -810,8 +886,8 @@
// Transfer permissions check
let target_collection = <Collection<T>>::get(collection_id);
- ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
- Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
+ Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
"Only item owner, collection owner and admins can modify item");
if target_collection.access == AccessMode::WhiteList {
@@ -852,8 +928,8 @@
// Transfer permissions check
let target_collection = <Collection<T>>::get(collection_id);
- ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
- Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
+ Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
"Only item owner, collection owner and admins can approve");
if target_collection.access == AccessMode::WhiteList {
@@ -919,7 +995,7 @@
// Transfer permissions check
let target_collection = <Collection<T>>::get(collection_id);
- ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
"Only item owner, collection owner and admins can modify items");
if target_collection.access == AccessMode::WhiteList {
@@ -987,6 +1063,17 @@
Ok(())
}
+
+ // Sudo permissions function
+ #[weight = 0]
+ pub fn set_chain_limits(
+ origin,
+ limits: ChainLimits
+ ) -> DispatchResult {
+ ensure_root(origin)?;
+ <ChainLimit>::put(limits);
+ Ok(())
+ }
}
}
@@ -1004,6 +1091,10 @@
<ItemListIndex>::insert(item.collection, current_index);
<FungibleItemList<T>>::insert(item.collection, current_index, itemcopy);
+ // Add current block
+ let v: Vec<BasketItem<T::AccountId, T::BlockNumber>> = Vec::new();
+ <FungibleTransferBasket<T>>::insert(item.collection, current_index, v);
+
// Update balance
let new_balance = <Balance<T>>::get(item.collection, owner.clone())
.checked_add(value)
@@ -1027,6 +1118,10 @@
<ItemListIndex>::insert(item.collection, current_index);
<ReFungibleItemList<T>>::insert(item.collection, current_index, itemcopy);
+ // Add current block
+ let block_number: T::BlockNumber = 0.into();
+ <ReFungibleTransferBasket<T>>::insert(item.collection, current_index, block_number);
+
// Update balance
let new_balance = <Balance<T>>::get(item.collection, owner.clone())
.checked_add(value)
@@ -1048,6 +1143,10 @@
<ItemListIndex>::insert(collection_id, current_index);
<NftItemList<T>>::insert(collection_id, current_index, item);
+ // Add current block
+ let block_number: T::BlockNumber = 0.into();
+ <NftTransferBasket<T>>::insert(collection_id, current_index, block_number);
+
// Update balance
let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())
.checked_add(1)
@@ -1057,7 +1156,11 @@
Ok(())
}
- fn burn_refungible_item(collection_id: u64, item_id: u64, owner: T::AccountId) -> DispatchResult {
+ fn burn_refungible_item(
+ collection_id: u64,
+ item_id: u64,
+ owner: T::AccountId,
+ ) -> DispatchResult {
ensure!(
<ReFungibleItemList<T>>::contains_key(collection_id, item_id),
"Item does not exists"
@@ -1149,7 +1252,6 @@
}
fn is_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> bool {
-
let target_collection = <Collection<T>>::get(collection_id);
let mut result: bool = subject == target_collection.owner;
let exists = <AdminList<T>>::contains_key(collection_id);
@@ -1163,12 +1265,17 @@
result
}
- fn check_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> DispatchResult {
-
+ fn check_owner_or_admin_permissions(
+ collection_id: u64,
+ subject: T::AccountId,
+ ) -> DispatchResult {
Self::collection_exists(collection_id)?;
let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());
- ensure!(result, "You do not have permissions to modify this collection");
+ ensure!(
+ result,
+ "You do not have permissions to modify this collection"
+ );
Ok(())
}
@@ -1193,7 +1300,6 @@
}
fn check_white_list(collection_id: u64, address: &T::AccountId) -> DispatchResult {
-
let mes = "Address is not in white list";
ensure!(<WhiteList<T>>::contains_key(collection_id), mes);
let wl = <WhiteList<T>>::get(collection_id);
@@ -1209,7 +1315,6 @@
owner: T::AccountId,
new_owner: T::AccountId,
) -> DispatchResult {
-
ensure!(
<FungibleItemList<T>>::contains_key(collection_id, item_id),
"Item not exists"
@@ -1299,7 +1404,6 @@
owner: T::AccountId,
new_owner: T::AccountId,
) -> DispatchResult {
-
ensure!(
<ReFungibleItemList<T>>::contains_key(collection_id, item_id),
"Item not exists"
@@ -1385,7 +1489,6 @@
sender: T::AccountId,
new_owner: T::AccountId,
) -> DispatchResult {
-
ensure!(
<NftItemList<T>>::contains_key(collection_id, item_id),
"Item not exists"
@@ -1422,24 +1525,34 @@
Ok(())
}
- fn init_collection(item: &CollectionType<T::AccountId>){
+ fn init_collection(item: &CollectionType<T::AccountId>) {
+ // check params
+ assert!(
+ item.decimal_points <= 4,
+ "decimal_points parameter must be lower than 4"
+ );
+ assert!(
+ item.name.len() <= 64,
+ "Collection name can not be longer than 63 char"
+ );
+ assert!(
+ item.name.len() <= 256,
+ "Collection description can not be longer than 255 char"
+ );
+ assert!(
+ item.token_prefix.len() <= 16,
+ "Token prefix can not be longer than 15 char"
+ );
- // check params
- assert!(item.decimal_points <= 4, "decimal_points parameter must be lower than 4");
- assert!(item.name.len() <= 64, "Collection name can not be longer than 63 char");
- assert!(item.name.len() <= 256, "Collection description can not be longer than 255 char");
- assert!(item.token_prefix.len() <= 16, "Token prefix can not be longer than 15 char");
-
- // Generate next collection ID
- let next_id = CreatedCollectionCount::get()
- .checked_add(1)
- .expect("collection id error");
-
- CreatedCollectionCount::put(next_id);
- }
+ // Generate next collection ID
+ let next_id = CreatedCollectionCount::get()
+ .checked_add(1)
+ .expect("collection id error");
- fn init_nft_token(item: &NftItemType<T::AccountId>){
+ CreatedCollectionCount::put(next_id);
+ }
+ fn init_nft_token(item: &NftItemType<T::AccountId>) {
let current_index = <ItemListIndex>::get(item.collection)
.checked_add(1)
.expect("Item list index id error");
@@ -1457,8 +1570,7 @@
<Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);
}
- fn init_fungible_token(item: &FungibleItemType<T::AccountId>){
-
+ fn init_fungible_token(item: &FungibleItemType<T::AccountId>) {
let current_index = <ItemListIndex>::get(item.collection)
.checked_add(1)
.expect("Item list index id error");
@@ -1476,8 +1588,7 @@
<Balance<T>>::insert(item.collection, owner.clone(), new_balance);
}
- fn init_refungible_token(item: &ReFungibleItemType<T::AccountId>){
-
+ fn init_refungible_token(item: &ReFungibleItemType<T::AccountId>) {
let current_index = <ItemListIndex>::get(item.collection)
.checked_add(1)
.expect("Item list index id error");
@@ -1497,6 +1608,21 @@
}
fn add_token_index(collection_id: u64, item_index: u64, owner: T::AccountId) -> DispatchResult {
+
+ // add to account limit
+ if <AccountItemCount<T>>::contains_key(owner.clone()) {
+
+ // bound Owned tokens by a single address
+ let count = <AccountItemCount<T>>::get(owner.clone());
+ ensure!(count < ChainLimit::get().account_token_ownership_limit, "Owned tokens by a single address bound exceeded");
+
+ <AccountItemCount<T>>::insert(owner.clone(),
+ count.checked_add(1).unwrap());
+ }
+ else {
+ <AccountItemCount<T>>::insert(owner.clone(), 1);
+ }
+
let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.clone());
if list_exists {
let mut list = <AddressTokens<T>>::get(collection_id, owner.clone());
@@ -1511,6 +1637,7 @@
let mut itm = Vec::new();
itm.push(item_index.clone());
<AddressTokens<T>>::insert(collection_id, owner, itm);
+
}
Ok(())
@@ -1521,6 +1648,12 @@
item_index: u64,
owner: T::AccountId,
) -> DispatchResult {
+
+ // update counter
+ <AccountItemCount<T>>::insert(owner.clone(),
+ <AccountItemCount<T>>::get(owner.clone()).checked_sub(1).unwrap());
+
+
let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.clone());
if list_exists {
let mut list = <AddressTokens<T>>::get(collection_id, owner.clone());
@@ -1628,7 +1761,65 @@
<Collection<T>>::get(collection_id).sponsor
}
Some(Call::transfer(_new_owner, collection_id, _item_id, _value)) => {
- <Collection<T>>::get(collection_id).sponsor
+ let _collection_mode = <Collection<T>>::get(collection_id).mode;
+
+ // sponsor timeout
+ let sponsor_transfer = match _collection_mode {
+ CollectionMode::NFT(_) => {
+ let basket = <NftTransferBasket<T>>::get(collection_id, _item_id);
+ let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
+ let limit_time = basket + ChainLimit::get().nft_sponsor_transfer_timeout.into();
+ if block_number >= limit_time {
+ <NftTransferBasket<T>>::insert(collection_id, _item_id, block_number);
+ true
+ }
+ else {
+ false
+ }
+ }
+ CollectionMode::Fungible(_) => {
+ let mut basket = <FungibleTransferBasket<T>>::get(collection_id, _item_id);
+ let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
+ if basket.iter().any(|i| i.address == _new_owner.clone())
+ {
+ let item = basket.iter_mut().find(|i| i.address == _new_owner.clone()).unwrap().clone();
+ let limit_time = item.start_block + ChainLimit::get().fungible_sponsor_transfer_timeout.into();
+ if block_number >= limit_time {
+ basket.retain(|x| x.address == item.address);
+ basket.push(BasketItem { start_block: block_number, address: _new_owner.clone() });
+ <FungibleTransferBasket<T>>::insert(collection_id, _item_id, basket);
+ true
+ }
+ else {
+ false
+ }
+ }
+ else {
+ basket.push(BasketItem { start_block: block_number, address: _new_owner.clone()});
+ true
+ }
+ }
+ CollectionMode::ReFungible(_, _) => {
+ let basket = <ReFungibleTransferBasket<T>>::get(collection_id, _item_id);
+ let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
+ let limit_time = basket + ChainLimit::get().nft_sponsor_transfer_timeout.into();
+ if block_number >= limit_time {
+ <ReFungibleTransferBasket<T>>::insert(collection_id, _item_id, block_number);
+ true
+ } else {
+ false
+ }
+ }
+ _ => {
+ false
+ },
+ };
+
+ if !sponsor_transfer {
+ T::AccountId::default()
+ } else {
+ <Collection<T>>::get(collection_id).sponsor
+ }
}
_ => T::AccountId::default(),
@@ -1745,4 +1936,4 @@
Ok(())
}
}
-// #endregion
\ No newline at end of file
+// #endregion
pallets/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