From 534e2b193805f965b0204f80cf63e6e51089fa4f Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Sat, 7 Dec 2024 20:00:52 +0000 Subject: [PATCH 1/5] update cache stale time --- .../src/hooks/useBridgeTransfer.ts | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts index 292f311d..8541252a 100644 --- a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts +++ b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts @@ -23,14 +23,15 @@ export const useBridgeTransfer = () => { try { return await fn() } catch (error: any) { - if (error?.response?.status === 429 && attempt < retries - 1) { - const baseDelay = delay *2**attempt - const jitter = baseDelay * (Math.random() * jitterFactor * 2 - jitterFactor) + const retryableStatusCodes = [429, 503] + if (retryableStatusCodes.includes(error?.response?.status) && attempt < retries - 1) { + const baseDelay = delay * 2 ** attempt + const jitter = baseDelay * (Math.random() * jitterFactor * 2 - jitterFactor) const retryDelay = Math.max(baseDelay + jitter, 0) await new Promise((resolve) => setTimeout(resolve, retryDelay)) attempt++ } else { - throw error // Rethrow error if not 429 or max retries reached + throw error } } } @@ -56,6 +57,14 @@ export const useBridgeTransfer = () => { return useQuery( ['transferData', txHash], async () => { + const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) + const cachedTransaction = transactions.find((t: any) => + isDeposit ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash + ) + + if (cachedTransaction?.status && !shouldFetchStatus(cachedTransaction)) { + return { status: cachedTransaction.status } + } const _bridgeTransfer = new BridgeTransfer({ txHash: txHash ?? '', destinationNetworkChainId: destinationChainId ?? 0, @@ -96,7 +105,7 @@ export const useBridgeTransfer = () => { if (cachedTransaction && cachedTransaction.status !== undefined) { status = cachedTransaction.status - return { status } // Return cached status + return { status, ...cachedTransaction } // Return cached status } throw error // Re-throw error if no cache @@ -221,9 +230,20 @@ export const useBridgeTransfer = () => { const destinationRpc = getNetworks(selectedNetworkType)?.find((n) => n.chainId === destinationChainId)?.rpcs[0] const originRpc = getNetworks(selectedNetworkType)?.find((n) => n.chainId === originChainId)?.rpcs[0] + // Check cache before setting up the query + const cachedTransactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) + const cachedTransaction = cachedTransactions.find((t: any) => + isDeposit ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash + ) + const hasCachedInputs = cachedTransaction?.transactionInputs !== undefined + + return useQuery( ['transactionInputs', txHash], async () => { + if (hasCachedInputs) { + return cachedTransaction.transactionInputs + } const _bridgeTransfer = new BridgeTransfer({ txHash: txHash ?? '', destinationNetworkChainId: destinationChainId ?? 0, @@ -232,8 +252,9 @@ export const useBridgeTransfer = () => { originSignerOrProviderOrRpc: originRpc }) - const transactionInputs = await _bridgeTransfer.getInfo() - + const transactionInputs = await retryWithExponentialBackoff( + async () => _bridgeTransfer.getInfo() + ) const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) // Update the cache with the latest status @@ -253,15 +274,11 @@ export const useBridgeTransfer = () => { }, { placeholderData: () => { - const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) - const cachedTransaction = transactions.find((t: any) => - isDeposit ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash - ) - if (cachedTransaction && cachedTransaction.transactionInputs !== undefined) { - return cachedTransaction?.transactionInputs + if (hasCachedInputs) { + return cachedTransaction.transactionInputs } }, - staleTime: 2 * 60 * 1000, + staleTime: 30 * 60 * 1000, refetchOnWindowFocus: false, enabled: !!txRecord } @@ -320,7 +337,7 @@ export const useBridgeTransfer = () => { return cachedTransaction?.highNetworkTimestamp }, - staleTime: 1 * 60 * 1000, + staleTime: Infinity, refetchInterval: false, refetchOnWindowFocus: false, enabled: !!txRecord && !!transferStatus?.completionTxHash // Run query only if data is valid From 931a9afaab43410a1054dd2a8bb4e715cafd8172 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Sat, 7 Dec 2024 20:30:40 +0000 Subject: [PATCH 2/5] Massively improve error --- .../src/hooks/useBridgeTransfer.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts index 8541252a..57d97b3c 100644 --- a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts +++ b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts @@ -23,11 +23,18 @@ export const useBridgeTransfer = () => { try { return await fn() } catch (error: any) { - const retryableStatusCodes = [429, 503] - if (retryableStatusCodes.includes(error?.response?.status) && attempt < retries - 1) { + // Add network failure errors to retryable conditions + const isNetworkError = error.message?.includes('net::ERR_FAILED') || + error.message?.includes('Network Error') || + error.code === 'ECONNABORTED' || + !error.response; + const retryableStatusCodes = [429, 503, 502, 500]; + + if ((isNetworkError || retryableStatusCodes.includes(error?.response?.status)) && attempt < retries - 1) { const baseDelay = delay * 2 ** attempt const jitter = baseDelay * (Math.random() * jitterFactor * 2 - jitterFactor) const retryDelay = Math.max(baseDelay + jitter, 0) + console.warn(`Retry attempt ${attempt + 1}/${retries} after ${retryDelay}ms due to:`, error.message) await new Promise((resolve) => setTimeout(resolve, retryDelay)) attempt++ } else { @@ -77,8 +84,6 @@ export const useBridgeTransfer = () => { // Fetch status with retry logic status = await retryWithExponentialBackoff(async () => await _bridgeTransfer.getStatus()) - const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) - // Update the cache with the latest status const newTransactions = transactions.map((t: any) => { const isSameHash = isDeposit @@ -255,6 +260,7 @@ export const useBridgeTransfer = () => { const transactionInputs = await retryWithExponentialBackoff( async () => _bridgeTransfer.getInfo() ) + console.log(transactionInputs) const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) // Update the cache with the latest status From c323ffe64c60fd0003d57776c346b046a36d3449 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Sat, 7 Dec 2024 21:13:27 +0000 Subject: [PATCH 3/5] update retryWithExp. backoff --- .../world-builder-dashboard/src/hooks/useBridgeTransfer.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts index 57d97b3c..ba39b699 100644 --- a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts +++ b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts @@ -257,10 +257,8 @@ export const useBridgeTransfer = () => { originSignerOrProviderOrRpc: originRpc }) - const transactionInputs = await retryWithExponentialBackoff( - async () => _bridgeTransfer.getInfo() - ) - console.log(transactionInputs) + const transactionInputs = await retryWithExponentialBackoff(async () => await _bridgeTransfer.getInfo()) + const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) // Update the cache with the latest status From 621535a795aef0de2d2362263b43b960c560e082 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Sat, 7 Dec 2024 21:15:42 +0000 Subject: [PATCH 4/5] update cache --- .../src/hooks/useBridgeTransfer.ts | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts index ba39b699..5b7c9662 100644 --- a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts +++ b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts @@ -16,7 +16,7 @@ interface UseTransferDataProps { export const useBridgeTransfer = () => { const { connectedAccount, selectedNetworkType, switchChain } = useBlockchainContext() // Retry function with exponential backoff for handling 429 errors - const retryWithExponentialBackoff = async (fn: () => Promise, retries = 5, delay = 1000, jitterFactor = 0.5) => { + const retryWithExponentialBackoff = async (fn: () => Promise, retries = 20, delay = 1000, jitterFactor = 0.5) => { let attempt = 0 while (attempt < retries) { @@ -59,7 +59,7 @@ export const useBridgeTransfer = () => { return isPending && timeSinceLastUpdate > 1 * 60 * 1000 } - let status: any + let transferStatus: any return useQuery( ['transferData', txHash], @@ -82,7 +82,9 @@ export const useBridgeTransfer = () => { try { // Fetch status with retry logic - status = await retryWithExponentialBackoff(async () => await _bridgeTransfer.getStatus()) + const statusResponse = await retryWithExponentialBackoff(async () => await _bridgeTransfer.getStatus()) + transferStatus = statusResponse + // Update the cache with the latest status const newTransactions = transactions.map((t: any) => { @@ -90,7 +92,7 @@ export const useBridgeTransfer = () => { ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash - return isSameHash ? { ...t, status: status?.status, lastUpdated: Date.now() } : t + return isSameHash ? { ...t, status: statusResponse?.status, lastUpdated: Date.now() } : t }) localStorage.setItem( @@ -98,7 +100,7 @@ export const useBridgeTransfer = () => { JSON.stringify(newTransactions) ) - return status + return statusResponse } catch (error) { console.error('Error fetching status:', error) @@ -109,8 +111,8 @@ export const useBridgeTransfer = () => { ) if (cachedTransaction && cachedTransaction.status !== undefined) { - status = cachedTransaction.status - return { status, ...cachedTransaction } // Return cached status + transferStatus = cachedTransaction.status + return { status: transferStatus, ...cachedTransaction } // Return cached status } throw error // Re-throw error if no cache @@ -125,8 +127,8 @@ export const useBridgeTransfer = () => { ) if (cachedTransaction && cachedTransaction.status !== undefined) { - status = cachedTransaction.status - return { status } + transferStatus = cachedTransaction.status + return { status: transferStatus } } }, staleTime: 0.5 * 60 * 1000, @@ -235,20 +237,21 @@ export const useBridgeTransfer = () => { const destinationRpc = getNetworks(selectedNetworkType)?.find((n) => n.chainId === destinationChainId)?.rpcs[0] const originRpc = getNetworks(selectedNetworkType)?.find((n) => n.chainId === originChainId)?.rpcs[0] - // Check cache before setting up the query - const cachedTransactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) - const cachedTransaction = cachedTransactions.find((t: any) => - isDeposit ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash - ) - const hasCachedInputs = cachedTransaction?.transactionInputs !== undefined - return useQuery( ['transactionInputs', txHash], async () => { - if (hasCachedInputs) { + // Get fresh cache data + const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) + const cachedTransaction = transactions.find((t: any) => + isDeposit ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash + ) + + // Check if we have cached inputs + if (cachedTransaction?.transactionInputs !== undefined) { return cachedTransaction.transactionInputs } + const _bridgeTransfer = new BridgeTransfer({ txHash: txHash ?? '', destinationNetworkChainId: destinationChainId ?? 0, @@ -257,17 +260,17 @@ export const useBridgeTransfer = () => { originSignerOrProviderOrRpc: originRpc }) - const transactionInputs = await retryWithExponentialBackoff(async () => await _bridgeTransfer.getInfo()) - - const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) + const transactionInputs = await retryWithExponentialBackoff( + async () => _bridgeTransfer.getInfo() + ) - // Update the cache with the latest status + // Update cache with new data const newTransactions = transactions.map((t: any) => { const isSameHash = isDeposit ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash - return isSameHash ? { ...t, transactionInputs: transactionInputs } : t + return isSameHash ? { ...t, transactionInputs: transactionInputs, lastUpdated: Date.now() } : t }) localStorage.setItem( @@ -278,9 +281,12 @@ export const useBridgeTransfer = () => { }, { placeholderData: () => { - if (hasCachedInputs) { - return cachedTransaction.transactionInputs - } + // Get fresh cache data for placeholder + const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) + const cachedTransaction = transactions.find((t: any) => + isDeposit ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash + ) + return cachedTransaction?.transactionInputs }, staleTime: 30 * 60 * 1000, refetchOnWindowFocus: false, @@ -288,7 +294,6 @@ export const useBridgeTransfer = () => { } ) } - const getHighNetworkTimestamp = ({ txRecord, transferStatus, From c48adef5a9fd47bc5ccfb3e42b1cb94304ad6837 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Sat, 7 Dec 2024 21:23:00 +0000 Subject: [PATCH 5/5] added loading to tokenSymbol --- .../src/components/bridge/history/Deposit.tsx | 20 ++++++++++++------- .../components/bridge/history/Withdrawal.tsx | 14 +++++++++---- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index 43a4a3b1..fdbb6d80 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -55,9 +55,15 @@ const Deposit: React.FC = ({ deposit }) => {
{timeAgo(deposit.lowNetworkTimestamp)}
-
{`${transactionInputs?.tokenSymbol === 'USDC' ? ethers.utils.formatUnits(transactionInputs?.amount, 6) : deposit.amount} ${transactionInputs?.tokenSymbol}`}
+ {!transactionInputs?.tokenSymbol ? ( +
+
Loading
+
+ ) : ( +
+ {`${transactionInputs.tokenSymbol === 'USDC' ? ethers.utils.formatUnits(transactionInputs.amount, 6) : deposit.amount} ${transactionInputs.tokenSymbol}`} +
+ )}
{depositInfo.from}
{depositInfo.to}
<> @@ -74,8 +80,8 @@ const Deposit: React.FC = ({ deposit }) => { >
{transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( + transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || + transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? (
Completed @@ -98,8 +104,8 @@ const Deposit: React.FC = ({ deposit }) => { ) : (
{transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( + transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || + transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( <>{timeAgo(highNetworkTimestamp)} ) : ( <>{ETA(deposit.lowNetworkTimestamp, deposit.retryableCreationTimeout ?? 15 * 60)} diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx index 6a0c1173..ce70c811 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx @@ -63,7 +63,7 @@ const Withdrawal: React.FC = ({ withdrawal }) => { const status = getStatus(withdrawal, lowNetworks, highNetworks) const { data: transferStatus, isLoading } = returnTransferData({ txRecord: withdrawal }) const { data: transactionInputs } = getTransactionInputs({ txRecord: withdrawal }) - + return ( <> {status?.isLoading && smallView ? ( @@ -92,9 +92,15 @@ const Withdrawal: React.FC = ({ withdrawal }) => {
{timeAgo(withdrawal.highNetworkTimestamp)}
-
{`${transactionInputs?.tokenSymbol === 'USDC' ? ethers.utils.formatUnits(transactionInputs?.amount, 6) : withdrawal.amount} ${transactionInputs?.tokenSymbol}`}
+ {!transactionInputs?.tokenSymbol ? ( +
+
Loading
+
+ ) : ( +
+ {`${transactionInputs.tokenSymbol === 'USDC' ? ethers.utils.formatUnits(transactionInputs.amount, 6) : withdrawal.amount} ${transactionInputs.tokenSymbol}`} +
+ )}
{status?.data?.from ?? ''}
{status?.data?.to ?? ''}