difftreelog
draft: scheduler tx fees test
in: master
4 files changed
runtime/common/scheduler.rsdiffbeforeafterboth24 transaction_validity::TransactionValidityError,24 transaction_validity::TransactionValidityError,25 DispatchErrorWithPostInfo, DispatchError,25 DispatchErrorWithPostInfo, DispatchError,26};26};27use crate::{Runtime, Call, Origin, Balances, ChargeTransactionPayment};27use crate::{Runtime, Call, Origin, Balances};28use up_common::types::{AccountId, Balance};28use up_common::types::{AccountId, Balance};29use fp_self_contained::SelfContainedCall;29use fp_self_contained::SelfContainedCall;30use pallet_unique_scheduler::DispatchCall;30use pallet_unique_scheduler::DispatchCall;31use pallet_transaction_payment::ChargeTransactionPayment;3233type SponsorshipChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;313432/// The SignedExtension to the basic transaction logic.35/// The SignedExtension to the basic transaction logic.33pub type SignedExtraScheduler = (36pub type SignedExtraScheduler = (36 frame_system::CheckEra<Runtime>,39 frame_system::CheckEra<Runtime>,37 frame_system::CheckNonce<Runtime>,40 frame_system::CheckNonce<Runtime>,38 frame_system::CheckWeight<Runtime>,41 frame_system::CheckWeight<Runtime>,42 ChargeTransactionPayment::<Runtime>,39);43);404441fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {45fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {47 from,51 from,48 )),52 )),49 frame_system::CheckWeight::<Runtime>::new(),53 frame_system::CheckWeight::<Runtime>::new(),50 // sponsoring transaction logic54 ChargeTransactionPayment::<Runtime>::from(0),51 // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),52 )55 )53}56}5457100 count: u32,103 count: u32,101 ) -> Result<(), DispatchError> {104 ) -> Result<(), DispatchError> {102 let dispatch_info = call.get_dispatch_info();105 let dispatch_info = call.get_dispatch_info();103 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)106 let weight: Balance = SponsorshipChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)104 .saturating_mul(count.into());107 .saturating_mul(count.into());105108106 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(109 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(116 call: <T as pallet_unique_scheduler::Config>::Call,119 call: <T as pallet_unique_scheduler::Config>::Call,117 ) -> Result<u128, DispatchError> {120 ) -> Result<u128, DispatchError> {118 let dispatch_info = call.get_dispatch_info();121 let dispatch_info = call.get_dispatch_info();119 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);122 let weight: Balance = SponsorshipChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);120 Ok(123 Ok(121 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(124 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(122 &id,125 &id,tests/src/.outdated/eth/scheduling.test.tsdiffbeforeafterboth--- a/tests/src/.outdated/eth/scheduling.test.ts
+++ b/tests/src/.outdated/eth/scheduling.test.ts
@@ -16,7 +16,7 @@
import {expect} from 'chai';
import {createEthAccountWithBalance, deployFlipper, GAS_ARGS, itWeb3, subToEth, transferBalanceToEth} from '../../deprecated-helpers/eth/helpers';
-import {scheduleExpectSuccess, waitNewBlocks, requirePallets, Pallets} from '../../deprecated-helpers/helpers';
+import {makeScheduledId, scheduleAfter, waitNewBlocks, requirePallets, Pallets} from '../../deprecated-helpers/helpers';
// TODO mrshiposha update this test in #581
describe.skip('Scheduing EVM smart contracts', () => {
@@ -25,6 +25,7 @@
});
itWeb3('Successfully schedules and periodically executes an EVM contract', async ({api, web3, privateKeyWrapper}) => {
+ const scheduledId = await makeScheduledId();
const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
const flipper = await deployFlipper(web3, deployer);
const initialValue = await flipper.methods.getValue().call();
@@ -45,8 +46,17 @@
);
const waitForBlocks = 4;
const periodBlocks = 2;
+ const repetitions = 2;
- await scheduleExpectSuccess(tx, alice, waitForBlocks, '0x' + '0'.repeat(32), periodBlocks, 2);
+ await expect(scheduleAfter(
+ api,
+ tx,
+ alice,
+ waitForBlocks,
+ scheduledId,
+ periodBlocks,
+ repetitions,
+ )).to.not.be.rejected;
expect(await flipper.methods.getValue().call()).to.be.equal(initialValue);
await waitNewBlocks(waitForBlocks - 1);
tests/src/.outdated/scheduler.test.tsdiffbeforeafterboth--- a/tests/src/.outdated/scheduler.test.ts
+++ b/tests/src/.outdated/scheduler.test.ts
@@ -33,6 +33,7 @@
enablePublicMintingExpectSuccess,
addToAllowListExpectSuccess,
waitNewBlocks,
+ makeScheduledId,
normalizeAccountId,
getTokenOwner,
getGenericResult,
@@ -45,19 +46,12 @@
requirePallets,
Pallets,
} from '../deprecated-helpers/helpers';
-import {IKeyringPair} from '@polkadot/types/types';
+import {IKeyringPair, SignatureOptions} from '@polkadot/types/types';
import {ApiPromise} from '@polkadot/api';
+import {objectSpread} from '@polkadot/util';
chai.use(chaiAsPromised);
-
-const scheduledIdBase: string = '0x' + '0'.repeat(31);
-let scheduledIdSlider = 0;
-// Loop scheduledId around 10. Unless there are concurrent tasks with long periods/repetitions, tests' tasks' ids shouldn't ovelap.
-function makeScheduledId(): string {
- return scheduledIdBase + ((scheduledIdSlider++) % 10);
-}
-
// Check that there are no failing Dispatched events in the block
function checkForFailedSchedulerEvents(api: ApiPromise, events: any[]) {
return new Promise((res, rej) => {
@@ -78,6 +72,13 @@
});
}
+function makeSignOptions(api: ApiPromise): SignatureOptions {
+ return objectSpread(
+ {blockHash: api.genesisHash, genesisHash: api.genesisHash},
+ {runtimeVersion: api.runtimeVersion, signedExtensions: api.registry.signedExtensions},
+ );
+}
+
describe('Scheduling token and balance transfers', () => {
let alice: IKeyringPair;
let bob: IKeyringPair;
@@ -96,20 +97,22 @@
await usingApi(async api => {
const collectionId = await createCollectionExpectSuccess();
const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
+ const scheduledId = await makeScheduledId();
- await scheduleTransferAndWaitExpectSuccess(api, collectionId, tokenId, alice, bob, 1, 4, makeScheduledId());
+ await scheduleTransferAndWaitExpectSuccess(api, collectionId, tokenId, alice, bob, 1, 4, scheduledId);
});
});
it('Can transfer funds periodically', async () => {
await usingApi(async api => {
+ const scheduledId = await makeScheduledId();
const waitForBlocks = 1;
const period = 2;
const repetitions = 2;
const amount = 1n * UNIQUE;
- await scheduleTransferFundsExpectSuccess(api, amount, alice, bob, waitForBlocks, makeScheduledId(), period, repetitions);
+ await scheduleTransferFundsExpectSuccess(api, amount, alice, bob, waitForBlocks, scheduledId, period, repetitions);
const bobsBalanceBefore = await getFreeBalance(bob);
await waitNewBlocks(waitForBlocks + 1);
@@ -134,7 +137,7 @@
await usingApi(async api => {
const collectionId = await createCollectionExpectSuccess();
const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
- const scheduledId = makeScheduledId();
+ const scheduledId = await makeScheduledId();
const waitForBlocks = 4;
const amount = 1;
@@ -154,7 +157,7 @@
const period = 3;
const repetitions = 2;
- const scheduledId = makeScheduledId();
+ const scheduledId = await makeScheduledId();
const amount = 1n * UNIQUE;
const bobsBalanceBefore = await getFreeBalance(bob);
@@ -184,10 +187,8 @@
await requirePallets(this, [Pallets.TestUtils]);
await usingApi(async api => {
- const scheduledId = makeScheduledId();
+ const scheduledId = await makeScheduledId();
const waitForBlocks = 4;
- const period = null;
- const priority = 0;
const initTestVal = 42;
const changedTestVal = 111;
@@ -197,17 +198,15 @@
const changeErrTx = api.tx.testUtils.setTestValueAndRollback(changedTestVal);
- const scheduleTx = api.tx.scheduler.scheduleNamedAfter(
+ await expect(scheduleAfter(
+ api,
+ changeErrTx,
+ alice,
+ waitForBlocks,
scheduledId,
- waitForBlocks,
- period,
- priority,
- {Value: changeErrTx as any},
- );
-
- await submitTransactionAsync(alice, scheduleTx);
+ )).to.not.be.rejected;
- await waitNewBlocks(waitForBlocks);
+ await waitNewBlocks(waitForBlocks + 1);
const testVal = (await api.query.testUtils.testValue()).toNumber();
expect(testVal, 'The test value should NOT be commited')
@@ -216,18 +215,30 @@
});
});
- it('Scheduled tasks should take some fees', async function() {
+ it.only('Scheduled tasks should take some fees', async function() {
await requirePallets(this, [Pallets.TestUtils]);
await usingApi(async api => {
- const scheduledId = makeScheduledId();
- const waitForBlocks = 10;
+ const scheduledId = await makeScheduledId();
+ const waitForBlocks = 8;
const period = 2;
- const repetitions = 1;
+ const repetitions = 2;
- const dummyTxFeeAmount = 100_000_000;
+ const dummyTx = api.tx.testUtils.justTakeFee();
+ const expectedFee = (await dummyTx.paymentInfo(alice)).partialFee.toBigInt();
+ const expFee = (await api.rpc.payment.queryFeeDetails(dummyTx.toHex())).inclusionFee.unwrap().toHuman();
+
+ console.log('>>>>>> expFee = ' + JSON.stringify(expFee));
+
+ // const collectionCreate = api.tx.unique.createCollectionEx({
+ // name: 0,
+ // tokenPrefix: 0xfaf,
+ // });
- const dummyTx = api.tx.testUtils.justTakeFee();
+ // const options = makeSignOptions(api);
+ // const signed = collectionCreate.sign(alice, options);
+ // const expFee2 = (await api.rpc.payment.queryFeeDetails(signed.toHex())).inclusionFee.unwrap().toHuman();
+ // console.log('!!!!!!!!!!!! expFee2 = ' + JSON.stringify(expFee2));
await expect(scheduleAfter(
api,
@@ -239,10 +250,12 @@
repetitions,
)).to.not.be.rejected;
+ await waitNewBlocks(1);
+
const aliceInitBalance = await getFreeBalance(alice);
let diff;
- await waitNewBlocks(waitForBlocks + 1);
+ await waitNewBlocks(waitForBlocks);
const aliceBalanceAfterFirst = await getFreeBalance(alice);
expect(
@@ -251,7 +264,7 @@
).to.be.true;
diff = aliceInitBalance - aliceBalanceAfterFirst;
- expect(diff).to.be.equal(dummyTxFeeAmount, 'Scheduled task should take the right amount of fees');
+ expect(diff).to.be.equal(expectedFee, 'Scheduled task should take the right amount of fees');
await waitNewBlocks(period);
@@ -262,14 +275,14 @@
).to.be.true;
diff = aliceBalanceAfterFirst - aliceBalanceAfterSecond;
- expect(diff).to.be.equal(dummyTxFeeAmount, 'Scheduled task should take the right amount of fees');
+ expect(diff).to.be.equal(expectedFee, 'Scheduled task should take the right amount of fees');
});
});
// FIXME What purpose of this test?
it.skip('Can schedule a scheduled operation of canceling the scheduled operation', async () => {
await usingApi(async api => {
- const scheduledId = makeScheduledId();
+ const scheduledId = await makeScheduledId();
const waitForBlocks = 2;
const period = 3;
@@ -323,7 +336,7 @@
await usingApi(async api => {
const collectionId = await createCollectionExpectSuccess();
const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
- const scheduledId = makeScheduledId();
+ const scheduledId = await makeScheduledId();
const waitForBlocks = 4;
const amount = 1;
@@ -338,7 +351,7 @@
const bobsBalanceBefore = await getFreeBalance(bob);
- await waitNewBlocks(waitForBlocks);
+ await waitNewBlocks(waitForBlocks + 1);
expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(bob.address));
expect(bobsBalanceBefore).to.be.equal(await getFreeBalance(bob));
@@ -347,7 +360,7 @@
it("Can't cancel an operation which is not scheduled", async () => {
await usingApi(async api => {
- const scheduledId = makeScheduledId();
+ const scheduledId = await makeScheduledId();
await expect(cancelScheduled(api, alice, scheduledId)).to.be.rejectedWith(/scheduler\.NotFound/);
});
});
@@ -356,7 +369,7 @@
await usingApi(async api => {
const collectionId = await createCollectionExpectSuccess();
const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
- const scheduledId = makeScheduledId();
+ const scheduledId = await makeScheduledId();
const waitForBlocks = 8;
const amount = 1;
@@ -364,7 +377,7 @@
await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, amount, waitForBlocks, scheduledId);
await expect(cancelScheduled(api, bob, scheduledId)).to.be.rejectedWith(/BadOrigin/);
- await waitNewBlocks(waitForBlocks);
+ await waitNewBlocks(waitForBlocks + 1);
expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(bob.address));
});
@@ -389,12 +402,13 @@
await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
await usingApi(async api => {
+ const scheduledId = await makeScheduledId();
const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
const bobBalanceBefore = await getFreeBalance(bob);
const waitForBlocks = 4;
// no need to wait to check, fees must be deducted on scheduling, immediately
- await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, 0, waitForBlocks, makeScheduledId());
+ await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, 0, waitForBlocks, scheduledId);
const bobBalanceAfter = await getFreeBalance(bob);
// expect(aliceBalanceAfter == aliceBalanceBefore).to.be.true;
expect(bobBalanceAfter < bobBalanceBefore).to.be.true;
@@ -420,10 +434,11 @@
// Mint a fresh NFT
const tokenId = await createItemExpectSuccess(zeroBalance, collectionId, 'NFT');
+ const scheduledId = await makeScheduledId();
// Schedule transfer of the NFT a few blocks ahead
const waitForBlocks = 5;
- await scheduleTransferExpectSuccess(api, collectionId, tokenId, zeroBalance, alice, 1, waitForBlocks, makeScheduledId());
+ await scheduleTransferExpectSuccess(api, collectionId, tokenId, zeroBalance, alice, 1, waitForBlocks, scheduledId);
// Get rid of the account's funds before the scheduled transaction takes place
const balanceTx2 = api.tx.balances.transfer(alice.address, UNIQUE * 68n / 100n);
@@ -452,10 +467,11 @@
await setCollectionSponsorExpectSuccess(collectionId, zeroBalance.address);
await confirmSponsorshipByKeyExpectSuccess(collectionId, zeroBalance);
+ const scheduledId = await makeScheduledId();
const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
const waitForBlocks = 5;
- await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, zeroBalance, 1, waitForBlocks, makeScheduledId());
+ await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, zeroBalance, 1, waitForBlocks, scheduledId);
const emptyBalanceSponsorTx = api.tx.balances.setBalance(zeroBalance.address, 0, 0);
const sudoTx = api.tx.sudo.sudo(emptyBalanceSponsorTx as any);
@@ -484,13 +500,14 @@
const createData = {nft: {const_data: [], variable_data: []}};
const creationTx = api.tx.unique.createItem(collectionId, normalizeAccountId(zeroBalance), createData as any);
+ const scheduledId = await makeScheduledId();
/*const badTransaction = async function () {
await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);
};
await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');*/
- await expect(scheduleAfter(api, creationTx, zeroBalance, 3, makeScheduledId(), 1, 3)).to.be.rejectedWith(/Inability to pay some fees/);
+ await expect(scheduleAfter(api, creationTx, zeroBalance, 3, scheduledId, 1, 3)).to.be.rejectedWith(/Inability to pay some fees/);
expect(await getFreeBalance(bob)).to.be.equal(bobBalanceBefore);
});
tests/src/deprecated-helpers/helpers.tsdiffbeforeafterboth--- a/tests/src/deprecated-helpers/helpers.ts
+++ b/tests/src/deprecated-helpers/helpers.ts
@@ -1260,15 +1260,9 @@
) {
const transferTx = api.tx.balances.transfer(recipient.address, amount);
-<<<<<<< HEAD
- const balanceBefore = await getFreeBalance(recipient);
-
- await scheduleExpectSuccess(transferTx, sender, blockSchedule, scheduledId, period, repetitions);
-=======
const balanceBefore = await getFreeBalance(recipient);
await expect(scheduleAfter(api, transferTx, sender, blocksBeforeExecution, scheduledId, period, repetitions)).to.not.be.rejected;
->>>>>>> test(scheduler): enable and add more coverage, leave sponsorship disabled
expect(await getFreeBalance(recipient)).to.be.equal(balanceBefore);
}