feat(governance): validator tables refocused on stake (#3780)
This commit is contained in:
parent
c0320c2468
commit
7b8d9dc94b
@ -131,20 +131,25 @@ export const ConsensusValidatorsTable = ({
|
|||||||
|
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
|
|
||||||
|
const thirdOfTotalStake = useMemo(
|
||||||
|
() => new BigNumber(totalStake).dividedBy(3),
|
||||||
|
[totalStake]
|
||||||
|
);
|
||||||
|
|
||||||
const nodes = useMemo(() => {
|
const nodes = useMemo(() => {
|
||||||
if (!data) return [];
|
if (!data) return [];
|
||||||
let canonisedNodes = data
|
let canonisedNodes = data
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const aVotingPower = new BigNumber(a.rankingScore.votingPower);
|
const aStakedTotal = new BigNumber(a.stakedTotal);
|
||||||
const bVotingPower = new BigNumber(b.rankingScore.votingPower);
|
const bStakedTotal = new BigNumber(b.stakedTotal);
|
||||||
return bVotingPower.minus(aVotingPower).toNumber();
|
return bStakedTotal.minus(aStakedTotal).toNumber();
|
||||||
})
|
})
|
||||||
.map((node, index) => {
|
.map((node, index) => {
|
||||||
const votingPowerRanking = index + 1;
|
const stakedTotalRanking = index + 1;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
votingPowerRanking,
|
stakedTotalRanking,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.map(
|
.map(
|
||||||
@ -157,7 +162,7 @@ export const ConsensusValidatorsTable = ({
|
|||||||
stakedTotal,
|
stakedTotal,
|
||||||
rankingScore: { stakeScore, votingPower },
|
rankingScore: { stakeScore, votingPower },
|
||||||
pendingStake,
|
pendingStake,
|
||||||
votingPowerRanking,
|
stakedTotalRanking,
|
||||||
stakedByUser,
|
stakedByUser,
|
||||||
pendingUserStake,
|
pendingUserStake,
|
||||||
userStakeShare,
|
userStakeShare,
|
||||||
@ -175,7 +180,7 @@ export const ConsensusValidatorsTable = ({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
[ValidatorFields.RANKING_INDEX]: votingPowerRanking,
|
[ValidatorFields.RANKING_INDEX]: stakedTotalRanking,
|
||||||
[ValidatorFields.VALIDATOR]: {
|
[ValidatorFields.VALIDATOR]: {
|
||||||
avatarUrl: logo,
|
avatarUrl: logo,
|
||||||
name,
|
name,
|
||||||
@ -236,16 +241,12 @@ export const ConsensusValidatorsTable = ({
|
|||||||
return canonisedNodes;
|
return canonisedNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The point of identifying and hiding the group that could halt the network
|
|
||||||
// is that we assume the top 1/3 of stake is held by considerably less than
|
|
||||||
// 1/3 of the validators and we really want people not to stake any more to
|
|
||||||
// that group, because we want to make it require as many difference
|
|
||||||
// validators to collude as possible to halt the network, so we hide them.
|
|
||||||
const { topThird, remaining } = canonisedNodes.reduce(
|
const { topThird, remaining } = canonisedNodes.reduce(
|
||||||
(acc, node) => {
|
(acc, node) => {
|
||||||
if (acc.cumulativeScore < 100 / 3) {
|
if (acc.cumulativeScore.isLessThan(thirdOfTotalStake)) {
|
||||||
acc.cumulativeScore += parseFloat(
|
const prev = acc.cumulativeScore;
|
||||||
node[ValidatorFields.NORMALISED_VOTING_POWER]
|
acc.cumulativeScore = prev.plus(
|
||||||
|
new BigNumber(node[ValidatorFields.STAKE])
|
||||||
);
|
);
|
||||||
acc.topThird.push(node);
|
acc.topThird.push(node);
|
||||||
return acc;
|
return acc;
|
||||||
@ -253,61 +254,70 @@ export const ConsensusValidatorsTable = ({
|
|||||||
acc.remaining.push(node);
|
acc.remaining.push(node);
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{ topThird: [], remaining: [], cumulativeScore: 0 } as {
|
{ topThird: [], remaining: [], cumulativeScore: new BigNumber(0) } as {
|
||||||
topThird: CanonisedConsensusNodeProps[];
|
topThird: CanonisedConsensusNodeProps[];
|
||||||
remaining: CanonisedConsensusNodeProps[];
|
remaining: CanonisedConsensusNodeProps[];
|
||||||
cumulativeScore: number;
|
cumulativeScore: BigNumber;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// We need to combine the top third of validators into a single node, this
|
// We need to combine the top third of validators into a single node, this
|
||||||
// way the combined values can be passed to AG grid so that the combined cell's
|
// way the combined values can be passed to AG grid so that the combined cell's
|
||||||
// values are correct for ordering.
|
// values are correct for ordering.
|
||||||
const combinedTopThird = topThird.reduce((acc, node) => {
|
const combinedTopThird = topThird.reduce(
|
||||||
const {
|
(acc, node) => {
|
||||||
[ValidatorFields.STAKE]: stake,
|
const {
|
||||||
[ValidatorFields.STAKE_SHARE]: stakeShare,
|
[ValidatorFields.STAKE]: stake,
|
||||||
[ValidatorFields.PENDING_STAKE]: pendingStake,
|
[ValidatorFields.STAKE_SHARE]: stakeShare,
|
||||||
[ValidatorFields.NORMALISED_VOTING_POWER]: normalisedVotingPower,
|
[ValidatorFields.PENDING_STAKE]: pendingStake,
|
||||||
[ValidatorFields.TOTAL_PENALTIES]: totalPenalties,
|
[ValidatorFields.NORMALISED_VOTING_POWER]: normalisedVotingPower,
|
||||||
} = node;
|
[ValidatorFields.TOTAL_PENALTIES]: totalPenalties,
|
||||||
|
} = node;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
[ValidatorFields.STAKE]: accStake,
|
[ValidatorFields.STAKE]: accStake,
|
||||||
[ValidatorFields.STAKE_SHARE]: accStakeShare,
|
[ValidatorFields.STAKE_SHARE]: accStakeShare,
|
||||||
[ValidatorFields.PENDING_STAKE]: accPendingStake,
|
[ValidatorFields.PENDING_STAKE]: accPendingStake,
|
||||||
[ValidatorFields.NORMALISED_VOTING_POWER]: accNormalisedVotingPower,
|
[ValidatorFields.NORMALISED_VOTING_POWER]: accNormalisedVotingPower,
|
||||||
[ValidatorFields.TOTAL_PENALTIES]: accTotalPenalties,
|
[ValidatorFields.TOTAL_PENALTIES]: accTotalPenalties,
|
||||||
} = acc;
|
} = acc;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
[ValidatorFields.STAKE]: toBigNum(accStake, decimals)
|
[ValidatorFields.STAKE]: new BigNumber(accStake)
|
||||||
.plus(toBigNum(stake, decimals))
|
.plus(new BigNumber(stake))
|
||||||
.toString(),
|
.toString(),
|
||||||
[ValidatorFields.STAKE_SHARE]: formatNumberPercentage(
|
[ValidatorFields.STAKE_SHARE]: formatNumberPercentage(
|
||||||
new BigNumber(parseFloat(accStakeShare)).plus(
|
new BigNumber(parseFloat(accStakeShare)).plus(
|
||||||
new BigNumber(parseFloat(stakeShare))
|
new BigNumber(parseFloat(stakeShare))
|
||||||
|
),
|
||||||
|
2
|
||||||
),
|
),
|
||||||
2
|
[ValidatorFields.PENDING_STAKE]: toBigNum(accPendingStake, decimals)
|
||||||
),
|
.plus(toBigNum(pendingStake, decimals))
|
||||||
[ValidatorFields.PENDING_STAKE]: toBigNum(accPendingStake, decimals)
|
.toString(),
|
||||||
.plus(toBigNum(pendingStake, decimals))
|
[ValidatorFields.NORMALISED_VOTING_POWER]: formatNumberPercentage(
|
||||||
.toString(),
|
new BigNumber(parseFloat(accNormalisedVotingPower)).plus(
|
||||||
[ValidatorFields.NORMALISED_VOTING_POWER]: formatNumberPercentage(
|
new BigNumber(parseFloat(normalisedVotingPower))
|
||||||
new BigNumber(parseFloat(accNormalisedVotingPower)).plus(
|
),
|
||||||
new BigNumber(parseFloat(normalisedVotingPower))
|
2
|
||||||
),
|
),
|
||||||
2
|
[ValidatorFields.TOTAL_PENALTIES]: formatNumberPercentage(
|
||||||
),
|
new BigNumber(parseFloat(accTotalPenalties)).plus(
|
||||||
[ValidatorFields.TOTAL_PENALTIES]: formatNumberPercentage(
|
new BigNumber(parseFloat(totalPenalties))
|
||||||
new BigNumber(parseFloat(accTotalPenalties)).plus(
|
),
|
||||||
new BigNumber(parseFloat(totalPenalties))
|
2
|
||||||
),
|
),
|
||||||
2
|
};
|
||||||
),
|
},
|
||||||
};
|
{
|
||||||
});
|
[ValidatorFields.STAKE]: '0',
|
||||||
|
[ValidatorFields.STAKE_SHARE]: '0',
|
||||||
|
[ValidatorFields.PENDING_STAKE]: '0',
|
||||||
|
[ValidatorFields.NORMALISED_VOTING_POWER]: '0',
|
||||||
|
[ValidatorFields.TOTAL_PENALTIES]: '0',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -322,6 +332,7 @@ export const ConsensusValidatorsTable = ({
|
|||||||
decimals,
|
decimals,
|
||||||
hideTopThird,
|
hideTopThird,
|
||||||
previousEpochData,
|
previousEpochData,
|
||||||
|
thirdOfTotalStake,
|
||||||
totalStake,
|
totalStake,
|
||||||
validatorsView,
|
validatorsView,
|
||||||
]);
|
]);
|
||||||
@ -352,6 +363,7 @@ export const ConsensusValidatorsTable = ({
|
|||||||
headerTooltip: t('StakeDescription').toString(),
|
headerTooltip: t('StakeDescription').toString(),
|
||||||
cellRenderer: TotalStakeRenderer,
|
cellRenderer: TotalStakeRenderer,
|
||||||
width: 120,
|
width: 120,
|
||||||
|
sort: 'desc',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: ValidatorFields.PENDING_STAKE,
|
field: ValidatorFields.PENDING_STAKE,
|
||||||
@ -373,7 +385,6 @@ export const ConsensusValidatorsTable = ({
|
|||||||
headerTooltip: t('NormalisedVotingPowerDescription').toString(),
|
headerTooltip: t('NormalisedVotingPowerDescription').toString(),
|
||||||
cellRenderer: VotingPowerRenderer,
|
cellRenderer: VotingPowerRenderer,
|
||||||
width: 200,
|
width: 200,
|
||||||
sort: 'desc',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: ValidatorFields.TOTAL_PENALTIES,
|
field: ValidatorFields.TOTAL_PENALTIES,
|
||||||
|
@ -57,16 +57,16 @@ export const StandbyPendingValidatorsTable = ({
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const aVotingPower = new BigNumber(a.rankingScore.votingPower);
|
const aStakedTotal = new BigNumber(a.stakedTotal);
|
||||||
const bVotingPower = new BigNumber(b.rankingScore.votingPower);
|
const bStakedTotal = new BigNumber(b.stakedTotal);
|
||||||
return bVotingPower.minus(aVotingPower).toNumber();
|
return bStakedTotal.minus(aStakedTotal).toNumber();
|
||||||
})
|
})
|
||||||
.map((node, index) => {
|
.map((node, index) => {
|
||||||
const votingPowerRanking = index + 1;
|
const stakedTotalRanking = index + 1;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
votingPowerRanking,
|
stakedTotalRanking,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.map(
|
.map(
|
||||||
@ -79,7 +79,7 @@ export const StandbyPendingValidatorsTable = ({
|
|||||||
stakedTotal,
|
stakedTotal,
|
||||||
rankingScore: { stakeScore },
|
rankingScore: { stakeScore },
|
||||||
pendingStake,
|
pendingStake,
|
||||||
votingPowerRanking,
|
stakedTotalRanking,
|
||||||
stakedByUser,
|
stakedByUser,
|
||||||
pendingUserStake,
|
pendingUserStake,
|
||||||
userStakeShare,
|
userStakeShare,
|
||||||
@ -125,7 +125,7 @@ export const StandbyPendingValidatorsTable = ({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
[ValidatorFields.RANKING_INDEX]: votingPowerRanking,
|
[ValidatorFields.RANKING_INDEX]: stakedTotalRanking,
|
||||||
[ValidatorFields.VALIDATOR]: {
|
[ValidatorFields.VALIDATOR]: {
|
||||||
avatarUrl,
|
avatarUrl,
|
||||||
name,
|
name,
|
||||||
@ -166,7 +166,7 @@ export const StandbyPendingValidatorsTable = ({
|
|||||||
: undefined,
|
: undefined,
|
||||||
[ValidatorFields.PENDING_USER_STAKE]: pendingUserStake,
|
[ValidatorFields.PENDING_USER_STAKE]: pendingUserStake,
|
||||||
[ValidatorFields.USER_STAKE_SHARE]: userStakeShare
|
[ValidatorFields.USER_STAKE_SHARE]: userStakeShare
|
||||||
? formatNumberPercentage(new BigNumber(userStakeShare))
|
? formatNumberPercentage(new BigNumber(userStakeShare), 2)
|
||||||
: undefined,
|
: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -210,6 +210,7 @@ export const StandbyPendingValidatorsTable = ({
|
|||||||
headerTooltip: t('StakeDescription').toString(),
|
headerTooltip: t('StakeDescription').toString(),
|
||||||
cellRenderer: TotalStakeRenderer,
|
cellRenderer: TotalStakeRenderer,
|
||||||
width: 120,
|
width: 120,
|
||||||
|
sort: 'desc',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: ValidatorFields.PENDING_STAKE,
|
field: ValidatorFields.PENDING_STAKE,
|
||||||
@ -233,7 +234,6 @@ export const StandbyPendingValidatorsTable = ({
|
|||||||
}),
|
}),
|
||||||
cellRenderer: StakeNeededForPromotionRenderer,
|
cellRenderer: StakeNeededForPromotionRenderer,
|
||||||
width: 210,
|
width: 210,
|
||||||
sort: 'asc',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: ValidatorFields.TOTAL_PENALTIES,
|
field: ValidatorFields.TOTAL_PENALTIES,
|
||||||
|
Loading…
Reference in New Issue
Block a user