git.delta.rocks / unique-network / refs/commits / 4bce10c77fc9

difftreelog

Fix collection limits

Greg Zaitsev2021-02-26parent: #4b68421.patch.diff
in: master

3 files changed

modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -383,7 +383,7 @@
         /// Collection limit bounds per collection exceeded
         CollectionLimitBoundsExceeded,
         /// Tried to enable permissions which are only permitted to be disabled
-        OwnerPermissionsCantBeReturned,
+        OwnerPermissionsCantBeReverted,
         /// Schema data size limit bound exceeded
         SchemaDataLimitExceeded,
         /// Maximum refungibility exceeded
@@ -626,7 +626,7 @@
             let sender = ensure_signed(origin)?;
             Self::check_owner_permissions(collection_id, sender)?;
 
-            let mut target_collection = <Collection<T>>::get(collection_id);
+            let target_collection = <Collection<T>>::get(collection_id);
             if !target_collection.limits.owner_can_destroy {
                 fail!(Error::<T>::NoPermission);
             }
@@ -1532,31 +1532,32 @@
         pub fn set_collection_limits(
             origin,
             collection_id: u32,
-            limits: CollectionLimits,
+            new_limits: CollectionLimits,
         ) -> DispatchResult {
             let sender = ensure_signed(origin)?;
             Self::check_owner_permissions(collection_id, sender.clone())?;
             let mut target_collection = <Collection<T>>::get(collection_id);
+            let old_limits = target_collection.limits;
             let chain_limits = ChainLimit::get();
-            let climits = target_collection.limits;
 
             // collection bounds
-            ensure!(limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&
-                limits.account_token_ownership_limit <= MAX_TOKEN_OWNERSHIP,  
+            ensure!(new_limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&
+                new_limits.account_token_ownership_limit <= MAX_TOKEN_OWNERSHIP && 
+                new_limits.sponsored_data_size <= chain_limits.custom_data_limit &&
+                new_limits.sponsored_mint_size <= chain_limits.custom_data_limit,
                 Error::<T>::CollectionLimitBoundsExceeded);
 
             // token_limit   check  prev
-            ensure!(climits.token_limit > limits.token_limit && 
-                limits.token_limit <= chain_limits.account_token_ownership_limit, 
-                Error::<T>::AccountTokenLimitExceeded);
+            ensure!(old_limits.token_limit >= new_limits.token_limit, Error::<T>::CollectionTokenLimitExceeded);
+            ensure!(new_limits.token_limit > 0, Error::<T>::CollectionTokenLimitExceeded);
 
             ensure!(
-                (climits.owner_can_transfer || !limits.owner_can_transfer) &&
-                (climits.owner_can_destroy || !limits.owner_can_destroy),
-                Error::<T>::OwnerPermissionsCantBeReturned,
+                (old_limits.owner_can_transfer || !new_limits.owner_can_transfer) &&
+                (old_limits.owner_can_destroy || !new_limits.owner_can_destroy),
+                Error::<T>::OwnerPermissionsCantBeReverted,
             );
 
-            target_collection.limits = limits;
+            target_collection.limits = new_limits;
             <Collection<T>>::insert(collection_id, target_collection);
 
             Ok(())
modifiedtests/src/setCollectionLimits.test.tsdiffbeforeafterboth
28const accountTokenOwnershipLimit = 0;28const accountTokenOwnershipLimit = 0;
29const sponsoredDataSize = 0;29const sponsoredDataSize = 0;
30const sponsoredMintSize = 0;30const sponsoredMintSize = 0;
31const tokenLimit = 0;31const sponsorTimeout = 1;
32
33describe('hooks', () => {
34 before(async () => {
35 await usingApi(async () => {
36 const keyring = new Keyring({ type: 'sr25519' });32const tokenLimit = 1;
37 alice = keyring.addFromUri('//Alice');
38 });
39 });
40 it('choose or create collection for testing', async () => {
41 await usingApi(async () => {
42 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
43 });
44 });
45});
4633
47describe('setCollectionLimits positive', () => {34describe('setCollectionLimits positive', () => {
48 let tx;35 let tx;
49 before(async () => {36 before(async () => {
50 await usingApi(async () => {37 await usingApi(async () => {
51 const keyring = new Keyring({ type: 'sr25519' });38 const keyring = new Keyring({ type: 'sr25519' });
52 alice = keyring.addFromUri('//Alice');39 alice = keyring.addFromUri('//Alice');
40 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
53 });41 });
54 });42 });
55 it('execute setCollectionLimits with predefined params ', async () => {
56 await usingApi(async (api: ApiPromise) => {
57 tx = api.tx.nft.setCollectionLimits(
58 collectionIdForTesting,
59 {
60 accountTokenOwnershipLimit,
61 sponsoredDataSize,
62 sponsoredMintSize,
63 tokenLimit,
64 },
65 );
66 const events = await submitTransactionAsync(alice, tx);
67 const result = getCreateItemResult(events);
68 // tslint:disable-next-line:no-unused-expression
69 expect(result.success).to.be.true;
70 });
71 });
72 it('get collection limits defined in previous test', async () => {43 it('execute setCollectionLimits with predefined params ', async () => {
73 await usingApi(async (api: ApiPromise) => {44 await usingApi(async (api: ApiPromise) => {
45 tx = api.tx.nft.setCollectionLimits(
46 collectionIdForTesting,
47 {
48 AccountTokenOwnershipLimit: accountTokenOwnershipLimit,
49 SponsoredMintSize: sponsoredDataSize,
50 TokenLimit: tokenLimit,
51 SponsorTimeout: sponsorTimeout,
52 OwnerCanTransfer: true,
53 OwnerCanDestroy: true
54 },
55 );
56 const events = await submitTransactionAsync(alice, tx);
57 const result = getCreateItemResult(events);
58
59 // get collection limits defined previously
74 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;60 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;
61
62 // tslint:disable-next-line:no-unused-expression
63 expect(result.success).to.be.true;
75 expect(collectionInfo.Limits.AccountTokenOwnershipLimit.toNumber()).to.be.equal(accountTokenOwnershipLimit);64 expect(collectionInfo.Limits.AccountTokenOwnershipLimit.toNumber()).to.be.equal(accountTokenOwnershipLimit);
76 expect(collectionInfo.Limits.SponsoredMintSize.toNumber()).to.be.equal(sponsoredMintSize);65 expect(collectionInfo.Limits.SponsoredMintSize.toNumber()).to.be.equal(sponsoredDataSize);
77 expect(collectionInfo.Limits.TokenLimit.toNumber()).to.be.equal(tokenLimit);66 expect(collectionInfo.Limits.TokenLimit.toNumber()).to.be.equal(tokenLimit);
78 expect(collectionInfo.Limits.SponsorTimeout.toNumber()).to.be.equal(sponsoredDataSize);67 expect(collectionInfo.Limits.SponsorTimeout.toNumber()).to.be.equal(sponsorTimeout);
68 expect(collectionInfo.Limits.OwnerCanTransfer.valueOf()).to.be.true;
69 expect(collectionInfo.Limits.OwnerCanDestroy.valueOf()).to.be.true;
79 });70 });
80 });71 });
81});72});
87 const keyring = new Keyring({ type: 'sr25519' });78 const keyring = new Keyring({ type: 'sr25519' });
88 alice = keyring.addFromUri('//Alice');79 alice = keyring.addFromUri('//Alice');
89 bob = keyring.addFromUri('//Bob');80 bob = keyring.addFromUri('//Bob');
81 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
90 });82 });
91 });83 });
92 it('execute setCollectionLimits for not exists collection', async () => {84 it('execute setCollectionLimits for not exists collection', async () => {
137 it('fails when trying to enable OwnerCanTransfer after it was disabled', async () => {129 it('fails when trying to enable OwnerCanTransfer after it was disabled', async () => {
138 const collectionId = await createCollectionExpectSuccess();130 const collectionId = await createCollectionExpectSuccess();
139 await setCollectionLimitsExpectSuccess(alice, collectionId, { OwnerCanTransfer: false });131 await setCollectionLimitsExpectSuccess(alice, collectionId, {
132 AccountTokenOwnershipLimit: accountTokenOwnershipLimit,
133 SponsoredMintSize: sponsoredDataSize,
134 TokenLimit: tokenLimit,
135 SponsorTimeout: sponsorTimeout,
136 OwnerCanTransfer: false,
137 OwnerCanDestroy: true
138 });
140 await setCollectionLimitsExpectFailure(alice, collectionId, { OwnerCanTransfer: true });139 await setCollectionLimitsExpectFailure(alice, collectionId, {
140 AccountTokenOwnershipLimit: accountTokenOwnershipLimit,
141 SponsoredMintSize: sponsoredDataSize,
142 TokenLimit: tokenLimit,
143 SponsorTimeout: sponsorTimeout,
144 OwnerCanTransfer: true,
145 OwnerCanDestroy: true
146 });
141 });147 });
142148
143 it('fails when trying to enable OwnerCanDestroy after it was disabled', async () => {149 it('fails when trying to enable OwnerCanDestroy after it was disabled', async () => {
144 const collectionId = await createCollectionExpectSuccess();150 const collectionId = await createCollectionExpectSuccess();
145 await setCollectionLimitsExpectSuccess(alice, collectionId, { OwnerCanDestroy: false });151 await setCollectionLimitsExpectSuccess(alice, collectionId, {
152 AccountTokenOwnershipLimit: accountTokenOwnershipLimit,
153 SponsoredMintSize: sponsoredDataSize,
154 TokenLimit: tokenLimit,
155 SponsorTimeout: sponsorTimeout,
156 OwnerCanTransfer: true,
157 OwnerCanDestroy: false
158 });
146 await setCollectionLimitsExpectFailure(alice, collectionId, { OwnerCanDestroy: true });159 await setCollectionLimitsExpectFailure(alice, collectionId, {
160 AccountTokenOwnershipLimit: accountTokenOwnershipLimit,
161 SponsoredMintSize: sponsoredDataSize,
162 TokenLimit: tokenLimit,
163 SponsorTimeout: sponsorTimeout,
164 OwnerCanTransfer: true,
165 OwnerCanDestroy: true
166 });
147 });167 });
modifiedtests/src/types.tsdiffbeforeafterboth
--- a/tests/src/types.ts
+++ b/tests/src/types.ts
@@ -17,6 +17,8 @@
     SponsoredMintSize: BN;
     TokenLimit: BN;
     SponsorTimeout: BN;
+    OwnerCanTransfer: boolean;
+    OwnerCanDestroy: boolean;
   };
   MintMode: boolean;
   Mode: {