Show validator rewards over eras (#2355)

This commit is contained in:
Jaco Greeff 2020-03-09 11:02:04 +01:00 committed by GitHub
parent b6a1cf2e4a
commit 5586692cd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 121 additions and 100 deletions

View File

@ -8,10 +8,10 @@
"packages/*"
],
"resolutions": {
"@polkadot/api": "^1.6.0-beta.11",
"@polkadot/api-contract": "^1.6.0-beta.11",
"@polkadot/api": "^1.6.0-beta.12",
"@polkadot/api-contract": "^1.6.0-beta.12",
"@polkadot/keyring": "^2.6.1",
"@polkadot/types": "^1.6.0-beta.11",
"@polkadot/types": "^1.6.0-beta.12",
"@polkadot/util": "^2.6.1",
"@polkadot/util-crypto": "^2.6.1",
"babel-core": "^7.0.0-bridge.0",

View File

@ -12,6 +12,6 @@
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.8.7",
"@polkadot/api-contract": "^1.6.0-beta.11"
"@polkadot/api-contract": "^1.6.0-beta.12"
}
}

View File

@ -21,69 +21,80 @@ type LineDataEntry = (BN | number)[];
type LineData = LineDataEntry[];
interface BlockChart {
blockChart: LineData;
blockLabels: string[];
interface ChartInfo {
chart: LineData;
labels: string[];
}
interface StakeChart {
stakeChart: LineData;
stakeLabels: string[];
}
// interface SplitEntry {
// colors: string[];
// label: string;
// tooltip: string;
// value: number;
// }
// type SplitData = SplitEntry[];
// const COLORS_MINE = ['#ff8c00'];
// const COLORS_OTHER = ['#acacac'];
// const COLORS_REWARD = ['#8c2200', '#008c22', '#acacac'];
const COLORS_REWARD = ['#8c2200', '#008c22', '#acacac'];
const COLORS_BLOCKS = [undefined, '#acacac'];
function balanceToNumber (amount: BN, divisor: BN): number {
return amount.muln(1000).div(divisor).toNumber() / 1000;
}
function extractBlocks (validatorId: string, rewards: DeriveStakerReward[] = []): BlockChart {
const blockLabels: string[] = [];
const avgSet: number[] = [];
const idxSet: number[] = [];
let total = 0;
function extractCharts (validatorId: string, divisor: BN, rewards: DeriveStakerReward[] = []): [ChartInfo, ChartInfo, ChartInfo] {
const labels: string[] = [];
const blockAvgSet: LineDataEntry = [];
const blockIdxSet: LineDataEntry = [];
const slashSet: LineDataEntry = [];
const rewardSet: LineDataEntry = [];
const rewardAvgSet: LineDataEntry = [];
const stakeSet: LineDataEntry = [];
let blockTotal = 0;
let rewardTotal = 0;
rewards.forEach(({ era, validators }, index): void => {
const points = validators[validatorId]?.points.toNumber() || 0;
rewards.forEach(({ era, eraPoints, eraReward, validators }, index): void => {
const points = validators[validatorId]?.points || new BN(0);
const myReward = eraPoints.gtn(0)
? balanceToNumber(
points
.mul(eraReward)
.div(eraPoints),
divisor
)
: 0;
total += points;
blockTotal += points.toNumber();
rewardTotal += myReward;
blockLabels.push(era.toHuman());
avgSet.push(Math.ceil(total / (index + 1) * 100) / 100);
idxSet.push(points);
});
labels.push(era.toHuman());
return {
blockChart: [idxSet, avgSet],
blockLabels
};
}
blockAvgSet.push(Math.ceil(blockTotal * 100 / (index + 1)) / 100);
blockIdxSet.push(points);
function extractStake (validatorId: string, divisor: BN, rewards: DeriveStakerReward[] = []): StakeChart {
const stakeLabels: string[] = [];
const stakeChart: LineDataEntry = [];
rewardSet.push(myReward);
rewardAvgSet.push(Math.ceil(rewardTotal * 100 / (index + 1)) / 100);
slashSet.push(0); // TODO
rewards.forEach(({ era, validators }): void => {
stakeLabels.push(era.toHuman());
stakeChart.push(
stakeSet.push(
balanceToNumber(validators[validatorId]?.exposure.total.toBn() || new BN(0), divisor)
);
});
return {
stakeChart: [stakeChart],
stakeLabels
};
return [
{ chart: [blockIdxSet, blockAvgSet], labels },
{ chart: [slashSet, rewardSet, rewardAvgSet], labels },
{ chart: [stakeSet], labels }
];
}
export default function Validator ({ className, validatorId }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const [{ blockChart, blockLabels }, setBlockChart] = useState<BlockChart>({ blockChart: [], blockLabels: [] });
const [{ stakeChart, stakeLabels }, setStakeChart] = useState<StakeChart>({ stakeChart: [], stakeLabels: [] });
const [[{ chart: blockChart, labels: blockLabels }, { chart: rewardChart, labels: rewardLabels }, { chart: stakeChart, labels: stakeLabels }], setCharts] = useState<[ChartInfo, ChartInfo, ChartInfo]>([{ chart: [], labels: [] }, { chart: [], labels: [] }, { chart: [], labels: [] }]);
const stakerRewards = useCall<DeriveStakerReward[]>(api.derive.staking.stakerRewards as any, [validatorId, true]);
const { currency, divisor } = useMemo((): { currency: string; divisor: BN } => ({
currency: formatBalance.getDefaults().unit,
@ -91,8 +102,7 @@ export default function Validator ({ className, validatorId }: Props): React.Rea
}), [formatBalance]);
useEffect((): void => {
setBlockChart(extractBlocks(validatorId, stakerRewards));
setStakeChart(extractStake(validatorId, divisor, stakerRewards));
setCharts(extractCharts(validatorId, divisor, stakerRewards));
}, [stakerRewards, validatorId]);
return (
@ -109,6 +119,17 @@ export default function Validator ({ className, validatorId }: Props): React.Rea
/>
</div>
)}
{!!rewardChart.length && (
<div className='staking--Chart'>
<h1>{t('rewards & slashes')}</h1>
<Chart.Line
colors={COLORS_REWARD}
labels={rewardLabels}
legends={[t('{{currency}} slashed', { replace: { currency } }), t('{{currency}} rewards', { replace: { currency } }), t('{{currency}} average', { replace: { currency } })]}
values={rewardChart}
/>
</div>
)}
</Column>
<Column emptyText={t('Loading staker data')}>
{stakeChart && !!stakeChart[0]?.length && (

View File

@ -31,7 +31,7 @@
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
"dependencies": {
"@babel/runtime": "^7.8.7",
"@polkadot/api": "^1.6.0-beta.11",
"@polkadot/api": "^1.6.0-beta.12",
"@polkadot/extension-dapp": "^0.22.1",
"rxjs-compat": "^6.5.4"
}

112
yarn.lock
View File

@ -2765,56 +2765,56 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/api-contract@npm:^1.6.0-beta.11":
version: 1.6.0-beta.11
resolution: "@polkadot/api-contract@npm:1.6.0-beta.11"
"@polkadot/api-contract@npm:^1.6.0-beta.12":
version: 1.6.0-beta.12
resolution: "@polkadot/api-contract@npm:1.6.0-beta.12"
dependencies:
"@babel/runtime": ^7.8.4
"@polkadot/api": 1.6.0-beta.11
"@polkadot/rpc-core": 1.6.0-beta.11
"@polkadot/types": 1.6.0-beta.11
"@polkadot/api": 1.6.0-beta.12
"@polkadot/rpc-core": 1.6.0-beta.12
"@polkadot/types": 1.6.0-beta.12
"@polkadot/util": ^2.6.1
bn.js: ^5.1.1
rxjs: ^6.5.4
checksum: 2/7a65b34c04adb1830ea2b3d2b1a93b51adf0050e3ca17be9751c8576beba231739edd4aa90f8f89cbcf72c096fcac33db18e3883cda9dc4dd1cd29a7f024934d
checksum: 2/864bbac9f125819b262bf3736465285a8bb7e37be090f40bd92bf683c24240222ed21ad6a28ad4a389338c9b5a1e46317e687ce85df7166b9ce09286c9576513
languageName: node
linkType: hard
"@polkadot/api-derive@npm:1.6.0-beta.11":
version: 1.6.0-beta.11
resolution: "@polkadot/api-derive@npm:1.6.0-beta.11"
"@polkadot/api-derive@npm:1.6.0-beta.12":
version: 1.6.0-beta.12
resolution: "@polkadot/api-derive@npm:1.6.0-beta.12"
dependencies:
"@babel/runtime": ^7.8.4
"@polkadot/api": 1.6.0-beta.11
"@polkadot/rpc-core": 1.6.0-beta.11
"@polkadot/rpc-provider": 1.6.0-beta.11
"@polkadot/types": 1.6.0-beta.11
"@polkadot/api": 1.6.0-beta.12
"@polkadot/rpc-core": 1.6.0-beta.12
"@polkadot/rpc-provider": 1.6.0-beta.12
"@polkadot/types": 1.6.0-beta.12
"@polkadot/util": ^2.6.1
"@polkadot/util-crypto": ^2.6.1
bn.js: ^5.1.1
memoizee: ^0.4.14
rxjs: ^6.5.4
checksum: 2/4c4cdb43f49e152c82ccaa3f34127943407fece918bccd701a19798bc434876b590d32ce27347cd77cad791e473c53fa4c62e0f1127d55be35637fe87b4301b5
checksum: 2/c2a340e081350133d8d6378d977f692a7ace663f7b6352525ab4963532296a449b6e8de5a0010b09e898935904f1e5e08a61772e95ad1fd36423639bf1417e90
languageName: node
linkType: hard
"@polkadot/api@npm:^1.6.0-beta.11":
version: 1.6.0-beta.11
resolution: "@polkadot/api@npm:1.6.0-beta.11"
"@polkadot/api@npm:^1.6.0-beta.12":
version: 1.6.0-beta.12
resolution: "@polkadot/api@npm:1.6.0-beta.12"
dependencies:
"@babel/runtime": ^7.8.4
"@polkadot/api-derive": 1.6.0-beta.11
"@polkadot/api-derive": 1.6.0-beta.12
"@polkadot/keyring": ^2.6.1
"@polkadot/metadata": 1.6.0-beta.11
"@polkadot/rpc-core": 1.6.0-beta.11
"@polkadot/rpc-provider": 1.6.0-beta.11
"@polkadot/types": 1.6.0-beta.11
"@polkadot/metadata": 1.6.0-beta.12
"@polkadot/rpc-core": 1.6.0-beta.12
"@polkadot/rpc-provider": 1.6.0-beta.12
"@polkadot/types": 1.6.0-beta.12
"@polkadot/util": ^2.6.1
"@polkadot/util-crypto": ^2.6.1
bn.js: ^5.1.1
eventemitter3: ^4.0.0
rxjs: ^6.5.4
checksum: 2/d6687399bd5c481b5fb44fa3b2f81aed72bf5a907a2d8d26006bab2b956d788f89bccf117ac2a82b9e3ae42f5231e4362b52524ac4da4dc8d422bb07de2a6f65
checksum: 2/20ca5de20925301b96f2d2730d264d94cb12ace13b09f70895a4a702e830b8147cf09ae4d1f5c2b11965cf5007ed96381d35178e4ffab57b0296c031a66cb7d0
languageName: node
linkType: hard
@ -2864,7 +2864,7 @@ __metadata:
resolution: "@polkadot/app-contracts@workspace:packages/page-contracts"
dependencies:
"@babel/runtime": ^7.8.7
"@polkadot/api-contract": ^1.6.0-beta.11
"@polkadot/api-contract": ^1.6.0-beta.12
languageName: unknown
linkType: soft
@ -3176,14 +3176,14 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/jsonrpc@npm:1.6.0-beta.11":
version: 1.6.0-beta.11
resolution: "@polkadot/jsonrpc@npm:1.6.0-beta.11"
"@polkadot/jsonrpc@npm:1.6.0-beta.12":
version: 1.6.0-beta.12
resolution: "@polkadot/jsonrpc@npm:1.6.0-beta.12"
dependencies:
"@babel/runtime": ^7.8.4
"@polkadot/types": 1.6.0-beta.11
"@polkadot/types": 1.6.0-beta.12
"@polkadot/util": ^2.6.1
checksum: 2/e9844fc6dd02f3314cfd39bb59ac5bacd9514344d839f1ef57998132ec64d2a423a2ea2cf2c32beed42f431d45e04b4203a0e1dc8c99c8c5f2c0e8fe2959dd3e
checksum: 2/78308980b99bb5e1826a6339812eb25f694a307ca4dd2bd6dd5fca99382d75f2e06c92fa1b2fbcd7a3f0705f3b3dd641c30239e6041ef8f4955aab5cc378b783
languageName: node
linkType: hard
@ -3198,16 +3198,16 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/metadata@npm:1.6.0-beta.11":
version: 1.6.0-beta.11
resolution: "@polkadot/metadata@npm:1.6.0-beta.11"
"@polkadot/metadata@npm:1.6.0-beta.12":
version: 1.6.0-beta.12
resolution: "@polkadot/metadata@npm:1.6.0-beta.12"
dependencies:
"@babel/runtime": ^7.8.4
"@polkadot/types": 1.6.0-beta.11
"@polkadot/types": 1.6.0-beta.12
"@polkadot/util": ^2.6.1
"@polkadot/util-crypto": ^2.6.1
bn.js: ^5.1.1
checksum: 2/970cfa427bfeffed4094b937425449f49e8b1be61f6220eb0523ad6583989ade567d43c4838e51f52e99da04660930de419c04aab37c6de4576f9e9839fe3ffb
checksum: 2/5985208b5f3c69a4250b72bfd66fc6039ba48d42def9801f56efa55ef1a715372085ffc9f274e1881064ce789b7a84ee58b1496a827f65e0daa34efbdf41f3af
languageName: node
linkType: hard
@ -3216,7 +3216,7 @@ __metadata:
resolution: "@polkadot/react-api@workspace:packages/react-api"
dependencies:
"@babel/runtime": ^7.8.7
"@polkadot/api": ^1.6.0-beta.11
"@polkadot/api": ^1.6.0-beta.12
"@polkadot/extension-dapp": ^0.22.1
rxjs-compat: ^6.5.4
languageName: unknown
@ -3328,37 +3328,37 @@ __metadata:
languageName: unknown
linkType: soft
"@polkadot/rpc-core@npm:1.6.0-beta.11":
version: 1.6.0-beta.11
resolution: "@polkadot/rpc-core@npm:1.6.0-beta.11"
"@polkadot/rpc-core@npm:1.6.0-beta.12":
version: 1.6.0-beta.12
resolution: "@polkadot/rpc-core@npm:1.6.0-beta.12"
dependencies:
"@babel/runtime": ^7.8.4
"@polkadot/jsonrpc": 1.6.0-beta.11
"@polkadot/metadata": 1.6.0-beta.11
"@polkadot/rpc-provider": 1.6.0-beta.11
"@polkadot/types": 1.6.0-beta.11
"@polkadot/jsonrpc": 1.6.0-beta.12
"@polkadot/metadata": 1.6.0-beta.12
"@polkadot/rpc-provider": 1.6.0-beta.12
"@polkadot/types": 1.6.0-beta.12
"@polkadot/util": ^2.6.1
memoizee: ^0.4.14
rxjs: ^6.5.4
checksum: 2/94f77fcae8dda61a2cd7cee8bce7da50b7bdfa02b19062a41bb7804ca9e2acac20ab740b02701a39df49b9f51f28d066cf4bb5ac928a8e61a1dd0252efd2b50a
checksum: 2/cbb5866302d35ded972ba1ca5026d04a42117cce35631e7888daf5b63cd316b1ac07547ed49e7d20969c913ca813935d81f6a639b6da10686d10056acd4e70a7
languageName: node
linkType: hard
"@polkadot/rpc-provider@npm:1.6.0-beta.11":
version: 1.6.0-beta.11
resolution: "@polkadot/rpc-provider@npm:1.6.0-beta.11"
"@polkadot/rpc-provider@npm:1.6.0-beta.12":
version: 1.6.0-beta.12
resolution: "@polkadot/rpc-provider@npm:1.6.0-beta.12"
dependencies:
"@babel/runtime": ^7.8.4
"@polkadot/jsonrpc": 1.6.0-beta.11
"@polkadot/metadata": 1.6.0-beta.11
"@polkadot/types": 1.6.0-beta.11
"@polkadot/jsonrpc": 1.6.0-beta.12
"@polkadot/metadata": 1.6.0-beta.12
"@polkadot/types": 1.6.0-beta.12
"@polkadot/util": ^2.6.1
"@polkadot/util-crypto": ^2.6.1
bn.js: ^5.1.1
eventemitter3: ^4.0.0
isomorphic-fetch: ^2.2.1
websocket: ^1.0.31
checksum: 2/49096502d4dbf9078a565d372c8f3de437491b955e11d1516f14bdb10c4f255caeba03d398d500e48b00fc8c82f0418d9347eda9ab20385de1c3ec7bf195f3f9
checksum: 2/8f366c287288be35f5377a5346afdc33701bfaddce09be77a1edac8fcd76131aa039b3e8bd470a54f0536d6bc0a11a4b3c6f93f94b5a050517d2cfc4448a90db
languageName: node
linkType: hard
@ -3371,19 +3371,19 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/types@npm:^1.6.0-beta.11":
version: 1.6.0-beta.11
resolution: "@polkadot/types@npm:1.6.0-beta.11"
"@polkadot/types@npm:^1.6.0-beta.12":
version: 1.6.0-beta.12
resolution: "@polkadot/types@npm:1.6.0-beta.12"
dependencies:
"@babel/runtime": ^7.8.4
"@polkadot/metadata": 1.6.0-beta.11
"@polkadot/metadata": 1.6.0-beta.12
"@polkadot/util": ^2.6.1
"@polkadot/util-crypto": ^2.6.1
"@types/bn.js": ^4.11.6
bn.js: ^5.1.1
memoizee: ^0.4.14
rxjs: ^6.5.4
checksum: 2/f3b0b6d2d238268cf4cb32d3847133490bd4bdfcb6ec0d2e700142c09f3329431ab1f2be2634eaff5540870377d775c08a1b4a055561f45a861f2e5634932a23
checksum: 2/28f5598a85819b599248fe0ae8c09d38bdfadd3ba75983122f680d2e862fd66bbd120571bbe3db9f915514ab72c232503156ed7a794f9f30297e6382e0e6a30e
languageName: node
linkType: hard