Expand max-nominations badge displays (#3563)

* Expand max-nominations badge displays

* Ignore > 64 in profitable selection

* Indicate oversubscribed

* Show oversubscribed in actions
This commit is contained in:
Jaco Greeff 2020-08-29 09:58:37 +02:00 committed by GitHub
parent cc908ce759
commit 5c3bf740cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 16 deletions

View File

@ -15,10 +15,24 @@ interface Props {
function ListNominees ({ nominating, stashId }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { nomsActive, nomsChilled, nomsInactive, nomsWaiting } = useInactives(stashId, nominating);
const { nomsActive, nomsChilled, nomsInactive, nomsOver, nomsWaiting } = useInactives(stashId, nominating);
return (
<>
{nomsOver && nomsOver.length !== 0 && (
<Expander
help={t<string>('The validators that are over-subscribed, only the top 64 backing stake will be rewarded.')}
summary={t<string>('Oversubscribed nominations ({{count}})', { replace: { count: nomsOver.length } })}
>
{nomsOver.map((nomineeId, index): React.ReactNode => (
<AddressMini
key={index}
value={nomineeId}
withBalance={false}
/>
))}
</Expander>
)}
{nomsActive && nomsActive.length !== 0 && (
<Expander
help={t<string>('The validators selected by the Phragmen algorithm to nominate for this era.')}

View File

@ -13,6 +13,7 @@ interface Inactives {
nomsActive?: string[];
nomsChilled?: string[];
nomsInactive?: string[];
nomsOver?: string[];
nomsWaiting?: string[];
}
@ -28,6 +29,15 @@ function extractState (stashId: string, slashes: Option<SlashingSpans>[], nomine
return !lastNonzeroSlash.isZero() && lastNonzeroSlash.gte(submittedIn);
});
// all nominations that are oversubscribed
const nomsOver = exposures
.map((exposure, index) =>
exposure.others.length > 64
? nominees[index]
: null
)
.filter((nominee): nominee is string => !!nominee && !nomsChilled.includes(nominee));
// first a blanket find of nominations not in the active set
let nomsInactive = exposures
.map((exposure, index) =>
@ -35,7 +45,7 @@ function extractState (stashId: string, slashes: Option<SlashingSpans>[], nomine
? null
: nominees[index]
)
.filter((inactiveId): inactiveId is string => !!inactiveId);
.filter((nominee): nominee is string => !!nominee);
// waiting if validator is inactive or we have not submitted long enough ago
const nomsWaiting = exposures
@ -44,19 +54,20 @@ function extractState (stashId: string, slashes: Option<SlashingSpans>[], nomine
? nominees[index]
: null
)
.filter((waitingId): waitingId is string => !!waitingId)
.filter((nominee) => !nomsChilled.includes(nominee));
.filter((nominee): nominee is string => !!nominee)
.filter((nominee) => !nomsChilled.includes(nominee) && !nomsOver.includes(nominee));
// filter based on all inactives
const nomsActive = nominees.filter((nominee) => !nomsInactive.includes(nominee) && !nomsChilled.includes(nominee));
const nomsActive = nominees.filter((nominee) => !nomsInactive.includes(nominee) && !nomsChilled.includes(nominee) && !nomsOver.includes(nominee));
// inactive also contains waiting, remove those
nomsInactive = nomsInactive.filter((nominee) => !nomsWaiting.includes(nominee) && !nomsChilled.includes(nominee));
nomsInactive = nomsInactive.filter((nominee) => !nomsWaiting.includes(nominee) && !nomsChilled.includes(nominee) && !nomsOver.includes(nominee));
return {
nomsActive,
nomsChilled,
nomsInactive,
nomsOver,
nomsWaiting
};
}

View File

@ -19,7 +19,7 @@ function MaxBadge ({ numNominators }: Props): React.ReactElement<Props> | null {
return (
<Badge
color='red'
info='64+'
info='64'
/>
);
}

View File

@ -9,12 +9,13 @@ import MaxBadge from '../../MaxBadge';
interface Props {
isElected: boolean;
isMain?: boolean;
numNominators?: number;
onlineCount?: false | number;
onlineMessage?: boolean;
}
function Status ({ isElected, numNominators, onlineCount, onlineMessage }: Props): React.ReactElement<Props> {
function Status ({ isElected, isMain, numNominators, onlineCount, onlineMessage }: Props): React.ReactElement<Props> {
return (
<>
{isElected
@ -26,11 +27,15 @@ function Status ({ isElected, numNominators, onlineCount, onlineMessage }: Props
)
: <Badge color='transparent' />
}
{(!!onlineCount || onlineMessage) && (
<Badge
color='green'
info={onlineCount || <Icon icon='envelope' />}
/>
{isMain && (
!!onlineCount || onlineMessage
? (
<Badge
color='green'
info={onlineCount || <Icon icon='envelope' />}
/>
)
: <Badge color='transparent' />
)}
<MaxBadge numNominators={numNominators} />
</>

View File

@ -120,7 +120,8 @@ function Address ({ address, className = '', filterName, hasQueries, isElected,
/>
<Status
isElected={isElected}
numNominators={nominatedBy?.length}
isMain={isMain}
numNominators={nominatedBy?.length || nominators.length}
onlineCount={onlineCount}
onlineMessage={onlineMessage}
/>

View File

@ -109,8 +109,8 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak
const _selectProfitable = useCallback(
() => setSelected(
(validators || []).reduce((result: string[], { hasIdentity, isElected, isFavorite, key, rewardPayout }): string[] => {
if ((result.length < MAX_NOMINATIONS) && (hasIdentity || !withIdentity) && (isElected || isFavorite) && !rewardPayout.isZero()) {
(validators || []).reduce((result: string[], { hasIdentity, isElected, isFavorite, key, numNominators, rewardPayout }): string[] => {
if ((numNominators < 64) && (result.length < MAX_NOMINATIONS) && (hasIdentity || !withIdentity) && (isElected || isFavorite) && !rewardPayout.isZero()) {
result.push(key);
}