difftreelog
tests(scheduler): exclude from parallel execution + adapt accounts
in: master
1 file changed
tests/src/scheduler.seqtest.tsdiffbeforeafterboth1// 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 {expect, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from './util';18import {IKeyringPair} from '@polkadot/types/types';19import {DevUniqueHelper} from './util/playgrounds/unique.dev';2021describe('Scheduling token and balance transfers', () => {22 let alice: IKeyringPair;23 let bob: IKeyringPair;24 let charlie: IKeyringPair;2526 before(async function() {27 await usingPlaygrounds(async (helper, privateKeyWrapper) => {28 alice = await privateKeyWrapper('//Alice');29 bob = await privateKeyWrapper('//Bob');30 charlie = await privateKeyWrapper('//Charlie');3132 requirePalletsOrSkip(this, helper, [Pallets.Scheduler]);3334 await helper.testUtils.enable();35 });36 });3738 itSub('Can delay a transfer of an owned token', async ({helper}) => {39 const collection = await helper.nft.mintCollection(alice, {tokenPrefix: 'schd'});40 const token = await collection.mintToken(alice);41 const schedulerId = await helper.arrange.makeScheduledId();42 const blocksBeforeExecution = 4;4344 await token.scheduleAfter(schedulerId, blocksBeforeExecution)45 .transfer(alice, {Substrate: bob.address});4647 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});4849 await helper.wait.newBlocks(blocksBeforeExecution + 1);5051 expect(await token.getOwner()).to.be.deep.equal({Substrate: bob.address});52 });5354 itSub('Can transfer funds periodically', async ({helper}) => {55 const scheduledId = await helper.arrange.makeScheduledId();56 const waitForBlocks = 1;5758 const amount = 1n * helper.balance.getOneTokenNominal();59 const periodic = {60 period: 2,61 repetitions: 2,62 };6364 const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);6566 await helper.scheduler.scheduleAfter(scheduledId, waitForBlocks, {periodic})67 .balance.transferToSubstrate(alice, bob.address, amount);6869 await helper.wait.newBlocks(waitForBlocks + 1);7071 const bobsBalanceAfterFirst = await helper.balance.getSubstrate(bob.address);72 expect(bobsBalanceAfterFirst)73 .to.be.equal(74 bobsBalanceBefore + 1n * amount,75 '#1 Balance of the recipient should be increased by 1 * amount',76 );7778 await helper.wait.newBlocks(periodic.period);7980 const bobsBalanceAfterSecond = await helper.balance.getSubstrate(bob.address);81 expect(bobsBalanceAfterSecond)82 .to.be.equal(83 bobsBalanceBefore + 2n * amount,84 '#2 Balance of the recipient should be increased by 2 * amount',85 );86 });8788 itSub('Can cancel a scheduled operation which has not yet taken effect', async ({helper}) => {89 const collection = await helper.nft.mintCollection(alice, {tokenPrefix: 'schd'});90 const token = await collection.mintToken(alice);9192 const scheduledId = await helper.arrange.makeScheduledId();93 const waitForBlocks = 4;9495 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});9697 await token.scheduleAfter(scheduledId, waitForBlocks)98 .transfer(alice, {Substrate: bob.address});99100 await helper.scheduler.cancelScheduled(alice, scheduledId);101102 await helper.wait.newBlocks(waitForBlocks + 1);103104 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});105 });106107 itSub('Can cancel a periodic operation (transfer of funds)', async ({helper}) => {108 const waitForBlocks = 1;109 const periodic = {110 period: 3,111 repetitions: 2,112 };113114 const scheduledId = await helper.arrange.makeScheduledId();115116 const amount = 1n * helper.balance.getOneTokenNominal();117118 const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);119120 await helper.scheduler.scheduleAfter(scheduledId, waitForBlocks, {periodic})121 .balance.transferToSubstrate(alice, bob.address, amount);122123 await helper.wait.newBlocks(waitForBlocks + 1);124125 const bobsBalanceAfterFirst = await helper.balance.getSubstrate(bob.address);126127 expect(bobsBalanceAfterFirst)128 .to.be.equal(129 bobsBalanceBefore + 1n * amount,130 '#1 Balance of the recipient should be increased by 1 * amount',131 );132133 await helper.scheduler.cancelScheduled(alice, scheduledId);134 await helper.wait.newBlocks(periodic.period);135136 const bobsBalanceAfterSecond = await helper.balance.getSubstrate(bob.address);137 expect(bobsBalanceAfterSecond)138 .to.be.equal(139 bobsBalanceAfterFirst,140 '#2 Balance of the recipient should not be changed',141 );142 });143144 itSub.ifWithPallets('Scheduled tasks are transactional', [Pallets.TestUtils], async ({helper}) => {145 const scheduledId = await helper.arrange.makeScheduledId();146 const waitForBlocks = 4;147148 const initTestVal = 42;149 const changedTestVal = 111;150151 await helper.testUtils.setTestValue(alice, initTestVal);152153 await helper.scheduler.scheduleAfter<DevUniqueHelper>(scheduledId, waitForBlocks)154 .testUtils.setTestValueAndRollback(alice, changedTestVal);155156 await helper.wait.newBlocks(waitForBlocks + 1);157158 const testVal = await helper.testUtils.testValue();159 expect(testVal, 'The test value should NOT be commited')160 .to.be.equal(initTestVal);161 });162163 itSub.ifWithPallets('Scheduled tasks should take correct fees', [Pallets.TestUtils], async function({helper}) {164 const scheduledId = await helper.arrange.makeScheduledId();165 const waitForBlocks = 4;166 const periodic = {167 period: 2,168 repetitions: 2,169 };170171 const dummyTx = helper.constructApiCall('api.tx.testUtils.justTakeFee', []);172 const scheduledLen = dummyTx.callIndex.length;173174 const expectedScheduledFee = (await helper.getPaymentInfo(alice, dummyTx, scheduledLen))175 .partialFee.toBigInt();176177 await helper.scheduler.scheduleAfter<DevUniqueHelper>(scheduledId, waitForBlocks, {periodic})178 .testUtils.justTakeFee(alice);179180 await helper.wait.newBlocks(1);181182 const aliceInitBalance = await helper.balance.getSubstrate(alice.address);183 let diff;184185 await helper.wait.newBlocks(waitForBlocks);186187 const aliceBalanceAfterFirst = await helper.balance.getSubstrate(alice.address);188 expect(189 aliceBalanceAfterFirst < aliceInitBalance,190 '[after execution #1] Scheduled task should take a fee',191 ).to.be.true;192193 diff = aliceInitBalance - aliceBalanceAfterFirst;194 expect(diff).to.be.equal(195 expectedScheduledFee,196 'Scheduled task should take the right amount of fees',197 );198199 await helper.wait.newBlocks(periodic.period);200201 const aliceBalanceAfterSecond = await helper.balance.getSubstrate(alice.address);202 expect(203 aliceBalanceAfterSecond < aliceBalanceAfterFirst,204 '[after execution #2] Scheduled task should take a fee',205 ).to.be.true;206207 diff = aliceBalanceAfterFirst - aliceBalanceAfterSecond;208 expect(diff).to.be.equal(209 expectedScheduledFee,210 'Scheduled task should take the right amount of fees',211 );212 });213214 // Check if we can cancel a scheduled periodic operation215 // in the same block in which it is running216 itSub.ifWithPallets('Can cancel the periodic sheduled tx when the tx is running', [Pallets.TestUtils], async ({helper}) => {217 const currentBlockNumber = await helper.chain.getLatestBlockNumber();218 const blocksBeforeExecution = 10;219 const firstExecutionBlockNumber = currentBlockNumber + blocksBeforeExecution;220221 const [222 scheduledId,223 scheduledCancelId,224 ] = await helper.arrange.makeScheduledIds(2);225226 const periodic = {227 period: 5,228 repetitions: 5,229 };230231 const initTestVal = 0;232 const incTestVal = initTestVal + 1;233 const finalTestVal = initTestVal + 2;234235 await helper.testUtils.setTestValue(alice, initTestVal);236237 await helper.scheduler.scheduleAt<DevUniqueHelper>(scheduledId, firstExecutionBlockNumber, {periodic})238 .testUtils.incTestValue(alice);239240 // Cancel the inc tx after 2 executions241 // *in the same block* in which the second execution is scheduled242 await helper.scheduler.scheduleAt(243 scheduledCancelId,244 firstExecutionBlockNumber + periodic.period,245 ).scheduler.cancelScheduled(alice, scheduledId);246247 await helper.wait.forParachainBlockNumber(firstExecutionBlockNumber);248249 // execution #0250 expect(await helper.testUtils.testValue())251 .to.be.equal(incTestVal);252253 await helper.wait.forParachainBlockNumber(firstExecutionBlockNumber + periodic.period);254255 // execution #1256 expect(await helper.testUtils.testValue())257 .to.be.equal(finalTestVal);258259 for (let i = 1; i < periodic.repetitions; i++) {260 await helper.wait.forParachainBlockNumber(firstExecutionBlockNumber + periodic.period * (i + 1));261 expect(await helper.testUtils.testValue())262 .to.be.equal(finalTestVal);263 }264 });265266 itSub.ifWithPallets('A scheduled operation can cancel itself', [Pallets.TestUtils], async ({helper}) => {267 const scheduledId = await helper.arrange.makeScheduledId();268 const waitForBlocks = 4;269 const periodic = {270 period: 2,271 repetitions: 5,272 };273274 const initTestVal = 0;275 const maxTestVal = 2;276277 await helper.testUtils.setTestValue(alice, initTestVal);278279 await helper.scheduler.scheduleAfter<DevUniqueHelper>(scheduledId, waitForBlocks, {periodic})280 .testUtils.selfCancelingInc(alice, scheduledId, maxTestVal);281282 await helper.wait.newBlocks(waitForBlocks + 1);283284 // execution #0285 expect(await helper.testUtils.testValue())286 .to.be.equal(initTestVal + 1);287288 await helper.wait.newBlocks(periodic.period);289290 // execution #1291 expect(await helper.testUtils.testValue())292 .to.be.equal(initTestVal + 2);293294 await helper.wait.newBlocks(periodic.period);295296 // <canceled>297 expect(await helper.testUtils.testValue())298 .to.be.equal(initTestVal + 2);299 });300301 itSub('Root can cancel any scheduled operation', async ({helper}) => {302 const collection = await helper.nft.mintCollection(bob, {tokenPrefix: 'schd'});303 const token = await collection.mintToken(bob);304305 const scheduledId = await helper.arrange.makeScheduledId();306 const waitForBlocks = 4;307308 await token.scheduleAfter(scheduledId, waitForBlocks)309 .transfer(bob, {Substrate: alice.address});310311 await helper.getSudo().scheduler.cancelScheduled(alice, scheduledId);312313 await helper.wait.newBlocks(waitForBlocks + 1);314315 expect(await token.getOwner()).to.be.deep.equal({Substrate: bob.address});316 });317318 itSub('Root can set prioritized scheduled operation', async ({helper}) => {319 const scheduledId = await helper.arrange.makeScheduledId();320 const waitForBlocks = 4;321322 const amount = 42n * helper.balance.getOneTokenNominal();323324 const balanceBefore = await helper.balance.getSubstrate(charlie.address);325326 await helper.getSudo()327 .scheduler.scheduleAfter(scheduledId, waitForBlocks, {priority: 42})328 .balance.forceTransferToSubstrate(alice, bob.address, charlie.address, amount);329330 await helper.wait.newBlocks(waitForBlocks + 1);331332 const balanceAfter = await helper.balance.getSubstrate(charlie.address);333334 expect(balanceAfter > balanceBefore).to.be.true;335336 const diff = balanceAfter - balanceBefore;337 expect(diff).to.be.equal(amount);338 });339340 itSub("Root can change scheduled operation's priority", async ({helper}) => {341 const collection = await helper.nft.mintCollection(bob, {tokenPrefix: 'schd'});342 const token = await collection.mintToken(bob);343344 const scheduledId = await helper.arrange.makeScheduledId();345 const waitForBlocks = 6;346347 await token.scheduleAfter(scheduledId, waitForBlocks)348 .transfer(bob, {Substrate: alice.address});349350 const priority = 112;351 await helper.getSudo().scheduler.changePriority(alice, scheduledId, priority);352353 const priorityChanged = await helper.wait.event(354 waitForBlocks,355 'scheduler',356 'PriorityChanged',357 );358359 expect(priorityChanged !== null).to.be.true;360 expect(priorityChanged!.event.data[2].toString()).to.be.equal(priority.toString());361 });362363 itSub('Prioritized operations executes in valid order', async ({helper}) => {364 const [365 scheduledFirstId,366 scheduledSecondId,367 ] = await helper.arrange.makeScheduledIds(2);368369 const currentBlockNumber = await helper.chain.getLatestBlockNumber();370 const blocksBeforeExecution = 6;371 const firstExecutionBlockNumber = currentBlockNumber + blocksBeforeExecution;372373 const prioHigh = 0;374 const prioLow = 255;375376 const periodic = {377 period: 6,378 repetitions: 2,379 };380381 const amount = 1n * helper.balance.getOneTokenNominal();382383 // Scheduler a task with a lower priority first, then with a higher priority384 await helper.getSudo().scheduler.scheduleAt(scheduledFirstId, firstExecutionBlockNumber, {priority: prioLow, periodic})385 .balance.forceTransferToSubstrate(alice, alice.address, bob.address, amount);386387 await helper.getSudo().scheduler.scheduleAt(scheduledSecondId, firstExecutionBlockNumber, {priority: prioHigh, periodic})388 .balance.forceTransferToSubstrate(alice, alice.address, bob.address, amount);389390 const capture = await helper.arrange.captureEvents('scheduler', 'Dispatched');391392 await helper.wait.forParachainBlockNumber(firstExecutionBlockNumber);393394 // Flip priorities395 await helper.getSudo().scheduler.changePriority(alice, scheduledFirstId, prioHigh);396 await helper.getSudo().scheduler.changePriority(alice, scheduledSecondId, prioLow);397398 await helper.wait.forParachainBlockNumber(firstExecutionBlockNumber + periodic.period);399400 const dispatchEvents = capture.extractCapturedEvents();401 expect(dispatchEvents.length).to.be.equal(4);402403 const dispatchedIds = dispatchEvents.map(r => r.event.data[1].toString());404405 const firstExecuctionIds = [dispatchedIds[0], dispatchedIds[1]];406 const secondExecuctionIds = [dispatchedIds[2], dispatchedIds[3]];407408 expect(firstExecuctionIds[0]).to.be.equal(scheduledSecondId);409 expect(firstExecuctionIds[1]).to.be.equal(scheduledFirstId);410411 expect(secondExecuctionIds[0]).to.be.equal(scheduledFirstId);412 expect(secondExecuctionIds[1]).to.be.equal(scheduledSecondId);413 });414415 itSub('Periodic operations always can be rescheduled', async ({helper}) => {416 const maxScheduledPerBlock = 50;417 const numFilledBlocks = 3;418 const ids = await helper.arrange.makeScheduledIds(numFilledBlocks * maxScheduledPerBlock + 1);419 const periodicId = ids[0];420 const fillIds = ids.slice(1);421422 const initTestVal = 0;423 const firstExecTestVal = 1;424 const secondExecTestVal = 2;425 await helper.testUtils.setTestValue(alice, initTestVal);426427 const currentBlockNumber = await helper.chain.getLatestBlockNumber();428 const blocksBeforeExecution = 8;429 const firstExecutionBlockNumber = currentBlockNumber + blocksBeforeExecution;430431 const period = 5;432433 const periodic = {434 period,435 repetitions: 2,436 };437438 // Fill `numFilledBlocks` blocks beginning from the block in which the second execution should occur439 const txs = [];440 for (let offset = 0; offset < numFilledBlocks; offset ++) {441 for (let i = 0; i < maxScheduledPerBlock; i++) {442443 const scheduledTx = helper.constructApiCall('api.tx.balances.transfer', [bob.address, 1n]);444445 const when = firstExecutionBlockNumber + period + offset;446 const tx = helper.constructApiCall('api.tx.scheduler.scheduleNamed', [fillIds[i + offset * maxScheduledPerBlock], when, null, null, scheduledTx]);447448 txs.push(tx);449 }450 }451 await helper.executeExtrinsic(alice, 'api.tx.testUtils.batchAll', [txs], true);452453 await helper.scheduler.scheduleAt<DevUniqueHelper>(periodicId, firstExecutionBlockNumber, {periodic})454 .testUtils.incTestValue(alice);455456 await helper.wait.newBlocks(blocksBeforeExecution);457 expect(await helper.testUtils.testValue()).to.be.equal(firstExecTestVal);458459 await helper.wait.newBlocks(period + numFilledBlocks);460461 // The periodic operation should be postponed by `numFilledBlocks`462 for (let i = 0; i < numFilledBlocks; i++) {463 expect(await helper.testUtils.testValue(firstExecutionBlockNumber + period + i)).to.be.equal(firstExecTestVal);464 }465466 // After the `numFilledBlocks` the periodic operation will eventually be executed467 expect(await helper.testUtils.testValue()).to.be.equal(secondExecTestVal);468 });469});470471describe('Negative Test: Scheduling', () => {472 let alice: IKeyringPair;473 let bob: IKeyringPair;474475 before(async function() {476 await usingPlaygrounds(async (helper, privateKeyWrapper) => {477 alice = await privateKeyWrapper('//Alice');478 bob = await privateKeyWrapper('//Bob');479480 requirePalletsOrSkip(this, helper, [Pallets.Scheduler]);481482 await helper.testUtils.enable();483 });484 });485486 itSub("Can't overwrite a scheduled ID", async ({helper}) => {487 const collection = await helper.nft.mintCollection(alice, {tokenPrefix: 'schd'});488 const token = await collection.mintToken(alice);489490 const scheduledId = await helper.arrange.makeScheduledId();491 const waitForBlocks = 4;492493 await token.scheduleAfter(scheduledId, waitForBlocks)494 .transfer(alice, {Substrate: bob.address});495496 const scheduled = helper.scheduler.scheduleAfter(scheduledId, waitForBlocks);497 await expect(scheduled.balance.transferToSubstrate(alice, bob.address, 1n * helper.balance.getOneTokenNominal()))498 .to.be.rejectedWith(/scheduler\.FailedToSchedule/);499500 const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);501502 await helper.wait.newBlocks(waitForBlocks + 1);503504 const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);505506 expect(await token.getOwner()).to.be.deep.equal({Substrate: bob.address});507 expect(bobsBalanceBefore).to.be.equal(bobsBalanceAfter);508 });509510 itSub("Can't cancel an operation which is not scheduled", async ({helper}) => {511 const scheduledId = await helper.arrange.makeScheduledId();512 await expect(helper.scheduler.cancelScheduled(alice, scheduledId))513 .to.be.rejectedWith(/scheduler\.NotFound/);514 });515516 itSub("Can't cancel a non-owned scheduled operation", async ({helper}) => {517 const collection = await helper.nft.mintCollection(alice, {tokenPrefix: 'schd'});518 const token = await collection.mintToken(alice);519520 const scheduledId = await helper.arrange.makeScheduledId();521 const waitForBlocks = 4;522523 await token.scheduleAfter(scheduledId, waitForBlocks)524 .transfer(alice, {Substrate: bob.address});525526 await expect(helper.scheduler.cancelScheduled(bob, scheduledId))527 .to.be.rejectedWith(/BadOrigin/);528529 await helper.wait.newBlocks(waitForBlocks + 1);530531 expect(await token.getOwner()).to.be.deep.equal({Substrate: bob.address});532 });533534 itSub("Regular user can't set prioritized scheduled operation", async ({helper}) => {535 const scheduledId = await helper.arrange.makeScheduledId();536 const waitForBlocks = 4;537538 const amount = 42n * helper.balance.getOneTokenNominal();539540 const balanceBefore = await helper.balance.getSubstrate(bob.address);541542 const scheduled = helper.scheduler.scheduleAfter(scheduledId, waitForBlocks, {priority: 42});543 544 await expect(scheduled.balance.transferToSubstrate(alice, bob.address, amount))545 .to.be.rejectedWith(/BadOrigin/);546547 await helper.wait.newBlocks(waitForBlocks + 1);548549 const balanceAfter = await helper.balance.getSubstrate(bob.address);550551 expect(balanceAfter).to.be.equal(balanceBefore);552 });553554 itSub("Regular user can't change scheduled operation's priority", async ({helper}) => {555 const collection = await helper.nft.mintCollection(bob, {tokenPrefix: 'schd'});556 const token = await collection.mintToken(bob);557558 const scheduledId = await helper.arrange.makeScheduledId();559 const waitForBlocks = 4;560561 await token.scheduleAfter(scheduledId, waitForBlocks)562 .transfer(bob, {Substrate: alice.address});563564 const priority = 112;565 await expect(helper.scheduler.changePriority(alice, scheduledId, priority))566 .to.be.rejectedWith(/BadOrigin/);567568 const priorityChanged = await helper.wait.event(569 waitForBlocks,570 'scheduler',571 'PriorityChanged',572 );573574 expect(priorityChanged === null).to.be.true;575 });576});577578// Implementation of the functionality tested here was postponed/shelved579describe.skip('Sponsoring scheduling', () => {580 // let alice: IKeyringPair;581 // let bob: IKeyringPair;582583 // before(async() => {584 // await usingApi(async (_, privateKeyWrapper) => {585 // alice = privateKeyWrapper('//Alice');586 // bob = privateKeyWrapper('//Bob');587 // });588 // });589590 it('Can sponsor scheduling a transaction', async () => {591 // const collectionId = await createCollectionExpectSuccess();592 // await setCollectionSponsorExpectSuccess(collectionId, bob.address);593 // await confirmSponsorshipExpectSuccess(collectionId, '//Bob');594595 // await usingApi(async api => {596 // const scheduledId = await makeScheduledId();597 // const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);598599 // const bobBalanceBefore = await getFreeBalance(bob);600 // const waitForBlocks = 4;601 // // no need to wait to check, fees must be deducted on scheduling, immediately602 // await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, 0, waitForBlocks, scheduledId);603 // const bobBalanceAfter = await getFreeBalance(bob);604 // // expect(aliceBalanceAfter == aliceBalanceBefore).to.be.true;605 // expect(bobBalanceAfter < bobBalanceBefore).to.be.true;606 // // wait for sequentiality matters607 // await waitNewBlocks(waitForBlocks - 1);608 // });609 });610611 it('Schedules and dispatches a transaction even if the caller has no funds at the time of the dispatch', async () => {612 // await usingApi(async (api, privateKeyWrapper) => {613 // // Find an empty, unused account614 // const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);615616 // const collectionId = await createCollectionExpectSuccess();617618 // // Add zeroBalance address to allow list619 // await enablePublicMintingExpectSuccess(alice, collectionId);620 // await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);621622 // // Grace zeroBalance with money, enough to cover future transactions623 // const balanceTx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);624 // await submitTransactionAsync(alice, balanceTx);625626 // // Mint a fresh NFT627 // const tokenId = await createItemExpectSuccess(zeroBalance, collectionId, 'NFT');628 // const scheduledId = await makeScheduledId();629630 // // Schedule transfer of the NFT a few blocks ahead631 // const waitForBlocks = 5;632 // await scheduleTransferExpectSuccess(api, collectionId, tokenId, zeroBalance, alice, 1, waitForBlocks, scheduledId);633634 // // Get rid of the account's funds before the scheduled transaction takes place635 // const balanceTx2 = api.tx.balances.transfer(alice.address, UNIQUE * 68n / 100n);636 // const events = await submitTransactionAsync(zeroBalance, balanceTx2);637 // expect(getGenericResult(events).success).to.be.true;638 // /*const emptyBalanceTx = api.tx.balances.setBalance(zeroBalance.address, 0, 0); // do not null reserved?639 // const sudoTx = api.tx.sudo.sudo(emptyBalanceTx as any);640 // const events = await submitTransactionAsync(alice, sudoTx);641 // expect(getGenericResult(events).success).to.be.true;*/642643 // // Wait for a certain number of blocks, discarding the ones that already happened while accepting the late transactions644 // await waitNewBlocks(waitForBlocks - 3);645646 // expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(alice.address));647 // });648 });649650 it('Sponsor going bankrupt does not impact a scheduled transaction', async () => {651 // const collectionId = await createCollectionExpectSuccess();652653 // await usingApi(async (api, privateKeyWrapper) => {654 // const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);655 // const balanceTx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);656 // await submitTransactionAsync(alice, balanceTx);657658 // await setCollectionSponsorExpectSuccess(collectionId, zeroBalance.address);659 // await confirmSponsorshipByKeyExpectSuccess(collectionId, zeroBalance);660661 // const scheduledId = await makeScheduledId();662 // const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);663664 // const waitForBlocks = 5;665 // await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, zeroBalance, 1, waitForBlocks, scheduledId);666667 // const emptyBalanceSponsorTx = api.tx.balances.setBalance(zeroBalance.address, 0, 0);668 // const sudoTx = api.tx.sudo.sudo(emptyBalanceSponsorTx as any);669 // const events = await submitTransactionAsync(alice, sudoTx);670 // expect(getGenericResult(events).success).to.be.true;671672 // // Wait for a certain number of blocks, save for the ones that already happened while accepting the late transactions673 // await waitNewBlocks(waitForBlocks - 3);674675 // expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(zeroBalance.address));676 // });677 });678679 it('Exceeding sponsor rate limit without having enough funds prevents scheduling a periodic transaction', async () => {680 // const collectionId = await createCollectionExpectSuccess();681 // await setCollectionSponsorExpectSuccess(collectionId, bob.address);682 // await confirmSponsorshipExpectSuccess(collectionId, '//Bob');683684 // await usingApi(async (api, privateKeyWrapper) => {685 // const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);686687 // await enablePublicMintingExpectSuccess(alice, collectionId);688 // await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);689690 // const bobBalanceBefore = await getFreeBalance(bob);691692 // const createData = {nft: {const_data: [], variable_data: []}};693 // const creationTx = api.tx.unique.createItem(collectionId, normalizeAccountId(zeroBalance), createData as any);694 // const scheduledId = await makeScheduledId();695696 // /*const badTransaction = async function () {697 // await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);698 // };699 // await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');*/700701 // await expect(scheduleAfter(api, creationTx, zeroBalance, 3, scheduledId, 1, 3)).to.be.rejectedWith(/Inability to pay some fees/);702703 // expect(await getFreeBalance(bob)).to.be.equal(bobBalanceBefore);704 // });705 });706});