From f35b2d4428cf153321cf68f57439d60fea8d6594 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 18 Sep 2019 14:53:51 +0200 Subject: [PATCH] Update fees, mortal & tips (#1590) * Update fees, mortal & tips * Linting * Revert findCall * Fix fee calculation (take version byte into account) * Remove MAX (weights), add weight note * does not * --- packages/app-accounts/src/modals/Transfer.tsx | 4 +-- .../src/Actions/Account/BondExtra.tsx | 4 +-- .../src/InputBalanceBonded.tsx | 4 +-- packages/react-components/src/InputNumber.tsx | 4 ++- .../react-signer/src/Checks/ContractCall.tsx | 18 ++++++------- .../src/Checks/ContractDeploy.tsx | 18 ++++++------- packages/react-signer/src/Checks/index.tsx | 26 ++++++++++++------- packages/react-signer/src/Modal.tsx | 3 ++- packages/react-signer/src/Transaction.tsx | 5 +++- packages/react-signer/src/index.tsx | 25 ++++++++---------- 10 files changed, 58 insertions(+), 53 deletions(-) diff --git a/packages/app-accounts/src/modals/Transfer.tsx b/packages/app-accounts/src/modals/Transfer.tsx index e92e4a8e19..4ca06daa3e 100644 --- a/packages/app-accounts/src/modals/Transfer.tsx +++ b/packages/app-accounts/src/modals/Transfer.tsx @@ -14,7 +14,7 @@ import React from 'react'; import styled from 'styled-components'; import { Button, InputAddress, InputBalance, Modal, TxButton } from '@polkadot/react-components'; import { Available } from '@polkadot/react-query'; -import Checks, { calcSignatureLength } from '@polkadot/react-signer/Checks'; +import Checks, { calcTxLength } from '@polkadot/react-signer/Checks'; import { withApi, withCalls, withMulti } from '@polkadot/react-api'; import { ZERO_FEES } from '@polkadot/react-signer/Checks/constants'; import { bnMax } from '@polkadot/util'; @@ -214,7 +214,7 @@ class Transfer extends React.PureComponent { prevMax = maxBalance; extrinsic = api.tx.balances.transfer(recipientId, prevMax); - const txLength = calcSignatureLength(extrinsic, accountNonce); + const txLength = calcTxLength(extrinsic, accountNonce); const fees = transactionBaseFee .add(transactionByteFee.mul(txLength)) .add(transferFee) diff --git a/packages/app-staking/src/Actions/Account/BondExtra.tsx b/packages/app-staking/src/Actions/Account/BondExtra.tsx index 35d60bf9cf..e692b188a3 100644 --- a/packages/app-staking/src/Actions/Account/BondExtra.tsx +++ b/packages/app-staking/src/Actions/Account/BondExtra.tsx @@ -10,7 +10,7 @@ import { CalculateBalanceProps } from '../../types'; import BN from 'bn.js'; import React from 'react'; import { Available, Button, InputAddress, InputBalance, Modal, TxButton, TxComponent } from '@polkadot/react-components'; -import { calcSignatureLength } from '@polkadot/react-signer/Checks'; +import { calcTxLength } from '@polkadot/react-signer/Checks'; import { SubmittableExtrinsic } from '@polkadot/api/promise/types'; import { withCalls, withApi, withMulti } from '@polkadot/react-api'; import { ZERO_BALANCE, ZERO_FEES } from '@polkadot/react-signer/Checks/constants'; @@ -159,7 +159,7 @@ class BondExtra extends TxComponent { ? api.tx.staking.bondExtra(maxAdditional) : null; - const txLength = calcSignatureLength(extrinsic, system_accountNonce); + const txLength = calcTxLength(extrinsic, system_accountNonce); const fees = transactionBaseFee.add(transactionByteFee.mul(txLength)); maxBalance = bnMax(availableBalance.sub(fees), ZERO); diff --git a/packages/react-components/src/InputBalanceBonded.tsx b/packages/react-components/src/InputBalanceBonded.tsx index 7b290f5959..a06e33e6b5 100644 --- a/packages/react-components/src/InputBalanceBonded.tsx +++ b/packages/react-components/src/InputBalanceBonded.tsx @@ -10,7 +10,7 @@ import BN from 'bn.js'; import React from 'react'; import { ApiProps } from '@polkadot/react-api/types'; import { BitLengthOption } from '@polkadot/react-components/constants'; -import { calcSignatureLength } from '@polkadot/react-signer/Checks'; +import { calcTxLength } from '@polkadot/react-signer/Checks'; import { InputNumber } from '@polkadot/react-components'; import { SubmittableExtrinsic } from '@polkadot/api/promise/types'; import { withCalls, withMulti, withApi } from '@polkadot/react-api'; @@ -124,7 +124,7 @@ class InputBalanceBonded extends React.PureComponent { extrinsic = api.tx.staking.bonExtra(prevMax); } - const txLength = calcSignatureLength(extrinsic, system_accountNonce); + const txLength = calcTxLength(extrinsic, system_accountNonce); const fees = transactionBaseFee.add(transactionByteFee.mul(txLength)); maxBalance = bnMax(freeBalance.sub(fees), ZERO); diff --git a/packages/react-components/src/InputNumber.tsx b/packages/react-components/src/InputNumber.tsx index ed6d9a986f..fe615aafec 100644 --- a/packages/react-components/src/InputNumber.tsx +++ b/packages/react-components/src/InputNumber.tsx @@ -15,6 +15,8 @@ import Dropdown from './Dropdown'; import Input, { KEYS, KEYS_PRE } from './Input'; import translate from './translate'; +const ALLOW_MAX = false; + interface Props extends BareProps, I18nProps { autoFocus?: boolean; bitLength?: BitLength; @@ -115,7 +117,7 @@ class InputNumber extends React.PureComponent { type='text' value={value} > - {(withMax && !!maxValue) && this.renderMaxButton()} + {(ALLOW_MAX && withMax && !!maxValue) && this.renderMaxButton()} {isSi && this.renderSiDropdown()} ); diff --git a/packages/react-signer/src/Checks/ContractCall.tsx b/packages/react-signer/src/Checks/ContractCall.tsx index 1a5b4999d0..83f8ba9ef3 100644 --- a/packages/react-signer/src/Checks/ContractCall.tsx +++ b/packages/react-signer/src/Checks/ContractCall.tsx @@ -6,7 +6,7 @@ import { DerivedContractFees } from '@polkadot/api-derive/types'; import { ExtraFees as State } from './types'; import BN from 'bn.js'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Compact, UInt } from '@polkadot/types'; interface Props { @@ -15,14 +15,14 @@ interface Props { onChange: (fees: State) => void; } -export default class ContractCall extends React.PureComponent { - public state: State = { +export default function ContractCall ({ endowment, fees, onChange }: Props): React.ReactElement | null { + const [state, setState] = useState({ extraFees: new BN(0), extraAmount: new BN(0), extraWarn: false - }; + }); - public static getDerivedStateFromProps ({ endowment, fees, onChange }: Props, state: State): State { + useEffect((): void => { const extraFees = new BN(fees.callBaseFee); const extraAmount = endowment instanceof Compact ? endowment.toBn() @@ -38,10 +38,8 @@ export default class ContractCall extends React.PureComponent { onChange(update); } - return update; - } + setState(update); + }, [endowment, fees]); - public render (): React.ReactNode { - return null; - } + return null; } diff --git a/packages/react-signer/src/Checks/ContractDeploy.tsx b/packages/react-signer/src/Checks/ContractDeploy.tsx index d10348975a..539c5d7b87 100644 --- a/packages/react-signer/src/Checks/ContractDeploy.tsx +++ b/packages/react-signer/src/Checks/ContractDeploy.tsx @@ -6,7 +6,7 @@ import { DerivedContractFees } from '@polkadot/api-derive/types'; import { ExtraFees as State } from './types'; import BN from 'bn.js'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Compact, UInt } from '@polkadot/types'; interface Props { @@ -15,14 +15,14 @@ interface Props { onChange: (fees: State) => void; } -export default class ContractDeploy extends React.PureComponent { - public state: State = { +export default function ContractDeploy ({ endowment, fees, onChange }: Props): React.ReactElement | null { + const [state, setState] = useState({ extraFees: new BN(0), extraAmount: new BN(0), extraWarn: false - }; + }); - public static getDerivedStateFromProps ({ endowment, fees, onChange }: Props, state: State): State { + useEffect((): void => { const extraFees = new BN(fees.createBaseFee).add(fees.contractFee); const extraAmount = endowment instanceof Compact ? endowment.toBn() @@ -38,10 +38,8 @@ export default class ContractDeploy extends React.PureComponent { onChange(update); } - return update; - } + setState(update); + }, [endowment, fees]); - public render (): React.ReactNode { - return null; - } + return null; } diff --git a/packages/react-signer/src/Checks/index.tsx b/packages/react-signer/src/Checks/index.tsx index 525f6cb192..06ec839924 100644 --- a/packages/react-signer/src/Checks/index.tsx +++ b/packages/react-signer/src/Checks/index.tsx @@ -44,17 +44,22 @@ interface Props extends ApiProps, I18nProps { isSendable: boolean; onChange?: (hasAvailable: boolean) => void; system_accountNonce?: BN; + tip?: BN; } -const LENGTH_PUBLICKEY = 32 + 1; // publicKey + prefix -const LENGTH_SIGNATURE = 64; -const LENGTH_ERA = 1; -export const SIGNATURE_SIZE = LENGTH_PUBLICKEY + LENGTH_SIGNATURE + LENGTH_ERA; +const LENGTH_ADDRESS = 32 + 1; // publicKey + prefix +const LENGTH_ERA = 2; // assuming mortals +const LENGTH_SIGNATURE = 64; // assuming ed25519 or sr25519 +const LENGTH_VERSION = 1; // 0x80 & version -export const calcSignatureLength = (extrinsic?: IExtrinsic | null, accountNonce?: BN): BN => { +export const calcTxLength = (extrinsic?: IExtrinsic | null, nonce?: BN, tip?: BN): BN => { return new BN( - SIGNATURE_SIZE + - (accountNonce ? compactToU8a(accountNonce).length : 0) + + LENGTH_VERSION + + LENGTH_ADDRESS + + LENGTH_SIGNATURE + + LENGTH_ERA + + compactToU8a(nonce || 0).length + + compactToU8a(tip || 0).length + (extrinsic ? extrinsic.encodedLength : 0) ); }; @@ -73,7 +78,7 @@ export class FeeDisplay extends React.PureComponent { overLimit: false }; - public static getDerivedStateFromProps ({ accountId, balances_all = ZERO_BALANCE, api, extrinsic, balances_fees = ZERO_FEES_BALANCES, system_accountNonce = new BN(0) }: Props, prevState: State): State | null { + public static getDerivedStateFromProps ({ accountId, balances_all = ZERO_BALANCE, api, extrinsic, balances_fees = ZERO_FEES_BALANCES, system_accountNonce = new BN(0), tip }: Props, prevState: State): State | null { if (!accountId || !extrinsic) { return null; } @@ -81,7 +86,7 @@ export class FeeDisplay extends React.PureComponent { const fn = api.findCall(extrinsic.callIndex); const extMethod = fn.method; const extSection = fn.section; - const txLength = calcSignatureLength(extrinsic, system_accountNonce); + const txLength = calcTxLength(extrinsic, system_accountNonce, tip); const isSameExtrinsic = prevState.extMethod === extMethod && prevState.extSection === extSection; const extraAmount = isSameExtrinsic @@ -195,11 +200,12 @@ export class FeeDisplay extends React.PureComponent { fees: formatBalance(allFees) } })} -
{t('{{total}} total transaction amount (fees + value)', { +
{t('{{total}} estimated total amount (fees + value)', { replace: { total: formatBalance(allTotal) } })}
+
{t('Estimation does not account for the transaction weight')}
); } diff --git a/packages/react-signer/src/Modal.tsx b/packages/react-signer/src/Modal.tsx index 3b567dc677..73e07607e8 100644 --- a/packages/react-signer/src/Modal.tsx +++ b/packages/react-signer/src/Modal.tsx @@ -190,7 +190,7 @@ class Signer extends React.PureComponent { } private renderContent (): React.ReactNode { - const { currentItem, isQrScanning, isQrVisible, isSendable, qrAddress, qrPayload } = this.state; + const { currentItem, isQrScanning, isQrVisible, isSendable, qrAddress, qrPayload, tip } = this.state; if (!currentItem) { return null; @@ -200,6 +200,7 @@ class Signer extends React.PureComponent { { diff --git a/packages/react-signer/src/Transaction.tsx b/packages/react-signer/src/Transaction.tsx index abd70dfb9e..5fefe1a42e 100644 --- a/packages/react-signer/src/Transaction.tsx +++ b/packages/react-signer/src/Transaction.tsx @@ -5,6 +5,7 @@ import { I18nProps } from '@polkadot/react-components/types'; import { QueueTx } from '@polkadot/react-components/Status/types'; +import BN from 'bn.js'; import React from 'react'; import { GenericCall } from '@polkadot/types'; import { Call, InputAddress, Modal } from '@polkadot/react-components'; @@ -16,10 +17,11 @@ interface Props extends I18nProps { children?: React.ReactNode; hideDetails?: boolean; isSendable: boolean; + tip?: BN; value: QueueTx; } -function Transaction ({ children, hideDetails, isSendable, value: { accountId, extrinsic, isUnsigned }, t }: Props): React.ReactElement | null { +function Transaction ({ children, hideDetails, isSendable, value: { accountId, extrinsic, isUnsigned }, t, tip }: Props): React.ReactElement | null { if (!extrinsic) { return null; } @@ -55,6 +57,7 @@ function Transaction ({ children, hideDetails, isSendable, value: { accountId, e accountId={accountId} extrinsic={extrinsic} isSendable={isSendable} + tip={tip} /> )} diff --git a/packages/react-signer/src/index.tsx b/packages/react-signer/src/index.tsx index a495da9b85..0d6902096e 100644 --- a/packages/react-signer/src/index.tsx +++ b/packages/react-signer/src/index.tsx @@ -3,12 +3,11 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { BareProps } from '@polkadot/react-components/types'; -import { QueueProps } from '@polkadot/react-components/Status/types'; import './index.css'; -import React from 'react'; -import { QueueConsumer } from '@polkadot/react-components/Status/Context'; +import React, { useContext } from 'react'; +import QueueContext from '@polkadot/react-components/Status/Context'; import Modal from './Modal'; @@ -17,20 +16,18 @@ interface Props extends BareProps { } export default function Signer ({ children, className, style }: Props): React.ReactElement { + const { txqueue, queueSetTxStatus } = useContext(QueueContext); + return ( <> {children} - - {({ txqueue, queueSetTxStatus }: QueueProps): React.ReactNode => ( - - )} - + ); }