diff --git a/packages/page-staking/src/Targets/index.tsx b/packages/page-staking/src/Targets/index.tsx index 72b6871586..3f996b9c9d 100644 --- a/packages/page-staking/src/Targets/index.tsx +++ b/packages/page-staking/src/Targets/index.tsx @@ -53,7 +53,8 @@ const CLASSES: Record = { rankComm: 'media--1100', rankNumNominators: 'media--1200' }; -const MAX_COMM_FILTER = 20; +const MAX_CAP_PERCENT = 75; +const MAX_COMM_PERCENT = 20; // % const MAX_DAYS = 7; const SORT_KEYS = ['rankNumNominators', 'rankComm', 'rankBondTotal', 'rankBondOwn', 'rankBondOther', 'rankOverall']; @@ -72,8 +73,8 @@ function filterValidators (validators: ValidatorInfo[], allIdentity: Record({ sortBy: 'rankOverall', sortFromMax: true }); @@ -254,16 +255,22 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak > ('limit operator exposure')} + label={t('single from operator')} onChange={setWithGroup} value={withGroup} /> ('no {{maxComm}}%+ comm', { replace: { maxComm: MAX_COMM_FILTER } })} + label={t('no {{maxComm}}%+ comm', { replace: { maxComm: MAX_COMM_PERCENT } })} onChange={setWithoutComm} value={withoutComm} /> + ('no {{maxCap}}%+ capacity', { replace: { maxCap: MAX_CAP_PERCENT } })} + onChange={setWithoutOver} + value={withoutOver} + /> {api.consts.babe && ( // FIXME have some sane era defaults for Aura )} - ('no oversubscribed')} - onChange={setWithoutOver} - value={withoutOver} - /> ('only elected')} diff --git a/packages/page-staking/src/useSortedTargets.ts b/packages/page-staking/src/useSortedTargets.ts index 4680bbd371..e32af69702 100644 --- a/packages/page-staking/src/useSortedTargets.ts +++ b/packages/page-staking/src/useSortedTargets.ts @@ -84,10 +84,11 @@ function sortValidators (list: ValidatorInfo[]): ValidatorInfo[] { ); } -function extractSingle (allAccounts: string[], derive: DeriveStakingElected | DeriveStakingWaiting, favorites: string[], perValidatorReward: BN, { eraLength, lastEra, sessionLength }: LastEra): [ValidatorInfo[], string[]] { +function extractSingle (allAccounts: string[], derive: DeriveStakingElected | DeriveStakingWaiting, favorites: string[], perValidatorReward: BN, { eraLength, lastEra, sessionLength }: LastEra, historyDepth?: BN): [ValidatorInfo[], string[]] { const nominators: Record = {}; const emptyExposure = registry.createType('Exposure'); const info = derive.info; + const earliestEra = historyDepth && lastEra.sub(historyDepth).addn(1); const list = info.map(({ accountId, exposure = emptyExposure, stakingLedger, validatorPrefs }): ValidatorInfo => { // some overrides (e.g. Darwinia Crab) does not have the own field in Exposure let bondOwn = exposure.own?.unwrap() || BN_ZERO; @@ -114,7 +115,11 @@ function extractSingle (allAccounts: string[], derive: DeriveStakingElected | De const lastEraPayout = !lastEra.isZero() ? stakingLedger.claimedRewards[stakingLedger.claimedRewards.length - 1] : undefined; - let lastPayout: BN | undefined = lastEraPayout; + + // only use if it is more recent than historyDepth + let lastPayout: BN | undefined = earliestEra && lastEraPayout && lastEraPayout.gt(earliestEra) + ? lastEraPayout + : undefined; if (lastPayout && !sessionLength.eq(BN_ONE)) { lastPayout = lastEra.sub(lastPayout).mul(eraLength); @@ -156,9 +161,9 @@ function extractSingle (allAccounts: string[], derive: DeriveStakingElected | De return [list, Object.keys(nominators)]; } -function extractInfo (api: ApiPromise, allAccounts: string[], electedDerive: DeriveStakingElected, waitingDerive: DeriveStakingWaiting, favorites: string[], totalIssuance: BN, lastEraInfo: LastEra, lastReward: BN): Partial { +function extractInfo (api: ApiPromise, allAccounts: string[], electedDerive: DeriveStakingElected, waitingDerive: DeriveStakingWaiting, favorites: string[], totalIssuance: BN, lastEraInfo: LastEra, lastReward: BN, historyDepth?: BN): Partial { const perValidatorReward = lastReward.divn(electedDerive.info.length); - const [elected, nominators] = extractSingle(allAccounts, electedDerive, favorites, perValidatorReward, lastEraInfo); + const [elected, nominators] = extractSingle(allAccounts, electedDerive, favorites, perValidatorReward, lastEraInfo, historyDepth); const [waiting] = extractSingle(allAccounts, waitingDerive, favorites, perValidatorReward, lastEraInfo); const activeTotals = elected .filter(({ isActive }) => isActive) @@ -206,6 +211,7 @@ const transformReward = { export default function useSortedTargets (favorites: string[]): SortedTargets { const { api } = useApi(); const { allAccounts } = useAccounts(); + const historyDepth = useCall(api.query.staking.historyDepth); const totalIssuance = useCall(api.query.balances.totalIssuance); const electedInfo = useCall(api.derive.staking.electedInfo); const waitingInfo = useCall(api.derive.staking.waitingInfo); @@ -214,9 +220,9 @@ export default function useSortedTargets (favorites: string[]): SortedTargets { const partial = useMemo( () => electedInfo && lastEraInfo && lastReward && totalIssuance && waitingInfo - ? extractInfo(api, allAccounts, electedInfo, waitingInfo, favorites, totalIssuance, lastEraInfo, lastReward) + ? extractInfo(api, allAccounts, electedInfo, waitingInfo, favorites, totalIssuance, lastEraInfo, lastReward, historyDepth) : EMPTY_PARTIAL, - [api, allAccounts, electedInfo, favorites, lastEraInfo, lastReward, totalIssuance, waitingInfo] + [api, allAccounts, electedInfo, favorites, historyDepth, lastEraInfo, lastReward, totalIssuance, waitingInfo] ); return { inflation: { inflation: 0, stakedReturn: 0 }, ...partial, lastReward };