Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking changes companion #63

Merged
merged 11 commits into from
Aug 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ Some tests require a zombienet network to be run in the background. The steps to
1. Run a local [swanky](https://github.com/AstarNetwork/swanky-node) test node. This is where the contracts will be deployed to locally. The command to run: `./swanky-node --dev --tmp`
2. Follow the instructions on [trappist](https://github.com/paritytech/trappist) and run the [full_network.toml](https://github.com/paritytech/trappist/blob/main/zombienet/full_network.toml) network.

After the swanky node and the zombienet network is running you can run all the tests:
After the swanky node and the zombienet network is running you can run all the tests. Keep in mind that this will take several minutes to run.

```
yarn test
# NOTE: we use the runInBand to run the tests sequentially since
# otherwise there could be some issues occuring.
yarn test -- --runInBand
```

The tests can take quite some time to run so, in case you want to run a specific test file, run the following command instead:
Expand Down
10 changes: 5 additions & 5 deletions __tests__/assetRegistry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('AssetRegistry', () => {
confidence: 0,
},
]);
});
}, 10000);

test('Getting assets by para id works', async () => {
const assets = await AssetRegistry.getAssetsOnBlockchain(
Expand All @@ -51,7 +51,7 @@ describe('AssetRegistry', () => {
confidence: 0,
},
]);
});
}, 10000);

test("Checking whether an asset exists on both chains works", async () => {
const GLMR = [
Expand Down Expand Up @@ -105,7 +105,7 @@ describe('AssetRegistry', () => {

const isUsdtSupported = await AssetRegistry.isSupportedOnBothChains("polkadot", "moonbeam", "acala", USDT);
expect(isUsdtSupported).toBe(true);
});
}, 10000);

test("Getting all assets supported on both chains works", async () => {
const statemine = 1000;
Expand Down Expand Up @@ -164,7 +164,7 @@ describe('AssetRegistry', () => {
confidence: 0,
},
]);
});
}, 10000);

test('xcmInteriorKey to MultiAsset works', () => {
const ksmXcmInteriorKey = [
Expand Down Expand Up @@ -250,5 +250,5 @@ describe('AssetRegistry', () => {
],
},
});
});
}, 10000);
});
73 changes: 48 additions & 25 deletions __tests__/crossChainRouter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Fungible, Receiver, Sender } from "../src/utils/transactionRouter/types

import IdentityContractFactory from "../types/constructors/identity";
import IdentityContract from "../types/contracts/identity";
import { AccountType, NetworkInfo } from "../types/types-arguments/identity";
import { AccountType, ChainInfo } from "../types/types-arguments/identity";

const wsProvider = new WsProvider("ws://127.0.0.1:9944");
const keyring = new Keyring({ type: "sr25519" });
Expand Down Expand Up @@ -41,32 +41,32 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
swankyApi
);

await addNetwork(identityContract, alice, {
rpcUrl: WS_ASSET_HUB_LOCAL,
await addChain(identityContract, alice, 1000, {
rpcUrls: [WS_ASSET_HUB_LOCAL],
accountType: AccountType.accountId32,
});

await addNetwork(identityContract, alice, {
rpcUrl: WS_TRAPPIST_LOCAL,
await addChain(identityContract, alice, 1836, {
rpcUrls: [WS_TRAPPIST_LOCAL],
accountType: AccountType.accountId32,
});

await addNetwork(identityContract, alice, {
rpcUrl: "ws://127.0.0.1:9930",
await addChain(identityContract, alice, 3000, {
rpcUrls: ["ws://127.0.0.1:9930"],
accountType: AccountType.accountId32,
});
});

test("Transferring cross-chain from asset's reserve chain works", async () => {
const sender: Sender = {
keypair: alice,
network: 0
chain: 1000
};

const receiver: Receiver = {
addressRaw: bob.addressRaw,
type: AccountType.accountId32,
network: 1,
chain: 1836,
};

const rococoProvider = new WsProvider(WS_ROROCO_LOCAL);
Expand All @@ -89,7 +89,7 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
await deactivateLockdown(trappistApi, alice);
}

// Create assets on both networks
// Create assets on both chains

if (!(await getAsset(assetHubApi, USDT_ASSET_ID))) {
await forceCreateAsset(rococoApi, assetHubApi, 1000, alice, USDT_ASSET_ID);
Expand Down Expand Up @@ -121,7 +121,7 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
const receiverBalanceBefore = await getAssetBalance(trappistApi, USDT_ASSET_ID, bob.address);

const amount = 4000000000000;
const assetReserveChainId = 0;
const assetReserveChainId = 1000;

const asset: Fungible = {
multiAsset: {
Expand All @@ -137,11 +137,14 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
};

await TransactionRouter.sendTokens(
identityContract,
sender,
receiver,
assetReserveChainId,
asset
asset,
{
originApi: assetHubApi,
destApi: trappistApi
}
);

const senderBalanceAfter = await getAssetBalance(assetHubApi, USDT_ASSET_ID, alice.address);
Expand Down Expand Up @@ -176,7 +179,7 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
await deactivateLockdown(trappistApi, alice);
}

// Create assets on both networks.
// Create assets on both chains.

if (!(await getAsset(assetHubApi, USDT_ASSET_ID))) {
await forceCreateAsset(rococoApi, assetHubApi, 1000, alice, USDT_ASSET_ID);
Expand Down Expand Up @@ -204,13 +207,13 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {

const sender: Sender = {
keypair: bob,
network: 1
chain: 1836
};

const receiver: Receiver = {
addressRaw: charlie.addressRaw,
type: AccountType.accountId32,
network: 0,
chain: 1000,
};

const asset: Fungible = {
Expand All @@ -231,7 +234,16 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
const receiverBalanceBefore = await getAssetBalance(assetHubApi, USDT_ASSET_ID, charlie.address);

// Transfer the tokens to charlies's account on asset hub:
await TransactionRouter.sendTokens(identityContract, sender, receiver, receiver.network, asset);
await TransactionRouter.sendTokens(
sender,
receiver,
receiver.chain,
asset,
{
originApi: trappistApi,
destApi: assetHubApi
}
);

// We need to wait a bit more to actually receive the assets on the base chain.
await delay(5000);
Expand Down Expand Up @@ -273,7 +285,7 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
await deactivateLockdown(trappistApi, alice);
}

// Create assets on all networks.
// Create assets on all chains.

if (!(await getAsset(assetHubApi, USDT_ASSET_ID))) {
await forceCreateAsset(rococoApi, assetHubApi, 1000, alice, USDT_ASSET_ID);
Expand Down Expand Up @@ -302,17 +314,17 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
}

const amount = 950000000000;
const assetReserveChainId = 0;
const assetReserveChainId = 1000;

const sender: Sender = {
keypair: bob,
network: 1
chain: 1836
};

const receiver: Receiver = {
addressRaw: bob.addressRaw,
type: AccountType.accountId32,
network: 2,
chain: 3000,
};

const asset: Fungible = {
Expand All @@ -333,7 +345,17 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
const receiverBalanceBefore = await getAssetBalance(baseApi, USDT_ASSET_ID, bob.address);

// Transfer the tokens to bob's account on base:
await TransactionRouter.sendTokens(identityContract, sender, receiver, assetReserveChainId, asset);
await TransactionRouter.sendTokens(
sender,
receiver,
assetReserveChainId,
asset,
{
originApi: trappistApi,
destApi: baseApi,
reserveApi: assetHubApi
}
);

// We need to wait a bit more to actually receive the assets on the base chain.
await delay(12000);
Expand All @@ -348,14 +370,15 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
}, 180000);
});

const addNetwork = async (
const addChain = async (
contract: IdentityContract,
signer: KeyringPair,
network: NetworkInfo
chainId: number,
chain: ChainInfo
): Promise<void> => {
await contract
.withSigner(signer)
.tx.addNetwork(network);
.tx.addChain(chainId, chain);
};

const createAsset = async (
Expand Down
76 changes: 38 additions & 38 deletions __tests__/identityKey.test.ts
Original file line number Diff line number Diff line change
@@ -1,86 +1,86 @@
import IdentityKey from "../src/utils/identityKey";

describe("IdentityKey",() => {
describe("IdentityKey", () => {
test("Creating a new cipher works", () => {
// Identity key would be stored in `window.localStorage`, but in the tests it
// will simply be stored locally.
let identityKey = "";

const polkadotNetworkId = 0;
identityKey = IdentityKey.newCipher(identityKey, polkadotNetworkId);
const polkadotChainId = 0;
identityKey = IdentityKey.newCipher(identityKey, polkadotChainId);

containsNetworkAndCipher(identityKey, polkadotNetworkId);
containsChainAndCipher(identityKey, polkadotChainId);

const moonbeamNetworkId = 1;
// Generate a new cipher for the Moonbeam network.
identityKey = IdentityKey.newCipher(identityKey, moonbeamNetworkId);
const moonbeamChainId = 1;
// Generate a new cipher for the Moonbeam chain.
identityKey = IdentityKey.newCipher(identityKey, moonbeamChainId);

// The identity Key should still have the Polkadot cipher.
containsNetworkAndCipher(identityKey, polkadotNetworkId);
containsChainAndCipher(identityKey, polkadotChainId);

containsNetworkAndCipher(identityKey, moonbeamNetworkId);
containsChainAndCipher(identityKey, moonbeamChainId);

// Ciphers are randomly generated so the two ciphers cannot be the same.
const polkadotCipher = IdentityKey.getNetworkCipher(identityKey, polkadotNetworkId);
const moonbeamCipher = IdentityKey.getNetworkCipher(identityKey, moonbeamNetworkId);
const polkadotCipher = IdentityKey.getChainCipher(identityKey, polkadotChainId);
const moonbeamCipher = IdentityKey.getChainCipher(identityKey, moonbeamChainId);

expect(polkadotCipher).not.toBe(moonbeamCipher);

// Cannot create a new Cipher for the same network twice.
expect(() => IdentityKey.newCipher(identityKey, moonbeamNetworkId))
.toThrow("There already exists a cipher that is attached to the provided networkId");
// Cannot create a new Cipher for the same chain twice.
expect(() => IdentityKey.newCipher(identityKey, moonbeamChainId))
.toThrow("There already exists a cipher that is attached to the provided chainId");
});

test("Updating cipher works", () => {
let identityKey = "";

const polkadotNetworkId = 0;
const moonbeamNetworkId = 1;
const polkadotChainId = 0;
const moonbeamChainId = 1;

identityKey = IdentityKey.newCipher(identityKey, polkadotNetworkId);
identityKey = IdentityKey.newCipher(identityKey, moonbeamNetworkId);
identityKey = IdentityKey.newCipher(identityKey, polkadotChainId);
identityKey = IdentityKey.newCipher(identityKey, moonbeamChainId);

containsNetworkAndCipher(identityKey, polkadotNetworkId);
containsNetworkAndCipher(identityKey, moonbeamNetworkId);
containsChainAndCipher(identityKey, polkadotChainId);
containsChainAndCipher(identityKey, moonbeamChainId);

const polkadotCipher = IdentityKey.getNetworkCipher(identityKey, polkadotNetworkId);
const moonbeamCipher = IdentityKey.getNetworkCipher(identityKey, moonbeamNetworkId);
const polkadotCipher = IdentityKey.getChainCipher(identityKey, polkadotChainId);
const moonbeamCipher = IdentityKey.getChainCipher(identityKey, moonbeamChainId);

identityKey = IdentityKey.updateCipher(identityKey, moonbeamNetworkId);
const newMoonbeamCipher = IdentityKey.getNetworkCipher(identityKey, moonbeamNetworkId);
identityKey = IdentityKey.updateCipher(identityKey, moonbeamChainId);
const newMoonbeamCipher = IdentityKey.getChainCipher(identityKey, moonbeamChainId);

// The moonbeam network cipher should be updated.
// The moonbeam chain cipher should be updated.
expect(moonbeamCipher).not.toBe(newMoonbeamCipher);

// The polkadot cipher shouldn't be affected.
expect(IdentityKey.getNetworkCipher(identityKey, polkadotNetworkId)).toBe(polkadotCipher);
expect(IdentityKey.getChainCipher(identityKey, polkadotChainId)).toBe(polkadotCipher);

// Cannot update a cipher of a network that does not exist.
expect(() => IdentityKey.updateCipher(identityKey, 42)).toThrow("Cannot find networkId");
// Cannot update a cipher of a chain that does not exist.
expect(() => IdentityKey.updateCipher(identityKey, 42)).toThrow("Cannot find chainId");
});

test("Encryption and decryption works", () => {
let identityKey = "";

const polkadotNetworkId = 0;
identityKey = IdentityKey.newCipher(identityKey, polkadotNetworkId);
const polkadotChainId = 0;
identityKey = IdentityKey.newCipher(identityKey, polkadotChainId);

containsNetworkAndCipher(identityKey, polkadotNetworkId);
containsChainAndCipher(identityKey, polkadotChainId);

const polkadotAddress = "126X27SbhrV19mBFawys3ovkyBS87SGfYwtwa8J2FjHrtbmA";
const encryptedAddress = IdentityKey.encryptAddress(identityKey, polkadotNetworkId, polkadotAddress);
const decryptedAddress = IdentityKey.decryptAddress(identityKey, polkadotNetworkId, encryptedAddress);
const encryptedAddress = IdentityKey.encryptAddress(identityKey, polkadotChainId, polkadotAddress);
const decryptedAddress = IdentityKey.decryptAddress(identityKey, polkadotChainId, encryptedAddress);

expect(polkadotAddress).toBe(decryptedAddress);
});
});

const containsNetworkAndCipher = (identityKey: string, networkId: number) => {
const containsNetwork = new RegExp(`\\b${networkId}:`, "g");
expect(containsNetwork.test(identityKey)).toBe(true);
const containsChainAndCipher = (identityKey: string, chainId: number) => {
const containsChain = new RegExp(`\\b${chainId}:`, "g");
expect(containsChain.test(identityKey)).toBe(true);

const networkCipher = IdentityKey.getNetworkCipher(identityKey, networkId);
expect(cipherSize(networkCipher)).toBe(16);
const chainCipher = IdentityKey.getChainCipher(identityKey, chainId);
expect(cipherSize(chainCipher)).toBe(16);
}

const cipherSize = (cipher: string) => Buffer.from(cipher, "base64").length;
Loading