Skip to content

Commit

Permalink
refactor: add cancel block query (#2116)
Browse files Browse the repository at this point in the history
  • Loading branch information
namgold authored Jul 25, 2023
1 parent 9b3112f commit 9f87316
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 81 deletions.
2 changes: 1 addition & 1 deletion src/components/swapv2/AdvancedSwapDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export function TradeSummaryBridge({ outputInfo }: { outputInfo: OutputBridgeInf
<Trans>{tokenInfoOut?.SwapFeeRatePerMillion}% Transaction Fee</Trans>
</Text>
{tokenInfoOut?.MinimumSwapFee === tokenInfoOut?.MaximumSwapFee ? (
outputInfo.fee > 0 && (
Number(outputInfo.fee) > 0 && (
<Text marginTop={'5px'}>
<Trans>
Gas Fee: {`${fee} ${tokenInfoOut.symbol} `}
Expand Down
15 changes: 11 additions & 4 deletions src/data/poolRate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const getHourlyRateData = async (
networkInfo: EVMNetworkInfo,
elasticClient: ApolloClient<NormalizedCacheObject>,
blockClient: ApolloClient<NormalizedCacheObject>,
abortSignal: AbortSignal,
signal: AbortSignal,
): Promise<[PoolRatesEntry[], PoolRatesEntry[]] | undefined> => {
try {
const utcEndTime = dayjs.utc()
Expand All @@ -39,8 +39,14 @@ export const getHourlyRateData = async (
}

// once you have all the timestamps, get the blocks for each timestamp in a bulk query
let blocks = await getBlocksFromTimestamps(isEnableBlockService, blockClient, timestamps, networkInfo.chainId)
if (abortSignal.aborted) return
let blocks = await getBlocksFromTimestamps(
isEnableBlockService,
blockClient,
timestamps,
networkInfo.chainId,
signal,
)
if (signal.aborted) return
// catch failing case
if (!blocks || blocks?.length === 0) {
return
Expand All @@ -52,9 +58,10 @@ export const getHourlyRateData = async (
elasticClient,
blocks,
[poolAddress],
signal,
100,
)
if (abortSignal.aborted) return
if (signal.aborted) return

// format token ETH price results
const values: {
Expand Down
26 changes: 19 additions & 7 deletions src/state/application/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { useActiveWeb3React } from 'hooks/index'
import { useAppSelector } from 'state/hooks'
import { AppDispatch, AppState } from 'state/index'
import { useTokenPricesWithLoading } from 'state/tokenPrices/hooks'
import { getBlockFromTimestamp, getPercentChange } from 'utils'
import { getBlocksFromTimestamps, getPercentChange } from 'utils'
import { createClient } from 'utils/client'

import {
Expand Down Expand Up @@ -228,9 +228,11 @@ export function useActivePopups() {
* Gets the current price of ETH, 24 hour price, and % change between them
*/
export const getEthPrice = async (
isEnableBlockService: boolean,
chainId: ChainId,
apolloClient: ApolloClient<NormalizedCacheObject>,
blockClient: ApolloClient<NormalizedCacheObject>,
signal: AbortSignal,
) => {
const utcCurrentTime = dayjs()
const utcOneDayBack = utcCurrentTime.subtract(1, 'day').startOf('minute').unix()
Expand All @@ -240,7 +242,9 @@ export const getEthPrice = async (
let priceChangeETH = 0

try {
const oneDayBlock = await getBlockFromTimestamp(utcOneDayBack, chainId, blockClient)
const oneDayBlock = (
await getBlocksFromTimestamps(isEnableBlockService, blockClient, [utcOneDayBack], chainId, signal)
)?.[0]?.number
const result = await apolloClient.query({
query: ETH_PRICE(),
fetchPolicy: 'network-only',
Expand All @@ -264,9 +268,11 @@ export const getEthPrice = async (
}

const getPrommEthPrice = async (
isEnableBlockService: boolean,
chainId: ChainId,
apolloClient: ApolloClient<NormalizedCacheObject>,
blockClient: ApolloClient<NormalizedCacheObject>,
signal: AbortSignal,
) => {
const utcCurrentTime = dayjs()
const utcOneDayBack = utcCurrentTime.subtract(1, 'day').startOf('minute').unix()
Expand All @@ -276,7 +282,9 @@ const getPrommEthPrice = async (
let priceChangeETH = 0

try {
const oneDayBlock = await getBlockFromTimestamp(utcOneDayBack, chainId, blockClient)
const oneDayBlock = (
await getBlocksFromTimestamps(isEnableBlockService, blockClient, [utcOneDayBack], chainId, signal)
)?.[0]?.number
const result = await apolloClient.query({
query: PROMM_ETH_PRICE(),
fetchPolicy: 'network-only',
Expand All @@ -303,22 +311,23 @@ let fetchingETHPrice = false
export function useETHPrice(version: string = VERSION.CLASSIC): AppState['application']['ethPrice'] {
const dispatch = useDispatch()
const { isEVM, chainId } = useActiveWeb3React()
const { elasticClient, classicClient, blockClient } = useKyberSwapConfig()
const { elasticClient, classicClient, blockClient, isEnableBlockService } = useKyberSwapConfig()

const ethPrice = useSelector((state: AppState) =>
version === VERSION.ELASTIC ? state.application.prommEthPrice : state.application.ethPrice,
)

useEffect(() => {
const controller = new AbortController()
if (!isEVM) return

async function checkForEthPrice() {
if (fetchingETHPrice) return
fetchingETHPrice = true
try {
const [newPrice, oneDayBackPrice, pricePercentChange] = await (version === VERSION.ELASTIC
? getPrommEthPrice(chainId, elasticClient, blockClient)
: getEthPrice(chainId, classicClient, blockClient))
? getPrommEthPrice(isEnableBlockService, chainId, elasticClient, blockClient, controller.signal)
: getEthPrice(isEnableBlockService, chainId, classicClient, blockClient, controller.signal))

dispatch(
version === VERSION.ELASTIC
Expand All @@ -338,7 +347,10 @@ export function useETHPrice(version: string = VERSION.CLASSIC): AppState['applic
}
}
checkForEthPrice()
}, [dispatch, chainId, version, isEVM, elasticClient, classicClient, blockClient])
return () => {
controller.abort()
}
}, [dispatch, chainId, version, isEVM, elasticClient, classicClient, blockClient, isEnableBlockService])

return ethPrice
}
Expand Down
35 changes: 18 additions & 17 deletions src/state/farms/classic/updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Contract } from '@ethersproject/contracts'
import { useEffect, useRef } from 'react'
import { useSelector } from 'react-redux'

import { ETHER_ADDRESS, ZERO_ADDRESS } from 'constants/index'
import { AbortedError, ETHER_ADDRESS, ZERO_ADDRESS } from 'constants/index'
import { EVMNetworkInfo } from 'constants/networks/type'
import { NativeCurrencies } from 'constants/tokens'
import { useActiveWeb3React } from 'hooks'
Expand Down Expand Up @@ -38,17 +38,17 @@ export default function Updater({ isInterval = true }: { isInterval?: boolean })
useEffect(() => {
if (!isEVM) return
console.count('running farm updater')
let cancelled = false
const abortController = new AbortController()

async function getListFarmsForContract(contract: Contract): Promise<Farm[]> {
const isV3 = (networkInfo as EVMNetworkInfo).classic.fairlaunchV3?.includes(contract.address)

if (!isEVM) return []
let rewardTokenAddresses: string[] = []
if (!isV3) rewardTokenAddresses = await contract?.getRewardTokens()
if (cancelled) throw new Error('canceled')
if (abortController.signal.aborted) throw new AbortedError()
const poolLength = await contract?.poolLength()
if (cancelled) throw new Error('canceled')
if (abortController.signal.aborted) throw new AbortedError()

const pids = [...Array(BigNumber.from(poolLength).toNumber()).keys()]

Expand All @@ -63,7 +63,7 @@ export default function Updater({ isInterval = true }: { isInterval?: boolean })
const poolInfos = await Promise.all(
pids.map(async (pid: number) => {
const poolInfo = await contract?.getPoolInfo(pid)
if (cancelled) throw new Error('canceled')
if (abortController.signal.aborted) throw new AbortedError()
if (isV2 || isV3) {
return {
...poolInfo,
Expand Down Expand Up @@ -98,22 +98,22 @@ export default function Updater({ isInterval = true }: { isInterval?: boolean })
const stakedBalances = await Promise.all(
pids.map(async (pid: number) => {
const stakedBalance = account ? await contract?.getUserInfo(pid, account as string) : { amount: 0 }
if (cancelled) throw new Error('canceled')
if (abortController.signal.aborted) throw new AbortedError()

return stakedBalance.amount
}),
)
if (cancelled) throw new Error('canceled')
if (abortController.signal.aborted) throw new AbortedError()

const pendingRewards = await Promise.all(
pids.map(async (pid: number) => {
const pendingRewards = account ? await contract?.pendingRewards(pid, account as string) : null
if (cancelled) throw new Error('canceled')
if (abortController.signal.aborted) throw new AbortedError()

return pendingRewards
}),
)
if (cancelled) throw new Error('canceled')
if (abortController.signal.aborted) throw new AbortedError()

const poolAddresses = poolInfos.map(poolInfo => poolInfo.stakeToken.toLowerCase())

Expand All @@ -124,8 +124,9 @@ export default function Updater({ isInterval = true }: { isInterval?: boolean })
blockClient,
chainId,
ethPriceRef.current,
abortController.signal,
)
if (cancelled) throw new Error('canceled')
if (abortController.signal.aborted) throw new AbortedError()

const farms: Farm[] = poolInfos.map((poolInfo, index) => {
return {
Expand Down Expand Up @@ -169,19 +170,19 @@ export default function Updater({ isInterval = true }: { isInterval?: boolean })
)

const promiseResult = await Promise.all(promises)
if (cancelled) throw new Error('canceled')
if (abortController.signal.aborted) throw new AbortedError()
fairLaunchAddresses.forEach((address, index) => {
result[address] = promiseResult[index]
})

if (latestChainId.current === chainId && (Object.keys(farmsDataRef.current).length === 0 || !cancelled)) {
if (latestChainId.current === chainId && Object.keys(farmsDataRef.current).length === 0) {
dispatch(setFarmsData(result))
}
} catch (err) {
if (!cancelled) {
console.error(err)
dispatch(setYieldPoolsError(err as Error))
}
if (err instanceof AbortedError) return
if (abortController.signal.aborted) return
console.error(err)
dispatch(setYieldPoolsError(err as Error))
}

dispatch(setLoading(false))
Expand All @@ -196,7 +197,7 @@ export default function Updater({ isInterval = true }: { isInterval?: boolean })
}, 30_000)

return () => {
cancelled = true
abortController.abort()
i && clearInterval(i)
}
}, [
Expand Down
40 changes: 22 additions & 18 deletions src/state/pools/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ export async function getBulkPoolDataFromPoolList(
apolloClient: ApolloClient<NormalizedCacheObject>,
blockClient: ApolloClient<NormalizedCacheObject>,
chainId: ChainId,
ethPrice?: string,
ethPrice: string | undefined,
signal: AbortSignal,
): Promise<any> {
try {
const current = await apolloClient.query({
Expand All @@ -146,7 +147,7 @@ export async function getBulkPoolDataFromPoolList(
})
let poolData
const [t1] = getTimestampsForChanges()
const blocks = await getBlocksFromTimestamps(isEnableBlockService, blockClient, [t1], chainId)
const blocks = await getBlocksFromTimestamps(isEnableBlockService, blockClient, [t1], chainId, signal)
if (!blocks.length) {
return current.data.pools
} else {
Expand Down Expand Up @@ -205,10 +206,11 @@ export async function getBulkPoolDataWithPagination(
blockClient: ApolloClient<NormalizedCacheObject>,
ethPrice: string,
chainId: ChainId,
signal: AbortSignal,
): Promise<any> {
try {
const [t1] = getTimestampsForChanges()
const blocks = await getBlocksFromTimestamps(isEnableBlockService, blockClient, [t1], chainId)
const blocks = await getBlocksFromTimestamps(isEnableBlockService, blockClient, [t1], chainId, signal)

// In case we can't get the block one day ago then we set it to 0 which is fine
// because our subgraph never syncs from block 0 => response is empty
Expand Down Expand Up @@ -322,7 +324,7 @@ export function useAllPoolsData(): {
const poolCountSubgraph = usePoolCountInSubgraph()
useEffect(() => {
if (!isEVM) return
let cancelled = false
const controller = new AbortController()

const getPoolsData = async () => {
try {
Expand All @@ -340,24 +342,25 @@ export function useAllPoolsData(): {
blockClient,
ethPrice,
chainId,
controller.signal,
),
)
}
const pools = (await Promise.all(promises.map(callback => callback()))).flat()
!cancelled && dispatch(updatePools({ pools }))
!cancelled && dispatch(setLoading(false))
if (controller.signal.aborted) return
dispatch(updatePools({ pools }))
dispatch(setLoading(false))
}
} catch (error) {
!cancelled && dispatch(setError(error as Error))
!cancelled && dispatch(setLoading(false))
if (controller.signal.aborted) return
dispatch(setError(error as Error))
dispatch(setLoading(false))
}
}

getPoolsData()

return () => {
cancelled = true
}
return () => controller.abort()
}, [
chainId,
dispatch,
Expand Down Expand Up @@ -396,7 +399,8 @@ export function useSinglePoolData(

useEffect(() => {
if (!isEVM) return
let isCanceled = false
const controller = new AbortController()

async function checkForPools() {
setLoading(true)

Expand All @@ -409,24 +413,24 @@ export function useSinglePoolData(
blockClient,
chainId,
ethPrice,
controller.signal,
)

if (controller.signal.aborted) return
if (pools.length > 0) {
!isCanceled && setPoolData(pools[0])
setPoolData(pools[0])
}
}
} catch (error) {
!isCanceled && setError(error as Error)
if (controller.signal.aborted) return
setError(error as Error)
}

setLoading(false)
}

checkForPools()

return () => {
isCanceled = true
}
return () => controller.abort()
}, [ethPrice, error, poolAddress, chainId, isEVM, networkInfo, classicClient, blockClient, isEnableBlockService])

return { loading, error, data: poolData }
Expand Down
Loading

0 comments on commit 9f87316

Please sign in to comment.