git.delta.rocks / unique-network / refs/commits / fdba90f71ab4

difftreelog

Add int.test for createItem rate limiting and some changes to rate limiting logic

Greg Zaitsev2021-01-18parent: #5743a92.patch.diff
in: master

2 files changed

modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
419 pub AddressTokens get(fn address_tokens): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => Vec<TokenId>;419 pub AddressTokens get(fn address_tokens): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => Vec<TokenId>;
420420
421 /// Tokens transfer baskets421 /// Tokens transfer baskets
422 pub CreateItemBasket get(fn create_item_basket): map hasher(identity) CollectionId => T::BlockNumber;422 pub CreateItemBasket get(fn create_item_basket): map hasher(twox_64_concat) (CollectionId, T::AccountId) => T::BlockNumber;
423 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;423 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;
424 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;424 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;
425 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;425 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;
23032303
2304 let limit = <Collection<T>>::get(collection_id).limits.sponsor_transfer_timeout;2304 let limit = <Collection<T>>::get(collection_id).limits.sponsor_transfer_timeout;
2305 let mut sponsored = true;2305 let mut sponsored = true;
2306 if <CreateItemBasket<T>>::contains_key(collection_id) {2306 if <CreateItemBasket<T>>::contains_key((collection_id, &who)) {
2307 let last_tx_block = <CreateItemBasket<T>>::get(collection_id);2307 let last_tx_block = <CreateItemBasket<T>>::get((collection_id, &who));
2308 let limit_time = last_tx_block + limit.into();2308 let limit_time = last_tx_block + limit.into();
2309 if block_number <= limit_time {2309 if block_number <= limit_time {
2310 sponsored = false;2310 sponsored = false;
2311 }2311 }
2312 }2312 }
2313 if sponsored {2313 if sponsored {
2314 <CreateItemBasket<T>>::insert(collection_id, block_number);2314 <CreateItemBasket<T>>::insert((collection_id, who.clone()), block_number);
2315 }2315 }
23162316
2317 // check free create limit2317 // check free create limit
modifiedtests/src/confirmSponsorship.test.tsdiffbeforeafterboth
--- a/tests/src/confirmSponsorship.test.ts
+++ b/tests/src/confirmSponsorship.test.ts
@@ -170,7 +170,7 @@
     });
   });
 
-  it('NFT: Sponsoring is rate limited', async () => {
+  it('NFT: Sponsoring of transfers is rate limited', async () => {
     const collectionId = await createCollectionExpectSuccess();
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
     await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
@@ -209,7 +209,7 @@
     });
   });
 
-  it('Fungible: Sponsoring is rate limited', async () => {
+  it('Fungible: Sponsoring of transfers is rate limited', async () => {
     const collectionId = await createCollectionExpectSuccess({mode: 'Fungible'});
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
     await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
@@ -246,7 +246,7 @@
     });
   });
 
-  it('ReFungible: Sponsoring is rate limited', async () => {
+  it('ReFungible: Sponsoring of transfers is rate limited', async () => {
     const collectionId = await createCollectionExpectSuccess({mode: 'ReFungible'});
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
     await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
@@ -285,6 +285,51 @@
     });
   });
 
+  it('NFT: Sponsoring of createItem is rate limited', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+
+    // Enable collection white list 
+    await enableWhiteListExpectSuccess(alice, collectionId);
+
+    // Enable public minting
+    await enablePublicMintingExpectSuccess(alice, collectionId);
+
+    await usingApi(async (api) => {
+      // Find unused address
+      const zeroBalance = await findUnusedAddress(api);
+
+      // Add zeroBalance address to white list
+      await addToWhiteListExpectSuccess(alice, collectionId, zeroBalance.address);
+
+      // Mint token using unused address as signer - gets sponsored
+      await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
+
+      // Second mint should fail
+      const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+      
+      const consoleError = console.error;
+      const consoleLog = console.log;
+      console.error = () => {};
+      console.log = () => {};
+      const badTransaction = async function () { 
+        await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
+      };
+      await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees");
+      console.error = consoleError;
+      console.log = consoleLog;
+      const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+      // Try again after Zero gets some balance - now it should succeed
+      const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);
+      await submitTransactionAsync(alice, balancetx);
+      await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
+
+      expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;
+    });
+  });
+
 });
 
 describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {