From 4588f8cac1c8d3b6c6902720975cc8e62ba69667 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 16:37:20 +0100 Subject: [PATCH 01/24] don't fetch withdrawals if nonce is zero --- .../arb-token-bridge-ui/src/util/AddressUtils.ts | 13 +++++++++++++ .../fetchTokenWithdrawalsFromEventLogs.ts | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/arb-token-bridge-ui/src/util/AddressUtils.ts b/packages/arb-token-bridge-ui/src/util/AddressUtils.ts index 4f33e3da77..9e15ef0750 100644 --- a/packages/arb-token-bridge-ui/src/util/AddressUtils.ts +++ b/packages/arb-token-bridge-ui/src/util/AddressUtils.ts @@ -1,3 +1,5 @@ +import { Provider } from '@ethersproject/providers' + import { getAPIBaseUrl } from '.' import { getProviderForChainId } from '../token-bridge-sdk/utils' @@ -29,3 +31,14 @@ export async function addressIsDenylisted(address: string) { return false } } + +export function getNonce( + address: string | undefined, + { provider }: { provider: Provider } +): Promise { + if (typeof address === 'undefined') { + return 0 as unknown as Promise + } + + return provider.getTransactionCount(address) +} diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts index 0b3d9531e3..ea0887c54c 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts @@ -2,6 +2,8 @@ import { Provider, BlockTag } from '@ethersproject/providers' import { Erc20Bridger, EventArgs } from '@arbitrum/sdk' import { WithdrawalInitiatedEvent } from '@arbitrum/sdk/dist/lib/abi/L2ArbitrumGateway' +import { getNonce } from '../AddressUtils' + function dedupeEvents( events: (EventArgs & { txHash: string @@ -39,9 +41,11 @@ export async function fetchTokenWithdrawalsFromEventLogs({ const erc20Bridger = await Erc20Bridger.fromProvider(l2Provider) const promises: ReturnType[] = [] + const senderNonce = await getNonce(sender, { provider: l2Provider }) + l2GatewayAddresses.forEach(gatewayAddress => { // funds sent by this address - if (sender) { + if (sender && senderNonce > 0) { promises.push( erc20Bridger.getWithdrawalEvents( l2Provider, From fb8e92fe16db82a7cdaf299461de1f0063f617e8 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 16:44:00 +0100 Subject: [PATCH 02/24] fix comments --- .../src/util/withdrawals/fetchETHWithdrawalsFromEventLogs.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchETHWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchETHWithdrawalsFromEventLogs.ts index a9955e6dc8..3d38e5318f 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchETHWithdrawalsFromEventLogs.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchETHWithdrawalsFromEventLogs.ts @@ -5,7 +5,7 @@ import { ChildToParentMessageReader } from '@arbitrum/sdk' * Fetches initiated ETH withdrawals from event logs in range of [fromBlock, toBlock]. * * @param query Query params - * @param query.receiver Address that will receive the funds + * @param query.receiver Address that received the funds * @param query.fromBlock Start at this block number (including) * @param query.toBlock Stop at this block number (including) * @param query.l2Provider Provider for the L2 network @@ -24,7 +24,8 @@ export function fetchETHWithdrawalsFromEventLogs({ if (typeof receiver === 'undefined') { return [] } - // funds sent by this address + + // funds received by this address return ChildToParentMessageReader.getChildToParentEvents( l2Provider, { fromBlock, toBlock }, From 57d4a29dd6d8020f4f8e5ebe04b34ca4fe868bc2 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 18:36:02 +0100 Subject: [PATCH 03/24] rename l2Provider to provider --- .../fetchTokenWithdrawalsFromEventLogs.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts index ea0887c54c..242701099e 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts @@ -20,7 +20,7 @@ function dedupeEvents( * @param query.receiver Address that received the funds * @param query.fromBlock Start at this block number (including) * @param query.toBlock Stop at this block number (including) - * @param query.l2Provider Provider for the L2 network + * @param query.provider Provider for the child network * @param query.l2GatewayAddresses L2 gateway addresses to use */ export async function fetchTokenWithdrawalsFromEventLogs({ @@ -28,27 +28,27 @@ export async function fetchTokenWithdrawalsFromEventLogs({ receiver, fromBlock, toBlock, - l2Provider, + provider, l2GatewayAddresses = [] }: { sender?: string receiver?: string fromBlock: BlockTag toBlock: BlockTag - l2Provider: Provider + provider: Provider l2GatewayAddresses?: string[] }) { - const erc20Bridger = await Erc20Bridger.fromProvider(l2Provider) + const erc20Bridger = await Erc20Bridger.fromProvider(provider) const promises: ReturnType[] = [] - const senderNonce = await getNonce(sender, { provider: l2Provider }) + const senderNonce = await getNonce(sender, { provider: provider }) l2GatewayAddresses.forEach(gatewayAddress => { // funds sent by this address if (sender && senderNonce > 0) { promises.push( erc20Bridger.getWithdrawalEvents( - l2Provider, + provider, gatewayAddress, { fromBlock, toBlock }, undefined, @@ -62,7 +62,7 @@ export async function fetchTokenWithdrawalsFromEventLogs({ if (receiver) { promises.push( erc20Bridger.getWithdrawalEvents( - l2Provider, + provider, gatewayAddress, { fromBlock, toBlock }, undefined, From b153022765af10d07a3f2daf3128152dbf2a47d7 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 19:41:53 +0100 Subject: [PATCH 04/24] wip --- packages/arb-token-bridge-ui/package.json | 3 +- .../fetchTokenWithdrawalsFromEventLogs.ts | 48 +++-- .../src/util/withdrawals/fetchWithdrawals.ts | 164 +++++++++++++++++- yarn.lock | 5 + 4 files changed, 192 insertions(+), 28 deletions(-) diff --git a/packages/arb-token-bridge-ui/package.json b/packages/arb-token-bridge-ui/package.json index abe147b101..775c8a38f7 100644 --- a/packages/arb-token-bridge-ui/package.json +++ b/packages/arb-token-bridge-ui/package.json @@ -25,6 +25,7 @@ "cheerio": "^1.0.0-rc.12", "dayjs": "^1.11.8", "ethers": "^5.6.0", + "exponential-backoff": "^3.1.1", "graphql": "^16.8.1", "lodash-es": "^4.17.21", "next": "^14.2.12", @@ -49,7 +50,7 @@ "zustand": "^4.3.9" }, "scripts": { - "predev": "yarn generateDenylist && yarn generateOpenGraphImages", + "predev": "yarn generateDenylist", "dev": "next dev", "prebuild": "yarn generateDenylist && yarn generateOpenGraphImages", "postinstall": "patch-package", diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts index 242701099e..74649ca08a 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts @@ -1,6 +1,7 @@ import { Provider, BlockTag } from '@ethersproject/providers' import { Erc20Bridger, EventArgs } from '@arbitrum/sdk' import { WithdrawalInitiatedEvent } from '@arbitrum/sdk/dist/lib/abi/L2ArbitrumGateway' +import { backOff } from 'exponential-backoff' import { getNonce } from '../AddressUtils' @@ -12,6 +13,10 @@ function dedupeEvents( return [...new Map(events.map(item => [item.txHash, item])).values()] } +function wait(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)) +} + /** * Fetches initiated token withdrawals from event logs in range of [fromBlock, toBlock]. * @@ -21,7 +26,7 @@ function dedupeEvents( * @param query.fromBlock Start at this block number (including) * @param query.toBlock Stop at this block number (including) * @param query.provider Provider for the child network - * @param query.l2GatewayAddresses L2 gateway addresses to use + * @param query.gateways L2 gateway addresses to use */ export async function fetchTokenWithdrawalsFromEventLogs({ sender, @@ -29,31 +34,35 @@ export async function fetchTokenWithdrawalsFromEventLogs({ fromBlock, toBlock, provider, - l2GatewayAddresses = [] + gateways = [] }: { sender?: string receiver?: string fromBlock: BlockTag toBlock: BlockTag provider: Provider - l2GatewayAddresses?: string[] + gateways?: string[] }) { const erc20Bridger = await Erc20Bridger.fromProvider(provider) const promises: ReturnType[] = [] const senderNonce = await getNonce(sender, { provider: provider }) - l2GatewayAddresses.forEach(gatewayAddress => { + await wait(1000) + + gateways.forEach(gatewayAddress => { // funds sent by this address if (sender && senderNonce > 0) { promises.push( - erc20Bridger.getWithdrawalEvents( - provider, - gatewayAddress, - { fromBlock, toBlock }, - undefined, - sender, - undefined + backOff(() => + erc20Bridger.getWithdrawalEvents( + provider, + gatewayAddress, + { fromBlock, toBlock }, + undefined, + sender, + undefined + ) ) ) } @@ -61,13 +70,16 @@ export async function fetchTokenWithdrawalsFromEventLogs({ // funds received by this address if (receiver) { promises.push( - erc20Bridger.getWithdrawalEvents( - provider, - gatewayAddress, - { fromBlock, toBlock }, - undefined, - undefined, - receiver + backOff( + () => + erc20Bridger.getWithdrawalEvents( + provider, + gatewayAddress, + { fromBlock, toBlock }, + undefined, + undefined, + receiver + ) as any ) ) } diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts index 624182bdae..cfcfa72609 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts @@ -1,4 +1,8 @@ -import { Provider } from '@ethersproject/providers' +import { + BlockTag, + Provider, + StaticJsonRpcProvider +} from '@ethersproject/providers' import { fetchETHWithdrawalsFromEventLogs } from './fetchETHWithdrawalsFromEventLogs' @@ -12,6 +16,9 @@ import { fetchL2Gateways } from '../fetchL2Gateways' import { Withdrawal } from '../../hooks/useTransactionHistory' import { attachTimestampToTokenWithdrawal } from './helpers' import { WithdrawalInitiated } from '../../hooks/arbTokenBridge.types' +import { Erc20Bridger, getArbitrumNetwork } from '@arbitrum/sdk' +import { ethers } from 'ethers' +import { getNonce } from '../AddressUtils' export type FetchWithdrawalsParams = { sender?: string @@ -25,6 +32,148 @@ export type FetchWithdrawalsParams = { searchString?: string } +type UnwrapPromise = T extends Promise ? U : T + +type WithdrawalQuery = { + params: { + sender?: string + receiver?: string + fromBlock: BlockTag + toBlock: BlockTag + provider: Provider + gateways?: string[] + } + priority: number +} + +type Result = UnwrapPromise> + +function wait(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)) +} + +async function fetchTokenWithdrawalsFromEventLogsSequentially( + address: string, + provider: Provider, + fromBlock: BlockTag +): Promise { + await wait(2000) + + const network = await getArbitrumNetwork(provider) + const senderNonce = await getNonce(address, { provider: provider }) + + const standardGateway = network.tokenBridge?.childErc20Gateway! + const customGateway = network.tokenBridge?.childCustomGateway! + const wethGateway = network.tokenBridge?.childWethGateway! + + let prio = 1 + + const queries: WithdrawalQuery[] = [] + + if (senderNonce > 0) { + queries.push({ + params: { + sender: address, + fromBlock, + toBlock: 'latest', + provider, + gateways: [standardGateway] + }, + priority: prio + }) + prio++ + if (wethGateway !== ethers.constants.AddressZero) { + queries.push({ + params: { + sender: address, + fromBlock, + toBlock: 'latest', + provider, + gateways: [wethGateway] + }, + priority: prio + }) + prio++ + } + queries.push({ + params: { + sender: address, + fromBlock, + toBlock: 'latest', + provider, + gateways: [customGateway] + }, + priority: prio + }) + prio++ + } + + queries.push({ + params: { + receiver: address, + fromBlock, + toBlock: 'latest', + provider, + gateways: [standardGateway] + }, + priority: prio + }) + prio++ + if (wethGateway !== ethers.constants.AddressZero) { + queries.push({ + params: { + receiver: address, + fromBlock, + toBlock: 'latest', + provider, + gateways: [wethGateway] + }, + priority: prio + }) + prio++ + } + queries.push({ + params: { + receiver: address, + fromBlock, + toBlock: 'latest', + provider, + gateways: [customGateway] + }, + priority: prio + }) + prio++ + + const maxPriority = queries.map(query => query.priority).sort()[ + queries.length - 1 + ]! + + let result: Result = [] + let currentPriority = 1 + + while (currentPriority <= maxPriority) { + const filteredQueries = queries.filter( + query => query.priority === currentPriority + ) + + const results = await Promise.all( + filteredQueries.map(query => + fetchTokenWithdrawalsFromEventLogs(query.params) + ) + ) + + results.forEach(r => { + result.push(...r) + }) + + await wait(2000) + + currentPriority += 1 + } + + return result +} + export async function fetchWithdrawals({ sender, receiver, @@ -93,14 +242,11 @@ export async function fetchWithdrawals({ toBlock: 'latest', l2Provider: l2Provider }), - fetchTokenWithdrawalsFromEventLogs({ - sender, - receiver, - fromBlock: toBlock + 1, - toBlock: 'latest', - l2Provider: l2Provider, - l2GatewayAddresses - }) + fetchTokenWithdrawalsFromEventLogsSequentially( + sender!, + l2Provider, + toBlock + 1 + ) ]) const mappedEthWithdrawalsFromEventLogs: Withdrawal[] = diff --git a/yarn.lock b/yarn.lock index da1ddc8a1f..e51b9d18df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7545,6 +7545,11 @@ expect@^29.0.0, expect@^29.5.0: jest-message-util "^29.5.0" jest-util "^29.5.0" +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + express@^4.17.3: version "4.21.0" resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915" From 565ad239cb02ea1fd53c57125202c700a983ffc8 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 19:49:55 +0100 Subject: [PATCH 05/24] reduce diff --- .../fetchTokenWithdrawalsFromEventLogs.ts | 58 ++++++++----------- .../src/util/withdrawals/fetchWithdrawals.ts | 28 ++++----- 2 files changed, 37 insertions(+), 49 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts index 74649ca08a..ea0887c54c 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts @@ -1,7 +1,6 @@ import { Provider, BlockTag } from '@ethersproject/providers' import { Erc20Bridger, EventArgs } from '@arbitrum/sdk' import { WithdrawalInitiatedEvent } from '@arbitrum/sdk/dist/lib/abi/L2ArbitrumGateway' -import { backOff } from 'exponential-backoff' import { getNonce } from '../AddressUtils' @@ -13,10 +12,6 @@ function dedupeEvents( return [...new Map(events.map(item => [item.txHash, item])).values()] } -function wait(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)) -} - /** * Fetches initiated token withdrawals from event logs in range of [fromBlock, toBlock]. * @@ -25,44 +20,40 @@ function wait(ms: number) { * @param query.receiver Address that received the funds * @param query.fromBlock Start at this block number (including) * @param query.toBlock Stop at this block number (including) - * @param query.provider Provider for the child network - * @param query.gateways L2 gateway addresses to use + * @param query.l2Provider Provider for the L2 network + * @param query.l2GatewayAddresses L2 gateway addresses to use */ export async function fetchTokenWithdrawalsFromEventLogs({ sender, receiver, fromBlock, toBlock, - provider, - gateways = [] + l2Provider, + l2GatewayAddresses = [] }: { sender?: string receiver?: string fromBlock: BlockTag toBlock: BlockTag - provider: Provider - gateways?: string[] + l2Provider: Provider + l2GatewayAddresses?: string[] }) { - const erc20Bridger = await Erc20Bridger.fromProvider(provider) + const erc20Bridger = await Erc20Bridger.fromProvider(l2Provider) const promises: ReturnType[] = [] - const senderNonce = await getNonce(sender, { provider: provider }) - - await wait(1000) + const senderNonce = await getNonce(sender, { provider: l2Provider }) - gateways.forEach(gatewayAddress => { + l2GatewayAddresses.forEach(gatewayAddress => { // funds sent by this address if (sender && senderNonce > 0) { promises.push( - backOff(() => - erc20Bridger.getWithdrawalEvents( - provider, - gatewayAddress, - { fromBlock, toBlock }, - undefined, - sender, - undefined - ) + erc20Bridger.getWithdrawalEvents( + l2Provider, + gatewayAddress, + { fromBlock, toBlock }, + undefined, + sender, + undefined ) ) } @@ -70,16 +61,13 @@ export async function fetchTokenWithdrawalsFromEventLogs({ // funds received by this address if (receiver) { promises.push( - backOff( - () => - erc20Bridger.getWithdrawalEvents( - provider, - gatewayAddress, - { fromBlock, toBlock }, - undefined, - undefined, - receiver - ) as any + erc20Bridger.getWithdrawalEvents( + l2Provider, + gatewayAddress, + { fromBlock, toBlock }, + undefined, + undefined, + receiver ) ) } diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts index cfcfa72609..b59284b661 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts @@ -40,8 +40,8 @@ type WithdrawalQuery = { receiver?: string fromBlock: BlockTag toBlock: BlockTag - provider: Provider - gateways?: string[] + l2Provider: Provider + l2GatewayAddresses?: string[] } priority: number } @@ -76,8 +76,8 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( sender: address, fromBlock, toBlock: 'latest', - provider, - gateways: [standardGateway] + l2Provider: provider, + l2GatewayAddresses: [standardGateway] }, priority: prio }) @@ -88,8 +88,8 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( sender: address, fromBlock, toBlock: 'latest', - provider, - gateways: [wethGateway] + l2Provider: provider, + l2GatewayAddresses: [wethGateway] }, priority: prio }) @@ -100,8 +100,8 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( sender: address, fromBlock, toBlock: 'latest', - provider, - gateways: [customGateway] + l2Provider: provider, + l2GatewayAddresses: [customGateway] }, priority: prio }) @@ -113,8 +113,8 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( receiver: address, fromBlock, toBlock: 'latest', - provider, - gateways: [standardGateway] + l2Provider: provider, + l2GatewayAddresses: [standardGateway] }, priority: prio }) @@ -125,8 +125,8 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( receiver: address, fromBlock, toBlock: 'latest', - provider, - gateways: [wethGateway] + l2Provider: provider, + l2GatewayAddresses: [wethGateway] }, priority: prio }) @@ -137,8 +137,8 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( receiver: address, fromBlock, toBlock: 'latest', - provider, - gateways: [customGateway] + l2Provider: provider, + l2GatewayAddresses: [customGateway] }, priority: prio }) From edcd366abb0ee48a9eb4698fd978e4cc1e2bec09 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 19:50:32 +0100 Subject: [PATCH 06/24] remove duplicate check --- .../util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts index ea0887c54c..0b3d9531e3 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts @@ -2,8 +2,6 @@ import { Provider, BlockTag } from '@ethersproject/providers' import { Erc20Bridger, EventArgs } from '@arbitrum/sdk' import { WithdrawalInitiatedEvent } from '@arbitrum/sdk/dist/lib/abi/L2ArbitrumGateway' -import { getNonce } from '../AddressUtils' - function dedupeEvents( events: (EventArgs & { txHash: string @@ -41,11 +39,9 @@ export async function fetchTokenWithdrawalsFromEventLogs({ const erc20Bridger = await Erc20Bridger.fromProvider(l2Provider) const promises: ReturnType[] = [] - const senderNonce = await getNonce(sender, { provider: l2Provider }) - l2GatewayAddresses.forEach(gatewayAddress => { // funds sent by this address - if (sender && senderNonce > 0) { + if (sender) { promises.push( erc20Bridger.getWithdrawalEvents( l2Provider, From 59928946744cb0413e4cc0c9bf2bd9d2d939277c Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 19:51:38 +0100 Subject: [PATCH 07/24] oops --- packages/arb-token-bridge-ui/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/arb-token-bridge-ui/package.json b/packages/arb-token-bridge-ui/package.json index 775c8a38f7..63b2533928 100644 --- a/packages/arb-token-bridge-ui/package.json +++ b/packages/arb-token-bridge-ui/package.json @@ -50,7 +50,7 @@ "zustand": "^4.3.9" }, "scripts": { - "predev": "yarn generateDenylist", + "predev": "yarn generateDenylist && yarn generateOpenGraphImages", "dev": "next dev", "prebuild": "yarn generateDenylist && yarn generateOpenGraphImages", "postinstall": "patch-package", From e9c8f5602219c8bc6658b253f3d2814b86262046 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 19:53:49 +0100 Subject: [PATCH 08/24] dupe check --- .../util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts index ea0887c54c..0b3d9531e3 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts @@ -2,8 +2,6 @@ import { Provider, BlockTag } from '@ethersproject/providers' import { Erc20Bridger, EventArgs } from '@arbitrum/sdk' import { WithdrawalInitiatedEvent } from '@arbitrum/sdk/dist/lib/abi/L2ArbitrumGateway' -import { getNonce } from '../AddressUtils' - function dedupeEvents( events: (EventArgs & { txHash: string @@ -41,11 +39,9 @@ export async function fetchTokenWithdrawalsFromEventLogs({ const erc20Bridger = await Erc20Bridger.fromProvider(l2Provider) const promises: ReturnType[] = [] - const senderNonce = await getNonce(sender, { provider: l2Provider }) - l2GatewayAddresses.forEach(gatewayAddress => { // funds sent by this address - if (sender && senderNonce > 0) { + if (sender) { promises.push( erc20Bridger.getWithdrawalEvents( l2Provider, From b158c1426717680a852b859d968d9c0d7ea6b694 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 19:55:46 +0100 Subject: [PATCH 09/24] add backOff --- .../src/util/withdrawals/fetchWithdrawals.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts index b59284b661..76f08729e5 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts @@ -3,6 +3,7 @@ import { Provider, StaticJsonRpcProvider } from '@ethersproject/providers' +import { backOff } from 'exponential-backoff' import { fetchETHWithdrawalsFromEventLogs } from './fetchETHWithdrawalsFromEventLogs' @@ -60,7 +61,9 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( await wait(2000) const network = await getArbitrumNetwork(provider) - const senderNonce = await getNonce(address, { provider: provider }) + const senderNonce = await backOff(() => + getNonce(address, { provider: provider }) + ) const standardGateway = network.tokenBridge?.childErc20Gateway! const customGateway = network.tokenBridge?.childCustomGateway! @@ -158,7 +161,7 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( const results = await Promise.all( filteredQueries.map(query => - fetchTokenWithdrawalsFromEventLogs(query.params) + backOff(() => fetchTokenWithdrawalsFromEventLogs(query.params)) ) ) From a33a55f0c9115a3e38f6f8111dbee7e6b6325b9c Mon Sep 17 00:00:00 2001 From: spsjvc Date: Mon, 9 Dec 2024 20:19:52 +0100 Subject: [PATCH 10/24] clean up --- packages/arb-token-bridge-ui/package.json | 1 - .../src/token-bridge-sdk/utils.ts | 26 ++++++++++++++++++- .../src/util/withdrawals/fetchWithdrawals.ts | 12 ++++----- yarn.lock | 5 ---- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/packages/arb-token-bridge-ui/package.json b/packages/arb-token-bridge-ui/package.json index 63b2533928..abe147b101 100644 --- a/packages/arb-token-bridge-ui/package.json +++ b/packages/arb-token-bridge-ui/package.json @@ -25,7 +25,6 @@ "cheerio": "^1.0.0-rc.12", "dayjs": "^1.11.8", "ethers": "^5.6.0", - "exponential-backoff": "^3.1.1", "graphql": "^16.8.1", "lodash-es": "^4.17.21", "next": "^14.2.12", diff --git a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts index 54e7483bbf..c611423955 100644 --- a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts +++ b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts @@ -12,6 +12,7 @@ import { getArbitrumNetwork } from '@arbitrum/sdk' import { isDepositMode } from '../util/isDepositMode' +import { ConnectionInfo } from 'ethers/lib/utils.js' export const getAddressFromSigner = async (signer: Signer) => { const address = await signer.getAddress() @@ -104,9 +105,32 @@ const getProviderForChainCache: { // start with empty cache } +const THROTTLE_LIMIT = 10 + +const connection: Omit = { + timeout: 300000, + allowGzip: true, + skipFetchSetup: true, + throttleLimit: THROTTLE_LIMIT, + throttleSlotInterval: 3000, + throttleCallback: async (attempt: number) => { + // Always retry until we hit the THROTTLE_LIMIT + // Otherwise, it only throttles for specific response codes + // Return true to continue retrying, false to stop + return attempt <= THROTTLE_LIMIT + }, + headers: { + Accept: '*/*', + 'Accept-Encoding': 'gzip, deflate, br' + } +} + function createProviderWithCache(chainId: ChainId) { const rpcUrl = rpcURLs[chainId] - const provider = new StaticJsonRpcProvider(rpcUrl, chainId) + const provider = new StaticJsonRpcProvider( + { ...connection, url: rpcUrl! }, + chainId + ) getProviderForChainCache[chainId] = provider return provider } diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts index 76f08729e5..b4ac47c5c7 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts @@ -3,7 +3,6 @@ import { Provider, StaticJsonRpcProvider } from '@ethersproject/providers' -import { backOff } from 'exponential-backoff' import { fetchETHWithdrawalsFromEventLogs } from './fetchETHWithdrawalsFromEventLogs' @@ -61,12 +60,13 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( await wait(2000) const network = await getArbitrumNetwork(provider) - const senderNonce = await backOff(() => - getNonce(address, { provider: provider }) - ) + const senderNonce = await getNonce(address, { provider: provider }) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain const standardGateway = network.tokenBridge?.childErc20Gateway! + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain const customGateway = network.tokenBridge?.childCustomGateway! + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain const wethGateway = network.tokenBridge?.childWethGateway! let prio = 1 @@ -151,7 +151,7 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( queries.length - 1 ]! - let result: Result = [] + const result: Result = [] let currentPriority = 1 while (currentPriority <= maxPriority) { @@ -161,7 +161,7 @@ async function fetchTokenWithdrawalsFromEventLogsSequentially( const results = await Promise.all( filteredQueries.map(query => - backOff(() => fetchTokenWithdrawalsFromEventLogs(query.params)) + fetchTokenWithdrawalsFromEventLogs(query.params) ) ) diff --git a/yarn.lock b/yarn.lock index e51b9d18df..da1ddc8a1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7545,11 +7545,6 @@ expect@^29.0.0, expect@^29.5.0: jest-message-util "^29.5.0" jest-util "^29.5.0" -exponential-backoff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" - integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== - express@^4.17.3: version "4.21.0" resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915" From 92e66ec64be0084cf588b2dd11c5b4094dfdaa76 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 12:30:37 +0100 Subject: [PATCH 11/24] clean up --- .../fetchTokenWithdrawalsFromEventLogs.ts | 18 +- ...kenWithdrawalsFromEventLogsSequentially.ts | 157 ++++++++++++++++ .../src/util/withdrawals/fetchWithdrawals.ts | 170 ++---------------- 3 files changed, 178 insertions(+), 167 deletions(-) create mode 100644 packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts index 0b3d9531e3..8296e2085f 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts @@ -10,6 +10,15 @@ function dedupeEvents( return [...new Map(events.map(item => [item.txHash, item])).values()] } +export type FetchTokenWithdrawalsFromEventLogsParams = { + sender?: string + receiver?: string + fromBlock: BlockTag + toBlock: BlockTag + l2Provider: Provider + l2GatewayAddresses?: string[] +} + /** * Fetches initiated token withdrawals from event logs in range of [fromBlock, toBlock]. * @@ -28,14 +37,7 @@ export async function fetchTokenWithdrawalsFromEventLogs({ toBlock, l2Provider, l2GatewayAddresses = [] -}: { - sender?: string - receiver?: string - fromBlock: BlockTag - toBlock: BlockTag - l2Provider: Provider - l2GatewayAddresses?: string[] -}) { +}: FetchTokenWithdrawalsFromEventLogsParams) { const erc20Bridger = await Erc20Bridger.fromProvider(l2Provider) const promises: ReturnType[] = [] diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts new file mode 100644 index 0000000000..31de7f8c7f --- /dev/null +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -0,0 +1,157 @@ +import { constants } from 'ethers' +import { Provider, BlockTag } from '@ethersproject/providers' +import { Erc20Bridger, getArbitrumNetwork } from '@arbitrum/sdk' + +import { + fetchTokenWithdrawalsFromEventLogs, + FetchTokenWithdrawalsFromEventLogsParams +} from './fetchTokenWithdrawalsFromEventLogs' +import { getNonce } from '../AddressUtils' + +function wait(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)) +} + +type WithdrawalQuery = { + params: FetchTokenWithdrawalsFromEventLogsParams + priority: number +} + +type UnwrapPromise = T extends Promise ? U : T + +type Result = UnwrapPromise> + +export type FetchTokenWithdrawalsFromEventLogsSequentiallyParams = { + sender?: string + receiver?: string + provider: Provider + fromBlock?: BlockTag + toBlock?: BlockTag +} + +export async function fetchTokenWithdrawalsFromEventLogsSequentially({ + sender, + receiver, + provider, + fromBlock = 0, + toBlock = 'latest' +}: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise { + await wait(2000) + + const network = await getArbitrumNetwork(provider) + const senderNonce = await getNonce(sender, { provider }) + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain + const standardGateway = network.tokenBridge?.childErc20Gateway! + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain + const customGateway = network.tokenBridge?.childCustomGateway! + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain + const wethGateway = network.tokenBridge?.childWethGateway! + + let prio = 1 + + const queries: WithdrawalQuery[] = [] + + if (senderNonce > 0) { + queries.push({ + params: { + sender, + fromBlock, + toBlock, + l2Provider: provider, + l2GatewayAddresses: [standardGateway] + }, + priority: prio + }) + prio++ + if (wethGateway !== constants.AddressZero) { + queries.push({ + params: { + sender, + fromBlock, + toBlock: 'latest', + l2Provider: provider, + l2GatewayAddresses: [wethGateway] + }, + priority: prio + }) + prio++ + } + queries.push({ + params: { + sender, + fromBlock, + toBlock: 'latest', + l2Provider: provider, + l2GatewayAddresses: [customGateway] + }, + priority: prio + }) + prio++ + } + + queries.push({ + params: { + receiver, + fromBlock, + toBlock: 'latest', + l2Provider: provider, + l2GatewayAddresses: [standardGateway] + }, + priority: prio + }) + prio++ + if (wethGateway !== constants.AddressZero) { + queries.push({ + params: { + receiver, + fromBlock, + toBlock: 'latest', + l2Provider: provider, + l2GatewayAddresses: [wethGateway] + }, + priority: prio + }) + prio++ + } + queries.push({ + params: { + receiver, + fromBlock, + toBlock: 'latest', + l2Provider: provider, + l2GatewayAddresses: [customGateway] + }, + priority: prio + }) + prio++ + + const maxPriority = queries.map(query => query.priority).sort()[ + queries.length - 1 + ]! + + const result: Result = [] + let currentPriority = 1 + + while (currentPriority <= maxPriority) { + const filteredQueries = queries.filter( + query => query.priority === currentPriority + ) + + const results = await Promise.all( + filteredQueries.map(query => + fetchTokenWithdrawalsFromEventLogs(query.params) + ) + ) + + results.forEach(r => { + result.push(...r) + }) + + await wait(2000) + + currentPriority += 1 + } + + return result +} diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts index b4ac47c5c7..8b4290ce28 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts @@ -1,8 +1,4 @@ -import { - BlockTag, - Provider, - StaticJsonRpcProvider -} from '@ethersproject/providers' +import { Provider } from '@ethersproject/providers' import { fetchETHWithdrawalsFromEventLogs } from './fetchETHWithdrawalsFromEventLogs' @@ -11,14 +7,12 @@ import { fetchWithdrawalsFromSubgraph } from './fetchWithdrawalsFromSubgraph' import { fetchLatestSubgraphBlockNumber } from '../SubgraphUtils' -import { fetchTokenWithdrawalsFromEventLogs } from './fetchTokenWithdrawalsFromEventLogs' + import { fetchL2Gateways } from '../fetchL2Gateways' import { Withdrawal } from '../../hooks/useTransactionHistory' import { attachTimestampToTokenWithdrawal } from './helpers' import { WithdrawalInitiated } from '../../hooks/arbTokenBridge.types' -import { Erc20Bridger, getArbitrumNetwork } from '@arbitrum/sdk' -import { ethers } from 'ethers' -import { getNonce } from '../AddressUtils' +import { fetchTokenWithdrawalsFromEventLogsSequentially } from './fetchTokenWithdrawalsFromEventLogsSequentially' export type FetchWithdrawalsParams = { sender?: string @@ -32,151 +26,6 @@ export type FetchWithdrawalsParams = { searchString?: string } -type UnwrapPromise = T extends Promise ? U : T - -type WithdrawalQuery = { - params: { - sender?: string - receiver?: string - fromBlock: BlockTag - toBlock: BlockTag - l2Provider: Provider - l2GatewayAddresses?: string[] - } - priority: number -} - -type Result = UnwrapPromise> - -function wait(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)) -} - -async function fetchTokenWithdrawalsFromEventLogsSequentially( - address: string, - provider: Provider, - fromBlock: BlockTag -): Promise { - await wait(2000) - - const network = await getArbitrumNetwork(provider) - const senderNonce = await getNonce(address, { provider: provider }) - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain - const standardGateway = network.tokenBridge?.childErc20Gateway! - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain - const customGateway = network.tokenBridge?.childCustomGateway! - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain - const wethGateway = network.tokenBridge?.childWethGateway! - - let prio = 1 - - const queries: WithdrawalQuery[] = [] - - if (senderNonce > 0) { - queries.push({ - params: { - sender: address, - fromBlock, - toBlock: 'latest', - l2Provider: provider, - l2GatewayAddresses: [standardGateway] - }, - priority: prio - }) - prio++ - if (wethGateway !== ethers.constants.AddressZero) { - queries.push({ - params: { - sender: address, - fromBlock, - toBlock: 'latest', - l2Provider: provider, - l2GatewayAddresses: [wethGateway] - }, - priority: prio - }) - prio++ - } - queries.push({ - params: { - sender: address, - fromBlock, - toBlock: 'latest', - l2Provider: provider, - l2GatewayAddresses: [customGateway] - }, - priority: prio - }) - prio++ - } - - queries.push({ - params: { - receiver: address, - fromBlock, - toBlock: 'latest', - l2Provider: provider, - l2GatewayAddresses: [standardGateway] - }, - priority: prio - }) - prio++ - if (wethGateway !== ethers.constants.AddressZero) { - queries.push({ - params: { - receiver: address, - fromBlock, - toBlock: 'latest', - l2Provider: provider, - l2GatewayAddresses: [wethGateway] - }, - priority: prio - }) - prio++ - } - queries.push({ - params: { - receiver: address, - fromBlock, - toBlock: 'latest', - l2Provider: provider, - l2GatewayAddresses: [customGateway] - }, - priority: prio - }) - prio++ - - const maxPriority = queries.map(query => query.priority).sort()[ - queries.length - 1 - ]! - - const result: Result = [] - let currentPriority = 1 - - while (currentPriority <= maxPriority) { - const filteredQueries = queries.filter( - query => query.priority === currentPriority - ) - - const results = await Promise.all( - filteredQueries.map(query => - fetchTokenWithdrawalsFromEventLogs(query.params) - ) - ) - - results.forEach(r => { - result.push(...r) - }) - - await wait(2000) - - currentPriority += 1 - } - - return result -} - export async function fetchWithdrawals({ sender, receiver, @@ -195,6 +44,7 @@ export async function fetchWithdrawals({ const l1ChainID = (await l1Provider.getNetwork()).chainId const l2ChainID = (await l2Provider.getNetwork()).chainId + // todo: use const l2GatewayAddresses = await fetchL2Gateways(l2Provider) if (!fromBlock) { @@ -245,11 +95,13 @@ export async function fetchWithdrawals({ toBlock: 'latest', l2Provider: l2Provider }), - fetchTokenWithdrawalsFromEventLogsSequentially( - sender!, - l2Provider, - toBlock + 1 - ) + fetchTokenWithdrawalsFromEventLogsSequentially({ + sender, + receiver, + fromBlock: toBlock + 1, + toBlock: 'latest', + provider: l2Provider + }) ]) const mappedEthWithdrawalsFromEventLogs: Withdrawal[] = From 924e0a410faff8e0cc13c018c1572b4258aebece Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 12:41:57 +0100 Subject: [PATCH 12/24] use custom custom gateways --- .../src/util/fetchL2Gateways.ts | 15 +---------- ...kenWithdrawalsFromEventLogsSequentially.ts | 26 +++++++++++++++++-- .../src/util/withdrawals/fetchWithdrawals.ts | 4 --- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/fetchL2Gateways.ts b/packages/arb-token-bridge-ui/src/util/fetchL2Gateways.ts index c23a7200f2..ed19d16c55 100644 --- a/packages/arb-token-bridge-ui/src/util/fetchL2Gateways.ts +++ b/packages/arb-token-bridge-ui/src/util/fetchL2Gateways.ts @@ -1,4 +1,3 @@ -import { constants } from 'ethers' import { Provider } from '@ethersproject/providers' import { getArbitrumNetwork } from '@arbitrum/sdk' @@ -19,15 +18,7 @@ import { export async function fetchL2Gateways(l2Provider: Provider) { const l2Network = await getArbitrumNetwork(l2Provider) - if (!l2Network.tokenBridge) { - return [] - } - - /* configure gateway addresses for fetching withdrawals */ - const { childErc20Gateway, childCustomGateway, childWethGateway } = - l2Network.tokenBridge - - const gatewaysToUse = [childErc20Gateway, childCustomGateway] + const gatewaysToUse = [] const l2ArbReverseGateway = l2ArbReverseGatewayAddresses[l2Network.chainId] const l2DaiGateway = l2DaiGatewayAddresses[l2Network.chainId] const l2wstETHGateway = l2wstETHGatewayAddresses[l2Network.chainId] @@ -35,10 +26,6 @@ export async function fetchL2Gateways(l2Provider: Provider) { const l2MoonGateway = l2MoonGatewayAddresses[l2Network.chainId] const l2UsdcGateway = l2UsdcGatewayAddresses[l2Network.chainId] - // custom gas token chains will have weth gateway set to address zero - if (childWethGateway !== constants.AddressZero) { - gatewaysToUse.push(childWethGateway) - } if (l2ArbReverseGateway) { gatewaysToUse.push(l2ArbReverseGateway) } diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index 31de7f8c7f..315da1813f 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -7,6 +7,7 @@ import { FetchTokenWithdrawalsFromEventLogsParams } from './fetchTokenWithdrawalsFromEventLogs' import { getNonce } from '../AddressUtils' +import { fetchL2Gateways } from '../fetchL2Gateways' function wait(ms: number) { return new Promise(resolve => setTimeout(resolve, ms)) @@ -36,8 +37,6 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ fromBlock = 0, toBlock = 'latest' }: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise { - await wait(2000) - const network = await getArbitrumNetwork(provider) const senderNonce = await getNonce(sender, { provider }) @@ -47,6 +46,7 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ const customGateway = network.tokenBridge?.childCustomGateway! // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain const wethGateway = network.tokenBridge?.childWethGateway! + const customCustomGateways = await fetchL2Gateways(provider) let prio = 1 @@ -88,6 +88,17 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ priority: prio }) prio++ + queries.push({ + params: { + sender, + fromBlock, + toBlock: 'latest', + l2Provider: provider, + l2GatewayAddresses: customCustomGateways + }, + priority: prio + }) + prio++ } queries.push({ @@ -125,6 +136,17 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ priority: prio }) prio++ + queries.push({ + params: { + receiver, + fromBlock, + toBlock: 'latest', + l2Provider: provider, + l2GatewayAddresses: customCustomGateways + }, + priority: prio + }) + prio++ const maxPriority = queries.map(query => query.priority).sort()[ queries.length - 1 diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts index 8b4290ce28..a8e977faf3 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts @@ -8,7 +8,6 @@ import { } from './fetchWithdrawalsFromSubgraph' import { fetchLatestSubgraphBlockNumber } from '../SubgraphUtils' -import { fetchL2Gateways } from '../fetchL2Gateways' import { Withdrawal } from '../../hooks/useTransactionHistory' import { attachTimestampToTokenWithdrawal } from './helpers' import { WithdrawalInitiated } from '../../hooks/arbTokenBridge.types' @@ -44,9 +43,6 @@ export async function fetchWithdrawals({ const l1ChainID = (await l1Provider.getNetwork()).chainId const l2ChainID = (await l2Provider.getNetwork()).chainId - // todo: use - const l2GatewayAddresses = await fetchL2Gateways(l2Provider) - if (!fromBlock) { fromBlock = 0 } From e15683ac58c0af4547a08ddb8855a0ad9d8a174e Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 12:47:04 +0100 Subject: [PATCH 13/24] clean up --- ...kenWithdrawalsFromEventLogsSequentially.ts | 75 +++++++++---------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index 315da1813f..f4433e384e 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -37,6 +37,24 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ fromBlock = 0, toBlock = 'latest' }: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise { + function buildQueryParams({ + sender, + receiver, + l2GatewayAddresses + }: Pick< + FetchTokenWithdrawalsFromEventLogsParams, + 'sender' | 'receiver' | 'l2GatewayAddresses' + >) { + return { + sender, + receiver, + fromBlock, + toBlock, + l2Provider: provider, + l2GatewayAddresses + } + } + const network = await getArbitrumNetwork(provider) const senderNonce = await getNonce(sender, { provider }) @@ -54,96 +72,71 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ if (senderNonce > 0) { queries.push({ - params: { + params: buildQueryParams({ sender, - fromBlock, - toBlock, - l2Provider: provider, l2GatewayAddresses: [standardGateway] - }, + }), priority: prio }) prio++ if (wethGateway !== constants.AddressZero) { queries.push({ - params: { + params: buildQueryParams({ sender, - fromBlock, - toBlock: 'latest', - l2Provider: provider, l2GatewayAddresses: [wethGateway] - }, + }), priority: prio }) prio++ } queries.push({ - params: { + params: buildQueryParams({ sender, - fromBlock, - toBlock: 'latest', - l2Provider: provider, l2GatewayAddresses: [customGateway] - }, + }), priority: prio }) prio++ queries.push({ - params: { + params: buildQueryParams({ sender, - fromBlock, - toBlock: 'latest', - l2Provider: provider, l2GatewayAddresses: customCustomGateways - }, + }), priority: prio }) prio++ } - queries.push({ - params: { + params: buildQueryParams({ receiver, - fromBlock, - toBlock: 'latest', - l2Provider: provider, l2GatewayAddresses: [standardGateway] - }, + }), priority: prio }) prio++ if (wethGateway !== constants.AddressZero) { queries.push({ - params: { + params: buildQueryParams({ receiver, - fromBlock, - toBlock: 'latest', - l2Provider: provider, l2GatewayAddresses: [wethGateway] - }, + }), priority: prio }) prio++ } queries.push({ - params: { + params: buildQueryParams({ receiver, - fromBlock, - toBlock: 'latest', - l2Provider: provider, l2GatewayAddresses: [customGateway] - }, + }), priority: prio }) prio++ queries.push({ - params: { + params: buildQueryParams({ receiver, - fromBlock, - toBlock: 'latest', - l2Provider: provider, l2GatewayAddresses: customCustomGateways - }, + }), priority: prio }) prio++ From 75d9823fc75ceef6eea94b9537eaf78bfdc612dd Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 12:51:36 +0100 Subject: [PATCH 14/24] clean up --- ...kenWithdrawalsFromEventLogsSequentially.ts | 55 ++++++------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index f4433e384e..f367cb8bd1 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -37,21 +37,23 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ fromBlock = 0, toBlock = 'latest' }: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise { + // function here so we can reuse common params function buildQueryParams({ sender, receiver, - l2GatewayAddresses - }: Pick< - FetchTokenWithdrawalsFromEventLogsParams, - 'sender' | 'receiver' | 'l2GatewayAddresses' - >) { + gateways = [] + }: { + sender?: string + receiver?: string + gateways?: string[] + }) { return { sender, receiver, fromBlock, toBlock, l2Provider: provider, - l2GatewayAddresses + l2GatewayAddresses: gateways } } @@ -70,73 +72,50 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ const queries: WithdrawalQuery[] = [] + // only add queries for sender if account has activity if (senderNonce > 0) { queries.push({ - params: buildQueryParams({ - sender, - l2GatewayAddresses: [standardGateway] - }), + params: buildQueryParams({ sender, gateways: [standardGateway] }), priority: prio }) prio++ if (wethGateway !== constants.AddressZero) { queries.push({ - params: buildQueryParams({ - sender, - l2GatewayAddresses: [wethGateway] - }), + params: buildQueryParams({ sender, gateways: [wethGateway] }), priority: prio }) prio++ } queries.push({ - params: buildQueryParams({ - sender, - l2GatewayAddresses: [customGateway] - }), + params: buildQueryParams({ sender, gateways: [customGateway] }), priority: prio }) prio++ queries.push({ - params: buildQueryParams({ - sender, - l2GatewayAddresses: customCustomGateways - }), + params: buildQueryParams({ sender, gateways: customCustomGateways }), priority: prio }) prio++ } queries.push({ - params: buildQueryParams({ - receiver, - l2GatewayAddresses: [standardGateway] - }), + params: buildQueryParams({ receiver, gateways: [standardGateway] }), priority: prio }) prio++ if (wethGateway !== constants.AddressZero) { queries.push({ - params: buildQueryParams({ - receiver, - l2GatewayAddresses: [wethGateway] - }), + params: buildQueryParams({ receiver, gateways: [wethGateway] }), priority: prio }) prio++ } queries.push({ - params: buildQueryParams({ - receiver, - l2GatewayAddresses: [customGateway] - }), + params: buildQueryParams({ receiver, gateways: [customGateway] }), priority: prio }) prio++ queries.push({ - params: buildQueryParams({ - receiver, - l2GatewayAddresses: customCustomGateways - }), + params: buildQueryParams({ receiver, gateways: customCustomGateways }), priority: prio }) prio++ From 3941f7b342ea5e0079e1f013a46016b3228de824 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 13:02:45 +0100 Subject: [PATCH 15/24] clean up more --- ...kenWithdrawalsFromEventLogsSequentially.ts | 81 +++++++------------ 1 file changed, 28 insertions(+), 53 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index f367cb8bd1..722b6a5872 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -37,8 +37,13 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ fromBlock = 0, toBlock = 'latest' }: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise { + // keep track of priority, and increment as new stuff is added + let priority = 1 + // keep track of queries + const queries: WithdrawalQuery[] = [] + // function here so we can reuse common params - function buildQueryParams({ + function buildQuery({ sender, receiver, gateways = [] @@ -46,14 +51,18 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ sender?: string receiver?: string gateways?: string[] - }) { + }): WithdrawalQuery { return { - sender, - receiver, - fromBlock, - toBlock, - l2Provider: provider, - l2GatewayAddresses: gateways + params: { + sender, + receiver, + fromBlock, + toBlock, + l2Provider: provider, + l2GatewayAddresses: gateways + }, + // todo: check if priority is incremented at the right time + priority: ++priority } } @@ -68,57 +77,23 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ const wethGateway = network.tokenBridge?.childWethGateway! const customCustomGateways = await fetchL2Gateways(provider) - let prio = 1 - - const queries: WithdrawalQuery[] = [] - - // only add queries for sender if account has activity + // sender queries, only add if nonce > 0 if (senderNonce > 0) { - queries.push({ - params: buildQueryParams({ sender, gateways: [standardGateway] }), - priority: prio - }) - prio++ + queries.push(buildQuery({ sender, gateways: [standardGateway] })) if (wethGateway !== constants.AddressZero) { - queries.push({ - params: buildQueryParams({ sender, gateways: [wethGateway] }), - priority: prio - }) - prio++ + queries.push(buildQuery({ sender, gateways: [wethGateway] })) } - queries.push({ - params: buildQueryParams({ sender, gateways: [customGateway] }), - priority: prio - }) - prio++ - queries.push({ - params: buildQueryParams({ sender, gateways: customCustomGateways }), - priority: prio - }) - prio++ + queries.push(buildQuery({ sender, gateways: [customGateway] })) + queries.push(buildQuery({ sender, gateways: customCustomGateways })) } - queries.push({ - params: buildQueryParams({ receiver, gateways: [standardGateway] }), - priority: prio - }) - prio++ + + // receiver queries + queries.push(buildQuery({ receiver, gateways: [standardGateway] })) if (wethGateway !== constants.AddressZero) { - queries.push({ - params: buildQueryParams({ receiver, gateways: [wethGateway] }), - priority: prio - }) - prio++ + queries.push(buildQuery({ receiver, gateways: [wethGateway] })) } - queries.push({ - params: buildQueryParams({ receiver, gateways: [customGateway] }), - priority: prio - }) - prio++ - queries.push({ - params: buildQueryParams({ receiver, gateways: customCustomGateways }), - priority: prio - }) - prio++ + queries.push(buildQuery({ receiver, gateways: [customGateway] })) + queries.push(buildQuery({ receiver, gateways: customCustomGateways })) const maxPriority = queries.map(query => query.priority).sort()[ queries.length - 1 From 6067f9cae9fc1f9b119462a39b6b4a022b4efafa Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 13:08:55 +0100 Subject: [PATCH 16/24] clean up --- ...kenWithdrawalsFromEventLogsSequentially.ts | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index 722b6a5872..103f717cdd 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -43,7 +43,7 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ const queries: WithdrawalQuery[] = [] // function here so we can reuse common params - function buildQuery({ + function buildQueryParams({ sender, receiver, gateways = [] @@ -51,21 +51,29 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ sender?: string receiver?: string gateways?: string[] - }): WithdrawalQuery { + }): WithdrawalQuery['params'] { return { - params: { - sender, - receiver, - fromBlock, - toBlock, - l2Provider: provider, - l2GatewayAddresses: gateways - }, - // todo: check if priority is incremented at the right time - priority: ++priority + sender, + receiver, + fromBlock, + toBlock, + l2Provider: provider, + l2GatewayAddresses: gateways } } + function addQuery(params: WithdrawalQuery['params']) { + const gateways = params.l2GatewayAddresses ?? [] + const gatewaysSanitized = gateways.filter(g => g !== constants.AddressZero) + + if (gatewaysSanitized.length === 0) { + return + } + + queries.push({ params, priority }) + priority++ + } + const network = await getArbitrumNetwork(provider) const senderNonce = await getNonce(sender, { provider }) @@ -77,23 +85,19 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ const wethGateway = network.tokenBridge?.childWethGateway! const customCustomGateways = await fetchL2Gateways(provider) - // sender queries, only add if nonce > 0 + // sender queries; only add if nonce > 0 if (senderNonce > 0) { - queries.push(buildQuery({ sender, gateways: [standardGateway] })) - if (wethGateway !== constants.AddressZero) { - queries.push(buildQuery({ sender, gateways: [wethGateway] })) - } - queries.push(buildQuery({ sender, gateways: [customGateway] })) - queries.push(buildQuery({ sender, gateways: customCustomGateways })) + addQuery(buildQueryParams({ sender, gateways: [standardGateway] })) + addQuery(buildQueryParams({ sender, gateways: [wethGateway] })) + addQuery(buildQueryParams({ sender, gateways: [customGateway] })) + addQuery(buildQueryParams({ sender, gateways: customCustomGateways })) } // receiver queries - queries.push(buildQuery({ receiver, gateways: [standardGateway] })) - if (wethGateway !== constants.AddressZero) { - queries.push(buildQuery({ receiver, gateways: [wethGateway] })) - } - queries.push(buildQuery({ receiver, gateways: [customGateway] })) - queries.push(buildQuery({ receiver, gateways: customCustomGateways })) + addQuery(buildQueryParams({ receiver, gateways: [standardGateway] })) + addQuery(buildQueryParams({ receiver, gateways: [wethGateway] })) + addQuery(buildQueryParams({ receiver, gateways: [customGateway] })) + addQuery(buildQueryParams({ receiver, gateways: customCustomGateways })) const maxPriority = queries.map(query => query.priority).sort()[ queries.length - 1 From 43a9f828e3d9738c57316d6f383c6bc25062a4b1 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 13:10:08 +0100 Subject: [PATCH 17/24] clean up --- .../fetchTokenWithdrawalsFromEventLogsSequentially.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index 103f717cdd..0592bcff68 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -70,8 +70,11 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ return } - queries.push({ params, priority }) - priority++ + queries.push({ + params: { ...params, l2GatewayAddresses: gatewaysSanitized }, + // todo: check + priority: priority++ + }) } const network = await getArbitrumNetwork(provider) From aeaa9a91bf766026c5d02ba2c0159170afd7b35c Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 13:15:35 +0100 Subject: [PATCH 18/24] clean up more --- ...kenWithdrawalsFromEventLogsSequentially.ts | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index 0592bcff68..e905e0d86d 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -13,6 +13,27 @@ function wait(ms: number) { return new Promise(resolve => setTimeout(resolve, ms)) } +async function getGateways(provider: Provider): Promise<{ + standardGateway: string + wethGateway: string + customGateway: string + otherGateways: string[] +}> { + const network = await getArbitrumNetwork(provider) + + const standardGateway = network.tokenBridge?.childErc20Gateway + const customGateway = network.tokenBridge?.childCustomGateway + const wethGateway = network.tokenBridge?.childWethGateway + const otherGateways = await fetchL2Gateways(provider) + + return { + standardGateway: standardGateway ?? constants.AddressZero, + wethGateway: wethGateway ?? constants.AddressZero, + customGateway: customGateway ?? constants.AddressZero, + otherGateways + } +} + type WithdrawalQuery = { params: FetchTokenWithdrawalsFromEventLogsParams priority: number @@ -77,30 +98,22 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ }) } - const network = await getArbitrumNetwork(provider) + const gateways = await getGateways(provider) const senderNonce = await getNonce(sender, { provider }) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain - const standardGateway = network.tokenBridge?.childErc20Gateway! - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain - const customGateway = network.tokenBridge?.childCustomGateway! - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain - const wethGateway = network.tokenBridge?.childWethGateway! - const customCustomGateways = await fetchL2Gateways(provider) - // sender queries; only add if nonce > 0 if (senderNonce > 0) { - addQuery(buildQueryParams({ sender, gateways: [standardGateway] })) - addQuery(buildQueryParams({ sender, gateways: [wethGateway] })) - addQuery(buildQueryParams({ sender, gateways: [customGateway] })) - addQuery(buildQueryParams({ sender, gateways: customCustomGateways })) + addQuery(buildQueryParams({ sender, gateways: [gateways.standardGateway] })) + addQuery(buildQueryParams({ sender, gateways: [gateways.wethGateway] })) + addQuery(buildQueryParams({ sender, gateways: [gateways.customGateway] })) + addQuery(buildQueryParams({ sender, gateways: gateways.otherGateways })) } // receiver queries - addQuery(buildQueryParams({ receiver, gateways: [standardGateway] })) - addQuery(buildQueryParams({ receiver, gateways: [wethGateway] })) - addQuery(buildQueryParams({ receiver, gateways: [customGateway] })) - addQuery(buildQueryParams({ receiver, gateways: customCustomGateways })) + addQuery(buildQueryParams({ receiver, gateways: [gateways.standardGateway] })) + addQuery(buildQueryParams({ receiver, gateways: [gateways.wethGateway] })) + addQuery(buildQueryParams({ receiver, gateways: [gateways.customGateway] })) + addQuery(buildQueryParams({ receiver, gateways: gateways.otherGateways })) const maxPriority = queries.map(query => query.priority).sort()[ queries.length - 1 From 33b224057833a072fc4bb693c83f464d26dc6f29 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 15:31:24 +0100 Subject: [PATCH 19/24] revert exponential back off for now --- .../src/token-bridge-sdk/utils.ts | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts index c611423955..54e7483bbf 100644 --- a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts +++ b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts @@ -12,7 +12,6 @@ import { getArbitrumNetwork } from '@arbitrum/sdk' import { isDepositMode } from '../util/isDepositMode' -import { ConnectionInfo } from 'ethers/lib/utils.js' export const getAddressFromSigner = async (signer: Signer) => { const address = await signer.getAddress() @@ -105,32 +104,9 @@ const getProviderForChainCache: { // start with empty cache } -const THROTTLE_LIMIT = 10 - -const connection: Omit = { - timeout: 300000, - allowGzip: true, - skipFetchSetup: true, - throttleLimit: THROTTLE_LIMIT, - throttleSlotInterval: 3000, - throttleCallback: async (attempt: number) => { - // Always retry until we hit the THROTTLE_LIMIT - // Otherwise, it only throttles for specific response codes - // Return true to continue retrying, false to stop - return attempt <= THROTTLE_LIMIT - }, - headers: { - Accept: '*/*', - 'Accept-Encoding': 'gzip, deflate, br' - } -} - function createProviderWithCache(chainId: ChainId) { const rpcUrl = rpcURLs[chainId] - const provider = new StaticJsonRpcProvider( - { ...connection, url: rpcUrl! }, - chainId - ) + const provider = new StaticJsonRpcProvider(rpcUrl, chainId) getProviderForChainCache[chainId] = provider return provider } From b45452b7fcd04e67aa472a938a0bc2a8d418647a Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 15:45:33 +0100 Subject: [PATCH 20/24] wrap up --- ...kenWithdrawalsFromEventLogsSequentially.ts | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index e905e0d86d..77c107597a 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -34,36 +34,42 @@ async function getGateways(provider: Provider): Promise<{ } } -type WithdrawalQuery = { +type UnwrapPromise = T extends Promise ? U : T + +type TokenWithdrawalQuery = { params: FetchTokenWithdrawalsFromEventLogsParams priority: number } -type UnwrapPromise = T extends Promise ? U : T - -type Result = UnwrapPromise> - export type FetchTokenWithdrawalsFromEventLogsSequentiallyParams = { sender?: string receiver?: string provider: Provider fromBlock?: BlockTag toBlock?: BlockTag + /** + * How long to delay in-between queries of different priority. + */ + delayMs?: number } +export type FetchTokenWithdrawalsFromEventLogsSequentiallyResult = + UnwrapPromise> + export async function fetchTokenWithdrawalsFromEventLogsSequentially({ sender, receiver, provider, fromBlock = 0, - toBlock = 'latest' -}: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise { - // keep track of priority, and increment as new stuff is added - let priority = 1 + toBlock = 'latest', + delayMs = 1_000 +}: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise { + // keep track of priority; increment as queries are added + let priority = 0 // keep track of queries - const queries: WithdrawalQuery[] = [] + const queries: TokenWithdrawalQuery[] = [] - // function here so we can reuse common params + // helper function to reuse common params function buildQueryParams({ sender, receiver, @@ -72,7 +78,7 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ sender?: string receiver?: string gateways?: string[] - }): WithdrawalQuery['params'] { + }): TokenWithdrawalQuery['params'] { return { sender, receiver, @@ -83,7 +89,8 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ } } - function addQuery(params: WithdrawalQuery['params']) { + // for sanitizing, adding queries and incrementing priority + function addQuery(params: TokenWithdrawalQuery['params']) { const gateways = params.l2GatewayAddresses ?? [] const gatewaysSanitized = gateways.filter(g => g !== constants.AddressZero) @@ -93,8 +100,7 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ queries.push({ params: { ...params, l2GatewayAddresses: gatewaysSanitized }, - // todo: check - priority: priority++ + priority: ++priority }) } @@ -115,31 +121,30 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ addQuery(buildQueryParams({ receiver, gateways: [gateways.customGateway] })) addQuery(buildQueryParams({ receiver, gateways: gateways.otherGateways })) - const maxPriority = queries.map(query => query.priority).sort()[ - queries.length - 1 - ]! - - const result: Result = [] + // for iterating through all priorities in the while loop below let currentPriority = 1 - while (currentPriority <= maxPriority) { - const filteredQueries = queries.filter( + // final result + const result: FetchTokenWithdrawalsFromEventLogsSequentiallyResult = [] + + while (currentPriority <= priority) { + const currentPriorityQueries = queries.filter( query => query.priority === currentPriority ) - const results = await Promise.all( - filteredQueries.map(query => + const currentPriorityResults = await Promise.all( + currentPriorityQueries.map(query => fetchTokenWithdrawalsFromEventLogs(query.params) ) ) - results.forEach(r => { + currentPriorityResults.forEach(r => { result.push(...r) }) - await wait(2000) + await wait(delayMs) - currentPriority += 1 + currentPriority++ } return result From 57ef6b90c4ad1a6d168ef9b1df611a14bcbd5745 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 15:48:07 +0100 Subject: [PATCH 21/24] increase delay --- .../fetchTokenWithdrawalsFromEventLogsSequentially.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index 77c107597a..7fc17c88fb 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -62,7 +62,7 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({ provider, fromBlock = 0, toBlock = 'latest', - delayMs = 1_000 + delayMs = 2_000 }: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise { // keep track of priority; increment as queries are added let priority = 0 From 82c13c17802d491c32c6630440aae9b8d2381d3d Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 16:30:26 +0100 Subject: [PATCH 22/24] use awaited --- .../fetchTokenWithdrawalsFromEventLogsSequentially.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index 7fc17c88fb..7d2ac67c0a 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -34,8 +34,6 @@ async function getGateways(provider: Provider): Promise<{ } } -type UnwrapPromise = T extends Promise ? U : T - type TokenWithdrawalQuery = { params: FetchTokenWithdrawalsFromEventLogsParams priority: number @@ -53,8 +51,9 @@ export type FetchTokenWithdrawalsFromEventLogsSequentiallyParams = { delayMs?: number } -export type FetchTokenWithdrawalsFromEventLogsSequentiallyResult = - UnwrapPromise> +export type FetchTokenWithdrawalsFromEventLogsSequentiallyResult = Awaited< + ReturnType +> export async function fetchTokenWithdrawalsFromEventLogsSequentially({ sender, From 751be46e598a73a06bb2c8fa7051be83c9162407 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 18:24:28 +0100 Subject: [PATCH 23/24] move file --- .../arb-token-bridge-ui/src/util/ExponentialBackoffUtils.ts | 3 +++ .../fetchTokenWithdrawalsFromEventLogsSequentially.ts | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 packages/arb-token-bridge-ui/src/util/ExponentialBackoffUtils.ts diff --git a/packages/arb-token-bridge-ui/src/util/ExponentialBackoffUtils.ts b/packages/arb-token-bridge-ui/src/util/ExponentialBackoffUtils.ts new file mode 100644 index 0000000000..b715e35da9 --- /dev/null +++ b/packages/arb-token-bridge-ui/src/util/ExponentialBackoffUtils.ts @@ -0,0 +1,3 @@ +export function wait(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)) +} diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts index 7d2ac67c0a..6815e32389 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts @@ -8,10 +8,7 @@ import { } from './fetchTokenWithdrawalsFromEventLogs' import { getNonce } from '../AddressUtils' import { fetchL2Gateways } from '../fetchL2Gateways' - -function wait(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)) -} +import { wait } from '../ExponentialBackoffUtils' async function getGateways(provider: Provider): Promise<{ standardGateway: string From 8ec6b170bc101ed53148f9cac2133ebf9159c20b Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 10 Dec 2024 18:29:09 +0100 Subject: [PATCH 24/24] fetch eth and token withdrawals sequentially --- .../src/util/withdrawals/fetchWithdrawals.ts | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts index a8e977faf3..fba6ff77e9 100644 --- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts +++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts @@ -12,6 +12,7 @@ import { Withdrawal } from '../../hooks/useTransactionHistory' import { attachTimestampToTokenWithdrawal } from './helpers' import { WithdrawalInitiated } from '../../hooks/arbTokenBridge.types' import { fetchTokenWithdrawalsFromEventLogsSequentially } from './fetchTokenWithdrawalsFromEventLogsSequentially' +import { wait } from '../ExponentialBackoffUtils' export type FetchWithdrawalsParams = { sender?: string @@ -83,22 +84,23 @@ export async function fetchWithdrawals({ console.log('Error fetching withdrawals from subgraph', error) } - const [ethWithdrawalsFromEventLogs, tokenWithdrawalsFromEventLogs] = - await Promise.all([ - fetchETHWithdrawalsFromEventLogs({ - receiver, - fromBlock: toBlock + 1, - toBlock: 'latest', - l2Provider: l2Provider - }), - fetchTokenWithdrawalsFromEventLogsSequentially({ - sender, - receiver, - fromBlock: toBlock + 1, - toBlock: 'latest', - provider: l2Provider - }) - ]) + const ethWithdrawalsFromEventLogs = await fetchETHWithdrawalsFromEventLogs({ + receiver, + fromBlock: toBlock + 1, + toBlock: 'latest', + l2Provider: l2Provider + }) + + await wait(2_000) + + const tokenWithdrawalsFromEventLogs = + await fetchTokenWithdrawalsFromEventLogsSequentially({ + sender, + receiver, + fromBlock: toBlock + 1, + toBlock: 'latest', + provider: l2Provider + }) const mappedEthWithdrawalsFromEventLogs: Withdrawal[] = ethWithdrawalsFromEventLogs.map(tx => {