Skip to content

Commit

Permalink
add mock for HeadData and test
Browse files Browse the repository at this point in the history
  • Loading branch information
Agusrodri committed Sep 20, 2024
1 parent 3d57f42 commit f9b89b5
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 1 deletion.
4 changes: 3 additions & 1 deletion solo-chains/runtime/starlight/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1508,13 +1508,15 @@ construct_runtime! {
AuthorNoting: pallet_author_noting = 17,
ServicesPayment: pallet_services_payment = 18,
DataPreservers: pallet_data_preservers = 19,
InflationRewards: pallet_inflation_rewards = 20,

// Session management
Session: pallet_session = 30,
Grandpa: pallet_grandpa = 31,
AuthorityDiscovery: pallet_authority_discovery = 32,

// TODO: recheck order
InflationRewards: pallet_inflation_rewards = 33,

// Governance stuff; uncallable initially.
Treasury: pallet_treasury = 40,
ConvictionVoting: pallet_conviction_voting = 41,
Expand Down
134 changes: 134 additions & 0 deletions test/suites/dev-tanssi-relay/inflation-rewards/test-rewards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import "@tanssi/api-augment";
import { describeSuite, expect, beforeAll, DevModeContext } from "@moonwall/cli";
import { ApiPromise } from "@polkadot/api";
import { Header, ParaId, HeadData, Digest, DigestItem } from "@polkadot/types/interfaces";
import { KeyringPair } from "@moonwall/util";
import { fetchIssuance, filterRewardFromContainer, jumpToSession } from "util/block";
import { PARACHAIN_BOND } from "util/constants";
import { numberToHex, stringToHex } from "@polkadot/util";

async function mockAndInsertHeadData(
context: DevModeContext,
paraId: ParaId,
blockNumber: number,
slotNumber: number,
sudoAccount: KeyringPair
) {
const relayApi = context.polkadotJs();
let aura_engine_id = stringToHex("aura");

const digestItem: DigestItem = await relayApi.createType("DigestItem", {
PreRuntime: [aura_engine_id, numberToHex(slotNumber, 64)],
});
const digest: Digest = await relayApi.createType("Digest", {
logs: [digestItem],
});
const header: Header = await relayApi.createType("Header", {
parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
number: blockNumber,
stateRoot: "0x0000000000000000000000000000000000000000000000000000000000000000",
extrinsicsRoot: "0x0000000000000000000000000000000000000000000000000000000000000000",
digest,
});

const headData: HeadData = await relayApi.createType("HeadData", header.toHex());
const paraHeadKey = await relayApi.query.paras.heads.key(paraId);

await context.createBlock(
relayApi.tx.sudo
.sudo(relayApi.tx.system.setStorage([[paraHeadKey, `0xc101${headData.toHex().slice(2)}`]]))
.signAsync(sudoAccount),
{ allowFailures: false }
);
}

describeSuite({
id: "DTR0410",
title: "Starlight: InflationRewards test suite",
foundationMethods: "dev",
testCases: ({ it, context }) => {
let polkadotJs: ApiPromise;
let alice: KeyringPair;

beforeAll(async () => {
polkadotJs = context.polkadotJs();
alice = context.keyring.alice;
});

it({
id: "E01",
title: "Parachain bond receives 30% of the inflation and pending rewards plus division dust",
test: async function () {
await context.createBlock();
let expectedAmountParachainBond = 0n;

const pendingChainRewards = await polkadotJs.query.inflationRewards.chainsToReward();
if (pendingChainRewards.isSome) {
const rewardPerChain = pendingChainRewards.unwrap().rewardsPerChain.toBigInt();
const pendingChainsToReward = BigInt(pendingChainRewards.unwrap().paraIds.length);
expectedAmountParachainBond += pendingChainsToReward * rewardPerChain;
}

const parachainBondBalanceBefore = (
await polkadotJs.query.system.account(PARACHAIN_BOND)
).data.free.toBigInt();

await context.createBlock();

const currentChainRewards = await polkadotJs.query.inflationRewards.chainsToReward();
const events = await polkadotJs.query.system.events();
const issuance = await fetchIssuance(events).amount.toBigInt();

let dust = 0n;
if (currentChainRewards.isSome) {
const currentRewardPerChain = currentChainRewards.unwrap().rewardsPerChain.toBigInt();
dust = (issuance * 7n) / 10n - 2n * currentRewardPerChain;
}
const parachainBondBalanceAfter = (
await polkadotJs.query.system.account(PARACHAIN_BOND)
).data.free.toBigInt();

expectedAmountParachainBond += (issuance * 3n) / 10n + dust;
await context.createBlock();

expect(parachainBondBalanceAfter - parachainBondBalanceBefore).to.equal(
expectedAmountParachainBond + 1n
);
},
});

it({
id: "E02",
title: "Collator receives the reward from container-chain block proposal",
test: async function () {
// Jump 2 sessions to have collators assigned to containers.
await jumpToSession(context, 2);
const assignment = (await polkadotJs.query.tanssiCollatorAssignment.collatorContainerChain()).toJSON();

// The first account of container 2000 will be rewarded.
let accountToReward: string = assignment.containerChains[2000][0];

const { block } = await context.createBlock();
const accountBalanceBefore = (
await polkadotJs.query.system.account(accountToReward)
).data.free.toBigInt();

await mockAndInsertHeadData(context, 2000, block.duration, 2, alice);
await context.createBlock();

const currentChainRewards = (await polkadotJs.query.inflationRewards.chainsToReward()).unwrap();
const events = await polkadotJs.query.system.events();
const receivedRewards = filterRewardFromContainer(events, accountToReward, 2000);

const accountBalanceAfter = (
await polkadotJs.query.system.account(accountToReward)
).data.free.toBigInt();

expect(accountBalanceAfter - accountBalanceBefore).to.equal(
currentChainRewards.rewardsPerChain.toBigInt()
);
expect(accountBalanceAfter - accountBalanceBefore).to.equal(receivedRewards);
},
});
},
});

0 comments on commit f9b89b5

Please sign in to comment.