Skip to content

Commit

Permalink
Merge pull request #32 from Cardinal-Cryptography/A0-1333-performance…
Browse files Browse the repository at this point in the history
…-per-validator

A0 1333 performance per validator
  • Loading branch information
Marcin-Radecki authored Sep 22, 2022
2 parents 52b7492 + 7ab8d67 commit 30d21e7
Show file tree
Hide file tree
Showing 11 changed files with 624 additions and 347 deletions.
50 changes: 29 additions & 21 deletions packages/page-staking/src/Performance/Address/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
// Copyright 2017-2022 @polkadot/app-staking authors & contributors
// SPDX-License-Identifier: Apache-2.0

import React, { useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';

import { ApiPromise } from '@polkadot/api';
import { AddressSmall } from '@polkadot/react-components';
import { AddressSmall, Icon, Spinner } from '@polkadot/react-components';
import { checkVisibility } from '@polkadot/react-components/util';
import { useApi, useDeriveAccountInfo } from '@polkadot/react-hooks';

import Favorite from './Favorite';

interface Props {
address: string;
className?: string;
filterName: string;
isFavorite: boolean;
toggleFavorite: (accountId: string) => void;
blocksCreated: number,
session?: number;
blocksCreated?: number,
blocksTarget: number,
rewardPercentage: string,
rewardPercentage?: string,
}

function useAddressCalls (api: ApiPromise, address: string) {
Expand All @@ -27,7 +23,11 @@ function useAddressCalls (api: ApiPromise, address: string) {
return { accountInfo };
}

function Address ({ address, blocksCreated, blocksTarget, className = '', filterName, isFavorite, rewardPercentage, toggleFavorite }: Props): React.ReactElement<Props> | null {
function queryAddress (address: string) {
window.location.hash = `/staking/query/${address}`;
}

function Address ({ address, blocksCreated, blocksTarget, filterName, rewardPercentage, session }: Props): React.ReactElement<Props> | null {
const { api } = useApi();
const { accountInfo } = useAddressCalls(api, address);

Expand All @@ -40,28 +40,36 @@ function Address ({ address, blocksCreated, blocksTarget, className = '', filter
return null;
}

// eslint-disable-next-line react-hooks/rules-of-hooks
const onQueryStats = useCallback(
() => queryAddress(address),
[address]
);

return (
<tr className={className}>
<td className='badge together'>
<Favorite
address={address}
isFavorite={isFavorite}
toggleFavorite={toggleFavorite}
/>
</td>
<tr>
<td className='address'>
<AddressSmall value={address} />
</td>
{session && <td className='number'>
{session}
</td>}
<td className='number'>
{blocksCreated}
{blocksCreated ?? <Spinner noLabel={true} />}
</td>
<td className='number'>
{blocksTarget}
</td>
<td className='number'>
{rewardPercentage}
{blocksCreated === undefined ? '' : rewardPercentage}
</td>

{!session && <td className='number'>
<Icon
className='staking--stats highlight--color'
icon='chart-line'
onClick={onQueryStats}
/>
</td>}
</tr>
);
}
Expand Down
79 changes: 36 additions & 43 deletions packages/page-staking/src/Performance/CurrentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import React, { useMemo, useRef, useState } from 'react';

import { ValidatorPerformance } from '@polkadot/app-staking/Performance/Performance';
import { EraValidatorPerformance } from '@polkadot/app-staking/Performance/Performance';
import { Table, Toggle } from '@polkadot/react-components';
import { useLoadingDelay } from '@polkadot/react-hooks';

Expand All @@ -13,34 +13,46 @@ import Address from './Address';

interface Props {
className?: string;
toggleFavorite: (address: string) => void;
session: number;
validatorPerformances: ValidatorPerformance[];
eraValidatorPerformances: EraValidatorPerformance[];
}

function sortValidatorsByFavourites (validatorPerformances: ValidatorPerformance[]): ValidatorPerformance[] {
return validatorPerformances
.sort(({ isFavourite: favA }: ValidatorPerformance, { isFavourite: favB }: ValidatorPerformance): number => {
return favA === favB ? 0 : (favA ? -1 : 1);
});
function getFiltered (displayOnlyCommittee: boolean, eraValidatorPerformances: EraValidatorPerformance[]) {
const validators = displayOnlyCommittee ? eraValidatorPerformances.filter((performance) => performance.isCommittee) : eraValidatorPerformances;

return validators;
}

function getFiltered (displayOnlyCommittee: boolean, validatorPerformances: ValidatorPerformance[]) {
const validators = displayOnlyCommittee ? validatorPerformances.filter((performance) => performance.isCommittee) : validatorPerformances;
export function calculatePercentReward (blocksCreated: number | undefined, blocksTargetValue: number) {
if (blocksCreated === undefined) {
return '';
}

let rewardPercentage = 0;

if (blocksTargetValue > 0) {
rewardPercentage = 100 * blocksCreated / blocksTargetValue;

if (rewardPercentage >= 90) {
rewardPercentage = 100;
}
} else if (blocksTargetValue === 0 && blocksCreated === 0) {
rewardPercentage = 100;
}

return sortValidatorsByFavourites(validators);
return rewardPercentage.toFixed(1);
}

function CurrentList ({ className, toggleFavorite, validatorPerformances }: Props): React.ReactElement<Props> {
function CurrentList ({ className, eraValidatorPerformances }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [nameFilter, setNameFilter] = useState<string>('');
const [displayOnlyCommittee, setDisplayOnlyCommittee] = useState(true);

const isLoading = useLoadingDelay();

const validators = useMemo(
() => getFiltered(displayOnlyCommittee, validatorPerformances),
[validatorPerformances, displayOnlyCommittee]
() => getFiltered(displayOnlyCommittee, eraValidatorPerformances),
[eraValidatorPerformances, displayOnlyCommittee]
);

const list = useMemo(
Expand All @@ -52,31 +64,14 @@ function CurrentList ({ className, toggleFavorite, validatorPerformances }: Prop

const headerRef = useRef(
[
[t('validators'), 'start', 2],
[t('validators'), 'start', 1],
[t('blocks created'), 'expand'],
[t('blocks expected'), 'media--1100'],
[t('max % reward')],
[],
[undefined, 'media--1200']
[t('blocks expected'), 'expand'],
[t('max % reward'), 'expand'],
[t('stats'), 'expand']
]
);

function calculatePercentReward (blocksCreated: number, blocksTargetValue: number) {
let rewardPercentage = 0;

if (blocksTargetValue > 0) {
rewardPercentage = 100 * blocksCreated / blocksTargetValue;

if (rewardPercentage >= 90) {
rewardPercentage = 100;
}
} else if (blocksTargetValue === 0 && blocksCreated === 0) {
rewardPercentage = 100;
}

return rewardPercentage;
}

return (
<Table
className={className}
Expand Down Expand Up @@ -107,16 +102,14 @@ function CurrentList ({ className, toggleFavorite, validatorPerformances }: Prop
}
header={headerRef.current}
>
{list.map((performance): React.ReactNode => (
{list.map(({ validatorPerformance }): React.ReactNode => (
<Address
address={performance.accountId}
blocksCreated={performance.blockCount}
blocksTarget={performance.expectedBlockCount}
address={validatorPerformance.accountId}
blocksCreated={validatorPerformance.blockCount}
blocksTarget={validatorPerformance.expectedBlockCount}
filterName={nameFilter}
isFavorite={performance.isFavourite}
key={performance.accountId}
rewardPercentage={calculatePercentReward(performance.blockCount, performance.expectedBlockCount).toFixed(1)}
toggleFavorite={toggleFavorite}
key={validatorPerformance.accountId}
rewardPercentage={calculatePercentReward(validatorPerformance.blockCount, validatorPerformance.expectedBlockCount)}
/>
))}
</Table>
Expand Down
Loading

0 comments on commit 30d21e7

Please sign in to comment.