fix(governance): validators display fixes (#4547)

This commit is contained in:
Sam Keen 2023-08-16 22:58:14 +01:00 committed by GitHub
parent 35e25d9a8f
commit cae1fc67a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 23 deletions

View File

@ -626,7 +626,8 @@
"status-tendermint": "Consensus",
"status-ersatz": "Standby",
"status-pending": "Candidate",
"ersatzDescription": "To be promoted, a standby validator must have more than the lowest consensus stake, plus a bonus given to existing validators. This currently requires a minimum of {{stakeNeededForPromotion}} stake assuming no penalties. Only one validator per epoch can be promoted.",
"ersatzDescription1": "To be promoted, a standby validator must have more than the lowest consensus stake, plus a bonus given to existing validators, and only one standby validator can be promoted per epoch. Currently this requires a minimum of",
"ersatzDescription2": "stake assuming no performance penalty incurred.",
"pendingDescription1": "Anyone can",
"pendingDescriptionLinkText": "set up and run a node on Vega",
"pendingDescription2": ". A node can move from being a candidate into standby based on how much nomination it attracts, assuming it has proven reliability by sending heartbeats to the network.",
@ -784,6 +785,7 @@
"PerformancePenaltyDescription": "Performance score is a measure of how often a validator proposed blocks in the last epoch relative to how many they should be expected to propose based on their voting power. Performance penalty is applied for having a performance score of less than 1",
"UnnormalisedVotingPowerDescription": "The voting power of the validator based on their final validator score after all penalties have been applied",
"NormalisedVotingPowerDescription": "The voting power of the validator, adjusted to ensure all validator scores sum to 1, used for distribution of rewards",
"NonConsensusVotingPowerDescription": "The voting power of the validator. Only consensus validators have voting power",
"Score": "Score",
"performancePenalty": "Performance penalty",
"overstaked": "Overstaked",

View File

@ -389,10 +389,10 @@ export const ConsensusValidatorsTable = ({
},
{
field: ValidatorFields.NORMALISED_VOTING_POWER,
headerName: t(ValidatorFields.NORMALISED_VOTING_POWER).toString(),
headerName: t('votingPower').toString(),
headerTooltip: t('NormalisedVotingPowerDescription').toString(),
cellRenderer: VotingPowerRenderer,
width: 200,
width: 120,
},
{
field: ValidatorFields.TOTAL_PENALTIES,

View File

@ -20,6 +20,7 @@ import {
TotalStakeRenderer,
StakeShareRenderer,
PendingStakeRenderer,
VotingPowerRenderer,
} from './shared';
import type { AgGridReact } from 'ag-grid-react';
import type { ColDef } from 'ag-grid-community';
@ -39,7 +40,6 @@ interface StandbyPendingValidatorsTableProps extends ValidatorsTableProps {
export const StandbyPendingValidatorsTable = ({
data,
previousEpochData,
totalStake,
stakeNeededForPromotion,
stakeNeededForPromotionDescription,
validatorsView,
@ -132,6 +132,8 @@ export const StandbyPendingValidatorsTable = ({
name,
},
[ValidatorFields.STAKE]: stakedTotal,
[ValidatorFields.NORMALISED_VOTING_POWER]: '0%',
[ValidatorFields.UNNORMALISED_VOTING_POWER]: '0%',
[ValidatorFields.STAKE_NEEDED_FOR_PROMOTION]:
individualStakeNeededForPromotion || null,
[ValidatorFields.STAKE_NEEDED_FOR_PROMOTION_DESCRIPTION]:
@ -223,7 +225,14 @@ export const StandbyPendingValidatorsTable = ({
headerName: t(ValidatorFields.STAKE_SHARE).toString(),
headerTooltip: t('StakeShareDescription').toString(),
cellRenderer: StakeShareRenderer,
width: 100,
width: 120,
},
{
field: ValidatorFields.NORMALISED_VOTING_POWER,
headerName: t('votingPower').toString(),
headerTooltip: t('NonConsensusVotingPowerDescription').toString(),
cellRenderer: VotingPowerRenderer,
width: 120,
},
// {
// field: ValidatorFields.STAKE_NEEDED_FOR_PROMOTION,

View File

@ -17,6 +17,10 @@ import type { PreviousEpochQuery } from '../../__generated__/PreviousEpoch';
import type { StakingQuery } from '../../__generated__/Staking';
import type { StakingDelegationFieldsFragment } from '../../__generated__/Staking';
import type { ValidatorWithUserData } from './shared';
import {
NetworkParams,
useNetworkParams,
} from '@vegaprotocol/network-parameters';
export interface ValidatorsTableProps {
nodesData: NodesQuery | undefined;
@ -41,6 +45,9 @@ export const ValidatorTables = ({
const {
appState: { decimals },
} = useAppState();
const { params } = useNetworkParams([
NetworkParams.network_validators_incumbentBonus,
]);
const [validatorsView, setValidatorsView] = useState<ValidatorsView>('all');
const totalStake = useMemo(
@ -52,6 +59,10 @@ export const ValidatorTables = ({
() => userStakingData?.party?.stakingSummary.currentStakeAvailable || '0',
[userStakingData?.party?.stakingSummary.currentStakeAvailable]
);
const incumbentBonus = useMemo(
() => new BigNumber(params?.network_validators_incumbentBonus),
[params?.network_validators_incumbentBonus]
);
let stakeNeededForPromotion = undefined;
let delegations: StakingDelegationFieldsFragment[] | undefined = undefined;
@ -126,28 +137,23 @@ export const ValidatorTables = ({
consensusValidators.length &&
(standbyValidators.length || pendingValidators.length)
) {
const lowestRankingConsensusScore = consensusValidators.reduce(
const lowestConsensusStake = consensusValidators.reduce(
(lowest: ValidatorWithUserData, validator: ValidatorWithUserData) => {
if (
Number(validator.rankingScore.rankingScore) <
Number(lowest.rankingScore.rankingScore)
) {
if (Number(validator.stakedTotal) < Number(lowest.stakedTotal)) {
lowest = validator;
}
return lowest;
}
).rankingScore.rankingScore;
).stakedTotal;
const lowestRankingBigNum = toBigNum(lowestRankingConsensusScore, 0);
const consensusStakedTotal = consensusValidators.reduce((acc, cur) => {
return acc.plus(toBigNum(cur.stakedTotal, decimals));
}, new BigNumber(0));
const lowestRankingBigNum = toBigNum(lowestConsensusStake, decimals);
stakeNeededForPromotion = formatNumber(
lowestRankingBigNum.times(consensusStakedTotal),
lowestRankingBigNum.multipliedBy(incumbentBonus.plus(1)),
2
).toString();
}
return (
<section data-testid="validator-tables">
<div className="grid w-full justify-end">
@ -187,12 +193,18 @@ export const ValidatorTables = ({
<div className="mb-10">
<SubHeading title={t('status-ersatz')} />
<p>
<Trans
i18nKey="ersatzDescription"
values={{
stakeNeededForPromotion,
}}
/>
<span>
<Trans i18nKey="ersatzDescription1" />
</span>
<span className="text-white font-bold">
{' '}
{stakeNeededForPromotion}{' '}
</span>
<span>
<Trans i18nKey="ersatzDescription2" />
</span>
</p>
<StandbyPendingValidatorsTable
data={standbyValidators}

View File

@ -68,7 +68,7 @@ export const calculateOverstakedPenalty = (nodeId: string, nodes: Node[]) => {
}
const penalty = new BigNumber(1)
.minus(
new BigNumber(node.rewardScore?.rawValidatorScore || 0).dividedBy(tts)
new BigNumber(node.rewardScore?.rawValidatorScore || 1).dividedBy(tts)
)
.times(100);
return penalty.isLessThan(0) ? new BigNumber(0) : penalty;

View File

@ -107,6 +107,7 @@ export const NetworkParams = {
market_liquidity_targetstake_triggering_ratio:
'market_liquidity_targetstake_triggering_ratio',
transfer_fee_factor: 'transfer_fee_factor',
network_validators_incumbentBonus: 'network_validators_incumbentBonus',
} as const;
type Params = typeof NetworkParams;