Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ValidatorPrefs with commission #1959

Merged
merged 2 commits into from
Nov 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"packages/*"
],
"resolutions": {
"@polkadot/api": "^0.97.0-beta.39",
"@polkadot/api-contract": "^0.97.0-beta.39",
"@polkadot/api": "^0.97.0-beta.40",
"@polkadot/api-contract": "^0.97.0-beta.40",
"@polkadot/keyring": "^1.7.1",
"@polkadot/types": "^0.97.0-beta.39",
"@polkadot/types": "^0.97.0-beta.40",
"@polkadot/util": "^1.7.1",
"@polkadot/util-crypto": "^1.7.1",
"babel-core": "^7.0.0-bridge.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/app-contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/api-contract": "^0.97.0-beta.39",
"@polkadot/api-contract": "^0.97.0-beta.40",
"@polkadot/react-components": "^0.37.0-beta.134"
}
}
70 changes: 46 additions & 24 deletions packages/app-staking/src/Actions/Account/Validate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { ValidatorPrefs, ValidatorPrefs0to145 } from '@polkadot/types/interfaces';
import { ValidatorPrefs, ValidatorPrefsTo145, ValidatorPrefsTo196 } from '@polkadot/types/interfaces';
import { ApiProps } from '@polkadot/react-api/types';
import { I18nProps } from '@polkadot/react-components/types';

import BN from 'bn.js';
import React from 'react';
import { withApi, withMulti } from '@polkadot/react-api';
import { registry, withApi, withMulti } from '@polkadot/react-api';
import { Button, InputAddress, InputBalance, InputNumber, Modal, TxButton, TxComponent } from '@polkadot/react-components';
import { createType } from '@polkadot/types';

import InputValidationUnstakeThreshold from './InputValidationUnstakeThreshold';
import translate from '../../translate';
Expand All @@ -19,17 +20,24 @@ interface Props extends ApiProps, I18nProps {
isOpen: boolean;
onClose: () => void;
stashId: string;
validatorPrefs?: ValidatorPrefs | ValidatorPrefs0to145;
validatorPrefs?: ValidatorPrefs | ValidatorPrefsTo145 | ValidatorPrefsTo196;
}

interface State {
unstakeThreshold?: BN;
hasCommission: boolean;
commission: BN;
unstakeThreshold: BN;
unstakeThresholdError: string | null;
validatorPayment?: BN;
validatorPayment: BN;
}

const COMM_MUL = new BN(10000000);
const MAX_COMM = new BN(100);

class Validate extends TxComponent<Props, State> {
public state: State = {
hasCommission: !!(createType(registry, 'ValidatorPrefs').commission),
commission: new BN(0),
unstakeThreshold: new BN(3),
unstakeThresholdError: null,
validatorPayment: new BN(0)
Expand Down Expand Up @@ -87,7 +95,7 @@ class Validate extends TxComponent<Props, State> {

private renderButtons (): React.ReactNode {
const { controllerId, isSubstrateV2, onClose, t } = this.props;
const { unstakeThreshold, unstakeThresholdError, validatorPayment } = this.state;
const { commission, hasCommission, unstakeThreshold, unstakeThresholdError, validatorPayment } = this.state;

return (
<Modal.Actions>
Expand All @@ -108,7 +116,9 @@ class Validate extends TxComponent<Props, State> {
onClick={onClose}
params={[
isSubstrateV2
? { validatorPayment }
? hasCommission
? { commission }
: { validatorPayment }
: { unstakeThreshold, validatorPayment }
]}
tx='staking.validate'
Expand All @@ -121,8 +131,8 @@ class Validate extends TxComponent<Props, State> {

private renderContent (): React.ReactNode {
const { controllerId, isSubstrateV2, stashId, t, validatorPrefs } = this.props;
const { unstakeThreshold, unstakeThresholdError } = this.state;
const defaultThreshold = validatorPrefs && (validatorPrefs as ValidatorPrefs0to145).unstakeThreshold && (validatorPrefs as ValidatorPrefs0to145).unstakeThreshold.toBn();
const { hasCommission, unstakeThreshold, unstakeThresholdError } = this.state;
const defaultThreshold = validatorPrefs && (validatorPrefs as ValidatorPrefsTo145).unstakeThreshold && (validatorPrefs as ValidatorPrefsTo145).unstakeThreshold.toBn();

return (
<>
Expand Down Expand Up @@ -161,30 +171,42 @@ class Validate extends TxComponent<Props, State> {
/>
</>
)}
<InputBalance
className='medium'
defaultValue={validatorPrefs?.validatorPayment?.toBn()}
help={t('Amount taken up-front from the reward by the validator before splitting the remainder between themselves and the nominators')}
isZeroable
label={t('reward commission')}
onChange={this.onChangePayment}
onEnter={this.sendTx}
/>
{
hasCommission
? <InputNumber
className='medium'
help={t('The percentage reward (0-100) that should be applied for the validator')}
isZeroable
label={t('reward commission percentage')}
maxValue={MAX_COMM}
onChange={this.onChangeCommission}
onEnter={this.sendTx}
/>
: <InputBalance
className='medium'
defaultValue={(validatorPrefs as ValidatorPrefsTo196)?.validatorPayment?.toBn()}
help={t('Amount taken up-front from the reward by the validator before splitting the remainder between themselves and the nominators')}
isZeroable
label={t('validator payment')}
onChange={this.onChangePayment}
onEnter={this.sendTx}
/>
}
</Modal.Content>
</>
);
}

private onChangeCommission = (commission?: BN): void => {
commission && this.setState({ commission: commission.mul(COMM_MUL) });
}

private onChangePayment = (validatorPayment?: BN): void => {
if (validatorPayment) {
this.setState({ validatorPayment });
}
validatorPayment && this.setState({ validatorPayment });
}

private onChangeThreshold = (unstakeThreshold?: BN): void => {
if (unstakeThreshold) {
this.setState({ unstakeThreshold });
}
unstakeThreshold && this.setState({ unstakeThreshold });
}

private onUnstakeThresholdError = (unstakeThresholdError: string | null): void => {
Expand Down
10 changes: 8 additions & 2 deletions packages/app-staking/src/Targets/Validator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface Props extends I18nProps {
toggleFavorite: (accountId: string) => void;
}

function Validator ({ info: { accountId, bondOther, bondOwn, bondTotal, commission, isFavorite, isNominating, key, numNominators, rankOverall, rewardPayout }, toggleFavorite }: Props): React.ReactElement<Props> {
function Validator ({ info: { accountId, bondOther, bondOwn, bondTotal, commissionPer, isCommission, isFavorite, isNominating, key, numNominators, rankOverall, rewardPayout, validatorPayment }, toggleFavorite }: Props): React.ReactElement<Props> {
const _onFavorite = (): void => toggleFavorite(key);
const _onQueryStats = (): void => {
window.location.hash = `/staking/query/${key}`;
Expand All @@ -34,7 +34,13 @@ function Validator ({ info: { accountId, bondOther, bondOwn, bondTotal, commissi
</td>
<td className='number'>{formatNumber(rankOverall)}</td>
<td className='address'><AddressMini value={accountId} /></td>
<td className='number'><FormatBalance value={commission} /></td>
<td className='number'>
{
isCommission
? `${commissionPer.toFixed(2)}%`
: <FormatBalance value={validatorPayment} />
}
</td>
<td className='number'>{formatNumber(numNominators)}</td>
<td className='number'><FormatBalance value={bondTotal} /></td>
<td className='number'><FormatBalance value={bondOwn} /></td>
Expand Down
32 changes: 21 additions & 11 deletions packages/app-staking/src/Targets/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import { DerivedStakingElected } from '@polkadot/api-derive/types';
import { I18nProps } from '@polkadot/react-components/types';
import { ValidatorPrefs, ValidatorPrefsTo196 } from '@polkadot/types/interfaces';
import { ComponentProps } from '../types';
import { ValidatorInfo } from './types';

Expand All @@ -18,6 +19,8 @@ import translate from '../translate';
import Summary from './Summary';
import Validator from './Validator';

const PERBILL = new BN(1000000000);

interface Props extends I18nProps, ComponentProps {
}

Expand All @@ -34,9 +37,9 @@ function sortValidators (list: ValidatorInfo[]): ValidatorInfo[] {

return info;
})
.sort((a, b): number => b.commission.cmp(a.commission))
.sort((a, b): number => b.validatorPayment.cmp(a.validatorPayment))
.map((info, index): ValidatorInfo => {
info.rankCommission = index + 1;
info.rankPayment = index + 1;

return info;
})
Expand All @@ -48,13 +51,13 @@ function sortValidators (list: ValidatorInfo[]): ValidatorInfo[] {
})
.sort((a, b): number =>
a.rankReward === b.rankReward
? a.rankCommission === b.rankCommission
? a.rankPayment === b.rankPayment
? a.rankBonded === b.rankBonded
? 0
: a.rankBonded < b.rankBonded
? 1
: -1
: a.rankCommission < b.rankCommission
: a.rankPayment < b.rankPayment
? 1
: -1
: a.rankReward < b.rankReward
Expand Down Expand Up @@ -96,19 +99,24 @@ function Targets ({ className, sessionRewards, t }: Props): React.ReactElement<P
const numValidators = electedInfo.info.length;
const validators = sortValidators(
electedInfo.info.map(({ accountId, stakers, validatorPrefs }): ValidatorInfo => {
console.error((validatorPrefs as ValidatorPrefs).commission.toString());

const exposure = stakers || {
total: api.createType('Compact<Balance>'),
own: api.createType('Compact<Balance>'),
others: api.createType('Vec<IndividualExposure>')
};
const prefs = validatorPrefs || {
validatorPayment: api.createType('Compact<Balance>')
const prefs = (validatorPrefs as (ValidatorPrefs | ValidatorPrefsTo196)) || {
commission: api.createType('Compact<Perbill>')
};
const bondOwn = exposure.own.unwrap();
const bondTotal = exposure.total.unwrap();
const commission = prefs.validatorPayment.unwrap();
const perValidatorReward = lastReward.divn(numValidators);
const validatorPayment = (prefs as ValidatorPrefsTo196).validatorPayment
? (prefs as ValidatorPrefsTo196).validatorPayment.unwrap() as BN
: (prefs as ValidatorPrefs).commission.unwrap().mul(perValidatorReward).div(PERBILL);
const key = accountId.toString();
const rewardSplit = lastReward.divn(numValidators).sub(commission);
const rewardSplit = perValidatorReward.sub(validatorPayment);
const calcAmount = amount || new BN(0);
const rewardPayout = rewardSplit.gtn(0)
? calcAmount.mul(rewardSplit).div(calcAmount.add(bondTotal))
Expand All @@ -125,17 +133,19 @@ function Targets ({ className, sessionRewards, t }: Props): React.ReactElement<P
bondOwn,
bondShare: 0,
bondTotal,
isCommission: !!(prefs as ValidatorPrefs).commission,
isFavorite: favorites.includes(key),
isNominating,
key,
commission,
commissionPer: (((prefs as ValidatorPrefs).commission?.unwrap() || new BN(0)).muln(10000).div(PERBILL).toNumber() / 100),
numNominators: exposure.others.length,
rankBonded: 0,
rankCommission: 0,
rankOverall: 0,
rankPayment: 0,
rankReward: 0,
rewardPayout,
rewardSplit
rewardSplit,
validatorPayment
};
})
);
Expand Down
6 changes: 4 additions & 2 deletions packages/app-staking/src/Targets/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ export interface ValidatorInfo {
bondOwn: Balance;
bondShare: number;
bondTotal: Balance;
commission: Balance;
commissionPer: number;
isCommission: boolean;
isFavorite: boolean;
isNominating: boolean;
key: string;
numNominators: number;
rankBonded: number;
rankCommission: number;
rankOverall: number;
rankPayment: number;
rankReward: number;
rewardPayout: BN;
rewardSplit: BN;
validatorPayment: BN;
}
2 changes: 1 addition & 1 deletion packages/react-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/api": "^0.97.0-beta.39",
"@polkadot/api": "^0.97.0-beta.40",
"@polkadot/extension-dapp": "^0.14.0-beta.6",
"edgeware-node-types": "^1.0.10",
"rxjs-compat": "^6.5.3"
Expand Down
33 changes: 22 additions & 11 deletions packages/react-components/src/AddressInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.

import { DerivedBalances, DerivedStaking } from '@polkadot/api-derive/types';
import { ValidatorPrefs0to145 } from '@polkadot/types/interfaces';
import { ValidatorPrefsTo145 } from '@polkadot/types/interfaces';
import { BareProps, I18nProps } from './types';

import BN from 'bn.js';
Expand Down Expand Up @@ -42,6 +42,8 @@ export interface ValidatorPrefsType {
validatorPayment?: boolean;
}

const PERBILL = new BN(1000000000);

interface Props extends BareProps, I18nProps {
address: string;
balancesAll?: DerivedBalances;
Expand Down Expand Up @@ -204,22 +206,31 @@ function renderValidatorPrefs ({ stakingInfo, t, withValidatorPrefs = false }: P
return (
<>
<div />
{validatorPrefsDisplay.unstakeThreshold && (stakingInfo.validatorPrefs as ValidatorPrefs0to145).unstakeThreshold && (
{validatorPrefsDisplay.unstakeThreshold && (stakingInfo.validatorPrefs as any as ValidatorPrefsTo145).unstakeThreshold && (
<>
<Label label={t('unstake threshold')} />
<div className='result'>
{(stakingInfo.validatorPrefs as ValidatorPrefs0to145).unstakeThreshold.toString()}
{(stakingInfo.validatorPrefs as any as ValidatorPrefsTo145).unstakeThreshold.toString()}
</div>
</>
)}
{validatorPrefsDisplay.validatorPayment && stakingInfo.validatorPrefs.validatorPayment && (
<>
<Label label={t('commission')} />
<FormatBalance
className='result'
value={stakingInfo.validatorPrefs.validatorPayment}
/>
</>
{validatorPrefsDisplay.validatorPayment && (stakingInfo.validatorPrefs.commission || (stakingInfo.validatorPrefs as any as ValidatorPrefsTo145).validatorPayment) && (
(stakingInfo.validatorPrefs as any as ValidatorPrefsTo145).validatorPayment
? (
<>
<Label label={t('commission')} />
<FormatBalance
className='result'
value={(stakingInfo.validatorPrefs as any as ValidatorPrefsTo145).validatorPayment}
/>
</>
)
: (
<>
<Label label={t('commission')} />
<span>{(stakingInfo.validatorPrefs.commission.unwrap().muln(10000).div(PERBILL).toNumber() / 100).toFixed(2)}%</span>
</>
)
)}
</>
);
Expand Down
Loading