Skip to content

Commit

Permalink
Update ValidatorPrefs with commission (#1959)
Browse files Browse the repository at this point in the history
* Update ValidatorPrefs with commission

* Bump API
  • Loading branch information
jacogr committed Nov 28, 2019
1 parent 3ed017f commit f6976e1
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 100 deletions.
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

0 comments on commit f6976e1

Please sign in to comment.