Skip to content

Commit

Permalink
Merge branch 'fix/oct-714-history-deposit-refetch' into 'master'
Browse files Browse the repository at this point in the history
OCT-714 Locking/unlocking GLM does not show up in history & effective deposit doesnt update

See merge request wildland/governance/octant!561
  • Loading branch information
aziolek committed Aug 3, 2023
2 parents b9fa136 + 1caaa0a commit 19ec6d2
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 14 deletions.
57 changes: 51 additions & 6 deletions client/src/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ import networkConfig from 'constants/networkConfig';
import web3, { alchemyProvider } from 'hooks/contracts/web3';
import useCryptoValues from 'hooks/queries/useCryptoValues';
import useCurrentEpoch from 'hooks/queries/useCurrentEpoch';
import useDepositEffectiveAtCurrentEpoch from 'hooks/queries/useDepositEffectiveAtCurrentEpoch';
import useHistory from 'hooks/queries/useHistory';
import useIndividualReward from 'hooks/queries/useIndividualReward';
import useIsDecisionWindowOpen from 'hooks/queries/useIsDecisionWindowOpen';
import useProposalsContract from 'hooks/queries/useProposalsContract';
import useUserAllocations from 'hooks/queries/useUserAllocations';
import useBlockNumber from 'hooks/subgraph/useBlockNumber';
import RootRoutes from 'routes/RootRoutes/RootRoutes';
import localStorageService from 'services/localStorageService';
import useAllocationsStore from 'store/allocations/store';
import useMetaStore, { initialState as metaInitialState } from 'store/meta/store';
import useOnboardingStore from 'store/onboarding/store';
import useSettingsStore from 'store/settings/store';
import useTipsStore from 'store/tips/store';
Expand Down Expand Up @@ -73,6 +77,10 @@ const App = (): ReactElement => {
isInitialized: meta.isInitialized,
setValuesFromLocalStorage,
}));
const { blockNumberWithLatestTx, setBlockNumberWithLatestTx } = useMetaStore(state => ({
blockNumberWithLatestTx: state.data.blockNumberWithLatestTx,
setBlockNumberWithLatestTx: state.setBlockNumberWithLatestTx,
}));
const queryClient = useQueryClient();
const { address, isConnected } = useAccount();
useCryptoValues(displayCurrency, {
Expand All @@ -91,6 +99,12 @@ const App = (): ReactElement => {
const { data: proposals } = useProposalsContract();
const { data: userAllocations } = useUserAllocations();
const { data: individualReward } = useIndividualReward();
const { data: blockNumber } = useBlockNumber(
blockNumberWithLatestTx !== metaInitialState.blockNumberWithLatestTx,
);
const { refetch: refetchDepositEffectiveAtCurrentEpoch } = useDepositEffectiveAtCurrentEpoch();
const { refetch: refetchHistory } = useHistory();

const [isAccountChanging, setIsAccountChanging] = useState(false);
const [isConnectedLocal, setIsConnectedLocal] = useState<boolean>(false);
const [currentAddressLocal, setCurrentAddressLocal] = useState<null | string>(null);
Expand All @@ -109,12 +123,6 @@ const App = (): ReactElement => {
}
}, [chainIdLocal]);

useEffect(() => {
if (chain && chain.id && chain.id !== chainIdLocal) {
setChainIdLocal(chain.id);
}
}, [chain, chainIdLocal, setChainIdLocal]);

useEffect(() => {
if (!chain || !chain.id || chain.id !== networkConfig.id) {
/**
Expand Down Expand Up @@ -149,6 +157,12 @@ const App = (): ReactElement => {
// eslint-disable-next-line
}, []);

useEffect(() => {
if (chain && chain.id && chain.id !== chainIdLocal) {
setChainIdLocal(chain.id);
}
}, [chain, chainIdLocal, setChainIdLocal]);

useEffect(() => {
if (isConnected !== isConnectedLocal) {
setIsConnectedLocal(isConnected);
Expand All @@ -173,6 +187,37 @@ const App = (): ReactElement => {
}
}, [isDecisionWindowOpen, isDecisionWindowOpenLocal, setIsDecisionWindowOpenLocal]);

useEffect(() => {
/**
* Locking and unlocking GLMs require updating history and effective deposit.
* Both these values are coming from backend, which takes them from subgraph (history - always, effective deposit only during epoch 1).
*
* The problem is that value in subgraph (and consequently in the backend)
* is updated only after block is indexed in the subgraph.
*
* So, after lock / unlock is done, blockNumberWithLatestTx is set to the value from transaction,
* polling starts in useBlockNumber hook and after the number
* of block changes, refetchHistory and refetchDepositEffectiveAtCurrentEpoch
* is triggered and blockNumberWithLatestTx to null.
*/
if (blockNumber && blockNumberWithLatestTx && blockNumber > blockNumberWithLatestTx) {
refetchHistory();

if (currentEpoch === 1) {
refetchDepositEffectiveAtCurrentEpoch();
}

setBlockNumberWithLatestTx(metaInitialState.blockNumberWithLatestTx);
}
}, [
currentEpoch,
blockNumber,
setBlockNumberWithLatestTx,
blockNumberWithLatestTx,
refetchHistory,
refetchDepositEffectiveAtCurrentEpoch,
]);

useEffect(() => {
const doesChainIdRequireFlush = chain && chain.id && chain.id !== chainIdLocal;
const doesIsConnectedRequireFlush = !isConnected && isConnectedLocal;
Expand Down
1 change: 1 addition & 0 deletions client/src/api/queryKeys/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const ROOTS: Root = {
};

export const QUERY_KEYS: QueryKeys = {
blockNumber: ['blockNumber'],
cryptoValues: fiatCurrency => [ROOTS.cryptoValues, fiatCurrency],
currentEpoch: ['currentEpoch'],
currentEpochEnd: ['currentEpochEnd'],
Expand Down
1 change: 1 addition & 0 deletions client/src/api/queryKeys/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type Root = {
};

export type QueryKeys = {
blockNumber: ['blockNumber'];
cryptoValues: (
fiatCurrency: NonNullable<SettingsData['displayCurrency']>,
) => [Root['cryptoValues'], NonNullable<SettingsData['displayCurrency']>];
Expand Down
17 changes: 10 additions & 7 deletions client/src/components/dedicated/GlmLock/GlmLock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import useAvailableFundsGlm from 'hooks/helpers/useAvailableFundsGlm';
import useMediaQuery from 'hooks/helpers/useMediaQuery';
import useLock from 'hooks/mutations/useLock';
import useUnlock from 'hooks/mutations/useUnlock';
import useDepositEffectiveAtCurrentEpoch from 'hooks/queries/useDepositEffectiveAtCurrentEpoch';
import useDepositValue from 'hooks/queries/useDepositValue';
import useProposalsContract from 'hooks/queries/useProposalsContract';
import useMetaStore from 'store/meta/store';
import triggerToast from 'utils/triggerToast';

import styles from './GlmLock.module.scss';
Expand All @@ -29,22 +29,25 @@ import { formInitialValues, validationSchema } from './utils';
const GlmLock: FC<GlmLockProps> = ({ currentMode, onCurrentModeChange, onCloseModal }) => {
const { i18n } = useTranslation();
const { address } = useAccount();
const { isDesktop } = useMediaQuery();
const { setBlockNumberWithLatestTx } = useMetaStore(state => ({
setBlockNumberWithLatestTx: state.setBlockNumberWithLatestTx,
}));

const { refetch: refetchDepositEffectiveAtCurrentEpoch } = useDepositEffectiveAtCurrentEpoch();
const { data: availableFundsGlm } = useAvailableFundsGlm();
const { data: depositsValue, refetch: refetchDeposit } = useDepositValue();
const { data: proposalsAddresses } = useProposalsContract();
const { data: depositsValue, refetch: refetchDeposit } = useDepositValue();
const contract = useContractErc20();
const { isDesktop } = useMediaQuery();

const [step, setStep] = useState<Step>(1);
const [transactionHash, setTransactionHash] = useState<string>('');
const [isCryptoOrFiatInputFocused, setIsCryptoOrFiatInputFocused] = useState(false);
const showBudgetBox = isDesktop || (!isDesktop && !isCryptoOrFiatInputFocused);

const onRefetch = async (): Promise<void> => {
const onRefetch = async (blockNumber: number): Promise<void> => {
// History and effective deposits are refetched in App.tsx. Look for a comment there.
setBlockNumberWithLatestTx(blockNumber);
await refetchDeposit();
await refetchDepositEffectiveAtCurrentEpoch();
};

const onMutate = async (): Promise<void> => {
Expand Down Expand Up @@ -72,7 +75,7 @@ const GlmLock: FC<GlmLockProps> = ({ currentMode, onCurrentModeChange, onCloseMo
};

const onSuccess = async (transactionResponse: TransactionReceipt): Promise<void> => {
await onRefetch();
await onRefetch(transactionResponse.blockNumber);
setTransactionHash(transactionResponse!.transactionHash);
setStep(3);
};
Expand Down
9 changes: 8 additions & 1 deletion client/src/components/dedicated/History/History.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,26 @@ import HistoryItemSkeleton from 'components/dedicated/History//HistoryItemSkelet
import HistoryList from 'components/dedicated/History/HistoryList/HistoryList';
import useCurrentEpoch from 'hooks/queries/useCurrentEpoch';
import useHistory from 'hooks/queries/useHistory';
import useMetaStore, { initialState as metaInitialState } from 'store/meta/store';
import getIsPreLaunch from 'utils/getIsPreLaunch';

import styles from './History.module.scss';
import HistoryProps from './types';

const History: FC<HistoryProps> = ({ className }) => {
const { i18n } = useTranslation('translation');
const { blockNumberWithLatestTx } = useMetaStore(state => ({
blockNumberWithLatestTx: state.data.blockNumberWithLatestTx,
}));

const { data: currentEpoch } = useCurrentEpoch();
const { data: history, isFetching: isFetchingHistory } = useHistory();

const isListAvailable = history !== undefined;
const isPreLaunch = getIsPreLaunch(currentEpoch);
const showLoader = !isListAvailable && isFetchingHistory && !isPreLaunch;
const showLoader =
blockNumberWithLatestTx !== metaInitialState.blockNumberWithLatestTx ||
(!isListAvailable && isFetchingHistory && !isPreLaunch);

return (
<BoxRounded
Expand Down
1 change: 1 addition & 0 deletions client/src/constants/networkConfig/network.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

jest.mock('wagmi/chains', () => ({
goerli: 'goerli-chain-mock',
mainnet: 'mainnet-chain-mock',
sepolia: 'sepolia-chain-mock',
}));
jest.mock('env', () => ({}));
Expand Down
8 changes: 8 additions & 0 deletions client/src/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
* Therefore it is highly recommended to use the babel or swc plugin for production.
*/
const documents = {
'\n query GetBlockNumber {\n _meta {\n block {\n number\n }\n }\n }\n':
types.GetBlockNumberDocument,
'\n query GetLockedSummaryLatest {\n lockedSummaryLatest(id: "latest") {\n id\n lockedTotal\n lockedRatio\n }\n }\n':
types.GetLockedSummaryLatestDocument,
};
Expand All @@ -31,6 +33,12 @@ const documents = {
*/
export function graphql(source: string): unknown;

/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(
source: '\n query GetBlockNumber {\n _meta {\n block {\n number\n }\n }\n }\n',
): (typeof documents)['\n query GetBlockNumber {\n _meta {\n block {\n number\n }\n }\n }\n'];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
39 changes: 39 additions & 0 deletions client/src/gql/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,13 @@ export enum _SubgraphErrorPolicy_ {
Deny = 'deny',
}

export type GetBlockNumberQueryVariables = Exact<{ [key: string]: never }>;

export type GetBlockNumberQuery = {
__typename?: 'Query';
_meta?: { __typename?: '_Meta_'; block: { __typename?: '_Block_'; number: number } } | null;
};

export type GetLockedSummaryLatestQueryVariables = Exact<{ [key: string]: never }>;

export type GetLockedSummaryLatestQuery = {
Expand All @@ -853,6 +860,38 @@ export type GetLockedSummaryLatestQuery = {
} | null;
};

export const GetBlockNumberDocument = {
kind: 'Document',
definitions: [
{
kind: 'OperationDefinition',
operation: 'query',
name: { kind: 'Name', value: 'GetBlockNumber' },
selectionSet: {
kind: 'SelectionSet',
selections: [
{
kind: 'Field',
name: { kind: 'Name', value: '_meta' },
selectionSet: {
kind: 'SelectionSet',
selections: [
{
kind: 'Field',
name: { kind: 'Name', value: 'block' },
selectionSet: {
kind: 'SelectionSet',
selections: [{ kind: 'Field', name: { kind: 'Name', value: 'number' } }],
},
},
],
},
},
],
},
},
],
} as unknown as DocumentNode<GetBlockNumberQuery, GetBlockNumberQueryVariables>;
export const GetLockedSummaryLatestDocument = {
kind: 'Document',
definitions: [
Expand Down
43 changes: 43 additions & 0 deletions client/src/hooks/subgraph/useBlockNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useQuery, UseQueryResult } from '@tanstack/react-query';
import request from 'graphql-request';

import { QUERY_KEYS } from 'api/queryKeys';
import env from 'env';
import { graphql } from 'gql/gql';

type Test = {
// eslint-disable-next-line @typescript-eslint/naming-convention
_meta?:
| {
block: {
number: number;
};
}
| undefined
| null;
};

const GET_BLOCK_NUMBER = graphql(`
query GetBlockNumber {
_meta {
block {
number
}
}
}
`);

export default function useBlockNumber(
isRefetchEnabled = true,
): UseQueryResult<number | null | undefined> {
const { subgraphAddress } = env;

return useQuery<Test, any, number | undefined, any>(
QUERY_KEYS.blockNumber,
async () => request(subgraphAddress, GET_BLOCK_NUMBER),
{
refetchInterval: isRefetchEnabled ? 1000 : false,
select: data => data._meta?.block.number,
},
);
}
17 changes: 17 additions & 0 deletions client/src/store/meta/store.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import useMetaStore from './store';

describe('useMetaStore', () => {
it('initial state should be correct', () => {
expect(useMetaStore.getState().data.blockNumberWithLatestTx).toEqual(null);
});

it('should correctly set setBlockNumberWithLatestTx', () => {
const { setBlockNumberWithLatestTx } = useMetaStore.getState();

expect(useMetaStore.getState().data.blockNumberWithLatestTx).toEqual(null);
setBlockNumberWithLatestTx(1000);
expect(useMetaStore.getState().data.blockNumberWithLatestTx).toEqual(1000);
setBlockNumberWithLatestTx(1001);
expect(useMetaStore.getState().data.blockNumberWithLatestTx).toEqual(1001);
});
});
19 changes: 19 additions & 0 deletions client/src/store/meta/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getStoreWithMeta } from 'store/utils/getStoreWithMeta';

import { MetaData, MetaMethods } from './types';

export const initialState: MetaData = {
blockNumberWithLatestTx: null,
};

export default getStoreWithMeta<MetaData, MetaMethods>({
getStoreMethods: set => ({
// eslint-disable-next-line @typescript-eslint/naming-convention
setBlockNumberWithLatestTx: payload => {
set(state => ({
data: { ...state.data, blockNumberWithLatestTx: payload },
}));
},
}),
initialState,
});
7 changes: 7 additions & 0 deletions client/src/store/meta/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface MetaData {
blockNumberWithLatestTx: number | null;
}

export interface MetaMethods {
setBlockNumberWithLatestTx: (payload: MetaData['blockNumberWithLatestTx']) => void;
}

0 comments on commit 19ec6d2

Please sign in to comment.