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

feat: add cache to registry #256

Merged
merged 23 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
5 changes: 3 additions & 2 deletions src/AssetsTransferApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
XcmPalletName,
} from './createXcmCalls/util/establishXcmPallet';
import { assetIdsContainRelayAsset } from './createXcmTypes/util/assetIdsContainsRelayAsset';
import { getAssetHubAssetId } from './createXcmTypes/util/getAssetHubAssetId';
import { getAssetId } from './createXcmTypes/util/getAssetId';
import { getChainIdBySpecName } from './createXcmTypes/util/getChainIdBySpecName';
import { isSystemChain } from './createXcmTypes/util/isSystemChain';
import { multiLocationAssetIsParachainsNativeAsset } from './createXcmTypes/util/multiLocationAssetIsParachainsNativeAsset';
Expand Down Expand Up @@ -192,8 +192,9 @@ export class AssetsTransferApi {
// for SystemToSystem, assetId is not the native relayChains asset and is not a number
// check for the general index of the assetId and assign the correct value for the local tx
// throws an error if the general index is not found
assetId = await getAssetHubAssetId(
assetId = await getAssetId(
_api,
registry,
assetId,
_specName,
isForeignAssetsTransfer
Expand Down
22 changes: 13 additions & 9 deletions src/createXcmTypes/ParaToSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import type {
} from './types';
import { constructForeignAssetMultiLocationFromAssetId } from './util/constructForeignAssetMultiLocationFromAssetId';
import { dedupeMultiAssets } from './util/dedupeMultiAssets';
import { getAssetHubAssetId } from './util/getAssetHubAssetId';
import { getAssetId } from './util/getAssetId';
import { isRelayNativeAsset } from './util/isRelayNativeAsset';
import { sortMultiAssetsAscending } from './util/sortMultiAssetsAscending';

Expand Down Expand Up @@ -221,6 +221,7 @@ export const ParaToSystem: ICreateXcmType = {

const assetIndex = getFeeAssetItemIndex(
api,
registry,
paysWithFeeDest,
multiAssets,
specName,
Expand Down Expand Up @@ -285,15 +286,16 @@ export const ParaToSystem: ICreateXcmType = {
assetId: string,
opts: CreateAssetsOpts
): Promise<XcmVersionedMultiAsset> => {
const { xcAssets } = opts.registry;
const { tokens: relayTokens } = opts.registry.currentRelayRegistry['0'];
const { registry } = opts;
const { xcAssets } = registry;
const { tokens: relayTokens } = registry.currentRelayRegistry['0'];
const parsedAssetIdAsNumber = Number.parseInt(assetId);
const isNotANumber = Number.isNaN(parsedAssetIdAsNumber);
const isRelayNative = isRelayNativeAsset(relayTokens, assetId);
const currentRelayChainSpecName = opts.registry.relayChain;
const currentRelayChainSpecName = registry.relayChain;

if (!isRelayNative && isNotANumber) {
assetId = await getAssetHubAssetId(api, assetId, specName);
assetId = await getAssetId(api, registry, assetId, specName);
}

// once we have the parachain assetId, use it to get the multilocation from the xc asset registry
Expand Down Expand Up @@ -395,8 +397,9 @@ const createXTokensMultiAssets = async (
assets: string[],
opts: CreateAssetsOpts
): Promise<VersionedMultiAssets> => {
const { xcAssets } = opts.registry;
const currentRelayChainSpecName = opts.registry.relayChain;
const { registry } = opts;
const { xcAssets } = registry;
const currentRelayChainSpecName = registry.relayChain;

let multiAssets: XcmMultiAsset[] = [];

Expand All @@ -408,7 +411,7 @@ const createXTokensMultiAssets = async (
const isNotANumber = Number.isNaN(parsedAssetIdAsNumber);

if (isNotANumber) {
assetId = await getAssetHubAssetId(api, assetId, specName);
assetId = await getAssetId(api, registry, assetId, specName);
}

// once we have the parachain assetId, use it to get the multilocation from the xc asset registry
Expand Down Expand Up @@ -517,8 +520,9 @@ const createParaToSystemMultiAssets = async (
const isNotANumber = Number.isNaN(parsedAssetIdAsNumber);

if (isNotANumber) {
assetId = await getAssetHubAssetId(
assetId = await getAssetId(
api,
registry,
assetId,
specName,
isForeignAssetsTransfer
Expand Down
6 changes: 4 additions & 2 deletions src/createXcmTypes/SystemToPara.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
import { constructForeignAssetMultiLocationFromAssetId } from './util/constructForeignAssetMultiLocationFromAssetId';
import { dedupeMultiAssets } from './util/dedupeMultiAssets';
import { fetchPalletInstanceId } from './util/fetchPalletInstanceId';
import { getAssetHubAssetId } from './util/getAssetHubAssetId';
import { getAssetId } from './util/getAssetId';
import { isRelayNativeAsset } from './util/isRelayNativeAsset';
import { isSystemChain } from './util/isSystemChain';
import { sortMultiAssetsAscending } from './util/sortMultiAssetsAscending';
Expand Down Expand Up @@ -244,6 +244,7 @@ export const SystemToPara: ICreateXcmType = {

const assetIndex = await getFeeAssetItemIndex(
api,
registry,
paysWithFeeDest,
multiAssets,
specName,
Expand Down Expand Up @@ -301,8 +302,9 @@ export const createSystemToParaMultiAssets = async (
const isRelayNative = isRelayNativeAsset(tokens, assetId);

if (!isRelayNative && isNotANumber) {
assetId = await getAssetHubAssetId(
assetId = await getAssetId(
api,
registry,
assetId,
specName,
isForeignAssetsTransfer
Expand Down
6 changes: 4 additions & 2 deletions src/createXcmTypes/SystemToSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
} from './types';
import { dedupeMultiAssets } from './util/dedupeMultiAssets';
import { fetchPalletInstanceId } from './util/fetchPalletInstanceId';
import { getAssetHubAssetId } from './util/getAssetHubAssetId';
import { getAssetId } from './util/getAssetId';
import { isRelayNativeAsset } from './util/isRelayNativeAsset';
import { isSystemChain } from './util/isSystemChain';
import { sortMultiAssetsAscending } from './util/sortMultiAssetsAscending';
Expand Down Expand Up @@ -237,6 +237,7 @@ export const SystemToSystem: ICreateXcmType = {

const assetIndex = getFeeAssetItemIndex(
api,
registry,
paysWithFeeDest,
multiAssets,
specName,
Expand Down Expand Up @@ -294,8 +295,9 @@ export const createSystemToSystemMultiAssets = async (

if (!isRelayNative) {
if (isNotANumber) {
assetId = await getAssetHubAssetId(
assetId = await getAssetId(
api,
registry,
assetId,
specName,
isForeignAssetsTransfer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@

import { Registry } from '../../registry';
import { mockSystemApi } from '../../testHelpers/mockSystemApi';
import { foreignAssetMultiLocationIsInRegistry } from './foreignAssetMultiLocationIsInRegistry';
import { foreignAssetMultiLocationIsInCacheOrRegistry } from './foreignAssetMultiLocationIsInCacheOrRegistry';

describe('foreignAssetMultiLocationIsInRegistry', () => {
describe('foreignAssetMultiLocationIsInCacheOrRegistry', () => {
it('Should return true if a given foreign asset multilocation exists in the asset api registry', () => {
const expected = true;
const multiLocation =
'{"parents":"1","interior":{ "X2":[{"Parachain":"2125"},{"GeneralIndex":"0"}]}}';
const registry = new Registry('statemine', {});

const foreignAssetExistsInRegistry = foreignAssetMultiLocationIsInRegistry(
mockSystemApi,
multiLocation,
registry
);
const foreignAssetExistsInRegistry =
foreignAssetMultiLocationIsInCacheOrRegistry(
mockSystemApi,
multiLocation,
registry
);

expect(foreignAssetExistsInRegistry).toEqual(expected);
});
Expand All @@ -26,11 +27,12 @@ describe('foreignAssetMultiLocationIsInRegistry', () => {
'{"parents":"1","interior":{"X1": {"Parachain":"200100510"}}}';
const registry = new Registry('statemine', {});

const foreignAssetExistsInRegistry = foreignAssetMultiLocationIsInRegistry(
mockSystemApi,
multiLocation,
registry
);
const foreignAssetExistsInRegistry =
foreignAssetMultiLocationIsInCacheOrRegistry(
mockSystemApi,
multiLocation,
registry
);

expect(foreignAssetExistsInRegistry).toEqual(expected);
});
Expand All @@ -44,7 +46,7 @@ describe('foreignAssetMultiLocationIsInRegistry', () => {
const registry = new Registry('statemine', {});

const err = () =>
foreignAssetMultiLocationIsInRegistry(
foreignAssetMultiLocationIsInCacheOrRegistry(
mockSystemApi,
multiLocation,
registry
Expand All @@ -62,7 +64,7 @@ describe('foreignAssetMultiLocationIsInRegistry', () => {
const registry = new Registry('statemine', {});

const err = () =>
foreignAssetMultiLocationIsInRegistry(
foreignAssetMultiLocationIsInCacheOrRegistry(
mockSystemApi,
multiLocation,
registry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,42 @@

import { ApiPromise } from '@polkadot/api';

import { ASSET_HUB_CHAIN_ID } from '../../consts';
import { BaseError, BaseErrorsEnum } from '../../errors';
import { Registry } from '../../registry';
import { ForeignAssetsInfo } from '../../registry/types';

export const foreignAssetMultiLocationIsInRegistry = (
export const foreignAssetMultiLocationIsInCacheOrRegistry = (
api: ApiPromise,
multilocationStr: string,
registry: Registry
): boolean => {
try {
const assetHubChainId = 1000;
// check if foreign asset exists in assets cache
const foreignAssetsCache =
registry.cache[registry.relayChain][ASSET_HUB_CHAIN_ID].foreignAssetsInfo;
if (checkForeignAssetExists(api, foreignAssetsCache, multilocationStr)) {
return true;
}

// check if foreign asset exists in registry
const foreignAssetsRegistry =
registry.currentRelayRegistry[ASSET_HUB_CHAIN_ID].foreignAssetsInfo;
return checkForeignAssetExists(api, foreignAssetsRegistry, multilocationStr);
};

const checkForeignAssetExists = (
api: ApiPromise,
foreignAssetsInfo: ForeignAssetsInfo,
multiLocationStr: string
): boolean => {
try {
const multiLocation = api.registry.createType(
'MultiLocation',
JSON.parse(multilocationStr)
JSON.parse(multiLocationStr)
);

const { foreignAssetsInfo: maybeForeignAssetsInfo } =
registry.currentRelayRegistry[assetHubChainId];

if (Object.keys(maybeForeignAssetsInfo).length > 0) {
const foreignAssetInfo = maybeForeignAssetsInfo as ForeignAssetsInfo;

const foreignAssets = Object.entries(foreignAssetInfo).map((data) => {
if (Object.keys(foreignAssetsInfo).length > 0) {
const foreignAssets = Object.entries(foreignAssetsInfo).map((data) => {
return data[1].multiLocation;
});

Expand Down
57 changes: 46 additions & 11 deletions src/createXcmTypes/util/foreignAssetsMultiLocationExists.spec.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
// Copyright 2023 Parity Technologies (UK) Ltd.

import { AssetsTransferApi } from '../../AssetsTransferApi';
import { Registry } from '../../registry';
import { adjustedMockSystemApi } from '../../testHelpers/adjustedMockSystemApi';
import { foreignAssetsMultiLocationExists } from './foreignAssetsMultiLocationExists';

describe('foreignMultiAssetMultiLocationExists', () => {
const systemAssetsApi = new AssetsTransferApi(
adjustedMockSystemApi,
'statemine',
2
);
const registry = new Registry('statemine', {});

it('Should return true for an existing foreign asset multilocation', async () => {
const expected = true;
const multiLocation =
'{"parents":"1","interior":{"X2": [{"Parachain":"2125"}, {"GeneralIndex": "0"}]}}';

const isValid = await foreignAssetsMultiLocationExists(
systemAssetsApi._api,
adjustedMockSystemApi,
registry,
multiLocation
);

Expand All @@ -30,7 +27,8 @@ describe('foreignMultiAssetMultiLocationExists', () => {
'{"parents":"1","interior":{"X1": {"Parachain":"21252525"}}}';

const isValid = await foreignAssetsMultiLocationExists(
systemAssetsApi._api,
adjustedMockSystemApi,
registry,
multiLocation
);

Expand All @@ -45,23 +43,60 @@ describe('foreignMultiAssetMultiLocationExists', () => {

await expect(async () => {
await foreignAssetsMultiLocationExists(
systemAssetsApi._api,
adjustedMockSystemApi,
registry,
multiLocation
);
}).rejects.toThrowError(expectedError);
});

it('Should throw an error when an comma is found in a multilocation keys value', async () => {
it('Should throw an error when a comma is found in a multilocation keys value', async () => {
const expectedError =
'Error creating MultiLocation type: Enum(Parachain) String should not contain decimal points or scientific notation';
const multiLocation =
'{"parents":"2","interior":{"X1": {"Parachain":"2,125"}}}';

await expect(async () => {
await foreignAssetsMultiLocationExists(
systemAssetsApi._api,
adjustedMockSystemApi,
registry,
multiLocation
);
}).rejects.toThrowError(expectedError);
});

it('Should correctly cache a valid foreign asset not found in the cache or registry', async () => {
const emptyRegistry = new Registry('statemine', {
injectedRegistry: {
kusama: {
'1000': {
assetsInfo: {},
poolPairsInfo: {},
foreignAssetsPalletInstance: null,
assetsPalletInstance: null,
specName: '',
tokens: [],
foreignAssetsInfo: {},
},
},
},
});
const multiLocation =
'{"parents":"1","interior":{"X2": [{"Parachain":"2125"}, {"GeneralIndex": "0"}]}}';

await foreignAssetsMultiLocationExists(
adjustedMockSystemApi,
emptyRegistry,
multiLocation
);

const result = emptyRegistry.cacheLookupForeignAsset('TNKR');

expect(result).toEqual({
multiLocation:
'{"parents":1,"interior":{"x2":[{"parachain":2125},{"generalIndex":0}]}}',
name: 'Tinkernet',
symbol: 'TNKR',
});
});
});
Loading