difftreelog
Fix collection limits
in: master
3 files changed
pallets/nft/src/lib.rsdiffbeforeafterboth383 /// Collection limit bounds per collection exceeded383 /// Collection limit bounds per collection exceeded384 CollectionLimitBoundsExceeded,384 CollectionLimitBoundsExceeded,385 /// Tried to enable permissions which are only permitted to be disabled385 /// Tried to enable permissions which are only permitted to be disabled386 OwnerPermissionsCantBeReturned,386 OwnerPermissionsCantBeReverted,387 /// Schema data size limit bound exceeded387 /// Schema data size limit bound exceeded388 SchemaDataLimitExceeded,388 SchemaDataLimitExceeded,389 /// Maximum refungibility exceeded389 /// Maximum refungibility exceeded626 let sender = ensure_signed(origin)?;626 let sender = ensure_signed(origin)?;627 Self::check_owner_permissions(collection_id, sender)?;627 Self::check_owner_permissions(collection_id, sender)?;628628629 let mut target_collection = <Collection<T>>::get(collection_id);629 let target_collection = <Collection<T>>::get(collection_id);630 if !target_collection.limits.owner_can_destroy {630 if !target_collection.limits.owner_can_destroy {631 fail!(Error::<T>::NoPermission);631 fail!(Error::<T>::NoPermission);632 }632 }1532 pub fn set_collection_limits(1532 pub fn set_collection_limits(1533 origin,1533 origin,1534 collection_id: u32,1534 collection_id: u32,1535 limits: CollectionLimits,1535 new_limits: CollectionLimits,1536 ) -> DispatchResult {1536 ) -> DispatchResult {1537 let sender = ensure_signed(origin)?;1537 let sender = ensure_signed(origin)?;1538 Self::check_owner_permissions(collection_id, sender.clone())?;1538 Self::check_owner_permissions(collection_id, sender.clone())?;1539 let mut target_collection = <Collection<T>>::get(collection_id);1539 let mut target_collection = <Collection<T>>::get(collection_id);1540 let old_limits = target_collection.limits;1540 let chain_limits = ChainLimit::get();1541 let chain_limits = ChainLimit::get();1541 let climits = target_collection.limits;154215421543 // collection bounds1543 // collection bounds1544 ensure!(limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&1544 ensure!(new_limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&1545 limits.account_token_ownership_limit <= MAX_TOKEN_OWNERSHIP, 1545 new_limits.account_token_ownership_limit <= MAX_TOKEN_OWNERSHIP && 1546 new_limits.sponsored_data_size <= chain_limits.custom_data_limit &&1547 new_limits.sponsored_mint_size <= chain_limits.custom_data_limit,1546 Error::<T>::CollectionLimitBoundsExceeded);1548 Error::<T>::CollectionLimitBoundsExceeded);154715491548 // token_limit check prev1550 // token_limit check prev1549 ensure!(climits.token_limit > limits.token_limit && 1551 ensure!(old_limits.token_limit >= new_limits.token_limit, Error::<T>::CollectionTokenLimitExceeded);1550 limits.token_limit <= chain_limits.account_token_ownership_limit, 1552 ensure!(new_limits.token_limit > 0, Error::<T>::CollectionTokenLimitExceeded);1551 Error::<T>::AccountTokenLimitExceeded);155215531553 ensure!(1554 ensure!(1554 (climits.owner_can_transfer || !limits.owner_can_transfer) &&1555 (old_limits.owner_can_transfer || !new_limits.owner_can_transfer) &&1555 (climits.owner_can_destroy || !limits.owner_can_destroy),1556 (old_limits.owner_can_destroy || !new_limits.owner_can_destroy),1556 Error::<T>::OwnerPermissionsCantBeReturned,1557 Error::<T>::OwnerPermissionsCantBeReverted,1557 );1558 );155815591559 target_collection.limits = limits;1560 target_collection.limits = new_limits;1560 <Collection<T>>::insert(collection_id, target_collection);1561 <Collection<T>>::insert(collection_id, target_collection);156115621562 Ok(())1563 Ok(())tests/src/setCollectionLimits.test.tsdiffbeforeafterboth28const accountTokenOwnershipLimit = 0;28const accountTokenOwnershipLimit = 0;29const sponsoredDataSize = 0;29const sponsoredDataSize = 0;30const sponsoredMintSize = 0;30const sponsoredMintSize = 0;31const tokenLimit = 0;31const sponsorTimeout = 1;3233describe('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});463347describe('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-expression69 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: true54 },55 );56 const events = await submitTransactionAsync(alice, tx);57 const result = getCreateItemResult(events);5859 // get collection limits defined previously74 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;60 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;6162 // tslint:disable-next-line:no-unused-expression63 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: true138 });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: true146 });141 });147 });142148143 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: false158 });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: true166 });147 });167 });tests/src/types.tsdiffbeforeafterboth17 SponsoredMintSize: BN;17 SponsoredMintSize: BN;18 TokenLimit: BN;18 TokenLimit: BN;19 SponsorTimeout: BN;19 SponsorTimeout: BN;20 OwnerCanTransfer: boolean;21 OwnerCanDestroy: boolean;20 };22 };21 MintMode: boolean;23 MintMode: boolean;22 Mode: {24 Mode: {