From b82b769ca506e2567bb0eba5bd461502ead47705 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sun, 17 Nov 2019 14:37:33 +0100 Subject: [PATCH] Cleanup reward graphs (#1904) * Cleanup reward graphs * Cleanup import --- packages/app-staking/src/Query/Validator.tsx | 36 ++++++++++++++++--- packages/app-staking/src/index.tsx | 3 +- .../src/useSessionRewards.tsx | 8 ++--- packages/react-hooks/src/index.ts | 2 +- 4 files changed, 37 insertions(+), 12 deletions(-) rename packages/{react-hooks => app-staking}/src/useSessionRewards.tsx (96%) diff --git a/packages/app-staking/src/Query/Validator.tsx b/packages/app-staking/src/Query/Validator.tsx index 1d6674f5ed..cc9a3dc7e4 100644 --- a/packages/app-staking/src/Query/Validator.tsx +++ b/packages/app-staking/src/Query/Validator.tsx @@ -127,19 +127,45 @@ function Validator ({ className, sessionRewards, t, validatorId }: Props): React const rewardsLabels: string[] = []; const rewardsChart: LineData = [[], [], []]; let total = new BN(0); + let lastRewardIndex = 0; + // we only work from the second position, the first deemed incomplete sessionRewards.forEach(({ blockNumber, reward, sessionIndex, slashes }, index): void => { - // this shows the start of the new era, however rewards are for previous - rewardsLabels.push(formatNumber(sessionIndex.subn(1))); + // we are trying to find the first index where rewards are allocated, this is our start + // since we only want complete eras, this means we drop some at the start + if (lastRewardIndex === 0) { + if (index && reward.gtn(0)) { + lastRewardIndex = index; + } + return; + } + + // slash is extracted from the available slashes const neg = extractEraSlash(validatorId, slashes); - const pos = index && blockCounts[index - 1] - ? reward.mul(blockCounts[index - 1]).div(blockNumber.sub(sessionRewards[index - 1].blockNumber)) - : new BN(0); + + // start of a new session, use the counts for the previous + const totalBlocks = blockCounts + .filter((count, countIndex): boolean => + !!count && countIndex >= lastRewardIndex && countIndex < index) + .reduce((total, count): BN => total.add(count), new BN(0)); + + // calculate the rewards based on our total share + const pos = reward + .mul(totalBlocks) + .div(blockNumber.sub(sessionRewards[lastRewardIndex].blockNumber)); // add this to the total total = total.add(neg).add(pos); + // if we have a reward here, set the reward index for the next iteration + if (reward.gtn(0)) { + lastRewardIndex = index; + } + + // this shows the start of the new era, however rewards are for previous + rewardsLabels.push(formatNumber(sessionIndex.subn(1))); + // calculate and format to 3 decimals rewardsChart[0].push(balanceToNumber(neg, divisor)); rewardsChart[1].push(balanceToNumber(pos, divisor)); diff --git a/packages/app-staking/src/index.tsx b/packages/app-staking/src/index.tsx index 0cb9da803d..ea357cea27 100644 --- a/packages/app-staking/src/index.tsx +++ b/packages/app-staking/src/index.tsx @@ -14,7 +14,7 @@ import styled from 'styled-components'; import { Option } from '@polkadot/types'; import { HelpOverlay } from '@polkadot/react-components'; import Tabs from '@polkadot/react-components/Tabs'; -import { trackStream, useAccounts, useApi, useSessionRewards } from '@polkadot/react-hooks'; +import { trackStream, useAccounts, useApi } from '@polkadot/react-hooks'; import Accounts from './Actions/Accounts'; import basicMd from './md/basic.md'; @@ -22,6 +22,7 @@ import Overview from './Overview'; import Query from './Query'; import { MAX_SESSIONS } from './constants'; import translate from './translate'; +import useSessionRewards from './useSessionRewards'; interface Props extends AppProps, I18nProps { } diff --git a/packages/react-hooks/src/useSessionRewards.tsx b/packages/app-staking/src/useSessionRewards.tsx similarity index 96% rename from packages/react-hooks/src/useSessionRewards.tsx rename to packages/app-staking/src/useSessionRewards.tsx index 44a411aab4..834d21e4aa 100644 --- a/packages/react-hooks/src/useSessionRewards.tsx +++ b/packages/app-staking/src/useSessionRewards.tsx @@ -1,19 +1,17 @@ -// Copyright 2017-2019 @polkadot/react-hooks authors & contributors +// Copyright 2017-2019 @polkadot/app-staking authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. import { Balance, BlockNumber, EventRecord, Hash, Header } from '@polkadot/types/interfaces'; -import { Slash, SessionRewards } from './types'; +import { Slash, SessionRewards } from '@polkadot/react-hooks/types'; import BN from 'bn.js'; import { useEffect, useState } from 'react'; import { ApiPromise } from '@polkadot/api'; +import { useApi, useCacheKey } from '@polkadot/react-hooks'; import { createType } from '@polkadot/types'; import { bnMax, u8aToU8a } from '@polkadot/util'; -import useApi from './useApi'; -import useCacheKey from './useCacheKey'; - interface SerializedSlash { accountId: string; amount: string; diff --git a/packages/react-hooks/src/index.ts b/packages/react-hooks/src/index.ts index f0ea2bed7e..e93c4c86dd 100644 --- a/packages/react-hooks/src/index.ts +++ b/packages/react-hooks/src/index.ts @@ -7,6 +7,6 @@ export { default as trackStream } from './track/trackStream'; export { default as useAccounts } from './useAccounts'; export { default as useAddresses } from './useAddresses'; export { default as useApi } from './useApi'; +export { default as useCacheKey } from './useCacheKey'; export { default as useDebounce } from './useDebounce'; export { default as useFavorites } from './useFavorites'; -export { default as useSessionRewards } from './useSessionRewards';