From 3da898d541a9d3a2a77c182666bb84b48247bc8d Mon Sep 17 00:00:00 2001 From: Fionna Chan Date: Mon, 5 Jun 2023 17:16:36 +0100 Subject: [PATCH] fix: clear stale pending tx after 7 days --- .../TransactionsTableWithdrawalRow.tsx | 7 ++----- .../syncers/PendingTransactionsUpdater.tsx | 16 ++++++++++++++-- .../arb-token-bridge-ui/src/util/CommonUtils.ts | 6 ++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTable/TransactionsTableWithdrawalRow.tsx b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTable/TransactionsTableWithdrawalRow.tsx index 505d266a1e..ff021f6587 100644 --- a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTable/TransactionsTableWithdrawalRow.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTable/TransactionsTableWithdrawalRow.tsx @@ -1,6 +1,5 @@ import { useMemo } from 'react' import { Popover } from '@headlessui/react' -import dayjs from 'dayjs' import { NodeBlockDeadlineStatusTypes } from '../../../hooks/arbTokenBridge.types' import { MergedTransaction } from '../../../state/app/state' @@ -9,7 +8,7 @@ import { useNetworksAndSigners } from '../../../hooks/useNetworksAndSigners' import { useClaimWithdrawal } from '../../../hooks/useClaimWithdrawal' import { WithdrawalCountdown } from '../../common/WithdrawalCountdown' import { ExternalLink } from '../../common/ExternalLink' -import { shortenTxHash } from '../../../util/CommonUtils' +import { isTxOlderThan7Days, shortenTxHash } from '../../../util/CommonUtils' import { Button } from '../../common/Button' import { Tooltip } from '../../common/Tooltip' import { getExplorerUrl, getNetworkName } from '../../../util/networks' @@ -306,11 +305,9 @@ function WithdrawalRowAction({ } if (isError) { - const isTxOlderThan7Days = dayjs().diff(dayjs(tx.createdAt), 'days') > 7 - return ( <> - {isTxOlderThan7Days ? ( + {isTxOlderThan7Days(tx.createdAt) ? ( // show a dropdown menu with the button diff --git a/packages/arb-token-bridge-ui/src/components/syncers/PendingTransactionsUpdater.tsx b/packages/arb-token-bridge-ui/src/components/syncers/PendingTransactionsUpdater.tsx index 9520c053d4..0f31d3533e 100644 --- a/packages/arb-token-bridge-ui/src/components/syncers/PendingTransactionsUpdater.tsx +++ b/packages/arb-token-bridge-ui/src/components/syncers/PendingTransactionsUpdater.tsx @@ -5,6 +5,7 @@ import { Transaction, txnTypeToLayer } from '../../hooks/useTransactions' import { useActions, useAppState } from '../../state' import { useInterval } from '../common/Hooks' import { useNetworksAndSigners } from '../../hooks/useNetworksAndSigners' +import { isTxOlderThan7Days } from '../../util/CommonUtils' export function PendingTransactionsUpdater(): JSX.Element { const actions = useActions() @@ -29,13 +30,14 @@ export function PendingTransactionsUpdater(): JSX.Element { const checkAndUpdatePendingTransactions = useCallback(() => { if (!arbTokenBridgeLoaded) return const pendingTransactions = actions.app.getPendingTransactions() + if (pendingTransactions.length) { console.info( `Checking and updating ${pendingTransactions.length} pending transactions' statuses` ) // eslint-disable-next-line consistent-return - return Promise.all( + Promise.all( pendingTransactions.map((tx: Transaction) => getTransactionReceipt(tx)) ).then((txReceipts: (TransactionReceipt | null)[]) => { txReceipts.forEach((txReceipt: TransactionReceipt | null, i) => { @@ -49,6 +51,16 @@ export function PendingTransactionsUpdater(): JSX.Element { } }) }) + + // If the Txs have been pending for over 7 days, + // they are cancelled so we should clear them from the history + const arePendingTxsAllOlderThan7Days = pendingTransactions.every( + pendingTx => isTxOlderThan7Days(pendingTx.timestampCreated) + ) + + if (arePendingTxsAllOlderThan7Days) { + arbTokenBridge?.transactions?.clearPendingTransactions() + } } }, [getTransactionReceipt, arbTokenBridge, arbTokenBridgeLoaded]) const { forceTrigger: forceTriggerUpdate } = useInterval( @@ -59,7 +71,7 @@ export function PendingTransactionsUpdater(): JSX.Element { useEffect(() => { // force trigger update each time loaded change happens forceTriggerUpdate() - }, [arbTokenBridgeLoaded]) + }, [arbTokenBridgeLoaded, forceTriggerUpdate]) return <> } diff --git a/packages/arb-token-bridge-ui/src/util/CommonUtils.ts b/packages/arb-token-bridge-ui/src/util/CommonUtils.ts index 987a628792..756dee6a11 100644 --- a/packages/arb-token-bridge-ui/src/util/CommonUtils.ts +++ b/packages/arb-token-bridge-ui/src/util/CommonUtils.ts @@ -1,3 +1,5 @@ +import dayjs from 'dayjs' + export function shortenAddress(address: string) { const addressLength = address.length @@ -18,3 +20,7 @@ export function shortenTxHash(txHash: string) { export const isTestingEnvironment = !!window.Cypress || process.env.NODE_ENV !== 'production' + +export function isTxOlderThan7Days(txCreatedAt: string | null | undefined) { + return dayjs().diff(dayjs(txCreatedAt), 'days') > 7 +}