Add estimation toggle (#3897)

* Add estimation toggle

* Adjust percentage display
This commit is contained in:
Jaco Greeff 2020-10-19 14:15:46 +02:00 committed by GitHub
parent b288c2f0f3
commit 770501b6ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 19 deletions

View File

@ -32,7 +32,7 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM
const { t } = useTranslation();
const message = contract.abi.messages[messageIndex];
const [accountId, setAccountId] = useAccountId();
const [estimatedMg, setEstimatedMg] = useState<BN | null>(null);
const [estimatedWeight, setEstimatedWeight] = useState<BN | null>(null);
const [value, isValueValid, setEndowment] = useFormField<BN>(BN_ZERO);
const [outcomes, setOutcomes] = useState<CallResult[]>([]);
const [execTx, setExecTx] = useState<SubmittableExtrinsic<'promise'> | null>(null);
@ -43,7 +43,7 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM
const dbParams = useDebounce(params);
useEffect((): void => {
setEstimatedMg(null);
setEstimatedWeight(null);
setParams([]);
}, [contract, messageIndex]);
@ -65,12 +65,12 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM
contract
.read(message, message.isPayable ? dbValue : 0, -1, ...dbParams)
.send(accountId)
.then(({ result }) => setEstimatedMg(
.then(({ result }) => setEstimatedWeight(
result.isSuccess
? result.asSuccess.gasConsumed.divn(1e6).iaddn(1)
? result.asSuccess.gasConsumed
: null
))
.catch(() => setEstimatedMg(null));
.catch(() => setEstimatedWeight(null));
}, [accountId, contract, message, dbParams, dbValue]);
const _onSubmitRpc = useCallback(
@ -161,9 +161,8 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM
/>
)}
<InputMegaGas
estimatedWeight={estimatedWeight}
help={t<string>('The maximum amount of gas to use for this contract call. If the call requires more, it will fail.')}
label={t<string>('max gas allowed (M)')}
labelExtra={estimatedMg && t<string>('estimated gas (M) {{estimatedMg}}', { replace: { estimatedMg: estimatedMg.toString() } })}
{...weight}
/>
{message.isMutating && (

View File

@ -160,7 +160,6 @@ function Deploy ({ codeHash, constructorIndex = 0, onClose, setConstructorIndex
/>
<InputMegaGas
help={t<string>('The maximum amount of gas that can be used by this deployment, if the code requires more, the deployment will fail.')}
label={t<string>('max gas allowed (M)')}
{...weight}
/>
</Modal.Content>

View File

@ -2,40 +2,70 @@
// SPDX-License-Identifier: Apache-2.0
import BN from 'bn.js';
import React from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import styled from 'styled-components';
import { InputNumber } from '@polkadot/react-components';
import { InputNumber, Toggle } from '@polkadot/react-components';
import { useTranslation } from '../translate';
interface Props {
className?: string;
estimatedWeight?: BN | null;
executionTime: number;
help: React.ReactNode;
isValid: boolean;
label: React.ReactNode;
labelExtra?: React.ReactNode;
megaGas: BN;
percentage: number;
setMegaGas: (value?: BN) => void;
}
function InputMegaGas ({ className, executionTime, help, isValid, label, labelExtra, megaGas, percentage, setMegaGas }: Props): React.ReactElement<Props> {
function InputMegaGas ({ className, estimatedWeight, executionTime, help, isValid, megaGas, percentage, setMegaGas }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [withEstimate, setWithEstimate] = useState(false);
const estimatedMg = useMemo(
() => estimatedWeight
? estimatedWeight.divn(1e6).iaddn(1)
: null,
[estimatedWeight]
);
const label = useMemo(
() => estimatedMg
? t<string>('max gas allowed (M, {{estimatedMg}} estimated)', { replace: { estimatedMg: estimatedMg.toString() } })
: t<string>('max gas allowed (M)'),
[estimatedMg, t]
);
useEffect((): void => {
estimatedMg && withEstimate && setMegaGas(estimatedMg);
}, [estimatedMg, setMegaGas, withEstimate]);
const isDisabled = !!estimatedMg && withEstimate;
return (
<div className={className}>
<InputNumber
defaultValue={estimatedMg && isDisabled ? estimatedMg.toString() : undefined}
help={help}
isDisabled={isDisabled}
isError={!isValid}
label={label}
labelExtra={labelExtra}
onChange={setMegaGas}
value={megaGas}
/>
onChange={isDisabled ? undefined : setMegaGas}
value={isDisabled ? undefined : megaGas}
>
{estimatedWeight && (
<Toggle
isOverlay
label={t<string>('use estimated gas')}
onChange={setWithEstimate}
value={withEstimate}
/>
)}
</InputNumber>
<div className='contracts--InputMegaGas-meter'>
{t<string>('{{executionTime}}s execution time', { replace: { executionTime: executionTime.toFixed(3) } })}{', '}
{t<string>('{{percentage}}% of block weight', { replace: { percentage } })}
{t<string>('{{percentage}}% of block weight', { replace: { percentage: percentage.toFixed(2) } })}
</div>
</div>
);

View File

@ -24,7 +24,7 @@ export default function useWeight (initialValue?: BN): UseWeight {
const weight = megaGas.mul(BN_MILLION);
const executionTime = weight.muln(blockTime).div(api.consts.system.maximumBlockWeight).toNumber();
const percentage = Math.round((executionTime / blockTime) * 100);
const percentage = (executionTime / blockTime) * 100;
// execution is 2s of 6s blocks, i.e. 1/3
return [executionTime / 3000, percentage, weight, !megaGas.isZero() && percentage < 100];