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

Fix WeightToFee function in MangataAdapter #111

Merged
merged 8 commits into from
Dec 5, 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: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"tabWidth": 2,
"useTabs": false,
"trailingComma": "all",
"printWidth": 150
}
58 changes: 19 additions & 39 deletions packages/adapter/src/chains/mangata.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import _ from "lodash";
import BN from "bn.js";
import type { SubmittableExtrinsic, AddressOrPair } from "@polkadot/api/types";
import type { u32, u64, u128, Option } from "@polkadot/types";
import type { u32, u128, Option } from "@polkadot/types";
import type { WeightV2 } from "@polkadot/types/interfaces";
import type { HexString } from "@polkadot/util/types";
import type { KeyringPair } from "@polkadot/keyring/types";
import { Weight } from "@oak-network/config";
import { ChainAdapter } from "./chainAdapter";
import {
convertAbsoluteLocationToRelative,
getDerivativeAccountV2,
sendExtrinsic,
} from "../util";
import { WEIGHT_REF_TIME_PER_SECOND } from "../constants";
import { getDerivativeAccountV2, sendExtrinsic } from "../util";
import { WEIGHT_REF_TIME_PER_NANOS, WEIGHT_REF_TIME_PER_SECOND, WEIGHT_PROOF_SIZE_PER_MB } from "../constants";
import { SendExtrinsicResult } from "../types";

// MangataAdapter implements ChainAdapter
Expand All @@ -31,12 +27,8 @@ export class MangataAdapter extends ChainAdapter {
* @returns Extrinsic weight
*/
// eslint-disable-next-line class-methods-use-this
async getExtrinsicWeight(
extrinsic: SubmittableExtrinsic<"promise">,
account: AddressOrPair,
): Promise<Weight> {
const { refTime, proofSize } = (await extrinsic.paymentInfo(account))
.weight as unknown as WeightV2;
async getExtrinsicWeight(extrinsic: SubmittableExtrinsic<"promise">, account: AddressOrPair): Promise<Weight> {
const { refTime, proofSize } = (await extrinsic.paymentInfo(account)).weight as unknown as WeightV2;
return new Weight(new BN(refTime.unwrap()), new BN(proofSize.unwrap()));
}

Expand All @@ -46,15 +38,10 @@ export class MangataAdapter extends ChainAdapter {
* @param instructionCount The number of XCM instructions
* @returns XCM overall weight
*/
async calculateXcmOverallWeight(
transactCallWeight: Weight,
instructionCount: number,
): Promise<Weight> {
async calculateXcmOverallWeight(transactCallWeight: Weight, instructionCount: number): Promise<Weight> {
const { xcm } = this.chainConfig;
if (_.isUndefined(xcm)) throw new Error("chainConfig.xcm not set");
const overallWeight = transactCallWeight.add(
xcm.instructionWeight.muln(instructionCount),
);
const overallWeight = transactCallWeight.add(xcm.instructionWeight.muln(instructionCount));
return overallWeight;
}

Expand All @@ -66,24 +53,24 @@ export class MangataAdapter extends ChainAdapter {
*/
async weightToFee(weight: Weight, assetLocation: any): Promise<BN> {
const [defaultAsset] = this.chainConfig.assets;
if (_.isUndefined(defaultAsset))
throw new Error("chainConfig.defaultAsset not set");
if (_.isUndefined(defaultAsset)) throw new Error("chainConfig.defaultAsset not set");

const api = this.getApi();
if (_.isEqual(defaultAsset.location, assetLocation)) {
const fee = (await api.call.transactionPaymentApi.queryWeightToFee(
weight,
)) as u64;
return fee;
const unit = new BN(10).pow(new BN(defaultAsset.decimals));
// ExtrinsicBaseWeight benchmark value: 114756 nano seconds
const extrinsicBaseWeight = WEIGHT_REF_TIME_PER_NANOS.mul(new BN(114756));
const feePerSecond = WEIGHT_REF_TIME_PER_SECOND.div(extrinsicBaseWeight).mul(unit);
const refTimeFee = weight.refTime.mul(feePerSecond).div(WEIGHT_REF_TIME_PER_SECOND);
const proofSizeFee = weight.proofSize.mul(feePerSecond).div(WEIGHT_PROOF_SIZE_PER_MB);
return refTimeFee.add(proofSizeFee);
}
const storageValue =
await api.query.assetRegistry.locationToAssetId(assetLocation);
const storageValue = await api.query.assetRegistry.locationToAssetId(assetLocation);
const item = storageValue as unknown as Option<u32>;
if (item.isNone) throw new Error("AssetTypeUnitsPerSecond is null");

const assetId = item.unwrap();
const metadataStorageValue =
await api.query.assetRegistry.metadata(assetId);
const metadataStorageValue = await api.query.assetRegistry.metadata(assetId);
const metadataItem = metadataStorageValue as unknown as Option<any>;
if (metadataItem.isNone) throw new Error("Metadata is null");

Expand Down Expand Up @@ -137,25 +124,18 @@ export class MangataAdapter extends ChainAdapter {
const { key } = this.chainConfig;
if (_.isUndefined(key)) throw new Error("chainConfig.key not set");

const transferAssetLocation = this.isNativeAsset(assetLocation)
? convertAbsoluteLocationToRelative(assetLocation)
: assetLocation;

const api = this.getApi();
const extrinsic = api.tx.xTokens.transferMultiasset(
{
V3: {
fun: { Fungible: assetAmount },
id: { Concrete: transferAssetLocation },
id: { Concrete: assetLocation },
},
},
{
V3: {
interior: {
X2: [
destination.interior.X1,
{ AccountId32: { id: recipient, network: null } },
],
X2: [destination.interior.X1, { AccountId32: { id: recipient, network: null } }],
},
parents: 1,
},
Expand Down
57 changes: 15 additions & 42 deletions packages/adapter/src/chains/moonbeam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ import type { HexString } from "@polkadot/util/types";
import type { KeyringPair } from "@polkadot/keyring/types";
import { Weight } from "@oak-network/config";
import { ChainAdapter, TaskScheduler } from "./chainAdapter";
import {
convertAbsoluteLocationToRelative,
getDerivativeAccountV3,
sendExtrinsic,
} from "../util";
import { convertAbsoluteLocationToRelative, getDerivativeAccountV3, sendExtrinsic } from "../util";
import { AccountType, SendExtrinsicResult } from "../types";
import { WEIGHT_REF_TIME_PER_SECOND } from "../constants";

Expand All @@ -25,11 +21,11 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler {
async initialize() {
// As of 12/02/2023, api.consts and api.query both return {} from all Moonriver endpoints.
// Maybe additional calls are required prior to fetch api.consts

// await this.fetchAndUpdateConfigs();

this.chainConfig.ss58Prefix = 1285;
this.chainConfig.paraId = 2023;
this.chainConfig.ss58Prefix = 1285;
this.chainConfig.paraId = 2023;
}

/**
Expand Down Expand Up @@ -74,12 +70,8 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler {
* @returns Extrinsic weight
*/
// eslint-disable-next-line class-methods-use-this
async getExtrinsicWeight(
extrinsic: SubmittableExtrinsic<"promise">,
account: AddressOrPair,
): Promise<Weight> {
const { refTime, proofSize } = (await extrinsic.paymentInfo(account))
.weight as unknown as WeightV2;
async getExtrinsicWeight(extrinsic: SubmittableExtrinsic<"promise">, account: AddressOrPair): Promise<Weight> {
const { refTime, proofSize } = (await extrinsic.paymentInfo(account)).weight as unknown as WeightV2;
return new Weight(new BN(refTime.unwrap()), new BN(proofSize.unwrap()));
}

Expand All @@ -89,15 +81,10 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler {
* @param instructionCount
* @returns XCM overall weight
*/
async calculateXcmOverallWeight(
transactCallWeight: Weight,
instructionCount: number,
): Promise<Weight> {
async calculateXcmOverallWeight(transactCallWeight: Weight, instructionCount: number): Promise<Weight> {
const { xcm } = this.chainConfig;
if (_.isUndefined(xcm)) throw new Error("chainConfig.xcm not set");
const overallWeight = transactCallWeight.add(
xcm.instructionWeight.muln(instructionCount),
);
const overallWeight = transactCallWeight.add(xcm.instructionWeight.muln(instructionCount));
return overallWeight;
}

Expand All @@ -109,13 +96,10 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler {
*/
async weightToFee(weight: Weight, assetLocation: any): Promise<BN> {
const [defaultAsset] = this.chainConfig.assets;
if (_.isUndefined(defaultAsset))
throw new Error("chainConfig.defaultAsset not set");
if (_.isUndefined(defaultAsset)) throw new Error("chainConfig.defaultAsset not set");
const api = this.getApi();
if (_.isEqual(defaultAsset.location, assetLocation)) {
const fee = (await api.call.transactionPaymentApi.queryWeightToFee(
weight,
)) as u64;
const fee = (await api.call.transactionPaymentApi.queryWeightToFee(weight)) as u64;
return fee;
}
const storageValue = await api.query.assetManager.assetTypeUnitsPerSecond({
Expand Down Expand Up @@ -159,11 +143,8 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler {
if (_.isUndefined(key)) throw new Error("chainConfig.key not set");

const [defaultAsset] = this.chainConfig.assets;
if (_.isUndefined(defaultAsset))
throw new Error("chainConfig.defaultAsset not set");
const currency = _.isEqual(feeLocation, defaultAsset.location)
? { AsCurrencyId: "SelfReserve" }
: { AsMultiLocation: { V3: feeLocation } };
if (_.isUndefined(defaultAsset)) throw new Error("chainConfig.defaultAsset not set");
const currency = _.isEqual(feeLocation, defaultAsset.location) ? { AsCurrencyId: "SelfReserve" } : { AsMultiLocation: { V3: feeLocation } };
const extrinsic = this.getApi().tx.xcmTransactor.transactThroughSigned(
{ V3: destination },
{ currency, feeAmount },
Expand All @@ -172,10 +153,7 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler {
false,
);

console.log(
`Send extrinsic from ${key} to schedule task. extrinsic:`,
extrinsic.method.toHex(),
);
console.log(`Send extrinsic from ${key} to schedule task. extrinsic:`, extrinsic.method.toHex());
const result = await sendExtrinsic(api, extrinsic, keyringPair);
return result;
}
Expand Down Expand Up @@ -221,9 +199,7 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler {
const { key } = this.chainConfig;
if (_.isUndefined(key)) throw new Error("chainConfig.key not set");

const transferAssetLocation = this.isNativeAsset(assetLocation)
? convertAbsoluteLocationToRelative(assetLocation)
: assetLocation;
const transferAssetLocation = this.isNativeAsset(assetLocation) ? convertAbsoluteLocationToRelative(assetLocation) : assetLocation;

const api = this.getApi();
const extrinsic = api.tx.xTokens.transferMultiasset(
Expand All @@ -236,10 +212,7 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler {
{
V3: {
interior: {
X2: [
destination.interior.X1,
{ AccountId32: { id: recipient, network: null } },
],
X2: [destination.interior.X1, { AccountId32: { id: recipient, network: null } }],
},
parents: 1,
},
Expand Down
57 changes: 57 additions & 0 deletions packages/adapter/src/chains/oak.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ import { AccountType, SendExtrinsicResult } from "../types";
import { WEIGHT_REF_TIME_PER_SECOND } from "../constants";
import { InvalidAddress } from "../errors";

export interface AutomationPriceTriggerParams {
chain: string;
exchange: string;
asset1: string;
asset2: string;
submittedAt: number;
triggerFunction: "lt" | "gt";
triggerParam: number[];
}

export enum OakAdapterTransactType {
PayThroughRemoteDerivativeAccount,
PayThroughSoverignAccount,
Expand Down Expand Up @@ -235,6 +245,53 @@ export class OakAdapter extends ChainAdapter {
return result;
}

/**
* Schedule XCMP task
* @param destination The location of the destination chain
* @param schedule Schedule setting
* @param scheduleFee Schedule fee
* @param executionFee Execution fee
* @param encodedCall Encoded call
* @param encodedCallWeight The encoded call weight weight of the XCM instructions
* @param overallWeight The overall weight of the XCM instructions
* @param keyringPair Operator's keyring pair
* @returns SendExtrinsicResult
*/
async scheduleXcmpPriceTask(
automationPriceTriggerParams: AutomationPriceTriggerParams,
destination: any,
scheduleFee: any,
executionFee: any,
encodedCall: HexString,
encodedCallWeight: Weight,
overallWeight: Weight,
keyringPair: KeyringPair,
): Promise<SendExtrinsicResult> {
const api = this.getApi();
const { key } = this.chainConfig;
if (_.isUndefined(key)) throw new Error("chainData.key not set");

const extrinsic = api.tx.automationPrice.scheduleXcmpTask(
automationPriceTriggerParams.chain,
automationPriceTriggerParams.exchange,
automationPriceTriggerParams.asset1,
automationPriceTriggerParams.asset2,
automationPriceTriggerParams.submittedAt,
automationPriceTriggerParams.triggerFunction,
automationPriceTriggerParams.triggerParam,
destination,
scheduleFee,
executionFee,
encodedCall,
encodedCallWeight,
overallWeight,
);

console.log(`Send extrinsic from ${key} to schedule price task. extrinsic:`, extrinsic.method.toHex());
const result = await sendExtrinsic(api, extrinsic, keyringPair);
return result;
}

/**
* Calculate the derivative account ID of a certain account ID
* @param accountId
Expand Down
1 change: 1 addition & 0 deletions packages/adapter/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import BN from "bn.js";

export const WEIGHT_REF_TIME_PER_NANOS = new BN(1000);
export const WEIGHT_REF_TIME_PER_SECOND = new BN(1000000000000);
export const WEIGHT_PROOF_SIZE_PER_MB = new BN(1024 * 1024);
Loading