WeightsV2 support for contracts pallet (#8538)
* Weights V2 support * estimated v2 * instantiate * [CI Skip] bump/beta 0.124.2-109-x skip-checks: true * contract call dry run * lint fix * uploading raw wasm type --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
3a6bd19940
commit
d317ee8888
@ -26,6 +26,7 @@
|
||||
"Save": "Save",
|
||||
"The code is not recognized as being in valid WASM format": "The code is not recognized as being in valid WASM format",
|
||||
"The codeHash is not a valid hex hash": "The codeHash is not a valid hex hash",
|
||||
"The maximum amount of gas to use for this contract call. If the call requires more, it will fail.": "The maximum amount of gas to use for this contract call. If the call requires more, it will fail.",
|
||||
"The value is not in a valid address format": "The value is not in a valid address format",
|
||||
"This operation does not impact the associated on-chain code or any of its contracts.": "This operation does not impact the associated on-chain code or any of its contracts.",
|
||||
"This operation does not remove the uploaded code WASM and ABI from the chain, nor any deployed contracts. The forget operation only limits your access to the code on this browser.": "This operation does not remove the uploaded code WASM and ABI from the chain, nor any deployed contracts. The forget operation only limits your access to the code on this browser.",
|
||||
@ -52,6 +53,10 @@
|
||||
"deployment constructor": "deployment constructor",
|
||||
"exec": "exec",
|
||||
"json for either ABI or .contract bundle": "json for either ABI or .contract bundle",
|
||||
"max ProofSize allowed": "max ProofSize allowed",
|
||||
"max ProofSize allowed ({{estimatedProofSize}} estimated)": "max ProofSize allowed ({{estimatedProofSize}} estimated)",
|
||||
"max RefTime allowed (M)": "max RefTime allowed (M)",
|
||||
"max RefTime allowed (M, {{estimatedRefTime}} estimated)": "max RefTime allowed (M, {{estimatedRefTime}} estimated)",
|
||||
"max gas allowed (M)": "max gas allowed (M)",
|
||||
"max gas allowed (M, {{estimatedMg}} estimated)": "max gas allowed (M, {{estimatedMg}} estimated)",
|
||||
"max read gas": "max read gas",
|
||||
|
||||
@ -82,23 +82,42 @@ function Upload ({ onClose }: Props): React.ReactElement {
|
||||
}, [abiName, setName]);
|
||||
|
||||
useEffect((): void => {
|
||||
let contract: SubmittableExtrinsic<'promise'> | null = null;
|
||||
let error: string | null = null;
|
||||
async function dryRun () {
|
||||
let contract: SubmittableExtrinsic<'promise'> | null = null;
|
||||
let error: string | null = null;
|
||||
|
||||
try {
|
||||
contract = code && contractAbi?.constructors[constructorIndex]?.method && value
|
||||
? code.tx[contractAbi.constructors[constructorIndex].method]({
|
||||
gasLimit: weight.weight,
|
||||
storageDepositLimit: null,
|
||||
value: contractAbi?.constructors[constructorIndex].isPayable ? value : undefined
|
||||
}, ...params)
|
||||
: null;
|
||||
} catch (e) {
|
||||
error = (e as Error).message;
|
||||
try {
|
||||
if (code && contractAbi?.constructors[constructorIndex]?.method && value && accountId) {
|
||||
const dryRunParams: Parameters<typeof api.call.contractsApi.instantiate> =
|
||||
[
|
||||
accountId,
|
||||
contractAbi?.constructors[constructorIndex].isPayable
|
||||
? api.registry.createType('Balance', value)
|
||||
: api.registry.createType('Balance', BN_ZERO),
|
||||
weight.weightV2,
|
||||
null,
|
||||
{ Upload: api.registry.createType('Raw', wasm) },
|
||||
contractAbi?.constructors[constructorIndex]?.toU8a(params),
|
||||
''
|
||||
];
|
||||
|
||||
const dryRunResult = await api.call.contractsApi.instantiate(...dryRunParams);
|
||||
|
||||
contract = code.tx[contractAbi.constructors[constructorIndex].method]({
|
||||
gasLimit: dryRunResult.gasRequired,
|
||||
storageDepositLimit: dryRunResult.storageDeposit.isCharge ? dryRunResult.storageDeposit.asCharge : null,
|
||||
value: contractAbi?.constructors[constructorIndex].isPayable ? value : undefined
|
||||
}, ...params);
|
||||
}
|
||||
} catch (e) {
|
||||
error = (e as Error).message;
|
||||
}
|
||||
|
||||
setUploadTx(() => [contract, error]);
|
||||
}
|
||||
|
||||
setUploadTx(() => [contract, error]);
|
||||
}, [code, contractAbi, constructorIndex, value, params, weight]);
|
||||
dryRun().catch((e) => console.error(e));
|
||||
}, [accountId, wasm, api, code, contractAbi, constructorIndex, value, params, weight]);
|
||||
|
||||
const _onAddWasm = useCallback(
|
||||
(wasm: Uint8Array, name: string): void => {
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
import type { SubmittableExtrinsic } from '@polkadot/api/types';
|
||||
import type { ContractPromise } from '@polkadot/api-contract';
|
||||
import type { ContractCallOutcome } from '@polkadot/api-contract/types';
|
||||
import type { WeightV2 } from '@polkadot/types/interfaces';
|
||||
import type { CallResult } from './types.js';
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { Button, Dropdown, Expander, InputAddress, InputBalance, Modal, styled, Toggle, TxButton } from '@polkadot/react-components';
|
||||
import { useAccountId, useDebounce, useFormField, useToggle } from '@polkadot/react-hooks';
|
||||
import { convertWeight } from '@polkadot/react-hooks/useWeight';
|
||||
import { useAccountId, useApi, useDebounce, useFormField, useToggle } from '@polkadot/react-hooks';
|
||||
import { Available } from '@polkadot/react-query';
|
||||
import { BN, BN_ONE, BN_ZERO } from '@polkadot/util';
|
||||
|
||||
@ -33,9 +33,11 @@ const MAX_CALL_WEIGHT = new BN(5_000_000_000_000).isub(BN_ONE);
|
||||
|
||||
function Call ({ className = '', contract, messageIndex, onCallResult, onChangeMessage, onClose }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const message = contract.abi.messages[messageIndex];
|
||||
const [accountId, setAccountId] = useAccountId();
|
||||
const [estimatedWeight, setEstimatedWeight] = useState<BN | null>(null);
|
||||
const [estimatedWeightV2, setEstimatedWeightV2] = useState<WeightV2 | null>(null);
|
||||
const [value, isValueValid, setValue] = useFormField<BN>(BN_ZERO);
|
||||
const [outcomes, setOutcomes] = useState<CallResult[]>([]);
|
||||
const [execTx, setExecTx] = useState<SubmittableExtrinsic<'promise'> | null>(null);
|
||||
@ -47,18 +49,46 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM
|
||||
|
||||
useEffect((): void => {
|
||||
setEstimatedWeight(null);
|
||||
setEstimatedWeightV2(null);
|
||||
setParams([]);
|
||||
}, [contract, messageIndex]);
|
||||
|
||||
useEffect((): void => {
|
||||
value && message.isMutating && setExecTx((): SubmittableExtrinsic<'promise'> | null => {
|
||||
try {
|
||||
return contract.tx[message.method]({ gasLimit: weight.weight, storageDepositLimit: null, value: message.isPayable ? value : 0 }, ...params);
|
||||
} catch {
|
||||
return null;
|
||||
async function dryRun () {
|
||||
if (accountId && value && message.isMutating) {
|
||||
const dryRunParams: Parameters<typeof api.call.contractsApi.call> =
|
||||
[
|
||||
accountId,
|
||||
contract.address,
|
||||
message.isPayable
|
||||
? api.registry.createType('Balance', value)
|
||||
: api.registry.createType('Balance', BN_ZERO),
|
||||
weight.weightV2,
|
||||
null,
|
||||
message.toU8a(params)
|
||||
];
|
||||
|
||||
const dryRunResult = await api.call.contractsApi.call(...dryRunParams);
|
||||
|
||||
setExecTx((): SubmittableExtrinsic<'promise'> | null => {
|
||||
try {
|
||||
return contract.tx[message.method](
|
||||
{
|
||||
gasLimit: dryRunResult.gasRequired,
|
||||
storageDepositLimit: dryRunResult.storageDeposit.isCharge ? dryRunResult.storageDeposit.asCharge : null,
|
||||
value: message.isPayable ? value : 0
|
||||
},
|
||||
...params
|
||||
);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [accountId, contract, message, value, weight, params]);
|
||||
}
|
||||
|
||||
dryRun().catch((e) => console.error(e));
|
||||
}, [api, accountId, contract, message, value, weight, params]);
|
||||
|
||||
useEffect((): void => {
|
||||
if (!accountId || !message || !dbParams || !dbValue) {
|
||||
@ -67,13 +97,26 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM
|
||||
|
||||
contract
|
||||
.query[message.method](accountId, { gasLimit: -1, storageDepositLimit: null, value: message.isPayable ? dbValue : 0 }, ...dbParams)
|
||||
.then(({ gasRequired, result }) => setEstimatedWeight(
|
||||
result.isOk
|
||||
? convertWeight(gasRequired).v1Weight
|
||||
: null
|
||||
))
|
||||
.catch(() => setEstimatedWeight(null));
|
||||
}, [accountId, contract, message, dbParams, dbValue]);
|
||||
.then(({ gasRequired, result }) => {
|
||||
if (weight.isWeightV2) {
|
||||
setEstimatedWeightV2(
|
||||
result.isOk
|
||||
? api.registry.createType('WeightV2', gasRequired)
|
||||
: null
|
||||
);
|
||||
} else {
|
||||
setEstimatedWeight(
|
||||
result.isOk
|
||||
? gasRequired.refTime.toBn()
|
||||
: null
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setEstimatedWeight(null);
|
||||
setEstimatedWeightV2(null);
|
||||
});
|
||||
}, [api, accountId, contract, message, dbParams, dbValue, weight.isWeightV2]);
|
||||
|
||||
const _onSubmitRpc = useCallback(
|
||||
(): void => {
|
||||
@ -82,7 +125,11 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM
|
||||
}
|
||||
|
||||
contract
|
||||
.query[message.method](accountId, { gasLimit: weight.isEmpty ? -1 : weight.weight, storageDepositLimit: null, value: message.isPayable ? value : 0 }, ...params)
|
||||
.query[message.method](
|
||||
accountId,
|
||||
{ gasLimit: weight.isWeightV2 ? weight.weightV2 : weight.isEmpty ? -1 : weight.weight, storageDepositLimit: null, value: message.isPayable ? value : 0 },
|
||||
...params
|
||||
)
|
||||
.then((result): void => {
|
||||
setOutcomes([{
|
||||
...result,
|
||||
@ -168,6 +215,13 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM
|
||||
)}
|
||||
<InputMegaGas
|
||||
estimatedWeight={message.isMutating ? estimatedWeight : MAX_CALL_WEIGHT}
|
||||
estimatedWeightV2={message.isMutating
|
||||
? estimatedWeightV2
|
||||
: api.registry.createType('WeightV2', {
|
||||
proofSize: new BN(1_000_000),
|
||||
refTIme: MAX_CALL_WEIGHT
|
||||
})
|
||||
}
|
||||
isCall={!message.isMutating}
|
||||
weight={weight}
|
||||
/>
|
||||
|
||||
@ -79,7 +79,7 @@ function Deploy ({ codeHash, constructorIndex = 0, onClose, setConstructorIndex
|
||||
if (blueprint && contractAbi?.constructors[constructorIndex]?.method) {
|
||||
try {
|
||||
return blueprint.tx[contractAbi.constructors[constructorIndex].method]({
|
||||
gasLimit: weight.weight,
|
||||
gasLimit: weight.isWeightV2 ? weight.weightV2 : weight.weight,
|
||||
salt: withSalt
|
||||
? salt
|
||||
: null,
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
// Copyright 2017-2023 @polkadot/app-contracts authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { WeightV2 } from '@polkadot/types/interfaces';
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { UseWeight } from '../types.js';
|
||||
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { InputNumber, styled, Toggle } from '@polkadot/react-components';
|
||||
import { InputNumber, Toggle } from '@polkadot/react-components';
|
||||
import { BN_MILLION, BN_ONE, BN_ZERO } from '@polkadot/util';
|
||||
|
||||
import { useTranslation } from '../translate.js';
|
||||
@ -14,11 +15,26 @@ import { useTranslation } from '../translate.js';
|
||||
interface Props {
|
||||
className?: string;
|
||||
estimatedWeight?: BN | null;
|
||||
estimatedWeightV2?: WeightV2 | null;
|
||||
isCall?: boolean;
|
||||
weight: UseWeight;
|
||||
}
|
||||
|
||||
function InputMegaGas ({ className, estimatedWeight, isCall, weight: { executionTime, isValid, megaGas, percentage, setIsEmpty, setMegaGas } }: Props): React.ReactElement<Props> {
|
||||
function InputMegaGas ({ className,
|
||||
estimatedWeight,
|
||||
estimatedWeightV2,
|
||||
isCall,
|
||||
weight: { executionTime,
|
||||
isValid,
|
||||
isWeightV2,
|
||||
megaGas,
|
||||
megaRefTime,
|
||||
percentage,
|
||||
proofSize,
|
||||
setIsEmpty,
|
||||
setMegaGas,
|
||||
setMegaRefTime,
|
||||
setProofSize } }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const [withEstimate, setWithEstimate] = useState(true);
|
||||
|
||||
@ -29,10 +45,32 @@ function InputMegaGas ({ className, estimatedWeight, isCall, weight: { execution
|
||||
[estimatedWeight]
|
||||
);
|
||||
|
||||
const estimatedMgRefTime = useMemo(
|
||||
() => estimatedWeightV2
|
||||
? estimatedWeightV2.refTime.toBn().div(BN_MILLION).iadd(BN_ONE)
|
||||
: null,
|
||||
[estimatedWeightV2]
|
||||
);
|
||||
|
||||
const estimatedProofSize = useMemo(
|
||||
() => estimatedWeightV2
|
||||
? estimatedWeightV2.proofSize.toBn()
|
||||
: null,
|
||||
[estimatedWeightV2]
|
||||
);
|
||||
|
||||
useEffect((): void => {
|
||||
withEstimate && estimatedMg && setMegaGas(estimatedMg);
|
||||
}, [estimatedMg, setMegaGas, withEstimate]);
|
||||
|
||||
useEffect((): void => {
|
||||
withEstimate && estimatedMgRefTime && setMegaRefTime(estimatedMgRefTime);
|
||||
}, [estimatedMgRefTime, setMegaRefTime, withEstimate]);
|
||||
|
||||
useEffect((): void => {
|
||||
withEstimate && estimatedProofSize && setProofSize(estimatedProofSize);
|
||||
}, [estimatedProofSize, setProofSize, withEstimate]);
|
||||
|
||||
useEffect((): void => {
|
||||
setIsEmpty(withEstimate && !!isCall);
|
||||
}, [isCall, setIsEmpty, withEstimate]);
|
||||
@ -40,43 +78,85 @@ function InputMegaGas ({ className, estimatedWeight, isCall, weight: { execution
|
||||
const isDisabled = !!estimatedMg && withEstimate;
|
||||
|
||||
return (
|
||||
<StyledDiv className={className}>
|
||||
<InputNumber
|
||||
defaultValue={estimatedMg && isDisabled ? estimatedMg.toString() : undefined}
|
||||
isDisabled={isDisabled}
|
||||
isError={!isValid}
|
||||
isZeroable={isCall}
|
||||
label={
|
||||
estimatedMg && (isCall ? !withEstimate : true)
|
||||
? t<string>('max gas allowed (M, {{estimatedMg}} estimated)', { replace: { estimatedMg: estimatedMg.toString() } })
|
||||
: t<string>('max gas allowed (M)')
|
||||
}
|
||||
labelExtra={(estimatedWeight || isCall) && (
|
||||
<Toggle
|
||||
<div className={className}>
|
||||
{isWeightV2
|
||||
? <>
|
||||
<InputNumber
|
||||
defaultValue={estimatedMgRefTime && isDisabled ? estimatedMgRefTime.toString() : undefined}
|
||||
isDisabled={isDisabled}
|
||||
isError={!isValid}
|
||||
isZeroable={isCall}
|
||||
label={
|
||||
isCall
|
||||
? t<string>('max read gas')
|
||||
: t<string>('use estimated gas')
|
||||
estimatedMgRefTime && (isCall ? !withEstimate : true)
|
||||
? t<string>('max RefTime allowed (M, {{estimatedRefTime}} estimated)', { replace: { estimatedMgRefTime: estimatedMgRefTime.toString() } })
|
||||
: t<string>('max RefTime allowed (M)')
|
||||
}
|
||||
onChange={setWithEstimate}
|
||||
value={withEstimate}
|
||||
onChange={isDisabled ? undefined : setMegaRefTime}
|
||||
value={isDisabled ? undefined : ((isCall && withEstimate) ? BN_ZERO : megaRefTime)}
|
||||
>
|
||||
{(estimatedWeightV2 || isCall) && (
|
||||
<Toggle
|
||||
label={
|
||||
isCall
|
||||
? t<string>('max read gas')
|
||||
: t<string>('use estimated gas')
|
||||
}
|
||||
onChange={setWithEstimate}
|
||||
value={withEstimate}
|
||||
/>
|
||||
)}
|
||||
</InputNumber>
|
||||
<InputNumber
|
||||
defaultValue={estimatedProofSize && isDisabled ? estimatedProofSize.toString() : undefined}
|
||||
isDisabled={isDisabled}
|
||||
isError={!isValid}
|
||||
isZeroable={isCall}
|
||||
label={
|
||||
estimatedProofSize && (isCall ? !withEstimate : true)
|
||||
? t<string>('max ProofSize allowed ({{estimatedProofSize}} estimated)', { replace: { estimatedProofSize: estimatedProofSize.toString() } })
|
||||
: t<string>('max ProofSize allowed')
|
||||
}
|
||||
onChange={isDisabled ? undefined : setProofSize}
|
||||
value={isDisabled ? undefined : ((isCall && withEstimate) ? BN_ZERO : proofSize)}
|
||||
/>
|
||||
)}
|
||||
onChange={isDisabled ? undefined : setMegaGas}
|
||||
value={isDisabled ? undefined : ((isCall && withEstimate) ? BN_ZERO : megaGas)}
|
||||
/>
|
||||
<div className='contracts--InputMegaGas-meter'>
|
||||
{t<string>('{{executionTime}}s execution time', { replace: { executionTime: executionTime.toFixed(3) } })}{', '}
|
||||
{t<string>('{{percentage}}% of block weight', { replace: { percentage: percentage.toFixed(2) } })}
|
||||
</div>
|
||||
</StyledDiv>
|
||||
<div className='contracts--Input-meter'>
|
||||
{t<string>('{{executionTime}}s execution time', { replace: { executionTime: executionTime.toFixed(3) } })}{', '}
|
||||
{t<string>('{{percentage}}% of block weight', { replace: { percentage: percentage.toFixed(2) } })}
|
||||
</div>
|
||||
</>
|
||||
: <>
|
||||
<InputNumber
|
||||
defaultValue={estimatedMg && isDisabled ? estimatedMg.toString() : undefined}
|
||||
isDisabled={isDisabled}
|
||||
isError={!isValid}
|
||||
isZeroable={isCall}
|
||||
label={
|
||||
estimatedMg && (isCall ? !withEstimate : true)
|
||||
? t<string>('max gas allowed (M, {{estimatedMg}} estimated)', { replace: { estimatedMg: estimatedMg.toString() } })
|
||||
: t<string>('max gas allowed (M)')
|
||||
}
|
||||
onChange={isDisabled ? undefined : setMegaGas}
|
||||
value={isDisabled ? undefined : ((isCall && withEstimate) ? BN_ZERO : megaGas)}
|
||||
>
|
||||
{(estimatedWeight || isCall) && (
|
||||
<Toggle
|
||||
label={
|
||||
isCall
|
||||
? t<string>('max read gas')
|
||||
: t<string>('use estimated gas')
|
||||
}
|
||||
onChange={setWithEstimate}
|
||||
value={withEstimate}
|
||||
/>
|
||||
)}
|
||||
</InputNumber>
|
||||
<div className='contracts--Input-meter'>
|
||||
{t<string>('{{executionTime}}s execution time', { replace: { executionTime: executionTime.toFixed(3) } })}{', '}
|
||||
{t<string>('{{percentage}}% of block weight', { replace: { percentage: percentage.toFixed(2) } })}
|
||||
</div>
|
||||
</>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
.contracts--InputMegaGas-meter {
|
||||
text-align: right;
|
||||
}
|
||||
`;
|
||||
|
||||
export default React.memo(InputMegaGas);
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Abi } from '@polkadot/api-contract';
|
||||
import type { WeightV2 } from '@polkadot/types/interfaces';
|
||||
import type { BN } from '@polkadot/util';
|
||||
|
||||
export interface CodeJson {
|
||||
@ -29,9 +30,15 @@ export interface UseWeight {
|
||||
executionTime: number;
|
||||
isEmpty: boolean;
|
||||
isValid: boolean;
|
||||
isWeightV2: boolean;
|
||||
megaGas: BN;
|
||||
megaRefTime: BN;
|
||||
proofSize: BN;
|
||||
percentage: number;
|
||||
setIsEmpty: React.Dispatch<boolean>
|
||||
setMegaGas: React.Dispatch<BN | undefined>;
|
||||
setMegaRefTime: React.Dispatch<BN | undefined>;
|
||||
setProofSize: React.Dispatch<BN | undefined>;
|
||||
weight: BN;
|
||||
weightV2: WeightV2;
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright 2017-2023 @polkadot/react-hooks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Weight } from '@polkadot/types/interfaces';
|
||||
import type { Weight, WeightV2 } from '@polkadot/types/interfaces';
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { UseWeight } from './types.js';
|
||||
|
||||
@ -9,11 +9,12 @@ import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { createNamedHook, useApi, useBlockInterval } from '@polkadot/react-hooks';
|
||||
import { convertWeight } from '@polkadot/react-hooks/useWeight';
|
||||
import { BN_MILLION, BN_TEN, BN_ZERO } from '@polkadot/util';
|
||||
import { BN_MILLION, BN_ONE, BN_TEN, BN_ZERO } from '@polkadot/util';
|
||||
|
||||
function useWeightImpl (): UseWeight {
|
||||
const { api } = useApi();
|
||||
const blockTime = useBlockInterval();
|
||||
const isWeightV2 = !!api.registry.createType<WeightV2>('Weight').proofSize;
|
||||
const [megaGas, _setMegaGas] = useState<BN>(
|
||||
convertWeight(
|
||||
api.consts.system.blockWeights
|
||||
@ -21,6 +22,16 @@ function useWeightImpl (): UseWeight {
|
||||
: api.consts.system.maximumBlockWeight as Weight
|
||||
).v1Weight.div(BN_MILLION).div(BN_TEN)
|
||||
);
|
||||
const [megaRefTime, _setMegaRefTime] = useState<BN>(
|
||||
api.consts.system.blockWeights
|
||||
? api.consts.system.blockWeights.perClass.normal.maxExtrinsic.unwrapOrDefault().refTime.toBn().div(BN_MILLION).div(BN_TEN)
|
||||
: BN_ZERO
|
||||
);
|
||||
const [proofSize, _setProofSize] = useState<BN>(
|
||||
api.consts.system.blockWeights
|
||||
? api.consts.system.blockWeights.perClass.normal.maxExtrinsic.unwrapOrDefault().proofSize.toBn()
|
||||
: BN_ZERO
|
||||
);
|
||||
const [isEmpty, setIsEmpty] = useState(false);
|
||||
|
||||
const setMegaGas = useCallback(
|
||||
@ -32,11 +43,33 @@ function useWeightImpl (): UseWeight {
|
||||
).v1Weight.div(BN_MILLION).div(BN_TEN)),
|
||||
[api]
|
||||
);
|
||||
const setMegaRefTime = useCallback(
|
||||
(value?: BN | undefined) =>
|
||||
_setMegaRefTime(
|
||||
value || api.consts.system.blockWeights
|
||||
? api.consts.system.blockWeights.perClass.normal.maxExtrinsic.unwrapOrDefault().refTime.toBn().div(BN_MILLION).div(BN_TEN)
|
||||
: BN_ZERO
|
||||
),
|
||||
[api]
|
||||
);
|
||||
const setProofSize = useCallback(
|
||||
(value?: BN | undefined) =>
|
||||
_setProofSize(
|
||||
value || api.consts.system.blockWeights
|
||||
? api.consts.system.blockWeights.perClass.normal.maxExtrinsic.unwrapOrDefault().proofSize.toBn()
|
||||
: BN_ZERO
|
||||
),
|
||||
[api]
|
||||
);
|
||||
|
||||
return useMemo((): UseWeight => {
|
||||
let executionTime = 0;
|
||||
let percentage = 0;
|
||||
let weight = BN_ZERO;
|
||||
let weightV2 = api.registry.createType('WeightV2', {
|
||||
proofSize: BN_ZERO,
|
||||
refTime: BN_ZERO
|
||||
});
|
||||
let isValid = false;
|
||||
|
||||
if (megaGas) {
|
||||
@ -53,17 +86,40 @@ function useWeightImpl (): UseWeight {
|
||||
isValid = !megaGas.isZero() && percentage < 65;
|
||||
}
|
||||
|
||||
if (isWeightV2 && megaRefTime && proofSize) {
|
||||
weightV2 = api.registry.createType('WeightV2', {
|
||||
proofSize,
|
||||
refTime: megaRefTime.mul(BN_MILLION)
|
||||
});
|
||||
executionTime = megaRefTime.mul(BN_MILLION).mul(blockTime).div(
|
||||
api.consts.system.blockWeights
|
||||
? api.consts.system.blockWeights.perClass.normal.maxExtrinsic.unwrapOrDefault().refTime.toBn()
|
||||
: BN_ONE
|
||||
).toNumber();
|
||||
percentage = (executionTime / blockTime.toNumber()) * 100;
|
||||
|
||||
// execution is 2s of 6s blocks, i.e. 1/3
|
||||
executionTime = executionTime / 3000;
|
||||
isValid = !megaRefTime.isZero(); // && percentage < 65;
|
||||
}
|
||||
|
||||
return {
|
||||
executionTime,
|
||||
isEmpty,
|
||||
isValid: isEmpty || isValid,
|
||||
isWeightV2,
|
||||
megaGas: megaGas || BN_ZERO,
|
||||
megaRefTime: megaRefTime || BN_ZERO,
|
||||
percentage,
|
||||
proofSize: proofSize || BN_ZERO,
|
||||
setIsEmpty,
|
||||
setMegaGas,
|
||||
weight
|
||||
setMegaRefTime,
|
||||
setProofSize,
|
||||
weight,
|
||||
weightV2
|
||||
};
|
||||
}, [api, blockTime, isEmpty, megaGas, setIsEmpty, setMegaGas]);
|
||||
}, [api, blockTime, isEmpty, isWeightV2, megaGas, megaRefTime, proofSize, setIsEmpty, setMegaGas, setMegaRefTime, setProofSize]);
|
||||
}
|
||||
|
||||
export default createNamedHook('useWeight', useWeightImpl);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user