Remove 64 fallback (#3575)
* Remove 64 fallback * toString * Protection * No slice-and-dice when in-range * linting * Ref for labels
This commit is contained in:
parent
4a1accf0ab
commit
eba24d5ca4
@ -6,7 +6,6 @@ import React from 'react';
|
||||
import { AddressMini, Expander } from '@polkadot/react-components';
|
||||
import { useApi } from '@polkadot/react-hooks';
|
||||
|
||||
import { MAX_NOM_PAYOUTS } from '../../constants';
|
||||
import { useTranslation } from '../../translate';
|
||||
import useInactives from '../useInactives';
|
||||
|
||||
@ -20,7 +19,7 @@ function ListNominees ({ nominating, stashId }: Props): React.ReactElement<Props
|
||||
const { api } = useApi();
|
||||
const { nomsActive, nomsChilled, nomsInactive, nomsOver, nomsWaiting } = useInactives(stashId, nominating);
|
||||
|
||||
const max = (api.consts.staking?.maxNominatorRewardedPerValidator || MAX_NOM_PAYOUTS).toString();
|
||||
const max = api.consts.staking?.maxNominatorRewardedPerValidator?.toString();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -10,8 +10,6 @@ import { ApiPromise } from '@polkadot/api';
|
||||
import { useApi, useCall, useIsMountedRef } from '@polkadot/react-hooks';
|
||||
import { Option } from '@polkadot/types';
|
||||
|
||||
import { MAX_NOM_PAYOUTS } from '../constants';
|
||||
|
||||
interface Inactives {
|
||||
nomsActive?: string[];
|
||||
nomsChilled?: string[];
|
||||
@ -21,7 +19,7 @@ interface Inactives {
|
||||
}
|
||||
|
||||
function extractState (api: ApiPromise, stashId: string, slashes: Option<SlashingSpans>[], nominees: string[], activeEra: EraIndex, submittedIn: EraIndex, exposures: Exposure[]): Inactives {
|
||||
const max = (api.consts.staking?.maxNominatorRewardedPerValidator || MAX_NOM_PAYOUTS);
|
||||
const max = api.consts.staking?.maxNominatorRewardedPerValidator;
|
||||
|
||||
// chilled
|
||||
const nomsChilled = nominees.filter((_, index): boolean => {
|
||||
@ -38,7 +36,7 @@ function extractState (api: ApiPromise, stashId: string, slashes: Option<Slashin
|
||||
const nomsOver = exposures
|
||||
.map(({ others }) => others.sort((a, b) => b.value.unwrap().cmp(a.value.unwrap())))
|
||||
.map((others, index) =>
|
||||
max.gtn(others.map(({ who }) => who.toString()).indexOf(stashId))
|
||||
!max || max.gtn(others.map(({ who }) => who.toString()).indexOf(stashId))
|
||||
? null
|
||||
: nominees[index]
|
||||
)
|
||||
|
||||
@ -7,7 +7,6 @@ import styled from 'styled-components';
|
||||
import { Badge, Icon } from '@polkadot/react-components';
|
||||
import { useApi } from '@polkadot/react-hooks';
|
||||
|
||||
import { MAX_NOM_PAYOUTS } from './constants';
|
||||
import { useTranslation } from './translate';
|
||||
|
||||
interface Props {
|
||||
@ -51,7 +50,7 @@ function Ledgend ({ className }: Props): React.ReactElement<Props> {
|
||||
<span>
|
||||
<Badge
|
||||
color='red'
|
||||
info={(api.consts.staking?.maxNominatorRewardedPerValidator || MAX_NOM_PAYOUTS).toString()}
|
||||
info={api.consts.staking?.maxNominatorRewardedPerValidator?.toString() || '64'}
|
||||
/>
|
||||
{t('Oversubscribed')}
|
||||
</span>
|
||||
|
||||
@ -6,8 +6,6 @@ import React from 'react';
|
||||
import { Badge } from '@polkadot/react-components';
|
||||
import { useApi } from '@polkadot/react-hooks';
|
||||
|
||||
import { MAX_NOM_PAYOUTS } from './constants';
|
||||
|
||||
interface Props {
|
||||
numNominators?: number;
|
||||
}
|
||||
@ -15,9 +13,9 @@ interface Props {
|
||||
function MaxBadge ({ numNominators }: Props): React.ReactElement<Props> | null {
|
||||
const { api } = useApi();
|
||||
|
||||
const max = (api.consts.staking?.maxNominatorRewardedPerValidator || MAX_NOM_PAYOUTS);
|
||||
const max = api.consts.staking?.maxNominatorRewardedPerValidator;
|
||||
|
||||
if (!numNominators || max.gten(numNominators)) {
|
||||
if (!numNominators || !max || max.gten(numNominators)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -9,21 +9,25 @@ import React, { useMemo } from 'react';
|
||||
import { AddressMini, Expander } from '@polkadot/react-components';
|
||||
import { useApi } from '@polkadot/react-hooks';
|
||||
import { FormatBalance } from '@polkadot/react-query';
|
||||
|
||||
import { MAX_NOM_PAYOUTS } from '../../constants';
|
||||
import { BN_ZERO } from '@polkadot/util';
|
||||
|
||||
interface Props {
|
||||
stakeOther?: BN;
|
||||
nominators: [string, Balance][];
|
||||
}
|
||||
|
||||
function StakeOther ({ nominators }: Props): React.ReactElement<Props> {
|
||||
function StakeOther ({ nominators, stakeOther }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
|
||||
const [rewarded, rewardedTotal, unrewarded, unrewardedTotal] = useMemo(
|
||||
(): [[string, Balance][], BN, [string, Balance][], BN] => {
|
||||
const sorted = nominators.sort((a, b) => b[1].cmp(a[1]));
|
||||
const max = (api.consts.staking?.maxNominatorRewardedPerValidator || MAX_NOM_PAYOUTS).toNumber();
|
||||
const max = api.consts.staking?.maxNominatorRewardedPerValidator?.toNumber();
|
||||
|
||||
if (!max || sorted.length <= max) {
|
||||
return [sorted, stakeOther || BN_ZERO, [], BN_ZERO];
|
||||
}
|
||||
|
||||
const rewarded = sorted.slice(0, max);
|
||||
const rewardedTotal = rewarded.reduce((total, [, value]) => total.iadd(value), new BN(0));
|
||||
const unrewarded = sorted.slice(max);
|
||||
@ -31,7 +35,7 @@ function StakeOther ({ nominators }: Props): React.ReactElement<Props> {
|
||||
|
||||
return [rewarded, rewardedTotal, unrewarded, unrewardedTotal];
|
||||
},
|
||||
[api, nominators]
|
||||
[api, nominators, stakeOther]
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@ -6,14 +6,14 @@ import { DeriveStakingOverview } from '@polkadot/api-derive/types';
|
||||
import { StakerState } from '@polkadot/react-hooks/types';
|
||||
import { SortedTargets, TargetSortBy, ValidatorInfo } from '../types';
|
||||
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Button, Icon, InputBalance, Table, Toggle } from '@polkadot/react-components';
|
||||
import { useApi, useAvailableSlashes } from '@polkadot/react-hooks';
|
||||
|
||||
import ElectionBanner from '../ElectionBanner';
|
||||
import Filtering from '../Filtering';
|
||||
import { MAX_NOMINATIONS, MAX_NOM_PAYOUTS } from '../constants';
|
||||
import { MAX_NOMINATIONS } from '../constants';
|
||||
import { useTranslation } from '../translate';
|
||||
import Nominate from './Nominate';
|
||||
import Summary from './Summary';
|
||||
@ -109,41 +109,41 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak
|
||||
);
|
||||
|
||||
const _selectProfitable = useCallback(
|
||||
() => setSelected(
|
||||
(validators || []).reduce((result: string[], { hasIdentity, isElected, isFavorite, key, numNominators, rewardPayout }): string[] => {
|
||||
if ((api.consts.staking?.maxNominatorRewardedPerValidator || MAX_NOM_PAYOUTS).gtn(numNominators) && (result.length < MAX_NOMINATIONS) && (hasIdentity || !withIdentity) && (isElected || isFavorite) && !rewardPayout.isZero()) {
|
||||
() => setSelected((): string[] => {
|
||||
const max = api.consts.staking?.maxNominatorRewardedPerValidator;
|
||||
|
||||
return (validators || []).reduce((result: string[], { hasIdentity, isElected, isFavorite, key, numNominators, rewardPayout }): string[] => {
|
||||
if ((result.length < MAX_NOMINATIONS) && (hasIdentity || !withIdentity) && (isElected || isFavorite) && !rewardPayout.isZero() && (!max || max.gtn(numNominators))) {
|
||||
result.push(key);
|
||||
}
|
||||
|
||||
return result;
|
||||
}, [])
|
||||
),
|
||||
}, []);
|
||||
}),
|
||||
[api, validators, withIdentity]
|
||||
);
|
||||
|
||||
const labels = useMemo(
|
||||
(): Record<string, string> => ({
|
||||
rankBondOther: t<string>('other stake'),
|
||||
rankBondOwn: t<string>('own stake'),
|
||||
rankBondTotal: t<string>('total stake'),
|
||||
rankComm: t<string>('comm.'),
|
||||
rankNumNominators: t<string>('nominators'),
|
||||
rankOverall: t<string>('profit/era')
|
||||
}),
|
||||
[t]
|
||||
);
|
||||
const labelsRef = useRef({
|
||||
rankBondOther: t<string>('other stake'),
|
||||
rankBondOwn: t<string>('own stake'),
|
||||
rankBondTotal: t<string>('total stake'),
|
||||
rankComm: t<string>('comm.'),
|
||||
rankNumNominators: t<string>('nominators'),
|
||||
rankOverall: t<string>('profit/era')
|
||||
});
|
||||
|
||||
const header = useMemo(() => [
|
||||
[t('validators'), 'start', 3],
|
||||
...['rankNumNominators', 'rankComm', 'rankBondTotal', 'rankBondOwn', 'rankBondOther', 'rankOverall'].map((header) => [
|
||||
<>{labels[header]}<Icon icon={sortBy === header ? (sortFromMax ? 'chevron-down' : 'chevron-up') : 'minus'} /></>,
|
||||
`${sorted ? `isClickable ${sortBy === header ? 'highlight--border' : ''} number` : 'number'} ${CLASSES[header] || ''}`,
|
||||
1,
|
||||
(): void => _sort(header as 'rankComm')
|
||||
]),
|
||||
...(['rankNumNominators', 'rankComm', 'rankBondTotal', 'rankBondOwn', 'rankBondOther', 'rankOverall'] as (keyof typeof labelsRef.current)[])
|
||||
.map((header) => [
|
||||
<>{labelsRef.current[header]}<Icon icon={sortBy === header ? (sortFromMax ? 'chevron-down' : 'chevron-up') : 'minus'} /></>,
|
||||
`${sorted ? `isClickable ${sortBy === header ? 'highlight--border' : ''} number` : 'number'} ${CLASSES[header] || ''}`,
|
||||
1,
|
||||
() => _sort(header as 'rankComm')
|
||||
]),
|
||||
[],
|
||||
[]
|
||||
], [_sort, labels, sortBy, sorted, sortFromMax, t]);
|
||||
], [_sort, labelsRef, sortBy, sorted, sortFromMax, t]);
|
||||
|
||||
const filter = useMemo(() => (
|
||||
sorted && (
|
||||
|
||||
@ -2,10 +2,6 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
|
||||
export const MAX_NOMINATIONS = 16;
|
||||
|
||||
export const MAX_NOM_PAYOUTS = new BN(64);
|
||||
|
||||
export const STORE_FAVS_BASE = 'staking:favorites';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user