diff --git a/packages/page-contracts/src/Contracts/Call.tsx b/packages/page-contracts/src/Contracts/Call.tsx index 1b7b7e66ac..20c6ad56c5 100644 --- a/packages/page-contracts/src/Contracts/Call.tsx +++ b/packages/page-contracts/src/Contracts/Call.tsx @@ -28,6 +28,8 @@ interface Props { onClose: () => void; } +const MAX_CALL_WEIGHT = new BN(5_000_000_000_000).subn(1); + function Call ({ className = '', contract, messageIndex, onCallResult, onChangeMessage, onClose }: Props): React.ReactElement | null { const { t } = useTranslation(); const message = contract.abi.messages[messageIndex]; @@ -76,7 +78,7 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM if (!accountId || !message || !value || !weight) return; contract - .read(message, message.isPayable ? value : 0, weight.weight, ...params) + .read(message, message.isPayable ? value : 0, weight.isEmpty ? -1 : weight.weight, ...params) .send(accountId) .then((result): void => { setOutcomes([{ @@ -159,8 +161,9 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM /> )} ('The maximum amount of gas to use for this contract call. If the call requires more, it will fail.')} + isCall={!message.isMutating} weight={weight} /> {message.isMutating && ( diff --git a/packages/page-contracts/src/shared/InputMegaGas.tsx b/packages/page-contracts/src/shared/InputMegaGas.tsx index 4f67028494..1365537e08 100644 --- a/packages/page-contracts/src/shared/InputMegaGas.tsx +++ b/packages/page-contracts/src/shared/InputMegaGas.tsx @@ -7,6 +7,7 @@ import BN from 'bn.js'; import React, { useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; import { InputNumber, Toggle } from '@polkadot/react-components'; +import { BN_ZERO } from '@polkadot/util'; import { useTranslation } from '../translate'; @@ -14,16 +15,19 @@ interface Props { className?: string; estimatedWeight?: BN; help: React.ReactNode; + isCall?: boolean; weight: UseWeight; } -function InputMegaGas ({ className, estimatedWeight, help, weight: { executionTime, isValid, megaGas, percentage, setMegaGas } }: Props): React.ReactElement { +const MEGA = new BN(1_000_000); + +function InputMegaGas ({ className, estimatedWeight, help, isCall, weight: { executionTime, isValid, megaGas, percentage, setIsEmpty, setMegaGas } }: Props): React.ReactElement { const { t } = useTranslation(); - const [withEstimate, setWithEstimate] = useState(false); + const [withEstimate, setWithEstimate] = useState(true); const estimatedMg = useMemo( () => estimatedWeight - ? estimatedWeight.divn(1e6).iaddn(1) + ? estimatedWeight.div(MEGA).iaddn(1) : null, [estimatedWeight] ); @@ -32,6 +36,10 @@ function InputMegaGas ({ className, estimatedWeight, help, weight: { executionTi withEstimate && estimatedMg && setMegaGas(estimatedMg); }, [estimatedMg, setMegaGas, withEstimate]); + useEffect((): void => { + setIsEmpty(withEstimate && !!isCall); + }, [isCall, setIsEmpty, withEstimate]); + const isDisabled = !!estimatedMg && withEstimate; return ( @@ -41,18 +49,23 @@ function InputMegaGas ({ className, estimatedWeight, help, weight: { executionTi help={help} isDisabled={isDisabled} isError={!isValid} + isZeroable={isCall} label={ - estimatedMg + estimatedMg && (isCall ? !withEstimate : true) ? t('max gas allowed (M, {{estimatedMg}} estimated)', { replace: { estimatedMg: estimatedMg.toString() } }) : t('max gas allowed (M)') } onChange={isDisabled ? undefined : setMegaGas} - value={isDisabled ? undefined : megaGas} + value={isDisabled ? undefined : ((isCall && withEstimate) ? BN_ZERO : megaGas)} > - {estimatedWeight && ( + {(estimatedWeight || isCall) && ( ('use estimated gas')} + label={ + isCall + ? t('max read gas') + : t('use estimated gas') + } onChange={setWithEstimate} value={withEstimate} /> diff --git a/packages/page-contracts/src/types.ts b/packages/page-contracts/src/types.ts index 43ba9d13a2..a86c91aacb 100644 --- a/packages/page-contracts/src/types.ts +++ b/packages/page-contracts/src/types.ts @@ -27,9 +27,11 @@ export interface ContractJsonOld { export interface UseWeight { executionTime: number; + isEmpty: boolean; isValid: boolean; megaGas: BN; percentage: number; + setIsEmpty: React.Dispatch setMegaGas: React.Dispatch; weight: BN; } diff --git a/packages/page-contracts/src/useWeight.ts b/packages/page-contracts/src/useWeight.ts index 071fbea487..c74ba6e710 100644 --- a/packages/page-contracts/src/useWeight.ts +++ b/packages/page-contracts/src/useWeight.ts @@ -8,12 +8,13 @@ import { useCallback, useMemo, useState } from 'react'; import { useApi, useBlockTime } from '@polkadot/react-hooks'; import { BN_TEN, BN_ZERO } from '@polkadot/util'; -const BN_MILLION = new BN(1e6); +const BN_MILLION = new BN(1_000_000); export default function useWeight (): UseWeight { const { api } = useApi(); const [blockTime] = useBlockTime(); const [megaGas, _setMegaGas] = useState(api.consts.system.maximumBlockWeight.div(BN_MILLION).div(BN_TEN)); + const [isEmpty, setIsEmpty] = useState(false); const setMegaGas = useCallback( (value?: BN | undefined) => _setMegaGas(value || api.consts.system.maximumBlockWeight.div(BN_MILLION).div(BN_TEN)), @@ -38,11 +39,13 @@ export default function useWeight (): UseWeight { return { executionTime, - isValid, + isEmpty, + isValid: isEmpty || isValid, megaGas: megaGas || BN_ZERO, percentage, + setIsEmpty, setMegaGas, weight }; - }, [api, blockTime, megaGas, setMegaGas]); + }, [api, blockTime, isEmpty, megaGas, setIsEmpty, setMegaGas]); }