mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 01:38:32 +00:00
Merge branch 'main' into misc/improve-e2e-tests
This commit is contained in:
commit
2aa3f760d8
1 changed files with 146 additions and 46 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { beforeAll, beforeEach, describeSuite, expect } from "@moonwall/cli";
|
||||
import { afterEach, beforeAll, beforeEach, describeSuite, expect } from "@moonwall/cli";
|
||||
import type { ApiPromise } from "@polkadot/api";
|
||||
|
||||
describeSuite({
|
||||
|
|
@ -12,13 +12,8 @@ describeSuite({
|
|||
api = context.polkadotJs();
|
||||
});
|
||||
|
||||
async function getSubstrateBlockNumber(): Promise<number> {
|
||||
const blockNumber = await api.query.system.number();
|
||||
return blockNumber.toNumber();
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
// Check if safe mode is already active from genesis
|
||||
// Ensure safe mode is active
|
||||
let enteredUntil = (await api.query.safeMode.enteredUntil()) as any;
|
||||
|
||||
if (!enteredUntil.isSome) {
|
||||
|
|
@ -26,12 +21,67 @@ describeSuite({
|
|||
const sudoTx = api.tx.sudo.sudo(enterSafeModeCall);
|
||||
await context.createBlock(sudoTx);
|
||||
|
||||
enteredUntil = (await api.query.safeMode.enteredUntil()) as any;
|
||||
}
|
||||
await context.createBlock();
|
||||
|
||||
expect(enteredUntil.isSome, "Safe mode should be active").to.be.true;
|
||||
enteredUntil = (await api.query.safeMode.enteredUntil()) as any;
|
||||
expect(enteredUntil.isSome, "Safe mode should be active after entering").to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
// Exit safe mode and verify
|
||||
const exitBlockBefore = await getSubstrateBlockNumber();
|
||||
const exitSafeModeCall = api.tx.safeMode.forceExit();
|
||||
const exitSudoTx = api.tx.sudo.sudo(exitSafeModeCall);
|
||||
|
||||
const blockHash = await context.createBlock(exitSudoTx);
|
||||
|
||||
const safeModeExited = await checkEvent("safeMode.Exited", blockHash);
|
||||
const sudoExecuted = await checkEvent("sudo.Sudid", blockHash);
|
||||
const extrinsicFailed = await checkEvent("system.ExtrinsicFailed", blockHash);
|
||||
|
||||
expect(safeModeExited, "SafeMode.Exited event should be present").to.be.true;
|
||||
expect(sudoExecuted, "Sudo.Sudid event should be present").to.be.true;
|
||||
expect(extrinsicFailed, "Extrinsic should not have failed").to.be.false;
|
||||
|
||||
const apiAtBlock = await getApiAtBlock(blockHash);
|
||||
const enteredUntilAtExitBlock = (await apiAtBlock.query.safeMode.enteredUntil()) as any;
|
||||
|
||||
expect(!enteredUntilAtExitBlock.isSome, "Safe mode should be deactivated.").to.be.true;
|
||||
|
||||
await context.createBlock();
|
||||
const exitBlockAfter = await getSubstrateBlockNumber();
|
||||
expect(exitBlockAfter, "Should be able to create blocks after exit").to.be.greaterThan(
|
||||
exitBlockBefore
|
||||
);
|
||||
});
|
||||
|
||||
async function getSubstrateBlockNumber(): Promise<number> {
|
||||
const blockNumber = await api.query.system.number();
|
||||
return blockNumber.toNumber();
|
||||
}
|
||||
|
||||
async function getApiAtBlock(
|
||||
blockHash?: string | Awaited<ReturnType<typeof context.createBlock>>
|
||||
) {
|
||||
const blockHashStr =
|
||||
typeof blockHash === "string" ? blockHash : (await api.rpc.chain.getBlockHash()).toString();
|
||||
return await api.at(blockHashStr);
|
||||
}
|
||||
|
||||
async function checkEvent(
|
||||
eventName: string,
|
||||
blockHash?: string | Awaited<ReturnType<typeof context.createBlock>>
|
||||
): Promise<boolean> {
|
||||
const [section, method] = eventName.split(".");
|
||||
const apiAtBlock = await getApiAtBlock(blockHash);
|
||||
const events = await apiAtBlock.query.system.events();
|
||||
return events.some((record: any) => {
|
||||
const { event } = record;
|
||||
return event.section === section && event.method === method;
|
||||
});
|
||||
}
|
||||
|
||||
it({
|
||||
id: "T01",
|
||||
title: "should produce blocks while in safe mode",
|
||||
|
|
@ -50,25 +100,6 @@ describeSuite({
|
|||
blocksToCreate,
|
||||
"Blocks should continue to be produced in safe mode"
|
||||
);
|
||||
|
||||
const exitBlockBefore = await getSubstrateBlockNumber();
|
||||
const exitSafeModeCall = api.tx.safeMode.forceExit();
|
||||
const exitSudoTx = api.tx.sudo.sudo(exitSafeModeCall);
|
||||
|
||||
await context.createBlock(exitSudoTx);
|
||||
|
||||
// Verify the exit block was created (ensures state is updated)
|
||||
const exitBlockAfter = await getSubstrateBlockNumber();
|
||||
expect(exitBlockAfter, "Exit block should have been created").to.be.greaterThan(
|
||||
exitBlockBefore
|
||||
);
|
||||
|
||||
const enteredUntilAfterExit = (await api.query.safeMode.enteredUntil()) as any;
|
||||
expect(!enteredUntilAfterExit.isSome, "Safe mode should be deactivated").to.be.true;
|
||||
|
||||
await context.createBlock();
|
||||
const finalBlock = await getSubstrateBlockNumber();
|
||||
expect(finalBlock).to.be.greaterThan(currentBlock);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -78,34 +109,103 @@ describeSuite({
|
|||
test: async () => {
|
||||
const startBlock = await getSubstrateBlockNumber();
|
||||
|
||||
// Create a block - this implicitly includes timestamp extrinsic
|
||||
// The fact that this succeeds proves Timestamp is whitelisted
|
||||
await context.createBlock();
|
||||
|
||||
// Verify the block was created (contains valid timestamp)
|
||||
const block = await context.viem().getBlock({ blockTag: "latest" });
|
||||
expect(Number(block.timestamp)).to.be.greaterThan(0);
|
||||
|
||||
// Verify block number increased
|
||||
const currentBlock = await getSubstrateBlockNumber();
|
||||
expect(currentBlock).to.be.greaterThan(startBlock);
|
||||
}
|
||||
});
|
||||
|
||||
// Exit safe mode
|
||||
const exitBlockBefore = await getSubstrateBlockNumber();
|
||||
const exitSafeModeCall = api.tx.safeMode.forceExit();
|
||||
const exitSudoTx = api.tx.sudo.sudo(exitSafeModeCall);
|
||||
it({
|
||||
id: "T03",
|
||||
title: "should allow system.remark calls in safe mode",
|
||||
test: async () => {
|
||||
const remarkData = "0x48656c6c6f"; // "Hello" in hex
|
||||
const remarkTx = api.tx.system.remarkWithEvent(remarkData);
|
||||
|
||||
await context.createBlock(exitSudoTx);
|
||||
const blockHash = await context.createBlock(remarkTx);
|
||||
|
||||
// Verify the exit block was created (ensures state is updated)
|
||||
const exitBlockAfter = await getSubstrateBlockNumber();
|
||||
expect(exitBlockAfter, "Exit block should have been created").to.be.greaterThan(
|
||||
exitBlockBefore
|
||||
);
|
||||
const remarkExecuted = await checkEvent("system.Remarked", blockHash);
|
||||
const extrinsicSuccess = await checkEvent("system.ExtrinsicSuccess", blockHash);
|
||||
|
||||
// Verify we exited safe mode
|
||||
const enteredUntilAfterExit = (await api.query.safeMode.enteredUntil()) as any;
|
||||
expect(!enteredUntilAfterExit.isSome, "Safe mode should be deactivated").to.be.true;
|
||||
expect(remarkExecuted, "System.Remarked event should be present").to.be.true;
|
||||
expect(extrinsicSuccess, "Extrinsic should have succeeded").to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it({
|
||||
id: "T04",
|
||||
title: "should allow preimage.notePreimage calls in safe mode",
|
||||
test: async () => {
|
||||
const preimageData = api.tx.system.remarkWithEvent("0x1234").method.toHex();
|
||||
const notePreimageTx = api.tx.preimage.notePreimage(preimageData);
|
||||
|
||||
const blockHash = await context.createBlock(notePreimageTx);
|
||||
|
||||
const preimageNoted = await checkEvent("preimage.Noted", blockHash);
|
||||
const extrinsicSuccess = await checkEvent("system.ExtrinsicSuccess", blockHash);
|
||||
|
||||
expect(preimageNoted, "Preimage.Noted event should be present").to.be.true;
|
||||
expect(extrinsicSuccess, "Extrinsic should have succeeded").to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it({
|
||||
id: "T05",
|
||||
title: "should allow scheduler calls in safe mode",
|
||||
test: async () => {
|
||||
const currentBlock = await getSubstrateBlockNumber();
|
||||
const scheduleAtBlock = currentBlock + 10;
|
||||
|
||||
const taskId = new Uint8Array(32).fill(0);
|
||||
taskId.set(new TextEncoder().encode("testTask"), 0);
|
||||
const call = api.tx.system.remarkWithEvent("0xabcd");
|
||||
const scheduleTx = api.tx.scheduler.scheduleNamed(taskId, scheduleAtBlock, null, 0, call);
|
||||
const sudoTx = api.tx.sudo.sudo(scheduleTx);
|
||||
const blockHash = await context.createBlock(sudoTx);
|
||||
|
||||
const sudoExecuted = await checkEvent("sudo.Sudid", blockHash);
|
||||
const scheduled = await checkEvent("scheduler.Scheduled", blockHash);
|
||||
|
||||
expect(sudoExecuted, "Sudo.Sudid event should be present").to.be.true;
|
||||
expect(scheduled, "Scheduler.Scheduled event should be present").to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it({
|
||||
id: "T06",
|
||||
title: "should allow txPause.pause calls in safe mode via sudo",
|
||||
test: async () => {
|
||||
const pauseCall = api.tx.txPause.pause(["System", "remark_with_event"]);
|
||||
const sudoTx = api.tx.sudo.sudo(pauseCall);
|
||||
const blockHash = await context.createBlock(sudoTx);
|
||||
const callPaused = await checkEvent("txPause.CallPaused", blockHash);
|
||||
expect(callPaused, "System.remark_with_event should have been paused").to.be.true;
|
||||
|
||||
const remarkTx = api.tx.system.remarkWithEvent("0xpaused");
|
||||
let remarkFailed = false;
|
||||
try {
|
||||
await context.createBlock(remarkTx);
|
||||
} catch (error: any) {
|
||||
remarkFailed = error.message.includes("Transaction call is not expected");
|
||||
}
|
||||
expect(remarkFailed, "Remark call should have been rejected due to pause").to.be.true;
|
||||
|
||||
// Unpause the call
|
||||
const unpauseCall = api.tx.txPause.unpause(["System", "remark_with_event"]);
|
||||
const unpauseSudoTx = api.tx.sudo.sudo(unpauseCall);
|
||||
const unpauseBlockHash = await context.createBlock(unpauseSudoTx);
|
||||
const callUnpaused = await checkEvent("txPause.CallUnpaused", unpauseBlockHash);
|
||||
expect(callUnpaused, "System.remark_with_event should have been unpaused").to.be.true;
|
||||
|
||||
// Verify remark now works after unpausing
|
||||
const remarkTx2 = api.tx.system.remarkWithEvent("0xunpaused");
|
||||
const remarkBlockHash = await context.createBlock(remarkTx2);
|
||||
const remarkSuccess = await checkEvent("system.ExtrinsicSuccess", remarkBlockHash);
|
||||
expect(remarkSuccess, "Remark call should succeed after unpausing").to.be.true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue