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
104}104}
105105
106export function bigIntToDecimals(number: bigint, decimals = 18): string {106export function bigIntToDecimals(number: bigint, decimals = 18): string {
107 let numberStr = number.toString();107 const numberStr = number.toString();
108 console.log('[0] str = ', numberStr);
109
110 // Get rid of `n` at the end
111 numberStr = numberStr.substring(0, numberStr.length - 1);
112 console.log('[1] str = ', numberStr);
113
114 const dotPos = numberStr.length - decimals;108 const dotPos = numberStr.length - decimals;
109
1794): Promise<EventRecord | null> {1789): Promise<EventRecord | null> {
17951790
1796 const promise = new Promise<EventRecord | null>(async (resolve) => {1791 const promise = new Promise<EventRecord | null>(async (resolve) => {
1797 const unsubscribe = await api.query.system.events(eventRecords => {1792 const unsubscribe = await api.rpc.chain.subscribeNewHeads(async header => {
1793 const blockNumber = header.number.toHuman();
1794 const blockHash = header.hash;
1795 const eventIdStr = `${eventSection}.${eventMethod}`;
1796 const waitLimitStr = `wait blocks remaining: ${maxBlocksToWait}`;
1797
1798 console.log(`[Block #${blockNumber}] Waiting for event \`${eventIdStr}\` (${waitLimitStr})`);
1799
1800 const apiAt = await api.at(blockHash);
1801 const eventRecords = await apiAt.query.system.events();
1802
1798 const neededEvent = eventRecords.find(r => {1803 const neededEvent = eventRecords.find(r => {
1799 return r.event.section == eventSection && r.event.method == eventMethod;1804 return r.event.section == eventSection && r.event.method == eventMethod;
1800 });1805 });
18011806
1802 if (neededEvent) {1807 if (neededEvent) {
1803 unsubscribe();1808 console.log(`Event \`${eventIdStr}\` is found`);
1804 resolve(neededEvent);1809
1805 }1810 unsubscribe();
18061811 resolve(neededEvent);
1807 if (maxBlocksToWait > 0) {1812 } else if (maxBlocksToWait > 0) {
1808 maxBlocksToWait--;1813 maxBlocksToWait--;
1809 } else {1814 } else {
1815 console.log(`Event \`${eventIdStr}\` is NOT found`);
1816
1810 unsubscribe();1817 unsubscribe();
1811 resolve(null);1818 resolve(null);
modifiedtests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth
--- a/tests/src/xcm/xcmQuartz.test.ts
+++ b/tests/src/xcm/xcmQuartz.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 {XcmV2TraitsOutcome, XcmV2TraitsError} from '../interfaces';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
@@ -34,6 +35,7 @@
 const KARURA_CHAIN = 2000;
 const MOONRIVER_CHAIN = 2023;
 
+const RELAY_PORT = 9844;
 const KARURA_PORT = 9946;
 const MOONRIVER_PORT = 9947;
 
@@ -55,6 +57,10 @@
   return parachainApiOptions(MOONRIVER_PORT);
 }
 
+function relayOptions(): ApiOptions {
+  return parachainApiOptions(RELAY_PORT);
+}
+
 describe_xcm('Integration test: Exchanging tokens with Karura', () => {
   let alice: IKeyringPair;
   let randomAccount: IKeyringPair;
@@ -200,8 +206,8 @@
         const karFees = balanceKaruraTokenInit - balanceKaruraTokenMiddle;
         const qtzIncomeTransfer = balanceQuartzForeignTokenMiddle - balanceQuartzForeignTokenInit;
 
-        console.log('
-          [Quartz -> Karura] transaction fees on Karura: %s KAR',
+        console.log(
+          '[Quartz -> Karura] transaction fees on Karura: %s KAR',
           bigIntToDecimals(karFees, KARURA_DECIMALS),
         );
         console.log('[Quartz -> Karura] income %s QTZ', bigIntToDecimals(qtzIncomeTransfer));
@@ -281,10 +287,100 @@
       expect(qtzFees == 0n).to.be.true;
     });
   });
+});
+
+// These tests are relevant only when the foreign asset pallet is disabled
+describe('Integration test: Quartz rejects non-native tokens', () => {
+  let alice: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+    });
+  });
+  
+  it('Quartz rejects tokens from the Relay', async () => {
+    await usingApi(async (api) => {
+      const destination = {
+        V1: {
+          parents: 0,
+          interior: {X1: {
+            Parachain: QUARTZ_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('Quartz rejects KAR tokens from Karura', 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',
+        '[Karura] xcmpQueue.FailEvent event is expected',
+      ).to.be.true;
+
+      const event = xcmpQueueFailEvent!.event;
+      const outcome = event.data[1] as XcmV2TraitsError;
+
+      expect(
+        outcome.isUntrustedReserveLocation,
+        '[Karura] The XCM error should be `UntrustedReserveLocation`',
       ).to.be.true;
     });
   });
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;
     });
   });