git.delta.rocks / unique-network / refs/commits / 503028ebb65c

difftreelog

test(xcm) qtz/unq rejects relay tokens

Daniel Shiposha2022-09-06parent: #6c9f876.patch.diff
in: master

3 files changed

modifiedtests/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);
       }
modifiedtests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth
26import {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';
2930
30chai.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;
3637
38const RELAY_PORT = 9844;
37const KARURA_PORT = 9946;39const KARURA_PORT = 9946;
38const MOONRIVER_PORT = 9947;40const MOONRIVER_PORT = 9947;
3941
55 return parachainApiOptions(MOONRIVER_PORT);57 return parachainApiOptions(MOONRIVER_PORT);
56}58}
5759
60function relayOptions(): ApiOptions {
61 return parachainApiOptions(RELAY_PORT);
62}
63
58describe_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;
202208
203 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});
284291
285 it('Quartz rejects KAR tokens from Karura', async () => {292// These tests are relevant only when the foreign asset pallet is disabled
293describe('Integration test: Quartz rejects non-native tokens', () => {
286 // This test is relevant only when the foreign asset pallet is disabled294 let alice: IKeyringPair;
287295
296 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 }};
312
313 const beneficiary = {
314 V1: {
315 parents: 0,
316 interior: {X1: {
317 AccountId32: {
318 network: 'Any',
319 id: alice.addressRaw,
320 },
321 }},
322 },
323 };
324
325 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 };
340
341 const feeAssetItem = 0;
342
343 const weightLimit = {
344 Limited: 5_000_000_000,
345 };
346
347 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());
352
353 await usingApi(async api => {
354 const maxWaitBlocks = 3;
355 const dmpQueueExecutedDownward = await waitEvent(
356 api,
357 maxWaitBlocks,
358 'dmpQueue',
359 'ExecutedDownward',
360 );
361
362 expect(
363 dmpQueueExecutedDownward != null,
364 '[Relay] dmpQueue.ExecutedDownward event is expected',
365 ).to.be.true;
366
367 const event = dmpQueueExecutedDownward!.event;
368 const outcome = event.data[1] as XcmV2TraitsOutcome;
369
370 expect(
371 outcome.isIncomplete,
372 '[Relay] The outcome of the XCM should be `Incomplete`',
373 ).to.be.true;
374
375 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 });
382
383 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 ],
321417
322 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;
422
423 const event = xcmpQueueFailEvent!.event;
424 const outcome = event.data[1] as XcmV2TraitsError;
425
426 expect(
427 outcome.isUntrustedReserveLocation,
428 '[Karura] The XCM error should be `UntrustedReserveLocation`',
325 ).to.be.true;429 ).to.be.true;
326 });430 });
327 });431 });
modifiedtests/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;
     });
   });