Skip to content

Commit

Permalink
feat(refactor): Remove pre-paged rewards deprecation logic (#2197)
Browse files Browse the repository at this point in the history
  • Loading branch information
rossbulat authored Aug 1, 2024
1 parent b431d78 commit c4fada1
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 113 deletions.
18 changes: 1 addition & 17 deletions src/config/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,9 @@ import WestendInlineSVG from 'img/westend_inline.svg?react';
import PolkadotTokenSVG from 'config/tokens/svg/DOT.svg?react';
import KusamaTokenSVG from 'config/tokens/svg/KSM.svg?react';
import WestendTokenSVG from 'config/tokens/svg/WND.svg?react';

import type { NetworkName, Networks } from 'types';
import type { Networks } from 'types';
import BigNumber from 'bignumber.js';

// DEPRECATION: Paged Rewards
//
// Temporary until paged rewards migration has completed on all networks. Wait 84 eras from Polkadot
// start: 1420 + 84 = 1504, when full history depth will be moved over to new paged rewards storage.
export const NetworksWithPagedRewards: NetworkName[] = [
'polkadot',
'kusama',
'westend',
];
export const PagedRewardsStartEra: Record<NetworkName, BigNumber | null> = {
polkadot: new BigNumber(1420),
kusama: new BigNumber(6514),
westend: new BigNumber(7167),
};

export const NetworkList: Networks = {
polkadot: {
name: 'polkadot',
Expand Down
1 change: 0 additions & 1 deletion src/contexts/Api/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,4 @@ export const defaultApiContext: APIContextInterface = {
activeEra: defaultActiveEra,
poolsConfig: defaultPoolsConfig,
stakingMetrics: defaultStakingMetrics,
isPagedRewardsActive: (e) => false,
};
19 changes: 1 addition & 18 deletions src/contexts/Api/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@

import { setStateWithRef } from '@w3ux/utils';
import { createContext, useContext, useEffect, useRef, useState } from 'react';
import {
NetworkList,
NetworksWithPagedRewards,
PagedRewardsStartEra,
} from 'config/networks';
import { NetworkList } from 'config/networks';

import type {
APIActiveEra,
Expand Down Expand Up @@ -355,18 +351,6 @@ export const APIProvider = ({ children, network }: APIProviderProps) => {
}
};

// Given an era, determine whether paged rewards are active.
const isPagedRewardsActive = (era: BigNumber): boolean => {
const networkStartEra = PagedRewardsStartEra[network];
if (!networkStartEra) {
return false;
}
return (
NetworksWithPagedRewards.includes(network) &&
era.isGreaterThanOrEqualTo(networkStartEra)
);
};

const reInitialiseApi = async (type: ConnectionType) => {
setApiStatus('disconnected');

Expand Down Expand Up @@ -462,7 +446,6 @@ export const APIProvider = ({ children, network }: APIProviderProps) => {
activeEra,
poolsConfig,
stakingMetrics,
isPagedRewardsActive,
}}
>
{children}
Expand Down
1 change: 0 additions & 1 deletion src/contexts/Api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,4 @@ export interface APIContextInterface {
activeEra: APIActiveEra;
poolsConfig: APIPoolsConfig;
stakingMetrics: APIStakingMetrics;
isPagedRewardsActive: (era: BigNumber) => boolean;
}
17 changes: 2 additions & 15 deletions src/contexts/Pools/PoolPerformance/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { useApi } from 'contexts/Api';
import BigNumber from 'bignumber.js';
import { mergeDeep, setStateWithRef } from '@w3ux/utils';
import { useStaking } from 'contexts/Staking';
import { formatRawExposures } from 'contexts/Staking/Utils';
import type {
PoolPerformanceContextInterface,
PoolPerformanceTasks,
Expand All @@ -39,9 +38,9 @@ export const PoolPerformanceProvider = ({
children: ReactNode;
}) => {
const { network } = useNetwork();
const { api, activeEra } = useApi();
const { getPagedErasStakers } = useStaking();
const { erasRewardPoints } = useValidators();
const { api, activeEra, isPagedRewardsActive } = useApi();

// Store pool performance task data under a given key as it is being fetched . NOTE: Requires a
// ref to be accessed in `processEra` before re-render.
Expand Down Expand Up @@ -187,19 +186,7 @@ export const PoolPerformanceProvider = ({
// NOTE: This will not make any difference on the first run.
updateTaskCurrentEra(key, era);

let exposures;
if (isPagedRewardsActive(era)) {
exposures = await getPagedErasStakers(era.toString());
} else {
// DEPRECATION: Paged Rewards
//
// Use deprecated `erasStakersClipped` if paged rewards not active for this era.
const result = await api.query.staking.erasStakersClipped.entries(
era.toString()
);
exposures = formatRawExposures(result);
}

const exposures = await getPagedErasStakers(era.toString());
const addresses = tasksRef.current[key]?.addresses || [];

worker.postMessage({
Expand Down
108 changes: 47 additions & 61 deletions src/contexts/Staking/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-3.0-only

import { greaterThanZero, rmCommas, setStateWithRef } from '@w3ux/utils';
import BigNumber from 'bignumber.js';
import type { ReactNode } from 'react';
import { createContext, useContext, useRef, useState } from 'react';
import { useBalances } from 'contexts/Balances';
Expand All @@ -23,11 +22,7 @@ import { useImportedAccounts } from 'contexts/Connect/ImportedAccounts';
import { useApi } from '../Api';
import { useBonded } from '../Bonded';
import { defaultEraStakers, defaultStakingContext } from './defaults';
import {
setLocalEraExposures,
getLocalEraExposures,
formatRawExposures,
} from './Utils';
import { setLocalEraExposures, getLocalEraExposures } from './Utils';
import type { NominationStatus } from 'library/ValidatorList/ValidatorItem/types';
import { SyncController } from 'controllers/Sync';

Expand All @@ -45,7 +40,7 @@ export const StakingProvider = ({ children }: { children: ReactNode }) => {
const { getLedger, getNominations } = useBalances();
const { accounts: connectAccounts } = useImportedAccounts();
const { activeAccount, getActiveAccount } = useActiveAccounts();
const { isReady, api, apiStatus, activeEra, isPagedRewardsActive } = useApi();
const { isReady, api, apiStatus, activeEra } = useApi();

// Store eras stakers in state.
const [eraStakers, setEraStakers] = useState<EraStakers>(defaultEraStakers);
Expand Down Expand Up @@ -224,70 +219,61 @@ export const StakingProvider = ({ children }: { children: ReactNode }) => {
!activeAccount ||
(!hasController() && !isBonding() && !isNominating() && !isUnlocking());

// If paged rewards are active for the era, fetch eras stakers from the new storage items,
// otherwise use the old storage items.
// Fetch eras stakers from storage.
const getPagedErasStakers = async (era: string) => {
if (!api) {
return [];
}

if (isPagedRewardsActive(new BigNumber(era))) {
const overview: AnyApi =
await api.query.staking.erasStakersOverview.entries(era);
const overview: AnyApi =
await api.query.staking.erasStakersOverview.entries(era);

const validators = overview.reduce(
(prev: Record<string, Exposure>, [keys, value]: AnyApi) => {
const validator = keys.toHuman()[1];
const { own, total } = value.toHuman();
return { ...prev, [validator]: { own, total } };
},
{}
);
const validatorKeys = Object.keys(validators);
const validators = overview.reduce(
(prev: Record<string, Exposure>, [keys, value]: AnyApi) => {
const validator = keys.toHuman()[1];
const { own, total } = value.toHuman();
return { ...prev, [validator]: { own, total } };
},
{}
);
const validatorKeys = Object.keys(validators);

const pagedResults = await Promise.all(
validatorKeys.map((v) =>
api.query.staking.erasStakersPaged.entries(era, v)
)
);
const pagedResults = await Promise.all(
validatorKeys.map((v) =>
api.query.staking.erasStakersPaged.entries(era, v)
)
);

const result: Exposure[] = [];
let i = 0;
for (const pagedResult of pagedResults) {
const validator = validatorKeys[i];
const { own, total } = validators[validator];
const others = pagedResult.reduce(
(prev: ExposureOther[], [, v]: AnyApi) => {
const o = v.toHuman()?.others || [];
if (!o.length) {
return prev;
}
return prev.concat(o);
},
[]
);
const result: Exposure[] = [];
let i = 0;
for (const pagedResult of pagedResults) {
const validator = validatorKeys[i];
const { own, total } = validators[validator];
const others = pagedResult.reduce(
(prev: ExposureOther[], [, v]: AnyApi) => {
const o = v.toHuman()?.others || [];
if (!o.length) {
return prev;
}
return prev.concat(o);
},
[]
);

result.push({
keys: [rmCommas(era), validator],
val: {
total: rmCommas(total),
own: rmCommas(own),
others: others.map(({ who, value }) => ({
who,
value: rmCommas(value),
})),
},
});
i++;
}
return result;
result.push({
keys: [rmCommas(era), validator],
val: {
total: rmCommas(total),
own: rmCommas(own),
others: others.map(({ who, value }) => ({
who,
value: rmCommas(value),
})),
},
});
i++;
}

// DEPRECATION: Paged Rewards
//
// Use legacy `erasStakers` storage item.
const result = await api.query.staking.erasStakers.entries(era);
return formatRawExposures(result);
return result;
};

useEffectIgnoreInitial(() => {
Expand Down

0 comments on commit c4fada1

Please sign in to comment.