Skip to content

Commit

Permalink
divide main and test-net it tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Chralt98 committed Dec 21, 2023
1 parent abe7c7c commit acfcfb5
Show file tree
Hide file tree
Showing 7 changed files with 530 additions and 243 deletions.
21 changes: 21 additions & 0 deletions integration-tests/configs/basilisk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
endpoint: wss://basilisk-rococo-rpc.play.hydration.cloud
mock-signature-host: true
block: ${env.BASILISK_BLOCK_NUMBER}
db: ./tmp/basilisk_db_mba.sqlite

import-storage:
System:
Account:
-
-
- 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
- providers: 1
data:
free: 1000000000000000
Tokens:
Accounts:
-
-
- 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
- 17
- free: '100000000000000000000'
20 changes: 10 additions & 10 deletions integration-tests/moonwall.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
},
{
"name": "chopsticks_zeitgeist_upgrade",
"testFileDir": ["tests/rt-upgrade-chopsticks"],
"testFileDir": ["tests/rt-upgrade-zeitgeist-chopsticks"],
"foundation": {
"type": "chopsticks",
"rtUpgradePath": "../target/release/wbuild/zeitgeist-runtime/zeitgeist_runtime.compact.compressed.wasm",
Expand Down Expand Up @@ -83,43 +83,43 @@
},
{
"name": "chopsticks_battery_station_upgrade",
"testFileDir": ["tests/rt-upgrade-chopsticks"],
"testFileDir": ["tests/rt-upgrade-battery-station-chopsticks"],
"foundation": {
"type": "chopsticks",
"rtUpgradePath": "../target/release/wbuild/battery-station-runtime/battery_station_runtime.compact.compressed.wasm",
"launchSpec": [
{
"name": "ZeitgeistDB",
"name": "BatteryStationDB",
"type": "parachain",
"configPath": "./configs/battery-station.yml"
},
{
"name": "HydraDXDB",
"name": "BasiliskDB",
"type": "parachain",
"configPath": "./configs/hydradx.yml"
"configPath": "./configs/basilisk.yml"
},
{
"name": "PolkadotDB",
"name": "RococoDB",
"type": "relaychain",
"configPath": "polkadot"
"configPath": "rococo"
}
]
},
"envVars": ["LOG_LEVEL=debug", "VERBOSE_LOG"],
"buildBlockMode": "manual",
"connections": [
{
"name": "ZeitgeistPara",
"name": "BatteryStationPara",
"type": "polkadotJs",
"endpoints": ["ws://127.0.0.1:8000"]
},
{
"name": "HydraDXPara",
"name": "BasiliskPara",
"type": "polkadotJs",
"endpoints": ["ws://127.0.0.1:8001"]
},
{
"name": "PolkadotRelay",
"name": "RococoRelay",
"type": "polkadotJs",
"endpoints": ["ws://127.0.0.1:8002"]
}
Expand Down
203 changes: 203 additions & 0 deletions integration-tests/tests/common-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
// Copyright (C) Moondance Labs Ltd.

import { expect, ChopsticksContext } from "@moonwall/cli";
import { generateKeyringPair } from "@moonwall/util";
import { ApiPromise, Keyring } from "@polkadot/api";
import WebSocket from "ws";

const MAX_BALANCE_TRANSFER_TRIES = 5;

export async function canCreateBlocks(
context: ChopsticksContext,
providerName: string,
paraApi: ApiPromise
) {
const currentHeight = (
await paraApi.rpc.chain.getBlock()
).block.header.number.toNumber();
await context.createBlock({ providerName: providerName, count: 2 });
const newHeight = (
await paraApi.rpc.chain.getBlock()
).block.header.number.toNumber();
expect(newHeight - currentHeight, "Block difference is not correct!").toBe(2);
}

export async function canSendBalanceTransfer(
context: ChopsticksContext,
providerName: string,
paraApi: ApiPromise
) {
const randomAccount = generateKeyringPair("sr25519");
const keyring = new Keyring({ type: "sr25519" });
const alice = keyring.addFromUri("//Alice", { name: "Alice default" });

let tries = 0;
const amount = BigInt("1000000000");
const balanceBefore = (
await paraApi.query.system.account(randomAccount.address)
).data.free.toBigInt();

/// It might happen that by accident we hit a session change
/// A block in which a session change occurs cannot hold any tx
/// Chopsticks does not have the notion of tx pool either, so we need to retry
/// Therefore we just retry at most MAX_BALANCE_TRANSFER_TRIES
while (tries < MAX_BALANCE_TRANSFER_TRIES) {
const tx = await paraApi.tx.balances.transfer(
randomAccount.address,
amount
);
const txHash = tx.signAndSend(alice, { nonce: -1 });
const result = await context.createBlock({
providerName: providerName,
count: 1,
});

const block = await paraApi.rpc.chain.getBlock(result.result);
const includedTxHashes = block.block.extrinsics.map((x) =>
x.hash.toString()
);
if (includedTxHashes.includes(txHash.toString())) {
break;
}
tries++;
}

// without this, the xcm transfer test has a timeout
await context.createBlock({ providerName: providerName, count: 1 });

const balanceAfter = (
await paraApi.query.system.account(randomAccount.address)
).data.free.toBigInt();
expect(balanceAfter > balanceBefore, "Balance did not increase").toBeTruthy();
}

export async function canSendXcmTransfer(
log: Debugger,
senderParaApi: ApiPromise,
receiverParaApi: ApiPromise,
receiverParaId: number,
tokensIndex: number
) {
const keyring = new Keyring({ type: "sr25519" });
const alice = keyring.addFromUri("//Alice", { name: "Alice default" });
const bob = keyring.addFromUri("//Bob", { name: "Bob default" });

const senderBalanceBefore = (
await senderParaApi.query.system.account(alice.address)
).data.free.toBigInt();
const receiverBalanceBefore = (
await receiverParaApi.query.tokens.accounts(bob.address, tokensIndex)
).free.toBigInt();

const ztg = { Ztg: null };
const amount: bigint = BigInt("192913122185847181");
const bobAccountId = senderParaApi
.createType("AccountId32", bob.address)
.toHex();
const destination = {
V3: {
parents: 1,
interior: {
X2: [
{ Parachain: receiverParaId },
{ AccountId32: { id: bobAccountId, network: null } },
],
},
},
};
const destWeightLimit = { Unlimited: null };

// Create a promise that resolves when the transaction is finalized
const finalizedPromise = new Promise((resolve, reject) => {
const xcmTransfer = senderParaApi.tx.xTokens.transfer(
ztg,
amount,
destination,
destWeightLimit
);
xcmTransfer.signAndSend(alice, { nonce: -1 }, ({ status }) => {
log(`Current status is ${status.toString()}`);
if (status.isFinalized) {
log(`Transaction finalized at blockHash ${status.asFinalized}`);
resolve(xcmTransfer);
} else if (status.isError) {
reject(new Error(`Transaction failed with status ${status}`));
}
});
});

// Wait for the transaction to be finalized
const xcmTransfer = await finalizedPromise;
const { partialFee, weight } = await xcmTransfer.paymentInfo(alice.address);
const transferFee: bigint = partialFee.toBigInt();
const senderBalanceAfter = (
await senderParaApi.query.system.account(alice.address)
).data.free.toBigInt();
expect(
senderBalanceBefore - senderBalanceAfter,
"Unexpected balance diff"
).toBe(amount + transferFee);

// RpcError: 1: Block 0x... not found, if using this `await context.createBlock({ providerName: "ReceiverPara", count: 1 });`
// Reported Bug here https://github.com/Moonsong-Labs/moonwall/issues/343

// use a workaround for creating a block
const blocksToRun = 2;
const currentHeight = (
await receiverParaApi.rpc.chain.getBlock()
).block.header.number.toNumber();
const newBlockPromise = new Promise((resolve, reject) => {
// ws://127.0.0.1:8001 represents the receiver chain endpoint
const ws = new WebSocket("ws://127.0.0.1:8001");

ws.on("open", function open() {
const message = {
jsonrpc: "2.0",
id: 1,
method: "dev_newBlock",
params: [{ count: blocksToRun }],
};

ws.send(JSON.stringify(message));
});

ws.on("message", async function message(data) {
const dataObj = JSON.parse(data.toString());
log("Received message:", dataObj);
resolve(dataObj.result);
});

ws.on("error", function error(error) {
log("Error:", error.toString());
reject(error);
});
});

const blockHash = await newBlockPromise;
const newHeight = (
await receiverParaApi.rpc.chain.getBlock()
).block.header.number.toNumber();
// TODO why +1 here?
expect(newHeight - currentHeight, "Block difference is not correct!").toBe(
blocksToRun + 1
);

const receiverBalanceAfter: bigint = (
await receiverParaApi.query.tokens.accounts(bob.address, tokensIndex)
).free.toBigInt();
expect(
receiverBalanceAfter > receiverBalanceBefore,
"Balance did not increase"
).toBeTruthy();
const xcmFee: bigint =
receiverBalanceBefore + amount - transferFee - receiverBalanceAfter;
// between 0.03 ZTG and 0.05 ZTG XCM fee
const approxXcmFeeLow = 300000000;
const approxXcmFeeHigh = 500000000;
expect(xcmFee).toBeGreaterThanOrEqual(approxXcmFeeLow);
expect(xcmFee).toBeLessThanOrEqual(approxXcmFeeHigh);
expect(
receiverBalanceAfter - receiverBalanceBefore,
"Unexpected xcm transfer balance diff"
).toBe(amount - transferFee - xcmFee);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright (C) Moondance Labs Ltd.

import {
MoonwallContext,
beforeAll,
describeSuite,
expect,
} from "@moonwall/cli";
import { KeyringPair } from "@moonwall/util";
import { ApiPromise, Keyring } from "@polkadot/api";
import {
canCreateBlocks,
canSendBalanceTransfer,
canSendXcmTransfer,
} from "tests/common-tests";

const ZEITGEIST_TOKENS_INDEX = 12;
const BASILISK_PARA_ID = 2090;
describeSuite({
id: "CAN",
title: "Chopsticks Battery Station Post-Upgrade Tests",
foundationMethods: "chopsticks",
testCases: function ({ it, context, log }) {
let batteryStationParaApi: ApiPromise;
let relayApi: ApiPromise;
let basiliskParaApi: ApiPromise;
let alice: KeyringPair;

beforeAll(async () => {
const keyring = new Keyring({ type: "sr25519" });
alice = keyring.addFromUri("//Alice", { name: "Alice default" });
batteryStationParaApi = context.polkadotJs("BatteryStationPara");
relayApi = context.polkadotJs("RococoRelay");
basiliskParaApi = context.polkadotJs("BasiliskPara");

const paraZeitgeistNetwork =
batteryStationParaApi.consts.system.version.specName.toString();
expect(paraZeitgeistNetwork, "Para API incorrect").to.contain(
"zeitgeist"
);

const relayNetwork = relayApi.consts.system.version.specName.toString();
expect(relayNetwork, "Relay API incorrect").to.contain("rococo");

const paraBasiliskNetwork =
basiliskParaApi.consts.system.version.specName.toString();
expect(paraBasiliskNetwork, "Para API incorrect").to.contain("basilisk");

const rtBefore =
batteryStationParaApi.consts.system.version.specVersion.toNumber();
log(`About to upgrade to runtime at:`);
log(MoonwallContext.getContext().rtUpgradePath);

await context.upgradeRuntime(context);

const rtafter =
batteryStationParaApi.consts.system.version.specVersion.toNumber();
log(
`RT upgrade has increased specVersion from ${rtBefore} to ${rtafter}`
);
});

it({
id: "T1",
timeout: 60000,
title: "Can create new blocks",
test: async () => {
await canCreateBlocks(
context,
"BatteryStationPara",
batteryStationParaApi
);
},
});

it({
id: "T2",
timeout: 60000,
title: "Can send balance transfers",
test: async () => {
await canSendBalanceTransfer(
context,
"BatteryStationPara",
batteryStationParaApi
);
},
});

/*
Currently not working, bug tracked here https://github.com/galacticcouncil/HydraDX-node/issues/725
it({
id: "T3",
timeout: 60000,
title: "Can send ZBS to Basilisk",
test: async () => {
await canSendXcmTransfer(
log,
batteryStationParaApi,
basiliskParaApi,
BASILISK_PARA_ID,
ZEITGEIST_TOKENS_INDEX
);
},
});
*/
},
});
Loading

0 comments on commit acfcfb5

Please sign in to comment.