git.delta.rocks / unique-network / refs/commits / 642e462ef530

difftreelog

Merge pull request #923 from UniqueNetwork/fix/xcm-tests-wait-for-events

Yaroslav Bolyukin2023-04-21parents: #1368751 #8a18c99.patch.diff
in: master

4 files changed

modifiedtests/src/scheduler.seqtest.tsdiffbeforeafterboth
1616
17import {expect, itSched, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from './util';17import {expect, itSched, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from './util';
18import {IKeyringPair} from '@polkadot/types/types';18import {IKeyringPair} from '@polkadot/types/types';
19import {DevUniqueHelper} from './util/playgrounds/unique.dev';19import {DevUniqueHelper, Event} from './util/playgrounds/unique.dev';
2020
21describe('Scheduling token and balance transfers', () => {21describe('Scheduling token and balance transfers', () => {
22 let superuser: IKeyringPair;22 let superuser: IKeyringPair;
411 const priority = 112;411 const priority = 112;
412 await helper.getSudo().scheduler.changePriority(superuser, scheduledId, priority);412 await helper.getSudo().scheduler.changePriority(superuser, scheduledId, priority);
413413
414 const priorityChanged = await helper.wait.event(414 const priorityChanged = await helper.wait.expectEvent(waitForBlocks, Event.Scheduler.PriorityChanged);
415 waitForBlocks,
416 'scheduler',
417 'PriorityChanged',
418 );
419
420 expect(priorityChanged !== null).to.be.true;
421415
422 const [blockNumber, index] = priorityChanged!.event.data[0].toJSON() as any[];416 const [blockNumber, index] = priorityChanged.task();
423 expect(blockNumber).to.be.equal(executionBlock);417 expect(blockNumber).to.be.equal(executionBlock);
424 expect(index).to.be.equal(0);418 expect(index).to.be.equal(0);
425419
426 expect(priorityChanged!.event.data[1].toString()).to.be.equal(priority.toString());420 expect(priorityChanged.priority().toString()).to.be.equal(priority.toString());
427 });421 });
428422
429 itSub('Prioritized operations execute in valid order', async ({helper}) => {423 itSub('Prioritized operations execute in valid order', async ({helper}) => {
668 await expect(helper.scheduler.changePriority(alice, scheduledId, priority))662 await expect(helper.scheduler.changePriority(alice, scheduledId, priority))
669 .to.be.rejectedWith(/BadOrigin/);663 .to.be.rejectedWith(/BadOrigin/);
670664
671 const priorityChanged = await helper.wait.event(665 await helper.wait.expectEvent(waitForBlocks, Event.Scheduler.PriorityChanged);
672 waitForBlocks,
673 'scheduler',
674 'PriorityChanged',
675 );
676
677 expect(priorityChanged === null).to.be.true;
678 });666 });
679});667});
680668
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
9import {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}
61
62export interface IEventHelper {
63 section(): string;
64
65 method(): string;
66
67 bindEventRecord(e: FrameSystemEventRecord): void;
68
69 raw(): FrameSystemEventRecord;
70}
71
72// eslint-disable-next-line @typescript-eslint/naming-convention
73function EventHelper(section: string, method: string) {
74 return class implements IEventHelper {
75 eventRecord: FrameSystemEventRecord | null;
76 _section: string;
77 _method: string;
78
79 constructor() {
80 this.eventRecord = null;
81 this._section = section;
82 this._method = method;
83 }
84
85 section(): string {
86 return this._section;
87 }
88
89 method(): string {
90 return this._method;
91 }
92
93 bindEventRecord(e: FrameSystemEventRecord) {
94 this.eventRecord = e;
95 }
96
97 raw() {
98 return this.eventRecord!;
99 }
100
101 eventJsonData<T = any>(index: number) {
102 return this.raw().event.data[index].toJSON() as T;
103 }
104
105 eventData<T>(index: number) {
106 return this.raw().event.data[index] as T;
107 }
108 };
109}
110
111// eslint-disable-next-line @typescript-eslint/naming-convention
112function EventSection(section: string) {
113 return class Section {
114 static section = section;
115
116 static Method(name: string) {
117 return EventHelper(Section.section, name);
118 }
119 };
120}
121
122export 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 }
128
129 threshold() {
130 return this.eventJsonData(1);
131 }
132 };
133
134 static Voted = class extends this.Method('Voted') {
135 voter() {
136 return this.eventJsonData(0);
137 }
138
139 referendumIndex() {
140 return this.eventJsonData<number>(1);
141 }
142
143 vote() {
144 return this.eventJsonData(2);
145 }
146 };
147
148 static Passed = class extends this.Method('Passed') {
149 referendumIndex() {
150 return this.eventJsonData<number>(0);
151 }
152 };
153 };
154
155 static Scheduler = class extends EventSection('scheduler') {
156 static PriorityChanged = class extends this.Method('PriorityChanged') {
157 task() {
158 return this.eventJsonData(0);
159 }
160
161 priority() {
162 return this.eventJsonData(1);
163 }
164 };
165 };
166
167 static XcmpQueue = class extends EventSection('xcmpQueue') {
168 static XcmpMessageSent = class extends this.Method('XcmpMessageSent') {
169 messageHash() {
170 return this.eventJsonData(0);
171 }
172 };
173
174 static Fail = class extends this.Method('Fail') {
175 messageHash() {
176 return this.eventJsonData(0);
177 }
178
179 outcome() {
180 return this.eventData<XcmV2TraitsError>(1);
181 }
182 };
183 };
184}
61185
62export 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 <<<
636760
637 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();
639763
640 // >>> 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 <<<
648772
649 // Wait the proposal to pass773 // Wait the proposal to pass
650 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 });
777
651 await this.helper.wait.newBlocks(1);778 await this.helper.wait.newBlocks(1);
652779
794 return promise;921 return promise;
795 }922 }
796923
797 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-executor
799 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}`;
805937
806 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;
810942
811 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 });
814954
815 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 }
829969
830 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);
832
833 if (eventRecord == null) {976 if (e == null) {
834 return null;
835 }
836
837 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}
843984
modifiedtests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import config from '../config';18import config from '../config';
19import {XcmV2TraitsError} from '../interfaces';
20import {itSub, expect, describeXCM, usingPlaygrounds, usingKaruraPlaygrounds, usingRelayPlaygrounds, usingMoonriverPlaygrounds, usingStateminePlaygrounds, usingShidenPlaygrounds} from '../util';19import {itSub, expect, describeXCM, usingPlaygrounds, usingKaruraPlaygrounds, usingRelayPlaygrounds, usingMoonriverPlaygrounds, usingStateminePlaygrounds, usingShidenPlaygrounds} from '../util';
21import {DevUniqueHelper} from '../util/playgrounds/unique.dev';20import {DevUniqueHelper, Event} from '../util/playgrounds/unique.dev';
2221
23const QUARTZ_CHAIN = 2095;22const QUARTZ_CHAIN = 2095;
24const STATEMINE_CHAIN = 1000;23const STATEMINE_CHAIN = 1000;
673 moreThanKaruraHas,672 moreThanKaruraHas,
674 );673 );
674
675 let maliciousXcmProgramSent: any;
676 const maxWaitBlocks = 3;
675677
676 // Try to trick Quartz678 // Try to trick Quartz
677 await usingKaruraPlaygrounds(karuraUrl, async (helper) => {679 await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
678 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);680 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);
681
682 maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
679 });683 });
680
681 const maxWaitBlocks = 3;
682 const outcomeField = 1;
683684
684 const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(685 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
685 maxWaitBlocks,686 return event.messageHash() == maliciousXcmProgramSent.messageHash()
686 'xcmpQueue',687 && event.outcome().isFailedToTransactAsset;
687 'Fail',
688 outcomeField,
689 );688 });
690
691 expect(
692 xcmpQueueFailEvent != null,
693 '\'xcmpQueue.FailEvent\' event is expected',
694 ).to.be.true;
695
696 expect(
697 xcmpQueueFailEvent!.isFailedToTransactAsset,
698 `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
699 ).to.be.true;
700689
701 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);690 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
702 expect(targetAccountBalance).to.be.equal(0n);691 expect(targetAccountBalance).to.be.equal(0n);
765 testAmount,754 testAmount,
766 );755 );
756
757 let maliciousXcmProgramFullIdSent: any;
758 let maliciousXcmProgramHereIdSent: any;
759 const maxWaitBlocks = 3;
767760
768 // Try to trick Quartz using full QTZ identification761 // Try to trick Quartz using full QTZ identification
769 await usingKaruraPlaygrounds(karuraUrl, async (helper) => {762 await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
770 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramFullId);763 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramFullId);
764
765 maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
771 });766 });
772
773 const maxWaitBlocks = 3;
774 const outcomeField = 1;
775767
776 let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(768 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
777 maxWaitBlocks,769 return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
778 'xcmpQueue',770 && event.outcome().isUntrustedReserveLocation;
779 'Fail',
780 outcomeField,
781 );771 });
782
783 expect(
784 xcmpQueueFailEvent != null,
785 '\'xcmpQueue.FailEvent\' event is expected',
786 ).to.be.true;
787
788 expect(
789 xcmpQueueFailEvent!.isUntrustedReserveLocation,
790 `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
791 ).to.be.true;
792772
793 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);773 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
794 expect(accountBalance).to.be.equal(0n);774 expect(accountBalance).to.be.equal(0n);
797 await usingKaruraPlaygrounds(karuraUrl, async (helper) => {777 await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
798 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramHereId);778 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramHereId);
779
780 maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
799 });781 });
800782
801 xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(783 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
802 maxWaitBlocks,784 return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
803 'xcmpQueue',785 && event.outcome().isUntrustedReserveLocation;
804 'Fail',
805 outcomeField,
806 );786 });
807
808 expect(
809 xcmpQueueFailEvent != null,
810 '\'xcmpQueue.FailEvent\' event is expected',
811 ).to.be.true;
812
813 expect(
814 xcmpQueueFailEvent!.isUntrustedReserveLocation,
815 `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
816 ).to.be.true;
817787
818 accountBalance = await helper.balance.getSubstrate(targetAccount.address);788 accountBalance = await helper.balance.getSubstrate(targetAccount.address);
819 expect(accountBalance).to.be.equal(0n);789 expect(accountBalance).to.be.equal(0n);
834 let quartzAccountMultilocation: any;804 let quartzAccountMultilocation: any;
835 let quartzCombinedMultilocation: any;805 let quartzCombinedMultilocation: any;
806
807 let messageSent: any;
808
809 const maxWaitBlocks = 3;
836810
837 before(async () => {811 before(async () => {
838 await usingPlaygrounds(async (helper, privateKey) => {812 await usingPlaygrounds(async (helper, privateKey) => {
883 });857 });
884 });858 });
885859
886 const expectFailedToTransact = async (network: string, helper: DevUniqueHelper) => {860 const expectFailedToTransact = async (helper: DevUniqueHelper, messageSent: any) => {
887 const maxWaitBlocks = 3;
888 const outcomeField = 1;
889
890 const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(861 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
891 maxWaitBlocks,862 return event.messageHash() == messageSent.messageHash()
892 'xcmpQueue',863 && event.outcome().isFailedToTransactAsset;
893 'Fail',
894 outcomeField,
895 );864 });
896
897 expect(
898 xcmpQueueFailEvent != null,
899 `[reject ${network} tokens] 'xcmpQueue.FailEvent' event is expected`,
900 ).to.be.true;
901
902 expect(
903 xcmpQueueFailEvent!.isFailedToTransactAsset,
904 `[reject ${network} tokens] The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
905 ).to.be.true;
906 };865 };
907866
908 itSub('Quartz rejects KAR tokens from Karura', async ({helper}) => {867 itSub('Quartz rejects KAR tokens from Karura', async ({helper}) => {
913 const destination = quartzCombinedMultilocation;872 const destination = quartzCombinedMultilocation;
914 await helper.xTokens.transfer(alice, id, testAmount, destination, 'Unlimited');873 await helper.xTokens.transfer(alice, id, testAmount, destination, 'Unlimited');
874
875 messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
915 });876 });
916877
917 await expectFailedToTransact('KAR', helper);878 await expectFailedToTransact(helper, messageSent);
918 });879 });
919880
920 itSub('Quartz rejects MOVR tokens from Moonriver', async ({helper}) => {881 itSub('Quartz rejects MOVR tokens from Moonriver', async ({helper}) => {
923 const destination = quartzCombinedMultilocation;884 const destination = quartzCombinedMultilocation;
924 await helper.xTokens.transfer(alith, id, testAmount, destination, 'Unlimited');885 await helper.xTokens.transfer(alith, id, testAmount, destination, 'Unlimited');
886
887 messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
925 });888 });
926889
927 await expectFailedToTransact('MOVR', helper);890 await expectFailedToTransact(helper, messageSent);
928 });891 });
929892
930 itSub('Quartz rejects SDN tokens from Shiden', async ({helper}) => {893 itSub('Quartz rejects SDN tokens from Shiden', async ({helper}) => {
953 feeAssetItem,916 feeAssetItem,
954 ]);917 ]);
918
919 messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
955 });920 });
956921
957 await expectFailedToTransact('SDN', helper);922 await expectFailedToTransact(helper, messageSent);
958 });923 });
959});924});
960925
1193 moreThanMoonriverHas,1158 moreThanMoonriverHas,
1194 );1159 );
1160
1161 let maliciousXcmProgramSent: any;
1162 const maxWaitBlocks = 3;
11951163
1196 // Try to trick Quartz1164 // Try to trick Quartz
1197 await usingMoonriverPlaygrounds(moonriverUrl, async (helper) => {1165 await usingMoonriverPlaygrounds(moonriverUrl, async (helper) => {
1201 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);1169 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
1202 await helper.fastDemocracy.executeProposal('try to spend more QTZ than Moonriver has', batchCall);1170 await helper.fastDemocracy.executeProposal('try to spend more QTZ than Moonriver has', batchCall);
1171
1172 maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1203 });1173 });
1204
1205 const maxWaitBlocks = 3;
1206 const outcomeField = 1;
12071174
1208 const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1175 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1209 maxWaitBlocks,1176 return event.messageHash() == maliciousXcmProgramSent.messageHash()
1210 'xcmpQueue',1177 && event.outcome().isFailedToTransactAsset;
1211 'Fail',
1212 outcomeField,
1213 );1178 });
1214
1215 expect(
1216 xcmpQueueFailEvent != null,
1217 '\'xcmpQueue.FailEvent\' event is expected',
1218 ).to.be.true;
1219
1220 expect(
1221 xcmpQueueFailEvent!.isFailedToTransactAsset,
1222 `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
1223 ).to.be.true;
12241179
1225 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);1180 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
1226 expect(targetAccountBalance).to.be.equal(0n);1181 expect(targetAccountBalance).to.be.equal(0n);
1293 testAmount,1248 testAmount,
1294 );1249 );
1250
1251 let maliciousXcmProgramFullIdSent: any;
1252 let maliciousXcmProgramHereIdSent: any;
1253 const maxWaitBlocks = 3;
12951254
1296 // Try to trick Quartz using full QTZ identification1255 // Try to trick Quartz using full QTZ identification
1297 await usingMoonriverPlaygrounds(moonriverUrl, async (helper) => {1256 await usingMoonriverPlaygrounds(moonriverUrl, async (helper) => {
1301 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);1260 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
1302 await helper.fastDemocracy.executeProposal('try to act like a reserve location for QTZ using path asset identification', batchCall);1261 await helper.fastDemocracy.executeProposal('try to act like a reserve location for QTZ using path asset identification', batchCall);
1262
1263 maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1303 });1264 });
1304
1305 const maxWaitBlocks = 3;
1306 const outcomeField = 1;
13071265
1308 let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1266 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1309 maxWaitBlocks,1267 return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
1310 'xcmpQueue',1268 && event.outcome().isUntrustedReserveLocation;
1311 'Fail',
1312 outcomeField,
1313 );1269 });
1314
1315 expect(
1316 xcmpQueueFailEvent != null,
1317 '\'xcmpQueue.FailEvent\' event is expected',
1318 ).to.be.true;
1319
1320 expect(
1321 xcmpQueueFailEvent!.isUntrustedReserveLocation,
1322 `The XCM error should be 'isUntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
1323 ).to.be.true;
13241270
1325 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);1271 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
1326 expect(accountBalance).to.be.equal(0n);1272 expect(accountBalance).to.be.equal(0n);
1333 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);1279 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
1334 await helper.fastDemocracy.executeProposal('try to act like a reserve location for QTZ using "here" asset identification', batchCall);1280 await helper.fastDemocracy.executeProposal('try to act like a reserve location for QTZ using "here" asset identification', batchCall);
1281
1282 maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1335 });1283 });
13361284
1337 xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1285 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1338 maxWaitBlocks,1286 return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
1339 'xcmpQueue',1287 && event.outcome().isUntrustedReserveLocation;
1340 'Fail',
1341 outcomeField,
1342 );1288 });
1343
1344 expect(
1345 xcmpQueueFailEvent != null,
1346 '\'xcmpQueue.FailEvent\' event is expected',
1347 ).to.be.true;
1348
1349 expect(
1350 xcmpQueueFailEvent!.isUntrustedReserveLocation,
1351 `The XCM error should be 'isUntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
1352 ).to.be.true;
13531289
1354 accountBalance = await helper.balance.getSubstrate(targetAccount.address);1290 accountBalance = await helper.balance.getSubstrate(targetAccount.address);
1355 expect(accountBalance).to.be.equal(0n);1291 expect(accountBalance).to.be.equal(0n);
1598 moreThanShidenHas,1534 moreThanShidenHas,
1599 );1535 );
1536
1537 let maliciousXcmProgramSent: any;
1538 const maxWaitBlocks = 3;
16001539
1601 // Try to trick Quartz1540 // Try to trick Quartz
1602 await usingShidenPlaygrounds(shidenUrl, async (helper) => {1541 await usingShidenPlaygrounds(shidenUrl, async (helper) => {
1603 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);1542 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);
1543
1544 maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1604 });1545 });
1605
1606 const maxWaitBlocks = 3;
1607 const outcomeField = 1;
16081546
1609 const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1547 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1610 maxWaitBlocks,1548 return event.messageHash() == maliciousXcmProgramSent.messageHash()
1611 'xcmpQueue',1549 && event.outcome().isFailedToTransactAsset;
1612 'Fail',
1613 outcomeField,
1614 );1550 });
1615
1616 expect(
1617 xcmpQueueFailEvent != null,
1618 '\'xcmpQueue.FailEvent\' event is expected',
1619 ).to.be.true;
1620
1621 expect(
1622 xcmpQueueFailEvent!.isFailedToTransactAsset,
1623 `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
1624 ).to.be.true;
16251551
1626 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);1552 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
1627 expect(targetAccountBalance).to.be.equal(0n);1553 expect(targetAccountBalance).to.be.equal(0n);
1690 testAmount,1616 testAmount,
1691 );1617 );
1618
1619 let maliciousXcmProgramFullIdSent: any;
1620 let maliciousXcmProgramHereIdSent: any;
1621 const maxWaitBlocks = 3;
16921622
1693 // Try to trick Quartz using full QTZ identification1623 // Try to trick Quartz using full QTZ identification
1694 await usingShidenPlaygrounds(shidenUrl, async (helper) => {1624 await usingShidenPlaygrounds(shidenUrl, async (helper) => {
1695 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramFullId);1625 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramFullId);
1626
1627 maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1696 });1628 });
1697
1698 const maxWaitBlocks = 3;
1699 const outcomeField = 1;
17001629
1701 let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1630 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1702 maxWaitBlocks,1631 return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
1703 'xcmpQueue',1632 && event.outcome().isUntrustedReserveLocation;
1704 'Fail',
1705 outcomeField,
1706 );1633 });
1707
1708 expect(
1709 xcmpQueueFailEvent != null,
1710 '\'xcmpQueue.FailEvent\' event is expected',
1711 ).to.be.true;
1712
1713 expect(
1714 xcmpQueueFailEvent!.isUntrustedReserveLocation,
1715 `The XCM error should be 'isUntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
1716 ).to.be.true;
17171634
1718 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);1635 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
1719 expect(accountBalance).to.be.equal(0n);1636 expect(accountBalance).to.be.equal(0n);
1722 await usingShidenPlaygrounds(shidenUrl, async (helper) => {1639 await usingShidenPlaygrounds(shidenUrl, async (helper) => {
1723 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramHereId);1640 await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgramHereId);
1641
1642 maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1724 });1643 });
17251644
1726 xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1645 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1727 maxWaitBlocks,1646 return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
1728 'xcmpQueue',1647 && event.outcome().isUntrustedReserveLocation;
1729 'Fail',
1730 outcomeField,
1731 );1648 });
1732
1733 expect(
1734 xcmpQueueFailEvent != null,
1735 '\'xcmpQueue.FailEvent\' event is expected',
1736 ).to.be.true;
1737
1738 expect(
1739 xcmpQueueFailEvent!.isUntrustedReserveLocation,
1740 `The XCM error should be 'isUntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
1741 ).to.be.true;
17421649
1743 accountBalance = await helper.balance.getSubstrate(targetAccount.address);1650 accountBalance = await helper.balance.getSubstrate(targetAccount.address);
1744 expect(accountBalance).to.be.equal(0n);1651 expect(accountBalance).to.be.equal(0n);
modifiedtests/src/xcm/xcmUnique.test.tsdiffbeforeafterboth
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import config from '../config';18import config from '../config';
19import {XcmV2TraitsError} from '../interfaces';
20import {itSub, expect, describeXCM, usingPlaygrounds, usingAcalaPlaygrounds, usingRelayPlaygrounds, usingMoonbeamPlaygrounds, usingStatemintPlaygrounds, usingAstarPlaygrounds} from '../util';19import {itSub, expect, describeXCM, usingPlaygrounds, usingAcalaPlaygrounds, usingRelayPlaygrounds, usingMoonbeamPlaygrounds, usingStatemintPlaygrounds, usingAstarPlaygrounds} from '../util';
21import {DevUniqueHelper} from '../util/playgrounds/unique.dev';20import {DevUniqueHelper, Event} from '../util/playgrounds/unique.dev';
2221
23const UNIQUE_CHAIN = 2037;22const UNIQUE_CHAIN = 2037;
24const STATEMINT_CHAIN = 1000;23const STATEMINT_CHAIN = 1000;
675 moreThanAcalaHas,674 moreThanAcalaHas,
676 );675 );
676
677 let maliciousXcmProgramSent: any;
678 const maxWaitBlocks = 3;
677679
678 // Try to trick Unique680 // Try to trick Unique
679 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {681 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
680 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);682 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
683
684 maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
681 });685 });
682
683 const maxWaitBlocks = 3;
684 const outcomeField = 1;
685686
686 const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(687 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
687 maxWaitBlocks,688 return event.messageHash() == maliciousXcmProgramSent.messageHash()
688 'xcmpQueue',689 && event.outcome().isFailedToTransactAsset;
689 'Fail',
690 outcomeField,
691 );690 });
692
693 expect(
694 xcmpQueueFailEvent != null,
695 '\'xcmpQueue.FailEvent\' event is expected',
696 ).to.be.true;
697
698 expect(
699 xcmpQueueFailEvent!.isFailedToTransactAsset,
700 `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
701 ).to.be.true;
702691
703 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);692 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
704 expect(targetAccountBalance).to.be.equal(0n);693 expect(targetAccountBalance).to.be.equal(0n);
767 testAmount,756 testAmount,
768 );757 );
758
759 let maliciousXcmProgramFullIdSent: any;
760 let maliciousXcmProgramHereIdSent: any;
761 const maxWaitBlocks = 3;
769762
770 // Try to trick Unique using full UNQ identification763 // Try to trick Unique using full UNQ identification
771 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {764 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
772 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramFullId);765 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramFullId);
766
767 maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
773 });768 });
774
775 const maxWaitBlocks = 3;
776 const outcomeField = 1;
777769
778 let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(770 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
779 maxWaitBlocks,771 return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
780 'xcmpQueue',772 && event.outcome().isUntrustedReserveLocation;
781 'Fail',
782 outcomeField,
783 );773 });
784
785 expect(
786 xcmpQueueFailEvent != null,
787 '\'xcmpQueue.FailEvent\' event is expected',
788 ).to.be.true;
789
790 expect(
791 xcmpQueueFailEvent!.isUntrustedReserveLocation,
792 `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
793 ).to.be.true;
794774
795 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);775 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
796 expect(accountBalance).to.be.equal(0n);776 expect(accountBalance).to.be.equal(0n);
799 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {779 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
800 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramHereId);780 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramHereId);
781
782 maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
801 });783 });
802784
803 xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(785 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
804 maxWaitBlocks,786 return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
805 'xcmpQueue',787 && event.outcome().isUntrustedReserveLocation;
806 'Fail',
807 outcomeField,
808 );788 });
809
810 expect(
811 xcmpQueueFailEvent != null,
812 '\'xcmpQueue.FailEvent\' event is expected',
813 ).to.be.true;
814
815 expect(
816 xcmpQueueFailEvent!.isUntrustedReserveLocation,
817 `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
818 ).to.be.true;
819789
820 accountBalance = await helper.balance.getSubstrate(targetAccount.address);790 accountBalance = await helper.balance.getSubstrate(targetAccount.address);
821 expect(accountBalance).to.be.equal(0n);791 expect(accountBalance).to.be.equal(0n);
836 let uniqueAccountMultilocation: any;806 let uniqueAccountMultilocation: any;
837 let uniqueCombinedMultilocation: any;807 let uniqueCombinedMultilocation: any;
808
809 let messageSent: any;
810
811 const maxWaitBlocks = 3;
838812
839 before(async () => {813 before(async () => {
840 await usingPlaygrounds(async (helper, privateKey) => {814 await usingPlaygrounds(async (helper, privateKey) => {
885 });859 });
886 });860 });
887861
888 const expectFailedToTransact = async (network: string, helper: DevUniqueHelper) => {862 const expectFailedToTransact = async (helper: DevUniqueHelper, messageSent: any) => {
889 const maxWaitBlocks = 3;
890 const outcomeField = 1;
891
892 const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(863 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
893 maxWaitBlocks,864 return event.messageHash() == messageSent.messageHash()
894 'xcmpQueue',865 && event.outcome().isFailedToTransactAsset;
895 'Fail',
896 outcomeField,
897 );866 });
898
899 expect(
900 xcmpQueueFailEvent != null,
901 `[reject ${network} tokens] 'xcmpQueue.FailEvent' event is expected`,
902 ).to.be.true;
903
904 expect(
905 xcmpQueueFailEvent!.isFailedToTransactAsset,
906 `[reject ${network} tokens] The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
907 ).to.be.true;
908 };867 };
909868
910 itSub('Unique rejects ACA tokens from Acala', async ({helper}) => {869 itSub('Unique rejects ACA tokens from Acala', async ({helper}) => {
915 const destination = uniqueCombinedMultilocation;874 const destination = uniqueCombinedMultilocation;
916 await helper.xTokens.transfer(alice, id, testAmount, destination, 'Unlimited');875 await helper.xTokens.transfer(alice, id, testAmount, destination, 'Unlimited');
876
877 messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
917 });878 });
918879
919 await expectFailedToTransact('ACA', helper);880 await expectFailedToTransact(helper, messageSent);
920 });881 });
921882
922 itSub('Unique rejects GLMR tokens from Moonbeam', async ({helper}) => {883 itSub('Unique rejects GLMR tokens from Moonbeam', async ({helper}) => {
925 const destination = uniqueCombinedMultilocation;886 const destination = uniqueCombinedMultilocation;
926 await helper.xTokens.transfer(alith, id, testAmount, destination, 'Unlimited');887 await helper.xTokens.transfer(alith, id, testAmount, destination, 'Unlimited');
888
889 messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
927 });890 });
928891
929 await expectFailedToTransact('GLMR', helper);892 await expectFailedToTransact(helper, messageSent);
930 });893 });
931894
932 itSub('Unique rejects ASTR tokens from Astar', async ({helper}) => {895 itSub('Unique rejects ASTR tokens from Astar', async ({helper}) => {
955 feeAssetItem,918 feeAssetItem,
956 ]);919 ]);
920
921 messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
957 });922 });
958923
959 await expectFailedToTransact('ASTR', helper);924 await expectFailedToTransact(helper, messageSent);
960 });925 });
961});926});
962927
1196 moreThanMoonbeamHas,1161 moreThanMoonbeamHas,
1197 );1162 );
1163
1164 let maliciousXcmProgramSent: any;
1165 const maxWaitBlocks = 3;
11981166
1199 // Try to trick Unique1167 // Try to trick Unique
1200 await usingMoonbeamPlaygrounds(moonbeamUrl, async (helper) => {1168 await usingMoonbeamPlaygrounds(moonbeamUrl, async (helper) => {
1204 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);1172 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
1205 await helper.fastDemocracy.executeProposal('try to spend more UNQ than Moonbeam has', batchCall);1173 await helper.fastDemocracy.executeProposal('try to spend more UNQ than Moonbeam has', batchCall);
1174
1175 maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1206 });1176 });
1207
1208 const maxWaitBlocks = 3;
1209 const outcomeField = 1;
12101177
1211 const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1178 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1212 maxWaitBlocks,1179 return event.messageHash() == maliciousXcmProgramSent.messageHash()
1213 'xcmpQueue',1180 && event.outcome().isFailedToTransactAsset;
1214 'Fail',
1215 outcomeField,
1216 );1181 });
1217
1218 expect(
1219 xcmpQueueFailEvent != null,
1220 '\'xcmpQueue.FailEvent\' event is expected',
1221 ).to.be.true;
1222
1223 expect(
1224 xcmpQueueFailEvent!.isFailedToTransactAsset,
1225 `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
1226 ).to.be.true;
12271182
1228 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);1183 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
1229 expect(targetAccountBalance).to.be.equal(0n);1184 expect(targetAccountBalance).to.be.equal(0n);
1296 testAmount,1251 testAmount,
1297 );1252 );
1253
1254 let maliciousXcmProgramFullIdSent: any;
1255 let maliciousXcmProgramHereIdSent: any;
1256 const maxWaitBlocks = 3;
12981257
1299 // Try to trick Unique using full UNQ identification1258 // Try to trick Unique using full UNQ identification
1300 await usingMoonbeamPlaygrounds(moonbeamUrl, async (helper) => {1259 await usingMoonbeamPlaygrounds(moonbeamUrl, async (helper) => {
1304 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);1263 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
1305 await helper.fastDemocracy.executeProposal('try to act like a reserve location for UNQ using path asset identification', batchCall);1264 await helper.fastDemocracy.executeProposal('try to act like a reserve location for UNQ using path asset identification', batchCall);
1265
1266 maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1306 });1267 });
1307
1308 const maxWaitBlocks = 3;
1309 const outcomeField = 1;
13101268
1311 let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1269 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1312 maxWaitBlocks,1270 return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
1313 'xcmpQueue',1271 && event.outcome().isUntrustedReserveLocation;
1314 'Fail',
1315 outcomeField,
1316 );1272 });
1317
1318 expect(
1319 xcmpQueueFailEvent != null,
1320 '\'xcmpQueue.FailEvent\' event is expected',
1321 ).to.be.true;
1322
1323 expect(
1324 xcmpQueueFailEvent!.isUntrustedReserveLocation,
1325 `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
1326 ).to.be.true;
13271273
1328 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);1274 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
1329 expect(accountBalance).to.be.equal(0n);1275 expect(accountBalance).to.be.equal(0n);
1336 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);1282 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
1337 await helper.fastDemocracy.executeProposal('try to act like a reserve location for UNQ using "here" asset identification', batchCall);1283 await helper.fastDemocracy.executeProposal('try to act like a reserve location for UNQ using "here" asset identification', batchCall);
1284
1285 maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1338 });1286 });
13391287
1340 xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1288 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1341 maxWaitBlocks,1289 return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
1342 'xcmpQueue',1290 && event.outcome().isUntrustedReserveLocation;
1343 'Fail',
1344 outcomeField,
1345 );1291 });
1346
1347 expect(
1348 xcmpQueueFailEvent != null,
1349 '\'xcmpQueue.FailEvent\' event is expected',
1350 ).to.be.true;
1351
1352 expect(
1353 xcmpQueueFailEvent!.isUntrustedReserveLocation,
1354 `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
1355 ).to.be.true;
13561292
1357 accountBalance = await helper.balance.getSubstrate(targetAccount.address);1293 accountBalance = await helper.balance.getSubstrate(targetAccount.address);
1358 expect(accountBalance).to.be.equal(0n);1294 expect(accountBalance).to.be.equal(0n);
1600 moreThanAstarHas,1536 moreThanAstarHas,
1601 );1537 );
1538
1539 let maliciousXcmProgramSent: any;
1540 const maxWaitBlocks = 3;
16021541
1603 // Try to trick Unique1542 // Try to trick Unique
1604 await usingAstarPlaygrounds(astarUrl, async (helper) => {1543 await usingAstarPlaygrounds(astarUrl, async (helper) => {
1605 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);1544 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
1545
1546 maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1606 });1547 });
1607
1608 const maxWaitBlocks = 3;
1609 const outcomeField = 1;
16101548
1611 const xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1549 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1612 maxWaitBlocks,1550 return event.messageHash() == maliciousXcmProgramSent.messageHash()
1613 'xcmpQueue',1551 && event.outcome().isFailedToTransactAsset;
1614 'Fail',
1615 outcomeField,
1616 );1552 });
1617
1618 expect(
1619 xcmpQueueFailEvent != null,
1620 '\'xcmpQueue.FailEvent\' event is expected',
1621 ).to.be.true;
1622
1623 expect(
1624 xcmpQueueFailEvent!.isFailedToTransactAsset,
1625 `The XCM error should be 'FailedToTransactAsset', got '${xcmpQueueFailEvent!.toHuman()}'`,
1626 ).to.be.true;
16271553
1628 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);1554 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
1629 expect(targetAccountBalance).to.be.equal(0n);1555 expect(targetAccountBalance).to.be.equal(0n);
1692 testAmount,1618 testAmount,
1693 );1619 );
1620
1621 let maliciousXcmProgramFullIdSent: any;
1622 let maliciousXcmProgramHereIdSent: any;
1623 const maxWaitBlocks = 3;
16941624
1695 // Try to trick Unique using full UNQ identification1625 // Try to trick Unique using full UNQ identification
1696 await usingAstarPlaygrounds(astarUrl, async (helper) => {1626 await usingAstarPlaygrounds(astarUrl, async (helper) => {
1697 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramFullId);1627 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramFullId);
1628
1629 maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1698 });1630 });
1699
1700 const maxWaitBlocks = 3;
1701 const outcomeField = 1;
17021631
1703 let xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1632 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1704 maxWaitBlocks,1633 return event.messageHash() == maliciousXcmProgramFullIdSent.messageHash()
1705 'xcmpQueue',1634 && event.outcome().isUntrustedReserveLocation;
1706 'Fail',
1707 outcomeField,
1708 );1635 });
1709
1710 expect(
1711 xcmpQueueFailEvent != null,
1712 '\'xcmpQueue.FailEvent\' event is expected',
1713 ).to.be.true;
1714
1715 expect(
1716 xcmpQueueFailEvent!.isUntrustedReserveLocation,
1717 `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
1718 ).to.be.true;
17191636
1720 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);1637 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
1721 expect(accountBalance).to.be.equal(0n);1638 expect(accountBalance).to.be.equal(0n);
1724 await usingAstarPlaygrounds(astarUrl, async (helper) => {1641 await usingAstarPlaygrounds(astarUrl, async (helper) => {
1725 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramHereId);1642 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgramHereId);
1643
1644 maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
1726 });1645 });
17271646
1728 xcmpQueueFailEvent = await helper.wait.eventData<XcmV2TraitsError>(1647 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => {
1729 maxWaitBlocks,1648 return event.messageHash() == maliciousXcmProgramHereIdSent.messageHash()
1730 'xcmpQueue',1649 && event.outcome().isUntrustedReserveLocation;
1731 'Fail',
1732 outcomeField,
1733 );1650 });
1734
1735 expect(
1736 xcmpQueueFailEvent != null,
1737 '\'xcmpQueue.FailEvent\' event is expected',
1738 ).to.be.true;
1739
1740 expect(
1741 xcmpQueueFailEvent!.isUntrustedReserveLocation,
1742 `The XCM error should be 'UntrustedReserveLocation', got '${xcmpQueueFailEvent!.toHuman()}'`,
1743 ).to.be.true;
17441651
1745 accountBalance = await helper.balance.getSubstrate(targetAccount.address);1652 accountBalance = await helper.balance.getSubstrate(targetAccount.address);
1746 expect(accountBalance).to.be.equal(0n);1653 expect(accountBalance).to.be.equal(0n);