Skip to content
Prev Previous commit
Next Next commit
Make Contracts Runtime Calls support WeightV2
  • Loading branch information
jasl committed Nov 11, 2022
commit 05093af73ecabdbe074b200a1f15b41a986da941
31 changes: 6 additions & 25 deletions packages/api-contract/src/base/Contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types';
import type { ApiTypes, DecorateMethod } from '@polkadot/api/types';
import type { Bytes } from '@polkadot/types';
import type { AccountId, ContractExecResult, EventRecord, Weight, WeightV2 } from '@polkadot/types/interfaces';
import type { AccountId, ContractExecResult, EventRecord } from '@polkadot/types/interfaces';
import type { ISubmittableResult } from '@polkadot/types/types';
import type { AbiMessage, ContractCallOutcome, ContractOptions, DecodedEvent, WeightAll } from '../types';
import type { ContractCallResult, ContractCallSend, ContractQuery, ContractTx, MapMessageQuery, MapMessageTx } from './types';
Expand All @@ -13,7 +13,7 @@ import { map } from 'rxjs';

import { SubmittableResult } from '@polkadot/api';
import { ApiBase } from '@polkadot/api/base';
import { BN, BN_HUNDRED, BN_ONE, BN_ZERO, isUndefined, logger } from '@polkadot/util';
import { BN_ZERO, isUndefined, logger } from '@polkadot/util';

import { Abi } from '../Abi';
import { applyOnEvent } from '../util';
Expand All @@ -24,9 +24,6 @@ export interface ContractConstructor<ApiType extends ApiTypes> {
new(api: ApiBase<ApiType>, abi: string | Record<string, unknown> | Abi, address: string | AccountId): Contract<ApiType>;
}

// As per Rust, 5 * GAS_PER_SEC
const MAX_CALL_GAS = new BN(5_000_000_000_000).isub(BN_ONE);

const l = logger('Contract');

function createQuery <ApiType extends ApiTypes> (meta: AbiMessage, fn: (origin: string | AccountId | Uint8Array, options: ContractOptions, params: unknown[]) => ContractCallResult<ApiType, ContractCallOutcome>): ContractQuery<ApiType> {
Expand Down Expand Up @@ -85,24 +82,6 @@ export class Contract<ApiType extends ApiTypes> extends Base<ApiType> {
return this.#tx;
}

#getGas = (_gasLimit: bigint | BN | string | number | WeightV2, isCall = false): WeightAll => {
const weight = convertWeight(_gasLimit);

if (weight.v1Weight.gt(BN_ZERO)) {
return weight;
}

return convertWeight(
isCall
? MAX_CALL_GAS
: convertWeight(
this.api.consts.system.blockWeights
? (this.api.consts.system.blockWeights as unknown as { maxBlock: WeightV2 }).maxBlock
: this.api.consts.system.maximumBlockWeight as Weight
).v1Weight.muln(64).div(BN_HUNDRED)
);
};

#exec = (messageOrId: AbiMessage | string | number, { gasLimit = BN_ZERO, storageDepositLimit = null, value = BN_ZERO }: ContractOptions, params: unknown[]): SubmittableExtrinsic<ApiType> => {
return this.api.tx.contracts.call(
this.address,
Expand Down Expand Up @@ -141,8 +120,10 @@ export class Contract<ApiType extends ApiTypes> extends Base<ApiType> {
origin,
this.address,
value,
// the runtime interface still used u64 inputs
this.#getGas(gasLimit, true).v1Weight,
this._isOldWeight
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not remove the old getGas here. It would still be applicable.

Rather when we detect v2 runtime (or rather v1 runtime) we swap to pushing through the old weight, not the option. So the existing will stay as-is for v1, but for v2 we will do the v2 weight thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I don't understand your means, do you mean I need to revert this part change?

Copy link
Member

@jacogr jacogr Nov 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It should rather be adapted to al check for the new stuff. You can do this by detecting which version is used, i.e something like -

...
value,
this.api.tx.contracts.call.meta.version === 1
  ? this.#getGas(gasLimit, true).v1Weight
  : this.#getGas(gasLimit, true).v2Weight
...

This is important since the getGas also allows the developer to pass a number - since we don't like breaking compat, we have not changed the signatures. And we have to ensure that the behviour on anything old stays exactly the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed as your suggest

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

packages/api-contract/src/base/Contract.ts:144:43 - error TS2339: Property 'version' does not exist on type 'FunctionMetadataLatest'.

144           this.api.tx.contracts.call.meta.version === 1

I'll dig

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems FunctionMetadataLatest doesn't have version field?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jacogr I still don't got this one

// jiggle v1 weights, metadata points to latest
? convertWeight(gasLimit).v1Weight as unknown as WeightAll['v2Weight']
: convertWeight(gasLimit).v2Weight,
storageDepositLimit,
message.toU8a(params)
).pipe(
Expand Down