difftreelog
draft: scheduler tx fees test
in: master
4 files changed
runtime/common/scheduler.rsdiffbeforeafterboth--- a/runtime/common/scheduler.rs
+++ b/runtime/common/scheduler.rs
@@ -24,11 +24,14 @@
transaction_validity::TransactionValidityError,
DispatchErrorWithPostInfo, DispatchError,
};
-use crate::{Runtime, Call, Origin, Balances, ChargeTransactionPayment};
+use crate::{Runtime, Call, Origin, Balances};
use up_common::types::{AccountId, Balance};
use fp_self_contained::SelfContainedCall;
use pallet_unique_scheduler::DispatchCall;
+use pallet_transaction_payment::ChargeTransactionPayment;
+type SponsorshipChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
+
/// The SignedExtension to the basic transaction logic.
pub type SignedExtraScheduler = (
frame_system::CheckSpecVersion<Runtime>,
@@ -36,6 +39,7 @@
frame_system::CheckEra<Runtime>,
frame_system::CheckNonce<Runtime>,
frame_system::CheckWeight<Runtime>,
+ ChargeTransactionPayment::<Runtime>,
);
fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
@@ -47,8 +51,7 @@
from,
)),
frame_system::CheckWeight::<Runtime>::new(),
- // sponsoring transaction logic
- // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
+ ChargeTransactionPayment::<Runtime>::from(0),
)
}
@@ -100,7 +103,7 @@
count: u32,
) -> Result<(), DispatchError> {
let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
+ let weight: Balance = SponsorshipChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
.saturating_mul(count.into());
<Balances as NamedReservableCurrency<AccountId>>::reserve_named(
@@ -116,7 +119,7 @@
call: <T as pallet_unique_scheduler::Config>::Call,
) -> Result<u128, DispatchError> {
let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
+ let weight: Balance = SponsorshipChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
Ok(
<Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
&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.tsdiffbeforeafterboth33 enablePublicMintingExpectSuccess,33 enablePublicMintingExpectSuccess,34 addToAllowListExpectSuccess,34 addToAllowListExpectSuccess,35 waitNewBlocks,35 waitNewBlocks,36 makeScheduledId,36 normalizeAccountId,37 normalizeAccountId,37 getTokenOwner,38 getTokenOwner,38 getGenericResult,39 getGenericResult,45 requirePallets,46 requirePallets,46 Pallets,47 Pallets,47} from '../deprecated-helpers/helpers';48} from '../deprecated-helpers/helpers';48import {IKeyringPair} from '@polkadot/types/types';49import {IKeyringPair, SignatureOptions} from '@polkadot/types/types';49import {ApiPromise} from '@polkadot/api';50import {ApiPromise} from '@polkadot/api';51import {objectSpread} from '@polkadot/util';505251chai.use(chaiAsPromised);53chai.use(chaiAsPromised);5253const scheduledIdBase: string = '0x' + '0'.repeat(31);54let scheduledIdSlider = 0;5556// Loop scheduledId around 10. Unless there are concurrent tasks with long periods/repetitions, tests' tasks' ids shouldn't ovelap.57function makeScheduledId(): string {58 return scheduledIdBase + ((scheduledIdSlider++) % 10);59}605461// Check that there are no failing Dispatched events in the block55// Check that there are no failing Dispatched events in the block62function checkForFailedSchedulerEvents(api: ApiPromise, events: any[]) {56function checkForFailedSchedulerEvents(api: ApiPromise, events: any[]) {78 });72 });79}73}7475function makeSignOptions(api: ApiPromise): SignatureOptions {76 return objectSpread(77 {blockHash: api.genesisHash, genesisHash: api.genesisHash},78 {runtimeVersion: api.runtimeVersion, signedExtensions: api.registry.signedExtensions},79 );80}808181describe('Scheduling token and balance transfers', () => {82describe('Scheduling token and balance transfers', () => {82 let alice: IKeyringPair;83 let alice: IKeyringPair;96 await usingApi(async api => {97 await usingApi(async api => {97 const collectionId = await createCollectionExpectSuccess();98 const collectionId = await createCollectionExpectSuccess();98 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');99 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');100 const scheduledId = await makeScheduledId();99101100 await scheduleTransferAndWaitExpectSuccess(api, collectionId, tokenId, alice, bob, 1, 4, makeScheduledId());102 await scheduleTransferAndWaitExpectSuccess(api, collectionId, tokenId, alice, bob, 1, 4, scheduledId);101 });103 });102 });104 });103105104 it('Can transfer funds periodically', async () => {106 it('Can transfer funds periodically', async () => {105 await usingApi(async api => {107 await usingApi(async api => {108 const scheduledId = await makeScheduledId();106 const waitForBlocks = 1;109 const waitForBlocks = 1;107 const period = 2;110 const period = 2;108 const repetitions = 2;111 const repetitions = 2;109112110 const amount = 1n * UNIQUE;113 const amount = 1n * UNIQUE;111114112 await scheduleTransferFundsExpectSuccess(api, amount, alice, bob, waitForBlocks, makeScheduledId(), period, repetitions);115 await scheduleTransferFundsExpectSuccess(api, amount, alice, bob, waitForBlocks, scheduledId, period, repetitions);113 const bobsBalanceBefore = await getFreeBalance(bob);116 const bobsBalanceBefore = await getFreeBalance(bob);114117115 await waitNewBlocks(waitForBlocks + 1);118 await waitNewBlocks(waitForBlocks + 1);134 await usingApi(async api => {137 await usingApi(async api => {135 const collectionId = await createCollectionExpectSuccess();138 const collectionId = await createCollectionExpectSuccess();136 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');139 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');137 const scheduledId = makeScheduledId();140 const scheduledId = await makeScheduledId();138 const waitForBlocks = 4;141 const waitForBlocks = 4;139142140 const amount = 1;143 const amount = 1;154 const period = 3;157 const period = 3;155 const repetitions = 2;158 const repetitions = 2;156159157 const scheduledId = makeScheduledId();160 const scheduledId = await makeScheduledId();158 const amount = 1n * UNIQUE;161 const amount = 1n * UNIQUE;159162160 const bobsBalanceBefore = await getFreeBalance(bob);163 const bobsBalanceBefore = await getFreeBalance(bob);184 await requirePallets(this, [Pallets.TestUtils]);187 await requirePallets(this, [Pallets.TestUtils]);185188186 await usingApi(async api => {189 await usingApi(async api => {187 const scheduledId = makeScheduledId();190 const scheduledId = await makeScheduledId();188 const waitForBlocks = 4;191 const waitForBlocks = 4;189 const period = null;190 const priority = 0;191192192 const initTestVal = 42;193 const initTestVal = 42;193 const changedTestVal = 111;194 const changedTestVal = 111;197198198 const changeErrTx = api.tx.testUtils.setTestValueAndRollback(changedTestVal);199 const changeErrTx = api.tx.testUtils.setTestValueAndRollback(changedTestVal);199200201 await expect(scheduleAfter(200 const scheduleTx = api.tx.scheduler.scheduleNamedAfter(202 api,201 scheduledId,203 changeErrTx,202 waitForBlocks, 204 alice,203 period,205 waitForBlocks,204 priority, 206 scheduledId,205 {Value: changeErrTx as any},206 );207 )).to.not.be.rejected;207208 await submitTransactionAsync(alice, scheduleTx);209208210 await waitNewBlocks(waitForBlocks);209 await waitNewBlocks(waitForBlocks + 1);211210212 const testVal = (await api.query.testUtils.testValue()).toNumber();211 const testVal = (await api.query.testUtils.testValue()).toNumber();213 expect(testVal, 'The test value should NOT be commited')212 expect(testVal, 'The test value should NOT be commited')216 });215 });217 });216 });218217219 it('Scheduled tasks should take some fees', async function() {218 it.only('Scheduled tasks should take some fees', async function() {220 await requirePallets(this, [Pallets.TestUtils]);219 await requirePallets(this, [Pallets.TestUtils]);221220222 await usingApi(async api => {221 await usingApi(async api => {223 const scheduledId = makeScheduledId();222 const scheduledId = await makeScheduledId();224 const waitForBlocks = 10;223 const waitForBlocks = 8;225 const period = 2;224 const period = 2;226 const repetitions = 1;225 const repetitions = 2;227228 const dummyTxFeeAmount = 100_000_000;229226230 const dummyTx = api.tx.testUtils.justTakeFee();227 const dummyTx = api.tx.testUtils.justTakeFee();228 const expectedFee = (await dummyTx.paymentInfo(alice)).partialFee.toBigInt();229 const expFee = (await api.rpc.payment.queryFeeDetails(dummyTx.toHex())).inclusionFee.unwrap().toHuman();230231 console.log('>>>>>> expFee = ' + JSON.stringify(expFee));232233 // const collectionCreate = api.tx.unique.createCollectionEx({234 // name: 0,235 // tokenPrefix: 0xfaf,236 // });237238 // const options = makeSignOptions(api);239 // const signed = collectionCreate.sign(alice, options);240 // const expFee2 = (await api.rpc.payment.queryFeeDetails(signed.toHex())).inclusionFee.unwrap().toHuman();241 // console.log('!!!!!!!!!!!! expFee2 = ' + JSON.stringify(expFee2));231242232 await expect(scheduleAfter(243 await expect(scheduleAfter(233 api,244 api,239 repetitions,250 repetitions,240 )).to.not.be.rejected;251 )).to.not.be.rejected;252253 await waitNewBlocks(1);241254242 const aliceInitBalance = await getFreeBalance(alice);255 const aliceInitBalance = await getFreeBalance(alice);243 let diff;256 let diff;244257245 await waitNewBlocks(waitForBlocks + 1);258 await waitNewBlocks(waitForBlocks);246259247 const aliceBalanceAfterFirst = await getFreeBalance(alice);260 const aliceBalanceAfterFirst = await getFreeBalance(alice);248 expect(261 expect(251 ).to.be.true;264 ).to.be.true;252265253 diff = aliceInitBalance - aliceBalanceAfterFirst;266 diff = aliceInitBalance - aliceBalanceAfterFirst;254 expect(diff).to.be.equal(dummyTxFeeAmount, 'Scheduled task should take the right amount of fees');267 expect(diff).to.be.equal(expectedFee, 'Scheduled task should take the right amount of fees');255268256 await waitNewBlocks(period);269 await waitNewBlocks(period);257270262 ).to.be.true;275 ).to.be.true;263276264 diff = aliceBalanceAfterFirst - aliceBalanceAfterSecond;277 diff = aliceBalanceAfterFirst - aliceBalanceAfterSecond;265 expect(diff).to.be.equal(dummyTxFeeAmount, 'Scheduled task should take the right amount of fees');278 expect(diff).to.be.equal(expectedFee, 'Scheduled task should take the right amount of fees');266 });279 });267 });280 });268281269 // FIXME What purpose of this test?282 // FIXME What purpose of this test?270 it.skip('Can schedule a scheduled operation of canceling the scheduled operation', async () => {283 it.skip('Can schedule a scheduled operation of canceling the scheduled operation', async () => {271 await usingApi(async api => {284 await usingApi(async api => {272 const scheduledId = makeScheduledId();285 const scheduledId = await makeScheduledId();273286274 const waitForBlocks = 2;287 const waitForBlocks = 2;275 const period = 3;288 const period = 3;323 await usingApi(async api => {336 await usingApi(async api => {324 const collectionId = await createCollectionExpectSuccess();337 const collectionId = await createCollectionExpectSuccess();325 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');338 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');326 const scheduledId = makeScheduledId();339 const scheduledId = await makeScheduledId();327 const waitForBlocks = 4;340 const waitForBlocks = 4;328 const amount = 1;341 const amount = 1;329342338351339 const bobsBalanceBefore = await getFreeBalance(bob);352 const bobsBalanceBefore = await getFreeBalance(bob);340353341 await waitNewBlocks(waitForBlocks);354 await waitNewBlocks(waitForBlocks + 1);342355343 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(bob.address));356 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(bob.address));344 expect(bobsBalanceBefore).to.be.equal(await getFreeBalance(bob));357 expect(bobsBalanceBefore).to.be.equal(await getFreeBalance(bob));347360348 it("Can't cancel an operation which is not scheduled", async () => {361 it("Can't cancel an operation which is not scheduled", async () => {349 await usingApi(async api => {362 await usingApi(async api => {350 const scheduledId = makeScheduledId();363 const scheduledId = await makeScheduledId();351 await expect(cancelScheduled(api, alice, scheduledId)).to.be.rejectedWith(/scheduler\.NotFound/);364 await expect(cancelScheduled(api, alice, scheduledId)).to.be.rejectedWith(/scheduler\.NotFound/);352 });365 });353 });366 });356 await usingApi(async api => {369 await usingApi(async api => {357 const collectionId = await createCollectionExpectSuccess();370 const collectionId = await createCollectionExpectSuccess();358 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');371 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');359 const scheduledId = makeScheduledId();372 const scheduledId = await makeScheduledId();360 const waitForBlocks = 8;373 const waitForBlocks = 8;361374362 const amount = 1;375 const amount = 1;363376364 await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, amount, waitForBlocks, scheduledId);377 await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, amount, waitForBlocks, scheduledId);365 await expect(cancelScheduled(api, bob, scheduledId)).to.be.rejectedWith(/BadOrigin/);378 await expect(cancelScheduled(api, bob, scheduledId)).to.be.rejectedWith(/BadOrigin/);366379367 await waitNewBlocks(waitForBlocks);380 await waitNewBlocks(waitForBlocks + 1);368381369 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(bob.address));382 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(bob.address));370 });383 });389 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');402 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');390403391 await usingApi(async api => {404 await usingApi(async api => {405 const scheduledId = await makeScheduledId();392 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);406 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);393407394 const bobBalanceBefore = await getFreeBalance(bob);408 const bobBalanceBefore = await getFreeBalance(bob);395 const waitForBlocks = 4;409 const waitForBlocks = 4;396 // no need to wait to check, fees must be deducted on scheduling, immediately410 // no need to wait to check, fees must be deducted on scheduling, immediately397 await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, 0, waitForBlocks, makeScheduledId());411 await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, 0, waitForBlocks, scheduledId);398 const bobBalanceAfter = await getFreeBalance(bob);412 const bobBalanceAfter = await getFreeBalance(bob);399 // expect(aliceBalanceAfter == aliceBalanceBefore).to.be.true;413 // expect(aliceBalanceAfter == aliceBalanceBefore).to.be.true;400 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;414 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;420434421 // Mint a fresh NFT435 // Mint a fresh NFT422 const tokenId = await createItemExpectSuccess(zeroBalance, collectionId, 'NFT');436 const tokenId = await createItemExpectSuccess(zeroBalance, collectionId, 'NFT');437 const scheduledId = await makeScheduledId();423438424 // Schedule transfer of the NFT a few blocks ahead439 // Schedule transfer of the NFT a few blocks ahead425 const waitForBlocks = 5;440 const waitForBlocks = 5;426 await scheduleTransferExpectSuccess(api, collectionId, tokenId, zeroBalance, alice, 1, waitForBlocks, makeScheduledId());441 await scheduleTransferExpectSuccess(api, collectionId, tokenId, zeroBalance, alice, 1, waitForBlocks, scheduledId);427442428 // Get rid of the account's funds before the scheduled transaction takes place443 // Get rid of the account's funds before the scheduled transaction takes place429 const balanceTx2 = api.tx.balances.transfer(alice.address, UNIQUE * 68n / 100n);444 const balanceTx2 = api.tx.balances.transfer(alice.address, UNIQUE * 68n / 100n);452 await setCollectionSponsorExpectSuccess(collectionId, zeroBalance.address);467 await setCollectionSponsorExpectSuccess(collectionId, zeroBalance.address);453 await confirmSponsorshipByKeyExpectSuccess(collectionId, zeroBalance);468 await confirmSponsorshipByKeyExpectSuccess(collectionId, zeroBalance);454469470 const scheduledId = await makeScheduledId();455 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);471 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);456472457 const waitForBlocks = 5;473 const waitForBlocks = 5;458 await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, zeroBalance, 1, waitForBlocks, makeScheduledId());474 await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, zeroBalance, 1, waitForBlocks, scheduledId);459475460 const emptyBalanceSponsorTx = api.tx.balances.setBalance(zeroBalance.address, 0, 0);476 const emptyBalanceSponsorTx = api.tx.balances.setBalance(zeroBalance.address, 0, 0);461 const sudoTx = api.tx.sudo.sudo(emptyBalanceSponsorTx as any);477 const sudoTx = api.tx.sudo.sudo(emptyBalanceSponsorTx as any);484500485 const createData = {nft: {const_data: [], variable_data: []}};501 const createData = {nft: {const_data: [], variable_data: []}};486 const creationTx = api.tx.unique.createItem(collectionId, normalizeAccountId(zeroBalance), createData as any);502 const creationTx = api.tx.unique.createItem(collectionId, normalizeAccountId(zeroBalance), createData as any);503 const scheduledId = await makeScheduledId();487504488 /*const badTransaction = async function () {505 /*const badTransaction = async function () {489 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);506 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);490 };507 };491 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');*/508 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');*/492509493 await expect(scheduleAfter(api, creationTx, zeroBalance, 3, makeScheduledId(), 1, 3)).to.be.rejectedWith(/Inability to pay some fees/);510 await expect(scheduleAfter(api, creationTx, zeroBalance, 3, scheduledId, 1, 3)).to.be.rejectedWith(/Inability to pay some fees/);494511495 expect(await getFreeBalance(bob)).to.be.equal(bobBalanceBefore);512 expect(await getFreeBalance(bob)).to.be.equal(bobBalanceBefore);496 });513 });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);
}