Skip to content

Commit

Permalink
tmp: check if all tests pass
Browse files Browse the repository at this point in the history
  • Loading branch information
TarekkMA committed Jan 8, 2025
1 parent 0b11025 commit 42e0a69
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 73 deletions.
34 changes: 27 additions & 7 deletions test/helpers/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,33 +178,48 @@ export const verifyBlockFees = async (
const baseFeePerGas = (
await context.viem().getBlock({ blockNumber: BigInt(number - 1) })
).baseFeePerGas!;
let priorityFee;

console.log("baseFeePerGas", baseFeePerGas);

let priorityFee;
let gasFee;
// Transaction is an enum now with as many variants as supported transaction types.
if (ethTxWrapper.isLegacy) {
priorityFee = ethTxWrapper.asLegacy.gasPrice.toBigInt();
gasFee = priorityFee;
} else if (ethTxWrapper.isEip2930) {
priorityFee = ethTxWrapper.asEip2930.gasPrice.toBigInt();
gasFee = priorityFee;
} else if (ethTxWrapper.isEip1559) {
priorityFee = ethTxWrapper.asEip1559.maxPriorityFeePerGas.toBigInt();
gasFee = ethTxWrapper.asEip1559.maxFeePerGas.toBigInt();
}

let effectiveTipPerGas = priorityFee - baseFeePerGas;
if (effectiveTipPerGas < 0n) {
effectiveTipPerGas = 0n;
console.log("priorityFee", priorityFee);
console.log("gasFee", gasFee);

let effectiveTipPerGas = gasFee - baseFeePerGas;
if (effectiveTipPerGas > priorityFee) {
effectiveTipPerGas = priorityFee;
}

// Calculate the fees paid for base fee independently of tip fee. Both are subject
// to split between (burn/treasury) but calculating these over the sum of the two
// rather than independently leads to off-by-one errors.
console.log("effectiveTipPerGas", effectiveTipPerGas);

// Calculate the fees paid for the base fee and tip fee independently.
// Only the base fee is subject to the split between burn and treasury.
const baseFeesPaid = gasUsed * baseFeePerGas;
const tipAsFeesPaid = gasUsed * effectiveTipPerGas;

console.log("baseFeesPaid", baseFeesPaid);
console.log("tipAsFeesPaid", tipAsFeesPaid);

const { burnt: baseFeePortionsBurnt } = calculateFeePortions(
feesTreasuryProportion,
baseFeesPaid
);

console.log("baseFeesPaid", baseFeesPaid);
console.log("tipAsFeesPaid", tipAsFeesPaid);
txFees += baseFeesPaid + tipAsFeesPaid;
txBurnt += baseFeePortionsBurnt;
} else {
Expand Down Expand Up @@ -275,6 +290,11 @@ export const verifyBlockFees = async (
await api.at(blockDetails.block.hash)
).query.system.account(origin)) as any;

console.log("origin", origin);
console.log("txFees", txFees);
console.log("diff", (((fromBalance.data.free.toBigInt() as any) -
toBalance.data.free.toBigInt()) as any) - expectedBalanceDiff);

expect(txFees.toString()).to.eq(
(
(((fromBalance.data.free.toBigInt() as any) -
Expand Down
Original file line number Diff line number Diff line change
@@ -1,71 +1,87 @@
import { describeSuite, expect, TransactionTypes } from "@moonwall/cli";
import {describeSuite, expect, extractInfo, TransactionTypes} from "@moonwall/cli";
import {
alith,
ALITH_ADDRESS,
baltathar,
BALTATHAR_ADDRESS,
BALTATHAR_ADDRESS, BALTATHAR_PRIVATE_KEY, CHARLETH_ADDRESS,
createRawTransfer,
extractFee,
Perbill,
TREASURY_ACCOUNT,
WEIGHT_PER_GAS,
} from "@moonwall/util";
import { parameterType, UNIT } from "./test-parameters";
import { BN } from "@polkadot/util";
import { calculateFeePortions, verifyLatestBlockFees } from "../../../../helpers";
import {parameterType, UNIT} from "./test-parameters";
import {BN} from "@polkadot/util";
import {calculateFeePortions, ConstantStore, verifyLatestBlockFees} from "../../../../helpers";
import {parseGwei, parseWei} from "viem";

interface TestCase {
proportion: Perbill;

transfer_amount: bigint;
tipAmount: bigint;
priorityFeePerGas: bigint;
}

describeSuite({
id: "DTemp03",
title: "Parameters - RuntimeConfig",
foundationMethods: "dev",
testCases: ({ it, context, log }) => {
testCases: ({it, context, log}) => {
let testCounter = 0;
const collatorAddress = ALITH_ADDRESS;
const senderPrivateKey = BALTATHAR_PRIVATE_KEY;
const senderKeyPair = baltathar;
const receiver = CHARLETH_ADDRESS;

const testCases: TestCase[] = [
{
proportion: new Perbill(0),
transfer_amount: 10n * UNIT,
tipAmount: 1n * UNIT,
priorityFeePerGas: parseGwei('1'),
},
{
proportion: new Perbill(1, 100),
transfer_amount: 1000n,
tipAmount: 100n,
priorityFeePerGas: 100n,
},
{
proportion: new Perbill(355, 1000),
transfer_amount: 5n * UNIT,
tipAmount: 111112n,
priorityFeePerGas: 111112n,
},
{
proportion: new Perbill(400, 1000),
transfer_amount: 10n * UNIT,
tipAmount: 1n * UNIT,
tipAmount: 2n * UNIT,
priorityFeePerGas: parseGwei('2'),
},
{
proportion: new Perbill(500, 1000),
transfer_amount: 10n * UNIT,
tipAmount: 1n * UNIT,
priorityFeePerGas: parseGwei('1'),
},
{
proportion: new Perbill(963, 1000),
transfer_amount: 10n * UNIT,
tipAmount: 128n,
priorityFeePerGas: 128,
},
{
proportion: new Perbill(99, 100),
transfer_amount: 10n * UNIT,
tipAmount: 3n,
priorityFeePerGas: 3n,
},
{
proportion: new Perbill(1, 1),
transfer_amount: 10n * UNIT,
tipAmount: 32n,
priorityFeePerGas: 32n,
},
];

Expand All @@ -82,74 +98,127 @@ describeSuite({
const calcIssuanceDecrease = (feeWithTip: bigint, maybeTip?: bigint): bigint => {
const tip = maybeTip ?? 0n;
const feeWithoutTip = feeWithTip - tip;
const { burnt: feeBurnt } = calculateFeePortions(treasuryPerbill, feeWithoutTip);
const { burnt: tipBurnt } = calculateFeePortions(treasuryPerbill, tip);
const {burnt: feeBurnt} = calculateFeePortions(treasuryPerbill, feeWithoutTip);
const {burnt: tipBurnt} = calculateFeePortions(treasuryPerbill, tip);

return feeBurnt + tipBurnt;
};

for (const txnType of TransactionTypes) {
it({
id: `T${++testCounter}`,
title:
`Changing FeesTreasuryProportion to ${treasuryPercentage}% for Ethereum ` +
`${txnType} transfers`,
test: async () => {
const param = parameterType(
context,
"RuntimeConfig",
"FeesTreasuryProportion",
t.proportion.value()
);
await context.createBlock(
context
.polkadotJs()
.tx.sudo.sudo(context.polkadotJs().tx.parameters.setParameter(param.toU8a()))
.signAsync(alith),
{ allowFailures: false }
);
for (const withTip of txnType === "eip1559" ? [false, true] : [false]) {
testCounter++;
it({
id: `T${testCounter}x`,
title:
`Changing FeesTreasuryProportion to ${treasuryPercentage}% for Ethereum ` +
`${txnType} transfers with ${withTip ? "" : "no "}tip`,
test: async () => {
const {specVersion} = context.polkadotJs().consts.system.version;
const GENESIS_BASE_FEE = ConstantStore(context).GENESIS_BASE_FEE.get(
specVersion.toNumber()
);
const WEIGHT_FEE = ConstantStore(context).WEIGHT_FEE.get(
specVersion.toNumber()
);

const balBefore = await context.viem().getBalance({ address: TREASURY_ACCOUNT });
const issuanceBefore = (
await context.polkadotJs().query.balances.totalIssuance()
).toBigInt();
const { result } = await context.createBlock(
await createRawTransfer(context, BALTATHAR_ADDRESS, t.transfer_amount, {
type: txnType,
})
);
const param = parameterType(
context,
"RuntimeConfig",
"FeesTreasuryProportion",
t.proportion.value()
);
await context.createBlock(
context
.polkadotJs()
.tx.sudo.sudo(context.polkadotJs().tx.parameters.setParameter(param.toU8a()))
.signAsync(alith),
{allowFailures: false}
);

const balAfter = await context.viem().getBalance({ address: TREASURY_ACCOUNT });
const issuanceAfter = (
await context.polkadotJs().query.balances.totalIssuance()
).toBigInt();
const balBefore = await context.viem().getBalance({address: TREASURY_ACCOUNT});
const collatorBalBefore = await context.viem().getBalance({address: collatorAddress});
const issuanceBefore = (
await context.polkadotJs().query.balances.totalIssuance()
).toBigInt();

const treasuryIncrease = balAfter - balBefore;
const issuanceDecrease = issuanceBefore - issuanceAfter;
const fee = extractFee(result?.events)!.amount.toBigInt();
const nextFeeMultiplier = (await context.polkadotJs().query.transactionPayment.nextFeeMultiplier()).toBigInt();
const baseFee = nextFeeMultiplier * (WEIGHT_FEE * WEIGHT_PER_GAS) / 1_000_000_000_000_000_000n;

expect(
treasuryIncrease + issuanceDecrease,
`Sum of TreasuryIncrease and IssuanceDecrease should be equal to the fees`
).to.equal(fee);
console.log("baseFee:", baseFee);

expect(
treasuryIncrease,
`${treasuryPercentage}% of the fees should go to treasury`
).to.equal(calcTreasuryIncrease(fee));
const {result} = await context.createBlock(
await createRawTransfer(context, receiver, t.transfer_amount, {
privateKey: senderPrivateKey,
type: txnType,
maxFeePerGas: withTip ? GENESIS_BASE_FEE : undefined,
maxPriorityFeePerGas: withTip ? t.priorityFeePerGas : undefined,
})
);

expect(issuanceDecrease, `${burnPercentage}% of the fees should be burned`).to.equal(
calcIssuanceDecrease(fee)
);
const receipt = await context
.viem("public")
.getTransactionReceipt({hash: result!.hash as `0x${string}`});

await verifyLatestBlockFees(context, t.transfer_amount);
},
});
console.log("receipt:", receipt);

const balAfter = await context.viem().getBalance({address: TREASURY_ACCOUNT});
const collatorBalAfter = await context.viem().getBalance({address: collatorAddress});
const issuanceAfter = (
await context.polkadotJs().query.balances.totalIssuance()
).toBigInt();

const treasuryIncrease = balAfter - balBefore;
const issuanceDecrease = issuanceBefore - issuanceAfter;
const collatorIncrease = collatorBalAfter - collatorBalBefore;
const tipPaid = withTip ? (() => {
let priorityPerGas = (GENESIS_BASE_FEE - baseFee);
if (priorityPerGas > t.priorityFeePerGas) {
priorityPerGas = t.priorityFeePerGas;
}
return BigInt(priorityPerGas) * BigInt(receipt!.gasUsed);
})() : 0n;
const fee = extractFee(result?.events)!.amount.toBigInt();
const feeWithoutTip = fee - tipPaid;

console.log("treasuryIncrease:", treasuryIncrease);
console.log("issuanceDecrease:", issuanceDecrease);
console.log("collatorIncrease:", collatorIncrease);
console.log("total fees :", fee);
console.log("feeWithoutTip :", feeWithoutTip);
console.log("tipPaid :", tipPaid);

expect(
treasuryIncrease + issuanceDecrease,
`Sum of TreasuryIncrease and IssuanceDecrease should be equal to the fees without tip`
).to.equal(feeWithoutTip);

expect(
treasuryIncrease,
`${treasuryPercentage}% of the fees should go to treasury`
).to.equal(calcTreasuryIncrease(feeWithoutTip));

expect(issuanceDecrease, `${burnPercentage}% of the fees should be burned`).to.equal(
calcIssuanceDecrease(feeWithoutTip)
);

if (withTip) {
expect(collatorIncrease, "100% of the tip should go to the collator").to.equal(
tipPaid
);
} else {
expect(collatorIncrease, "No tip should be paid to the collator").to.equal(0n);
}

await verifyLatestBlockFees(context, t.transfer_amount);
},
});
}
}

for (const withTip of [false, true]) {
testCounter++;
it({
id: `T${++testCounter}`,
id: `T${testCounter}x`,
title:
`Changing FeesTreasuryProportion to ${treasuryPercentage}% for Substrate based ` +
`transactions with ${withTip ? "" : "no "}tip`,
Expand All @@ -165,23 +234,23 @@ describeSuite({
.polkadotJs()
.tx.sudo.sudo(context.polkadotJs().tx.parameters.setParameter(param.toU8a()))
.signAsync(alith),
{ allowFailures: false }
{allowFailures: false}
);

const balanceBefore = await context.viem().getBalance({ address: TREASURY_ACCOUNT });
const balanceBefore = await context.viem().getBalance({address: TREASURY_ACCOUNT});
const issuanceBefore = (
await context.polkadotJs().query.balances.totalIssuance()
).toBigInt();

const { result } = await context.createBlock(
const {result} = await context.createBlock(
context
.polkadotJs()
.tx.balances.transferKeepAlive(alith.address, t.transfer_amount)
.signAsync(baltathar, { tip: withTip ? t.tipAmount : 0n }),
{ allowFailures: false }
.tx.balances.transferKeepAlive(receiver, t.transfer_amount)
.signAsync(senderKeyPair, {tip: withTip ? t.tipAmount : 0n}),
{allowFailures: false}
);

const balanceAfter = await context.viem().getBalance({ address: TREASURY_ACCOUNT });
const balanceAfter = await context.viem().getBalance({address: TREASURY_ACCOUNT});
const issuanceAfter = (
await context.polkadotJs().query.balances.totalIssuance()
).toBigInt();
Expand Down

0 comments on commit 42e0a69

Please sign in to comment.