Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minimal tests to show that new runtime API endpoints exist #2254

Merged
merged 17 commits into from
May 18, 2023
Merged
42 changes: 41 additions & 1 deletion tests/tests/test-fees/test-fee-multiplier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
} from "../../util/xcm";
import { expectOk } from "../../util/expect";
import { KeyringPair } from "@substrate/txwrapper-core";
import { TARGET_FILL_AMOUNT } from "../../util/constants";
import { GLMR, TARGET_FILL_AMOUNT, WEIGHT_FEE } from "../../util/constants";
import { verifyLatestBlockFees } from "../../util/block";

// Note on the values from 'transactionPayment.nextFeeMultiplier': this storage item is actually a
// FixedU128, which is basically a u128 with an implicit denominator of 10^18. However, this
Expand Down Expand Up @@ -425,3 +426,42 @@ describeDevMoonbeam("Fee Multiplier - XCM Executions", (context) => {
expect(initialValue.eq(postValue), "Fee Multiplier has changed between blocks").to.be.true;
});
});

describeDevMoonbeam("TransactionPayment Runtime Queries", (context) => {
it("should be able to query length fee", async function () {
// this test is really meant to show that `queryLengthToFee()` works, but for the inquisitive,
// this is how our length fee is calculated:
// fee = N**3 + N * 1_000_000_000 (where N: size_in_bytes):
const numBytes = 1n;
const coefficient = 1_000_000_000n;
const exponent = 3n;
const expected = numBytes ** exponent + numBytes * coefficient;

const adjusted_length_fee =
await context.polkadotApi.call.transactionPaymentApi.queryLengthToFee(numBytes);
expect(adjusted_length_fee.toBigInt()).to.eq(expected);
});

it("should be able to query weight fee", async function () {
const adjusted_weight_fee =
await context.polkadotApi.call.transactionPaymentApi.queryWeightToFee({
refTime: 1,
proofSize: 1,
});
expect(adjusted_weight_fee.toBigInt()).to.eq(WEIGHT_FEE);
});

it("should be able to calculate entire fee", async function () {
const tx = await context.polkadotApi.tx.balances.transfer(alith.address, GLMR).signAsync(alith);
const result = await context.createBlock(tx);
await verifyLatestBlockFees(context);
});

it("should be able to calculate entire fee including tip", async function () {
const tx = await context.polkadotApi.tx.balances
.transfer(alith.address, GLMR)
.signAsync(alith, { tip: 123 });
const result = await context.createBlock(tx);
await verifyLatestBlockFees(context);
});
});
44 changes: 39 additions & 5 deletions tests/util/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
import { FrameSystemEventRecord, SpWeightsWeightV2Weight } from "@polkadot/types/lookup";
import { u32, u64, u128, Option } from "@polkadot/types";
import { expect } from "chai";
import { WEIGHT_PER_GAS } from "./constants";

import { EXTRINSIC_BASE_WEIGHT, WEIGHT_PER_GAS } from "./constants";
import { DevTestContext } from "./setup-dev-tests";
import { rateLimiter } from "./common";
import type { Block, AccountId20 } from "@polkadot/types/interfaces/runtime/types";
Expand Down Expand Up @@ -138,7 +139,9 @@ export const verifyBlockFees = async (
let blockBurnt = 0n;

// iterate over every extrinsic
for (const { events, extrinsic, fee } of blockDetails.txWithEvents) {
for (const txWithEvents of blockDetails.txWithEvents) {
let { events, extrinsic, fee } = txWithEvents;

// This hash will only exist if the transaction was executed through ethereum.
let ethereumAddress = "";

Expand Down Expand Up @@ -217,9 +220,40 @@ export const verifyBlockFees = async (
txBurnt += tipFeePortions.burnt;
} else {
// For a regular substrate tx, we use the partialFee
let feePortions = calculateFeePortions(fee.partialFee.toBigInt());
txFees = fee.partialFee.toBigInt();
txBurnt += feePortions.burnt;
const feePortions = calculateFeePortions(fee.partialFee.toBigInt());
const tipPortions = calculateFeePortions(extrinsic.tip.toBigInt());
txFees += fee.partialFee.toBigInt() + extrinsic.tip.toBigInt();
txBurnt += feePortions.burnt + tipPortions.burnt;

// verify entire substrate txn fee
const apiAt = await context.polkadotApi.at(previousBlockHash);
const lengthFee = (
(await apiAt.call.transactionPaymentApi.queryLengthToFee(
extrinsic.encodedLength
)) as any
).toBigInt();

const unadjustedWeightFee = (
(await apiAt.call.transactionPaymentApi.queryWeightToFee({
refTime: fee.weight,
proofSize: 0n,
})) as any
).toBigInt();
const multiplier = await apiAt.query.transactionPayment.nextFeeMultiplier();
const denominator = 1_000_000_000_000_000_000n;
const weightFee = (unadjustedWeightFee * multiplier.toBigInt()) / denominator;

const baseFee = (
(await apiAt.call.transactionPaymentApi.queryWeightToFee({
refTime: EXTRINSIC_BASE_WEIGHT,
proofSize: 0n,
})) as any
).toBigInt();

const tip = extrinsic.tip.toBigInt();
const expectedPartialFee = lengthFee + weightFee + baseFee;

expect(expectedPartialFee).to.eq(fee.partialFee.toBigInt());
}

blockFees += txFees;
Expand Down