difftreelog
refactor event helpers
in: master
4 files changed
tests/src/scheduler.seqtest.tsdiffbeforeafterboth--- a/tests/src/scheduler.seqtest.ts
+++ b/tests/src/scheduler.seqtest.ts
@@ -16,7 +16,7 @@
import {expect, itSched, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from './util';
import {IKeyringPair} from '@polkadot/types/types';
-import {DevUniqueHelper} from './util/playgrounds/unique.dev';
+import {DevUniqueHelper, Event} from './util/playgrounds/unique.dev';
describe('Scheduling token and balance transfers', () => {
let superuser: IKeyringPair;
@@ -411,19 +411,13 @@
const priority = 112;
await helper.getSudo().scheduler.changePriority(superuser, scheduledId, priority);
- const priorityChanged = await helper.wait.event(
- waitForBlocks,
- 'scheduler',
- 'PriorityChanged',
- );
-
- expect(priorityChanged !== null).to.be.true;
+ const priorityChanged = await helper.wait.expectEvent(waitForBlocks, Event.Scheduler.PriorityChanged);
- const [blockNumber, index] = priorityChanged!.event.data[0].toJSON() as any[];
+ const [blockNumber, index] = priorityChanged.task();
expect(blockNumber).to.be.equal(executionBlock);
expect(index).to.be.equal(0);
- expect(priorityChanged!.event.data[1].toString()).to.be.equal(priority.toString());
+ expect(priorityChanged.priority().toString()).to.be.equal(priority.toString());
});
itSub('Prioritized operations execute in valid order', async ({helper}) => {
@@ -668,13 +662,7 @@
await expect(helper.scheduler.changePriority(alice, scheduledId, priority))
.to.be.rejectedWith(/BadOrigin/);
- const priorityChanged = await helper.wait.event(
- waitForBlocks,
- 'scheduler',
- 'PriorityChanged',
- );
-
- expect(priorityChanged === null).to.be.true;
+ await helper.wait.expectEvent(waitForBlocks, Event.Scheduler.PriorityChanged);
});
});
tests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth9import {IKeyringPair} from '@polkadot/types/types';9import {IKeyringPair} from '@polkadot/types/types';10import {EventRecord} from '@polkadot/types/interfaces';10import {EventRecord} from '@polkadot/types/interfaces';11import {ICrossAccountId, IPovInfo, TSigner} from './types';11import {ICrossAccountId, IPovInfo, TSigner} from './types';12import {FrameSystemEventRecord} from '@polkadot/types/lookup';12import {FrameSystemEventRecord, XcmV2TraitsError} from '@polkadot/types/lookup';13import {VoidFn} from '@polkadot/api/types';13import {VoidFn} from '@polkadot/api/types';14import {Pallets} from '..';14import {Pallets} from '..';15import {spawnSync} from 'child_process';15import {spawnSync} from 'child_process';59 }59 }60}60}6162export interface IEventHelper {63 section(): string;6465 method(): string;6667 bindEventRecord(e: FrameSystemEventRecord): void;6869 raw(): FrameSystemEventRecord;70}7172// eslint-disable-next-line @typescript-eslint/naming-convention73function EventHelper(section: string, method: string) {74 return class implements IEventHelper {75 eventRecord: FrameSystemEventRecord | null;76 _section: string;77 _method: string;7879 constructor() {80 this.eventRecord = null;81 this._section = section;82 this._method = method;83 }8485 section(): string {86 return this._section;87 }8889 method(): string {90 return this._method;91 }9293 bindEventRecord(e: FrameSystemEventRecord) {94 this.eventRecord = e;95 }9697 raw() {98 return this.eventRecord!;99 }100101 eventJsonData<T = any>(index: number) {102 return this.raw().event.data[index].toJSON() as T;103 }104105 eventData<T>(index: number) {106 return this.raw().event.data[index] as T;107 }108 };109}110111// eslint-disable-next-line @typescript-eslint/naming-convention112function EventSection(section: string) {113 return class Section {114 static section = section;115116 static Method(name: string) {117 return EventHelper(Section.section, name);118 }119 };120}121122export class Event {123 static Democracy = class extends EventSection('democracy') {124 static Started = class extends this.Method('Started') {125 referendumIndex() {126 return this.eventJsonData<number>(0);127 }128129 threshold() {130 return this.eventJsonData(1);131 }132 };133134 static Voted = class extends this.Method('Voted') {135 voter() {136 return this.eventJsonData(0);137 }138139 referendumIndex() {140 return this.eventJsonData<number>(1);141 }142143 vote() {144 return this.eventJsonData(2);145 }146 };147148 static Passed = class extends this.Method('Passed') {149 referendumIndex() {150 return this.eventJsonData<number>(0);151 }152 };153 };154155 static Scheduler = class extends EventSection('scheduler') {156 static PriorityChanged = class extends this.Method('PriorityChanged') {157 task() {158 return this.eventJsonData(0);159 }160161 priority() {162 return this.eventJsonData(1);163 }164 };165 };166167 static XcmpQueue = class extends EventSection('xcmpQueue') {168 static XcmpMessageSent = class extends this.Method('XcmpMessageSent') {169 messageHash() {170 return this.eventJsonData(0);171 }172 };173174 static Fail = class extends this.Method('Fail') {175 messageHash() {176 return this.eventJsonData(0);177 }178179 outcome() {180 return this.eventData<XcmV2TraitsError>(1);181 }182 };183 };184}6118562export class DevUniqueHelper extends UniqueHelper {186export class DevUniqueHelper extends UniqueHelper {63 /**187 /**634 console.log('\t* Fast track proposal through technical committee.......DONE');758 console.log('\t* Fast track proposal through technical committee.......DONE');635 // <<< Fast track proposal through technical committee <<<759 // <<< Fast track proposal through technical committee <<<636760637 const refIndexField = 0;638 const referendumIndex = await this.helper.wait.eventData<number>(3, 'democracy', 'Started', refIndexField);761 const democracyStarted = await this.helper.wait.expectEvent(3, Event.Democracy.Started);762 const referendumIndex = democracyStarted.referendumIndex();639763640 // >>> Referendum voting >>>764 // >>> Referendum voting >>>641 console.log(`\t* Referendum #${referendumIndex} voting.......`);765 console.log(`\t* Referendum #${referendumIndex} voting.......`);642 await this.helper.democracy.referendumVote(dorothyAccount, referendumIndex!, {766 await this.helper.democracy.referendumVote(dorothyAccount, referendumIndex, {643 balance: 10_000_000_000_000_000_000n,767 balance: 10_000_000_000_000_000_000n,644 vote: {aye: true, conviction: 1},768 vote: {aye: true, conviction: 1},645 });769 });646 console.log(`\t* Referendum #${referendumIndex} voting.......DONE`);770 console.log(`\t* Referendum #${referendumIndex} voting.......DONE`);647 // <<< Referendum voting <<<771 // <<< Referendum voting <<<648772649 // Wait the proposal to pass773 // Wait the proposal to pass650 await this.helper.wait.event(3, 'democracy', 'Passed');774 await this.helper.wait.expectEvent(3, Event.Democracy.Passed, event => {775 return event.referendumIndex() == referendumIndex;776 });777651 await this.helper.wait.newBlocks(1);778 await this.helper.wait.newBlocks(1);652779794 return promise;921 return promise;795 }922 }796923797 event(maxBlocksToWait: number, eventSection: string, eventMethod: string) {924 event<T extends IEventHelper>(925 maxBlocksToWait: number,926 eventHelperType: new () => T,927 filter: (_: T) => boolean = () => { return true; },928 ) {798 // eslint-disable-next-line no-async-promise-executor929 // eslint-disable-next-line no-async-promise-executor799 const promise = new Promise<EventRecord | null>(async (resolve) => {930 const promise = new Promise<T | null>(async (resolve) => {800 const unsubscribe = await this.helper.getApi().rpc.chain.subscribeNewHeads(async header => {931 const unsubscribe = await this.helper.getApi().rpc.chain.subscribeNewHeads(async header => {932 const eventHelper = new eventHelperType();801 const blockNumber = header.number.toHuman();933 const blockNumber = header.number.toHuman();802 const blockHash = header.hash;934 const blockHash = header.hash;803 const eventIdStr = `${eventSection}.${eventMethod}`;935 const eventIdStr = `${eventHelper.section()}.${eventHelper.method()}`;804 const waitLimitStr = `wait blocks remaining: ${maxBlocksToWait}`;936 const waitLimitStr = `wait blocks remaining: ${maxBlocksToWait}`;805937806 this.helper.logger.log(`[Block #${blockNumber}] Waiting for event \`${eventIdStr}\` (${waitLimitStr})`);938 this.helper.logger.log(`[Block #${blockNumber}] Waiting for event \`${eventIdStr}\` (${waitLimitStr})`);809 const eventRecords = (await apiAt.query.system.events()) as any;941 const eventRecords = (await apiAt.query.system.events()) as any;810942811 const neededEvent = eventRecords.toArray().find((r: FrameSystemEventRecord) => {943 const neededEvent = eventRecords.toArray().find((r: FrameSystemEventRecord) => {944 if (812 return r.event.section == eventSection && r.event.method == eventMethod;945 r.event.section == eventHelper.section()946 && r.event.method == eventHelper.method()947 ) {948 eventHelper.bindEventRecord(r);949 return filter(eventHelper);950 } else {951 return false;952 }813 });953 });814954815 if (neededEvent) {955 if (neededEvent) {816 unsubscribe();956 unsubscribe();817 resolve(neededEvent);957 resolve(eventHelper);818 } else if (maxBlocksToWait > 0) {958 } else if (maxBlocksToWait > 0) {819 maxBlocksToWait--;959 maxBlocksToWait--;820 } else {960 } else {821 this.helper.logger.log(`Event \`${eventIdStr}\` is NOT found`);961 this.helper.logger.log(`Eligible event \`${eventIdStr}\` is NOT found`);822 unsubscribe();962 unsubscribe();823 resolve(null);963 resolve(null);824 }964 }827 return promise;967 return promise;828 }968 }829969830 async eventData<EventT>(maxBlocksToWait: number, eventSection: string, eventMethod: string, fieldIndex: number) {970 async expectEvent<T extends IEventHelper>(971 maxBlocksToWait: number,972 eventHelperType: new () => T,973 filter: (e: T) => boolean = () => { return true; },974 ) {831 const eventRecord = await this.event(maxBlocksToWait, eventSection, eventMethod);975 const e = await this.event(maxBlocksToWait, eventHelperType, filter);832833 if (eventRecord == null) {976 if (e == null) {834 return null;835 }836837 const event = eventRecord!.event;977 const eventHelper = new eventHelperType();838 const data = event.data[fieldIndex] as EventT;978 throw Error(`The event '${eventHelper.section()}.${eventHelper.method()}' is expected`);839979 } else {840 return data;980 return e;981 }841 }982 }842}983}843984tests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth--- a/tests/src/xcm/xcmQuartz.test.ts
+++ b/tests/src/xcm/xcmQuartz.test.ts
@@ -16,9 +16,8 @@
import {IKeyringPair} from '@polkadot/types/types';
import config from '../config';
-import {XcmV2TraitsError} from '../interfaces';
import {itSub, expect, describeXCM, usingPlaygrounds, usingKaruraPlaygrounds, usingRelayPlaygrounds, usingMoonriverPlaygrounds, usingStateminePlaygrounds, usingShidenPlaygrounds} from '../util';
-import {DevUniqueHelper} from '../util/playgrounds/unique.dev';
+import {DevUniqueHelper, Event} from '../util/playgrounds/unique.dev';
const QUARTZ_CHAIN = 2095;
const STATEMINE_CHAIN = 1000;
@@ -673,30 +672,20 @@
moreThanKaruraHas,
);
+ let maliciousXcmProgramSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Quartz
await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);
+
+ maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isFailedToTransactAsset,
- `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramSent.messageHash()
+ && event.outcome().isFailedToTransactAsset;
+ });
targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(targetAccountBalance).to.be.equal(0n);
@@ -765,30 +754,21 @@
testAmount,
);
+ let maliciousXcmProgramFullIdSent: any;
+ let maliciousXcmProgramHereIdSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Quartz using full QTZ identification
await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramFullId);
- });
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
+ maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -796,24 +776,14 @@
// Try to trick Quartz using shortened QTZ identification
await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramHereId);
- });
- xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -834,6 +804,10 @@
let quartzAccountMultilocation: any;
let quartzCombinedMultilocation: any;
+ let messageSent: any;
+
+ const maxWaitBlocks = 3;
+
before(async () => {
await usingPlaygrounds(async (helper, privateKey) => {
alice = await privateKey('//Alice');
@@ -883,26 +857,11 @@
});
});
- const expectFailedToTransact = async (network: string, helper: DevUniqueHelper) => {
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- `[reject ${network} tokens] 'xcmpQueue.FailEvent' event is expected`,
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isFailedToTransactAsset,
- `[reject ${network} tokens] The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ const expectFailedToTransact = async (helper: DevUniqueHelper, messageSent: any) => {
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == messageSent.messageHash()
+ && event.outcome().isFailedToTransactAsset;
+ });
};
itSub('Quartz rejects KAR tokens from Karura', async ({helper}) => {
@@ -912,9 +871,11 @@
};
const destination = quartzCombinedMultilocation;
await helper.xTokens.transfer(alice, id, testAmount, destination, 'Unlimited');
+
+ messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- await expectFailedToTransact('KAR', helper);
+ await expectFailedToTransact(helper, messageSent);
});
itSub('Quartz rejects MOVR tokens from Moonriver', async ({helper}) => {
@@ -922,9 +883,11 @@
const id = 'SelfReserve';
const destination = quartzCombinedMultilocation;
await helper.xTokens.transfer(alith, id, testAmount, destination, 'Unlimited');
+
+ messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- await expectFailedToTransact('MOVR', helper);
+ await expectFailedToTransact(helper, messageSent);
});
itSub('Quartz rejects SDN tokens from Shiden', async ({helper}) => {
@@ -952,9 +915,11 @@
assets,
feeAssetItem,
]);
+
+ messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- await expectFailedToTransact('SDN', helper);
+ await expectFailedToTransact(helper, messageSent);
});
});
@@ -1193,6 +1158,9 @@
moreThanMoonriverHas,
);
+ let maliciousXcmProgramSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Quartz
await usingMoonriverPlaygrounds(moonriverUrl, async (helper) => {
const xcmSend = helper.constructApiCall('api.tx.polkadotXcm.send', [quartzMultilocation, maliciousXcmProgram]);
@@ -1200,27 +1168,14 @@
// Needed to bypass the call filter.
const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
await helper.fastDemocracy.executeProposal('try to spend more QTZ than Moonriver has', batchCall);
- });
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isFailedToTransactAsset,
- `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramSent.messageHash()
+ && event.outcome().isFailedToTransactAsset;
+ });
targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(targetAccountBalance).to.be.equal(0n);
@@ -1293,6 +1248,10 @@
testAmount,
);
+ let maliciousXcmProgramFullIdSent: any;
+ let maliciousXcmProgramHereIdSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Quartz using full QTZ identification
await usingMoonriverPlaygrounds(moonriverUrl, async (helper) => {
const xcmSend = helper.constructApiCall('api.tx.polkadotXcm.send', [quartzMultilocation, maliciousXcmProgramFullId]);
@@ -1300,27 +1259,14 @@
// Needed to bypass the call filter.
const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
await helper.fastDemocracy.executeProposal('try to act like a reserve location for QTZ using path asset identification', batchCall);
- });
-
- const maxWaitBlocks = 3;
- const outcomeField = 1;
- let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'isUntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -1332,24 +1278,14 @@
// Needed to bypass the call filter.
const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
await helper.fastDemocracy.executeProposal('try to act like a reserve location for QTZ using "here" asset identification', batchCall);
- });
- xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'isUntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -1598,31 +1534,21 @@
moreThanShidenHas,
);
+ let maliciousXcmProgramSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Quartz
await usingShidenPlaygrounds(shidenUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);
+
+ maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramSent.messageHash()
+ && event.outcome().isFailedToTransactAsset;
+ });
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isFailedToTransactAsset,
- `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
-
targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(targetAccountBalance).to.be.equal(0n);
@@ -1690,30 +1616,21 @@
testAmount,
);
+ let maliciousXcmProgramFullIdSent: any;
+ let maliciousXcmProgramHereIdSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Quartz using full QTZ identification
await usingShidenPlaygrounds(shidenUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramFullId);
- });
- const maxWaitBlocks = 3;
- const outcomeField = 1;
+ maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'isUntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -1721,24 +1638,14 @@
// Try to trick Quartz using shortened QTZ identification
await usingShidenPlaygrounds(shidenUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramHereId);
- });
- xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'isUntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
tests/src/xcm/xcmUnique.test.tsdiffbeforeafterboth--- a/tests/src/xcm/xcmUnique.test.ts
+++ b/tests/src/xcm/xcmUnique.test.ts
@@ -16,9 +16,8 @@
import {IKeyringPair} from '@polkadot/types/types';
import config from '../config';
-import {XcmV2TraitsError} from '../interfaces';
import {itSub, expect, describeXCM, usingPlaygrounds, usingAcalaPlaygrounds, usingRelayPlaygrounds, usingMoonbeamPlaygrounds, usingStatemintPlaygrounds, usingAstarPlaygrounds} from '../util';
-import {DevUniqueHelper} from '../util/playgrounds/unique.dev';
+import {DevUniqueHelper, Event} from '../util/playgrounds/unique.dev';
const UNIQUE_CHAIN = 2037;
const STATEMINT_CHAIN = 1000;
@@ -675,30 +674,20 @@
moreThanAcalaHas,
);
+ let maliciousXcmProgramSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Unique
await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
+
+ maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isFailedToTransactAsset,
- `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramSent.messageHash()
+ && event.outcome().isFailedToTransactAsset;
+ });
targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(targetAccountBalance).to.be.equal(0n);
@@ -767,30 +756,21 @@
testAmount,
);
+ let maliciousXcmProgramFullIdSent: any;
+ let maliciousXcmProgramHereIdSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Unique using full UNQ identification
await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramFullId);
- });
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
+ maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -798,24 +778,14 @@
// Try to trick Unique using shortened UNQ identification
await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramHereId);
- });
- xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -836,6 +806,10 @@
let uniqueAccountMultilocation: any;
let uniqueCombinedMultilocation: any;
+ let messageSent: any;
+
+ const maxWaitBlocks = 3;
+
before(async () => {
await usingPlaygrounds(async (helper, privateKey) => {
alice = await privateKey('//Alice');
@@ -885,26 +859,11 @@
});
});
- const expectFailedToTransact = async (network: string, helper: DevUniqueHelper) => {
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- `[reject ${network} tokens] 'xcmpQueue.FailEvent' event is expected`,
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isFailedToTransactAsset,
- `[reject ${network} tokens] The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ const expectFailedToTransact = async (helper: DevUniqueHelper, messageSent: any) => {
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == messageSent.messageHash()
+ && event.outcome().isFailedToTransactAsset;
+ });
};
itSub('Unique rejects ACA tokens from Acala', async ({helper}) => {
@@ -914,9 +873,11 @@
};
const destination = uniqueCombinedMultilocation;
await helper.xTokens.transfer(alice, id, testAmount, destination, 'Unlimited');
+
+ messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- await expectFailedToTransact('ACA', helper);
+ await expectFailedToTransact(helper, messageSent);
});
itSub('Unique rejects GLMR tokens from Moonbeam', async ({helper}) => {
@@ -924,9 +885,11 @@
const id = 'SelfReserve';
const destination = uniqueCombinedMultilocation;
await helper.xTokens.transfer(alith, id, testAmount, destination, 'Unlimited');
+
+ messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- await expectFailedToTransact('GLMR', helper);
+ await expectFailedToTransact(helper, messageSent);
});
itSub('Unique rejects ASTR tokens from Astar', async ({helper}) => {
@@ -954,9 +917,11 @@
assets,
feeAssetItem,
]);
+
+ messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- await expectFailedToTransact('ASTR', helper);
+ await expectFailedToTransact(helper, messageSent);
});
});
@@ -1196,6 +1161,9 @@
moreThanMoonbeamHas,
);
+ let maliciousXcmProgramSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Unique
await usingMoonbeamPlaygrounds(moonbeamUrl, async (helper) => {
const xcmSend = helper.constructApiCall('api.tx.polkadotXcm.send', [uniqueMultilocation, maliciousXcmProgram]);
@@ -1203,27 +1171,14 @@
// Needed to bypass the call filter.
const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
await helper.fastDemocracy.executeProposal('try to spend more UNQ than Moonbeam has', batchCall);
- });
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isFailedToTransactAsset,
- `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramSent.messageHash()
+ && event.outcome().isFailedToTransactAsset;
+ });
targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(targetAccountBalance).to.be.equal(0n);
@@ -1296,6 +1251,10 @@
testAmount,
);
+ let maliciousXcmProgramFullIdSent: any;
+ let maliciousXcmProgramHereIdSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Unique using full UNQ identification
await usingMoonbeamPlaygrounds(moonbeamUrl, async (helper) => {
const xcmSend = helper.constructApiCall('api.tx.polkadotXcm.send', [uniqueMultilocation, maliciousXcmProgramFullId]);
@@ -1303,27 +1262,14 @@
// Needed to bypass the call filter.
const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
await helper.fastDemocracy.executeProposal('try to act like a reserve location for UNQ using path asset identification', batchCall);
- });
-
- const maxWaitBlocks = 3;
- const outcomeField = 1;
- let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -1335,24 +1281,14 @@
// Needed to bypass the call filter.
const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
await helper.fastDemocracy.executeProposal('try to act like a reserve location for UNQ using "here" asset identification', batchCall);
- });
- xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -1600,31 +1536,21 @@
moreThanAstarHas,
);
+ let maliciousXcmProgramSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Unique
await usingAstarPlaygrounds(astarUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
+
+ maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
});
- const maxWaitBlocks = 3;
- const outcomeField = 1;
-
- const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramSent.messageHash()
+ && event.outcome().isFailedToTransactAsset;
+ });
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isFailedToTransactAsset,
- `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
-
targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(targetAccountBalance).to.be.equal(0n);
@@ -1692,30 +1618,21 @@
testAmount,
);
+ let maliciousXcmProgramFullIdSent: any;
+ let maliciousXcmProgramHereIdSent: any;
+ const maxWaitBlocks = 3;
+
// Try to trick Unique using full UNQ identification
await usingAstarPlaygrounds(astarUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramFullId);
- });
- const maxWaitBlocks = 3;
- const outcomeField = 1;
+ maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
-
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);
@@ -1723,24 +1640,14 @@
// Try to trick Unique using shortened UNQ identification
await usingAstarPlaygrounds(astarUrl, async (helper) => {
await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramHereId);
- });
- xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(
- maxWaitBlocks,
- 'xcmpQueue',
- 'Fail',
- outcomeField,
- );
-
- expect(
- xcmpQueueFailEvent != null,
- '\'xcmpQueue.FailEvent\' event is expected',
- ).to.be.true;
+ maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
+ });
- expect(
- xcmpQueueFailEvent!.isUntrustedReserveLocation,
- `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
- ).to.be.true;
+ await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
+ return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
+ && event.outcome().isUntrustedReserveLocation;
+ });
accountBalance = await helper.balance.getSubstrate(targetAccount.address);
expect(accountBalance).to.be.equal(0n);