Skip to content

Commit

Permalink
add PoolPerformance context
Browse files Browse the repository at this point in the history
  • Loading branch information
Ross Bulat committed Oct 24, 2023
1 parent 2f17189 commit 09e5ecb
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 58 deletions.
2 changes: 2 additions & 0 deletions src/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { OtherAccountsProvider } from 'contexts/Connect/OtherAccounts';
import { useActiveAccounts } from 'contexts/ActiveAccounts';
import { DappName } from 'consts';
import { ImportedAccountsProvider } from 'contexts/Connect/ImportedAccounts';
import { PoolPerformanceProvider } from 'contexts/Pools/PoolPerformance';

// Embed providers from hook.
export const Providers = () => {
Expand Down Expand Up @@ -91,6 +92,7 @@ export const Providers = () => {
FavoriteValidatorsProvider,
FastUnstakeProvider,
PayoutsProvider,
PoolPerformanceProvider,
UIProvider,
SetupProvider,
MenuProvider,
Expand Down
9 changes: 9 additions & 0 deletions src/contexts/Pools/PoolPerformance/defaults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2023 @paritytech/polkadot-staking-dashboard authors & contributors
// SPDX-License-Identifier: GPL-3.0-only
/* eslint-disable @typescript-eslint/no-unused-vars */

import type { PoolPerformanceContextInterface } from './types';

export const defaultPoolPerformanceContext: PoolPerformanceContextInterface = {
poolRewardPoints: {},
};
90 changes: 90 additions & 0 deletions src/contexts/Pools/PoolPerformance/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright 2023 @paritytech/polkadot-staking-dashboard authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import React, { useState } from 'react';
import { MaxEraRewardPointsEras } from 'consts';
import { useEffectIgnoreInitial } from '@polkadot-cloud/react/hooks';
import Worker from 'workers/poolPerformance?worker';
import { useNetwork } from 'contexts/Network';
import { useValidators } from 'contexts/Validators/ValidatorEntries';
import { useBondedPools } from 'contexts/Pools/BondedPools';
import type { AnyJson } from 'types';
import { useNetworkMetrics } from 'contexts/NetworkMetrics';
import { useApi } from 'contexts/Api';
import type { PoolPerformanceContextInterface } from './types';
import { defaultPoolPerformanceContext } from './defaults';

const worker = new Worker();

export const PoolPerformanceProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const {
networkData: { endpoints },
} = useNetwork();
const { isLightClient } = useApi();
const { bondedPools } = useBondedPools();
const { activeEra } = useNetworkMetrics();
const { erasRewardPointsFetched, erasRewardPoints } = useValidators();

// Store pool performance data.
const [poolRewardPoints, setPoolRewardPoints] = useState<AnyJson>({});

// Handle worker message on completed exposure check.
worker.onmessage = (message: MessageEvent) => {
if (message) {
const { data } = message;
const { task } = data;
// eslint-disable-next-line
if (task !== 'processNominationPoolsRewardData') return;

const { poolRewardData } = data;
setPoolRewardPoints(poolRewardData);
}
};

// Trigger worker to calculate pool reward data for garaphs once:
//
// - active era is synced.
// - era reward points are fetched.
// - bonded pools have been fetched.
//
// Re-calculates when any of the above change.
useEffectIgnoreInitial(() => {
if (
bondedPools.length &&
activeEra.index.isGreaterThan(0) &&
erasRewardPointsFetched === 'synced'
) {
worker.postMessage({
task: 'processNominationPoolsRewardData',
activeEra: activeEra.index.toString(),
bondedPools: bondedPools.map((b) => b.addresses.stash),
endpoints,
isLightClient,
erasRewardPoints,
maxEras: MaxEraRewardPointsEras,
});
}
}, [bondedPools, activeEra, erasRewardPointsFetched]);

return (
<PoolPerformanceContext.Provider
value={{
poolRewardPoints,
}}
>
{children}
</PoolPerformanceContext.Provider>
);
};

export const PoolPerformanceContext =
React.createContext<PoolPerformanceContextInterface>(
defaultPoolPerformanceContext
);

export const usePoolPerformance = () =>
React.useContext(PoolPerformanceContext);
8 changes: 8 additions & 0 deletions src/contexts/Pools/PoolPerformance/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright 2023 @paritytech/polkadot-staking-dashboard authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import type { AnyJson } from '@polkadot-cloud/react/types';

export interface PoolPerformanceContextInterface {
poolRewardPoints: AnyJson;
}
1 change: 0 additions & 1 deletion src/contexts/UI/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ export const defaultUIContext: UIContextInterface = {
isSyncing: false,
isNetworkSyncing: false,
isPoolSyncing: false,
poolRewardPoints: {},
};
53 changes: 2 additions & 51 deletions src/contexts/UI/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,25 @@
import { localStorageOrDefault, setStateWithRef } from '@polkadot-cloud/utils';
import BigNumber from 'bignumber.js';
import React, { useEffect, useRef, useState } from 'react';
import { MaxEraRewardPointsEras, SideMenuStickyThreshold } from 'consts';
import { SideMenuStickyThreshold } from 'consts';
import { useBalances } from 'contexts/Balances';
import type { ImportedAccount } from '@polkadot-cloud/react/types';
import { useActivePools } from 'contexts/Pools/ActivePools';
import { useEffectIgnoreInitial } from '@polkadot-cloud/react/hooks';
import { useImportedAccounts } from 'contexts/Connect/ImportedAccounts';
import Worker from 'workers/poolRewards?worker';
import { useNetwork } from 'contexts/Network';
import { useValidators } from 'contexts/Validators/ValidatorEntries';
import { useBondedPools } from 'contexts/Pools/BondedPools';
import type { AnyJson } from 'types';
import { useApi } from '../Api';
import { useNetworkMetrics } from '../NetworkMetrics';
import { useStaking } from '../Staking';
import * as defaults from './defaults';
import type { UIContextInterface } from './types';

const worker = new Worker();

export const UIProvider = ({ children }: { children: React.ReactNode }) => {
const {
networkData: { endpoints },
} = useNetwork();
const { isReady } = useApi();
const { balances } = useBalances();
const { bondedPools } = useBondedPools();
const { isReady, isLightClient } = useApi();
const { staking, eraStakers } = useStaking();
const { activeEra, metrics } = useNetworkMetrics();
const { synced: activePoolsSynced } = useActivePools();
const { accounts: connectAccounts } = useImportedAccounts();
const { erasRewardPointsFetched, erasRewardPoints } = useValidators();

// set whether the network has been synced.
const [isNetworkSyncing, setIsNetworkSyncing] = useState(false);
Expand All @@ -48,9 +36,6 @@ export const UIProvider = ({ children }: { children: React.ReactNode }) => {
// side menu control
const [sideMenuOpen, setSideMenuOpen] = useState(false);

// Store pool reward points data
const [poolRewardPoints, setPoolRewardPoints] = useState<AnyJson>({});

// get side menu minimised state from local storage, default to false.
const [userSideMenuMinimised, setUserSideMenuMinimisedState] = useState(
localStorageOrDefault('side_menu_minimised', false, true) as boolean
Expand Down Expand Up @@ -152,39 +137,6 @@ export const UIProvider = ({ children }: { children: React.ReactNode }) => {
setContainerRefsState(v);
};

// handle worker message on completed exposure check.
worker.onmessage = (message: MessageEvent) => {
if (message) {
const { data } = message;
const { task } = data;
// eslint-disable-next-line
if (task !== 'processNominationPoolsRewardData') return;

const { poolRewardData } = data;
setPoolRewardPoints(poolRewardData);
}
};

// Trigger worker to calculate pool reward data for garaphs once active era, era reward points and
// bonded pools have been fetched.
useEffectIgnoreInitial(() => {
if (
bondedPools.length &&
activeEra.index.isGreaterThan(0) &&
erasRewardPointsFetched === 'synced'
) {
worker.postMessage({
task: 'processNominationPoolsRewardData',
activeEra: activeEra.index.toString(),
bondedPools: bondedPools.map((b) => b.addresses.stash),
endpoints,
isLightClient,
erasRewardPoints,
maxEras: MaxEraRewardPointsEras,
});
}
}, [bondedPools, activeEra, erasRewardPointsFetched]);

return (
<UIContext.Provider
value={{
Expand All @@ -198,7 +150,6 @@ export const UIProvider = ({ children }: { children: React.ReactNode }) => {
isNetworkSyncing,
isPoolSyncing,
containerRefs,
poolRewardPoints,
}}
>
{children}
Expand Down
3 changes: 0 additions & 3 deletions src/contexts/UI/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright 2023 @paritytech/polkadot-staking-dashboard authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import type { AnyJson } from '@polkadot-cloud/react/types';

export interface UIContextInterface {
setSideMenu: (v: boolean) => void;
setUserSideMenuMinimised: (v: boolean) => void;
Expand All @@ -14,5 +12,4 @@ export interface UIContextInterface {
isSyncing: boolean;
isNetworkSyncing: boolean;
isPoolSyncing: boolean;
poolRewardPoints: AnyJson;
}
4 changes: 2 additions & 2 deletions src/library/Pool/Rewards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ import {
normaliseEraPoints,
prefillEraPoints,
} from 'library/ValidatorList/ValidatorItem/Utils';
import { useUi } from 'contexts/UI';
import type { AnyJson } from '@polkadot-cloud/react/types';
import { usePoolPerformance } from 'contexts/Pools/PoolPerformance';

export const Rewards = ({ address, displayFor = 'default' }: any) => {
// const { t } = useTranslation('library');
const { isReady } = useApi();
const { poolRewardPoints } = useUi();
const { setTooltipTextAndOpen } = useTooltip();
const { poolRewardPoints } = usePoolPerformance();
const { eraPointsBoundaries, erasRewardPoints } = useValidators();

const eraRewardPoints = Object.fromEntries(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ ctx.addEventListener('message', async (event: AnyJson) => {
});

// Process `erasStakersClipped` and generate nomination pool reward data.
// TODO: takes pool stash addresses as input.
const processErasStakersForNominationPoolRewards = async ({
activeEra,
maxEras,
Expand Down

0 comments on commit 09e5ecb

Please sign in to comment.