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

difftreelog

source

tests/src/maintenanceMode.seqtest.ts12.1 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {IKeyringPair} from '@polkadot/types/types';18import {ApiPromise} from '@polkadot/api';19import {expect, itSub, Pallets, usingPlaygrounds} from './util';20import {itEth} from './eth/util';2122async function maintenanceEnabled(api: ApiPromise): Promise<boolean> {23  return (await api.query.maintenance.enabled()).toJSON() as boolean;24}2526describe('Integration Test: Maintenance Mode', () => {27  let superuser: IKeyringPair;28  let donor: IKeyringPair;29  let bob: IKeyringPair;3031  before(async () => {32    await usingPlaygrounds(async (helper, privateKey) => {33      superuser = await privateKey('//Alice');34      donor = await privateKey({filename: __filename});35      [bob] = await helper.arrange.createAccounts([100n], donor);3637      if (await maintenanceEnabled(helper.getApi())) {38        console.warn('\tMaintenance mode was left enabled BEFORE the test suite! Disabling it now.');39        await expect(helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', [])).to.be.fulfilled;40      }41    });42  });4344  itSub('Allows superuser to enable and disable maintenance mode - and disallows anyone else', async ({helper}) => {45    // Make sure non-sudo can't enable maintenance mode46    await expect(helper.executeExtrinsic(superuser, 'api.tx.maintenance.enable', []), 'on commoner enabling MM').to.be.rejected; //With(/NoPermission/);4748    // Set maintenance mode49    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.enable', []);50    expect(await maintenanceEnabled(helper.getApi()), 'MM is OFF when it should be ON').to.be.true;5152    // Make sure non-sudo can't disable maintenance mode53    await expect(helper.executeExtrinsic(bob, 'api.tx.maintenance.disable', []), 'on commoner disabling MM').to.be.rejected; //With(/NoPermission/);5455    // Disable maintenance mode56    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', []);57    expect(await maintenanceEnabled(helper.getApi()), 'MM is ON when it should be OFF').to.be.false;58  });5960  itSub('MM blocks unique pallet calls', async ({helper}) => {61    // Can create an NFT collection before enabling the MM62    const nftCollection = await helper.nft.mintCollection(bob, {63      tokenPropertyPermissions: [{key: 'test', permission: {64        collectionAdmin: true,65        tokenOwner: true,66        mutable: true,67      }}],68    });6970    // Can mint an NFT before enabling the MM71    const nft = await nftCollection.mintToken(bob);7273    // Can create an FT collection before enabling the MM74    const ftCollection = await helper.ft.mintCollection(superuser);7576    // Can mint an FT before enabling the MM77    await expect(ftCollection.mint(superuser)).to.be.fulfilled;7879    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.enable', []);80    expect(await maintenanceEnabled(helper.getApi()), 'MM is OFF when it should be ON').to.be.true;8182    // Unable to create a collection when the MM is enabled83    await expect(helper.nft.mintCollection(superuser), 'cudo forbidden stuff').to.be.rejected;8485    // Unable to set token properties when the MM is enabled86    await expect(nft.setProperties(87      bob,88      [{key: 'test', value: 'test-val'}],89    )).to.be.rejected;9091    // Unable to mint an NFT when the MM is enabled92    await expect(nftCollection.mintToken(superuser)).to.be.rejected;9394    // Unable to mint an FT when the MM is enabled95    await expect(ftCollection.mint(superuser)).to.be.rejected;9697    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', []);98    expect(await maintenanceEnabled(helper.getApi()), 'MM is ON when it should be OFF').to.be.false;99100    // Can create a collection after disabling the MM101    await expect(helper.nft.mintCollection(bob), 'MM is disabled, the collection should be created').to.be.fulfilled;102103    // Can set token properties after disabling the MM104    await nft.setProperties(bob, [{key: 'test', value: 'test-val'}]);105106    // Can mint an NFT after disabling the MM107    await nftCollection.mintToken(bob);108109    // Can mint an FT after disabling the MM110    await ftCollection.mint(superuser);111  });112113  itSub.ifWithPallets('MM blocks unique pallet calls (Re-Fungible)', [Pallets.ReFungible], async ({helper}) => {114    // Can create an RFT collection before enabling the MM115    const rftCollection = await helper.rft.mintCollection(superuser);116117    // Can mint an RFT before enabling the MM118    await expect(rftCollection.mintToken(superuser)).to.be.fulfilled;119120    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.enable', []);121    expect(await maintenanceEnabled(helper.getApi()), 'MM is OFF when it should be ON').to.be.true;122123    // Unable to mint an RFT when the MM is enabled124    await expect(rftCollection.mintToken(superuser)).to.be.rejected;125    126    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', []);127    expect(await maintenanceEnabled(helper.getApi()), 'MM is ON when it should be OFF').to.be.false;128129    // Can mint an RFT after disabling the MM130    await rftCollection.mintToken(superuser);131  });132133  itSub('MM allows native token transfers and RPC calls', async ({helper}) => {134    // We can use RPC before the MM is enabled135    const totalCount = await helper.collection.getTotalCount();136137    // We can transfer funds before the MM is enabled138    await expect(helper.balance.transferToSubstrate(superuser, bob.address, 2n)).to.be.fulfilled;139140    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.enable', []);141    expect(await maintenanceEnabled(helper.getApi()), 'MM is OFF when it should be ON').to.be.true;142143    // RPCs work while in maintenance144    expect(await helper.collection.getTotalCount()).to.be.deep.equal(totalCount);145146    // We still able to transfer funds147    await expect(helper.balance.transferToSubstrate(bob, superuser.address, 1n)).to.be.fulfilled;148149    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', []);150    expect(await maintenanceEnabled(helper.getApi()), 'MM is ON when it should be OFF').to.be.false;151152    // RPCs work after maintenance153    expect(await helper.collection.getTotalCount()).to.be.deep.equal(totalCount);154155    // Transfers work after maintenance156    await expect(helper.balance.transferToSubstrate(bob, superuser.address, 1n)).to.be.fulfilled;157  });158159  itSub.ifWithPallets('MM blocks scheduled calls and the scheduler itself', [Pallets.Scheduler], async ({helper}) => {160    const collection = await helper.nft.mintCollection(bob);161162    const nftBeforeMM = await collection.mintToken(bob);163    const nftDuringMM = await collection.mintToken(bob);164    const nftAfterMM = await collection.mintToken(bob);165166    const scheduledIdBeforeMM = '0x' + '0'.repeat(31) + '0';167    const scheduledIdDuringMM = '0x' + '0'.repeat(31) + '1';168    const scheduledIdBunkerThroughMM = '0x' + '0'.repeat(31) + '2';169    const scheduledIdAttemptDuringMM = '0x' + '0'.repeat(31) + '3';170    const scheduledIdAfterMM = '0x' + '0'.repeat(31) + '4';171172    const blocksToWait = 6;173174    // Scheduling works before the maintenance175    await nftBeforeMM.scheduleAfter(scheduledIdBeforeMM, blocksToWait)176      .transfer(bob, {Substrate: superuser.address});177178    await helper.wait.newBlocks(blocksToWait + 1);179    expect(await nftBeforeMM.getOwner()).to.be.deep.equal({Substrate: superuser.address});180181    // Schedule a transaction that should occur *during* the maintenance182    await nftDuringMM.scheduleAfter(scheduledIdDuringMM, blocksToWait)183      .transfer(bob, {Substrate: superuser.address});184    185    // Schedule a transaction that should occur *after* the maintenance186    await nftDuringMM.scheduleAfter(scheduledIdBunkerThroughMM, blocksToWait * 2)187      .transfer(bob, {Substrate: superuser.address});188189    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.enable', []);190    expect(await maintenanceEnabled(helper.getApi()), 'MM is OFF when it should be ON').to.be.true;191192    await helper.wait.newBlocks(blocksToWait + 1);193    // The owner should NOT change since the scheduled transaction should be rejected194    expect(await nftDuringMM.getOwner()).to.be.deep.equal({Substrate: bob.address});195196    // Any attempts to schedule a tx during the MM should be rejected197    await expect(nftDuringMM.scheduleAfter(scheduledIdAttemptDuringMM, blocksToWait)198      .transfer(bob, {Substrate: superuser.address})).to.be.rejected;199200    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', []);201    expect(await maintenanceEnabled(helper.getApi()), 'MM is ON when it should be OFF').to.be.false;202203    // Scheduling works after the maintenance204    await nftAfterMM.scheduleAfter(scheduledIdAfterMM, blocksToWait)205      .transfer(bob, {Substrate: superuser.address});206    207    await helper.wait.newBlocks(blocksToWait + 1);208209    expect(await nftAfterMM.getOwner()).to.be.deep.equal({Substrate: superuser.address});210    // The owner of the token scheduled for transaction *before* maintenance should now change *after* maintenance211    expect(await nftDuringMM.getOwner()).to.be.deep.equal({Substrate: superuser.address});212  });213214  itEth('Disallows Ethereum transactions to execute while in maintenance', async ({helper}) => {215    const owner = await helper.eth.createAccountWithBalance(donor);216    const receiver = helper.eth.createAccount();217    218    const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'A', 'B', 'C', '');219220    // Set maintenance mode221    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.enable', []);222    expect(await maintenanceEnabled(helper.getApi()), 'MM is OFF when it should be ON').to.be.true;223224    const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);225    const tokenId = await contract.methods.nextTokenId().call();226    expect(tokenId).to.be.equal('1');227228    /*const result = */229    await contract.methods.mintWithTokenURI(230      receiver,231      'Test URI',232    ).send();233    /*const expectedTokenId = result.events.Transfer.returnValues.tokenId;234    expect(expectedTokenId).to.be.equal(tokenId);*/235236    await expect(contract.methods.ownerOf(tokenId).call()).rejectedWith(/token not found/);237238    // Disable maintenance mode239    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', []);240    expect(await maintenanceEnabled(helper.getApi()), 'MM is ON when it should be OFF').to.be.false;241  });242243  itSub('Allows to enable and disable MM repeatedly', async ({helper}) => {244    // Set maintenance mode245    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.enable', []);246    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.enable', []);247    expect(await maintenanceEnabled(helper.getApi()), 'MM is OFF when it should be ON').to.be.true;248249    // Disable maintenance mode250    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', []);251    await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', []);252    expect(await maintenanceEnabled(helper.getApi()), 'MM is ON when it should be OFF').to.be.false;253  });254255  afterEach(async () => {256    await usingPlaygrounds(async helper => {257      if (await maintenanceEnabled(helper.getApi())) {258        console.warn('\tMaintenance mode was left enabled AFTER a test has finished! Be careful. Disabling it now.');259        await helper.getSudo().executeExtrinsic(superuser, 'api.tx.maintenance.disable', []);260      }261      expect(await maintenanceEnabled(helper.getApi()), 'Disastrous! Exited the test suite with maintenance mode on.').to.be.false;262    });263  });264});