difftreelog
test(xcm) qtz/unq rejects relay tokens
in: master
3 files changed
tests/src/util/helpers.tsdiffbeforeafterboth--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -104,14 +104,9 @@
}
export function bigIntToDecimals(number: bigint, decimals = 18): string {
- let numberStr = number.toString();
- console.log('[0] str = ', numberStr);
-
- // Get rid of `n` at the end
- numberStr = numberStr.substring(0, numberStr.length - 1);
- console.log('[1] str = ', numberStr);
-
+ const numberStr = number.toString();
const dotPos = numberStr.length - decimals;
+
if (dotPos <= 0) {
return '0.' + numberStr;
} else {
@@ -1794,19 +1789,31 @@
): Promise<EventRecord | null> {
const promise = new Promise<EventRecord | null>(async (resolve) => {
- const unsubscribe = await api.query.system.events(eventRecords => {
+ const unsubscribe = await api.rpc.chain.subscribeNewHeads(async header => {
+ const blockNumber = header.number.toHuman();
+ const blockHash = header.hash;
+ const eventIdStr = `${eventSection}.${eventMethod}`;
+ const waitLimitStr = `wait blocks remaining: ${maxBlocksToWait}`;
+
+ console.log(`[Block #${blockNumber}] Waiting for event \`${eventIdStr}\` (${waitLimitStr})`);
+
+ const apiAt = await api.at(blockHash);
+ const eventRecords = await apiAt.query.system.events();
+
const neededEvent = eventRecords.find(r => {
return r.event.section == eventSection && r.event.method == eventMethod;
});
if (neededEvent) {
+ console.log(`Event \`${eventIdStr}\` is found`);
+
unsubscribe();
resolve(neededEvent);
- }
-
- if (maxBlocksToWait > 0) {
+ } else if (maxBlocksToWait > 0) {
maxBlocksToWait--;
} else {
+ console.log(`Event \`${eventIdStr}\` is NOT found`);
+
unsubscribe();
resolve(null);
}
tests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth26import {blake2AsHex} from '@polkadot/util-crypto';26import {blake2AsHex} from '@polkadot/util-crypto';27import waitNewBlocks from '../substrate/wait-new-blocks';27import waitNewBlocks from '../substrate/wait-new-blocks';28import getBalance from '../substrate/get-balance';28import getBalance from '../substrate/get-balance';29import {XcmV2TraitsOutcome, XcmV2TraitsError} from '../interfaces';293030chai.use(chaiAsPromised);31chai.use(chaiAsPromised);31const expect = chai.expect;32const expect = chai.expect;34const KARURA_CHAIN = 2000;35const KARURA_CHAIN = 2000;35const MOONRIVER_CHAIN = 2023;36const MOONRIVER_CHAIN = 2023;363738const RELAY_PORT = 9844;37const KARURA_PORT = 9946;39const KARURA_PORT = 9946;38const MOONRIVER_PORT = 9947;40const MOONRIVER_PORT = 9947;394155 return parachainApiOptions(MOONRIVER_PORT);57 return parachainApiOptions(MOONRIVER_PORT);56}58}575960function relayOptions(): ApiOptions {61 return parachainApiOptions(RELAY_PORT);62}6358describe_xcm('Integration test: Exchanging tokens with Karura', () => {64describe_xcm('Integration test: Exchanging tokens with Karura', () => {59 let alice: IKeyringPair;65 let alice: IKeyringPair;60 let randomAccount: IKeyringPair;66 let randomAccount: IKeyringPair;200 const karFees = balanceKaruraTokenInit - balanceKaruraTokenMiddle;206 const karFees = balanceKaruraTokenInit - balanceKaruraTokenMiddle;201 const qtzIncomeTransfer = balanceQuartzForeignTokenMiddle - balanceQuartzForeignTokenInit;207 const qtzIncomeTransfer = balanceQuartzForeignTokenMiddle - balanceQuartzForeignTokenInit;202208203 console.log('209 console.log(204 [Quartz -> Karura] transaction fees on Karura: %s KAR',210 '[Quartz -> Karura] transaction fees on Karura: %s KAR',205 bigIntToDecimals(karFees, KARURA_DECIMALS),211 bigIntToDecimals(karFees, KARURA_DECIMALS),206 );212 );207 console.log('[Quartz -> Karura] income %s QTZ', bigIntToDecimals(qtzIncomeTransfer));213 console.log('[Quartz -> Karura] income %s QTZ', bigIntToDecimals(qtzIncomeTransfer));281 expect(qtzFees == 0n).to.be.true;287 expect(qtzFees == 0n).to.be.true;282 });288 });283 });289 });290});284291285 it('Quartz rejects KAR tokens from Karura', async () => {292// These tests are relevant only when the foreign asset pallet is disabled293describe('Integration test: Quartz rejects non-native tokens', () => {286 // This test is relevant only when the foreign asset pallet is disabled294 let alice: IKeyringPair;287295296 before(async () => {297 await usingApi(async (api, privateKeyWrapper) => {298 alice = privateKeyWrapper('//Alice');299 });300 });301 302 it('Quartz rejects tokens from the Relay', async () => {288 await usingApi(async (api) => {303 await usingApi(async (api) => {289 const destination = {304 const destination = {290 V1: {305 V1: {306 parents: 0,307 interior: {X1: {308 Parachain: QUARTZ_CHAIN,309 },310 },311 }};312313 const beneficiary = {314 V1: {315 parents: 0,316 interior: {X1: {317 AccountId32: {318 network: 'Any',319 id: alice.addressRaw,320 },321 }},322 },323 };324325 const assets = {326 V1: [327 {328 id: {329 Concrete: {330 parents: 0,331 interior: 'Here',332 },333 },334 fun: {335 Fungible: 50_000_000_000_000_000n,336 },337 },338 ],339 };340341 const feeAssetItem = 0;342343 const weightLimit = {344 Limited: 5_000_000_000,345 };346347 const tx = api.tx.xcmPallet.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);348 const events = await submitTransactionAsync(alice, tx);349 const result = getGenericResult(events);350 expect(result.success).to.be.true;351 }, relayOptions());352353 await usingApi(async api => {354 const maxWaitBlocks = 3;355 const dmpQueueExecutedDownward = await waitEvent(356 api,357 maxWaitBlocks,358 'dmpQueue',359 'ExecutedDownward',360 );361362 expect(363 dmpQueueExecutedDownward != null,364 '[Relay] dmpQueue.ExecutedDownward event is expected',365 ).to.be.true;366367 const event = dmpQueueExecutedDownward!.event;368 const outcome = event.data[1] as XcmV2TraitsOutcome;369370 expect(371 outcome.isIncomplete,372 '[Relay] The outcome of the XCM should be `Incomplete`',373 ).to.be.true;374375 const incomplete = outcome.asIncomplete;376 expect(377 incomplete[1].toString() == 'AssetNotFound',378 '[Relay] The XCM error should be `AssetNotFound`',379 ).to.be.true;380 });381 });382383 it('Quartz rejects KAR tokens from Karura', async () => {384 await usingApi(async (api) => {385 const destination = {386 V1: {291 parents: 1,387 parents: 1,292 interior: {388 interior: {293 X2: [389 X2: [294 {Parachain: QUARTZ_CHAIN},390 {Parachain: QUARTZ_CHAIN},295 {391 {296 AccountId32: {392 AccountId32: {297 network: 'Any',393 network: 'Any',298 id: randomAccount.addressRaw,394 id: alice.addressRaw,299 },395 },300 },396 },301 ],397 ],321417322 expect(418 expect(323 xcmpQueueFailEvent != null,419 xcmpQueueFailEvent != null,324 'Only native token is supported when the Foreign-Assets pallet is not connected',420 '[Karura] xcmpQueue.FailEvent event is expected',421 ).to.be.true;422423 const event = xcmpQueueFailEvent!.event;424 const outcome = event.data[1] as XcmV2TraitsError;425426 expect(427 outcome.isUntrustedReserveLocation,428 '[Karura] The XCM error should be `UntrustedReserveLocation`',325 ).to.be.true;429 ).to.be.true;326 });430 });327 });431 });tests/src/xcm/xcmUnique.test.tsdiffbeforeafterboth--- a/tests/src/xcm/xcmUnique.test.ts
+++ b/tests/src/xcm/xcmUnique.test.ts
@@ -26,6 +26,7 @@
import {blake2AsHex} from '@polkadot/util-crypto';
import waitNewBlocks from '../substrate/wait-new-blocks';
import getBalance from '../substrate/get-balance';
+import {XcmV2TraitsError, XcmV2TraitsOutcome} from '../interfaces';
chai.use(chaiAsPromised);
const expect = chai.expect;
@@ -34,6 +35,7 @@
const ACALA_CHAIN = 2000;
const MOONBEAM_CHAIN = 2004;
+const RELAY_PORT = 9844;
const ACALA_PORT = 9946;
const MOONBEAM_PORT = 9947;
@@ -55,6 +57,10 @@
return parachainApiOptions(MOONBEAM_PORT);
}
+function relayOptions(): ApiOptions {
+ return parachainApiOptions(RELAY_PORT);
+}
+
describe_xcm('Integration test: Exchanging tokens with Acala', () => {
let alice: IKeyringPair;
let randomAccount: IKeyringPair;
@@ -281,10 +287,100 @@
expect(unqFees == 0n).to.be.true;
});
});
+});
+
+// These tests are relevant only when the foreign asset pallet is disabled
+describe('Integration test: Unique rejects non-native tokens', () => {
+ let alice: IKeyringPair;
+
+ before(async () => {
+ await usingApi(async (api, privateKeyWrapper) => {
+ alice = privateKeyWrapper('//Alice');
+ });
+ });
+
+ it('Unique rejects tokens from the Relay', async () => {
+ await usingApi(async (api) => {
+ const destination = {
+ V1: {
+ parents: 0,
+ interior: {X1: {
+ Parachain: UNIQUE_CHAIN,
+ },
+ },
+ }};
+
+ const beneficiary = {
+ V1: {
+ parents: 0,
+ interior: {X1: {
+ AccountId32: {
+ network: 'Any',
+ id: alice.addressRaw,
+ },
+ }},
+ },
+ };
+
+ const assets = {
+ V1: [
+ {
+ id: {
+ Concrete: {
+ parents: 0,
+ interior: 'Here',
+ },
+ },
+ fun: {
+ Fungible: 50_000_000_000_000_000n,
+ },
+ },
+ ],
+ };
+
+ const feeAssetItem = 0;
+
+ const weightLimit = {
+ Limited: 5_000_000_000,
+ };
+
+ const tx = api.tx.xcmPallet.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);
+ const events = await submitTransactionAsync(alice, tx);
+ const result = getGenericResult(events);
+ expect(result.success).to.be.true;
+ }, relayOptions());
+
+ await usingApi(async api => {
+ const maxWaitBlocks = 3;
+ const dmpQueueExecutedDownward = await waitEvent(
+ api,
+ maxWaitBlocks,
+ 'dmpQueue',
+ 'ExecutedDownward',
+ );
+
+ expect(
+ dmpQueueExecutedDownward != null,
+ '[Relay] dmpQueue.ExecutedDownward event is expected',
+ ).to.be.true;
+
+ const event = dmpQueueExecutedDownward!.event;
+ const outcome = event.data[1] as XcmV2TraitsOutcome;
+
+ expect(
+ outcome.isIncomplete,
+ '[Relay] The outcome of the XCM should be `Incomplete`',
+ ).to.be.true;
+
+ const incomplete = outcome.asIncomplete;
+ expect(
+ incomplete[1].toString() == 'AssetNotFound',
+ '[Relay] The XCM error should be `AssetNotFound`',
+ ).to.be.true;
+ });
+ });
it('Unique rejects ACA tokens from Acala', async () => {
- // This test is relevant only when the foreign asset pallet is disabled
-
await usingApi(async (api) => {
const destination = {
V1: {
@@ -295,7 +391,7 @@
{
AccountId32: {
network: 'Any',
- id: randomAccount.addressRaw,
+ id: alice.addressRaw,
},
},
],
@@ -321,7 +417,15 @@
expect(
xcmpQueueFailEvent != null,
- 'Only native token is supported when the Foreign-Assets pallet is not connected',
+ '[Acala] xcmpQueue.FailEvent event is expected',
+ ).to.be.true;
+
+ const event = xcmpQueueFailEvent!.event;
+ const outcome = event.data[1] as XcmV2TraitsError;
+
+ expect(
+ outcome.isUntrustedReserveLocation,
+ '[Acala] The XCM error should be `UntrustedReserveLocation`',
).to.be.true;
});
});