From a3db7ce31993e32b92fa74bf76ae1e864bbf7447 Mon Sep 17 00:00:00 2001 From: nicholaspai Date: Fri, 7 Feb 2025 17:08:21 -0500 Subject: [PATCH] improve(l1l2Finalizer): Make sure L1 finalizer uses hub chain spokepool's lookback Currently we are always using the hub pool client's lookback to find events in the l1 to l2 direction, which is hardcoded to 8 hours. But if we wanted to increase this lookback using the MAX_FINALIZER_LOOKBACK environment variable, it would unexpectedly not affect the lookback in the L1 to L2 direction. --- src/finalizer/index.ts | 1 + src/finalizer/types.ts | 4 +++- src/finalizer/utils/cctp/l1ToL2.ts | 37 ++++++++++++++++++----------- src/finalizer/utils/linea/l1ToL2.ts | 24 ++++++------------- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/finalizer/index.ts b/src/finalizer/index.ts index 564f14b62d..4026cfca28 100644 --- a/src/finalizer/index.ts +++ b/src/finalizer/index.ts @@ -246,6 +246,7 @@ export async function finalize( hubSigner, hubPoolClient, client, + spokePoolClients[hubChainId], l1ToL2AddressesToFinalize ); diff --git a/src/finalizer/types.ts b/src/finalizer/types.ts index 69f0edabe4..3f1c5d1a91 100644 --- a/src/finalizer/types.ts +++ b/src/finalizer/types.ts @@ -35,7 +35,9 @@ export interface ChainFinalizer { logger: winston.Logger, signer: Signer, hubPoolClient: HubPoolClient, - spokePoolClient: SpokePoolClient, + l2SpokePoolClient: SpokePoolClient, + // The following types are only used in L1->L2 finalizers currently and can be omitted in L2->L1 finalizers. + l1SpokePoolClient: SpokePoolClient, l1ToL2AddressesToFinalize: string[] ): Promise; } diff --git a/src/finalizer/utils/cctp/l1ToL2.ts b/src/finalizer/utils/cctp/l1ToL2.ts index a11d77af55..49cbd40902 100644 --- a/src/finalizer/utils/cctp/l1ToL2.ts +++ b/src/finalizer/utils/cctp/l1ToL2.ts @@ -24,20 +24,21 @@ export async function cctpL1toL2Finalizer( logger: winston.Logger, _signer: Signer, hubPoolClient: HubPoolClient, - spokePoolClient: SpokePoolClient, + l2SpokePoolClient: SpokePoolClient, + l1SpokePoolClient: SpokePoolClient, l1ToL2AddressesToFinalize: string[] ): Promise { - const cctpMessageReceiverDetails = CONTRACT_ADDRESSES[spokePoolClient.chainId].cctpMessageTransmitter; + const cctpMessageReceiverDetails = CONTRACT_ADDRESSES[l2SpokePoolClient.chainId].cctpMessageTransmitter; const contract = new ethers.Contract( cctpMessageReceiverDetails.address, cctpMessageReceiverDetails.abi, - spokePoolClient.spokePool.provider + l2SpokePoolClient.spokePool.provider ); const decodedMessages = await resolveRelatedTxnReceipts( l1ToL2AddressesToFinalize, hubPoolClient.chainId, - spokePoolClient.chainId, - hubPoolClient + l2SpokePoolClient.chainId, + l1SpokePoolClient ); const unprocessedMessages = decodedMessages.filter((message) => message.status === "ready"); const statusesGrouped = groupObjectCountsByProp( @@ -45,13 +46,17 @@ export async function cctpL1toL2Finalizer( (message: { status: CCTPMessageStatus }) => message.status ); logger.debug({ - at: `Finalizer#CCTPL1ToL2Finalizer:${spokePoolClient.chainId}`, - message: `Detected ${unprocessedMessages.length} ready to finalize messages for CCTP L1 to ${spokePoolClient.chainId}`, + at: `Finalizer#CCTPL1ToL2Finalizer:${l2SpokePoolClient.chainId}`, + message: `Detected ${unprocessedMessages.length} ready to finalize messages for CCTP L1 to ${l2SpokePoolClient.chainId}`, statusesGrouped, }); return { - crossChainMessages: await generateDepositData(unprocessedMessages, hubPoolClient.chainId, spokePoolClient.chainId), + crossChainMessages: await generateDepositData( + unprocessedMessages, + hubPoolClient.chainId, + l2SpokePoolClient.chainId + ), callData: await generateMultiCallData(contract, unprocessedMessages), }; } @@ -59,7 +64,7 @@ export async function cctpL1toL2Finalizer( async function findRelevantTxnReceiptsForCCTPDeposits( currentChainId: number, addressesToSearch: string[], - hubPoolClient: HubPoolClient + l1SpokePoolClient: SpokePoolClient ): Promise { const provider = getCachedProvider(currentChainId); const tokenMessengerContract = new Contract( @@ -74,9 +79,9 @@ async function findRelevantTxnReceiptsForCCTPDeposits( addressesToSearch // All depositors that we are monitoring for ); const searchConfig: EventSearchConfig = { - fromBlock: hubPoolClient.eventSearchConfig.fromBlock, - toBlock: hubPoolClient.eventSearchConfig.toBlock, - maxBlockLookBack: hubPoolClient.eventSearchConfig.maxBlockLookBack, + fromBlock: l1SpokePoolClient.eventSearchConfig.fromBlock, + toBlock: l1SpokePoolClient.eventSearchConfig.toBlock, + maxBlockLookBack: l1SpokePoolClient.eventSearchConfig.maxBlockLookBack, }; const events = await paginatedEventQuery(tokenMessengerContract, eventFilter, searchConfig); const receipts = await Promise.all(events.map((event) => provider.getTransactionReceipt(event.transactionHash))); @@ -88,9 +93,13 @@ async function resolveRelatedTxnReceipts( addressesToSearch: string[], currentChainId: number, targetDestinationChainId: number, - hubPoolClient: HubPoolClient + l1SpokePoolClient: SpokePoolClient ): Promise { - const allReceipts = await findRelevantTxnReceiptsForCCTPDeposits(currentChainId, addressesToSearch, hubPoolClient); + const allReceipts = await findRelevantTxnReceiptsForCCTPDeposits( + currentChainId, + addressesToSearch, + l1SpokePoolClient + ); return resolveCCTPRelatedTxns(allReceipts, currentChainId, targetDestinationChainId); } diff --git a/src/finalizer/utils/linea/l1ToL2.ts b/src/finalizer/utils/linea/l1ToL2.ts index 93055e8e7a..e765edce7a 100644 --- a/src/finalizer/utils/linea/l1ToL2.ts +++ b/src/finalizer/utils/linea/l1ToL2.ts @@ -3,7 +3,7 @@ import { OnChainMessageStatus } from "@consensys/linea-sdk"; import { Contract } from "ethers"; import { groupBy } from "lodash"; import { HubPoolClient, SpokePoolClient } from "../../../clients"; -import { CHAIN_MAX_BLOCK_LOOKBACK, CONTRACT_ADDRESSES } from "../../../common"; +import { CONTRACT_ADDRESSES } from "../../../common"; import { EventSearchConfig, Signer, convertFromWei, winston, CHAIN_IDs, ethers, BigNumber } from "../../../utils"; import { CrossChainMessage, FinalizerPromise } from "../../types"; import { @@ -11,7 +11,6 @@ import { findMessageFromTokenBridge, findMessageFromUsdcBridge, findMessageSentEvents, - getBlockRangeByHoursOffsets, getL1MessageServiceContractFromL1ClaimingService, initLineaSdk, } from "./common"; @@ -39,8 +38,8 @@ export async function lineaL1ToL2Finalizer( logger: winston.Logger, signer: Signer, hubPoolClient: HubPoolClient, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _spokePoolClient: SpokePoolClient, + l2SpokePoolClient: SpokePoolClient, + l1SpokePoolClient: SpokePoolClient, l1ToL2AddressesToFinalize: string[] ): Promise { const [l1ChainId] = [hubPoolClient.chainId, hubPoolClient.hubPool.address]; @@ -62,19 +61,10 @@ export async function lineaL1ToL2Finalizer( hubPoolClient.hubPool.provider ); - // Optimize block range for querying Linea's MessageSent events on L1. - const { fromBlock, toBlock } = await getBlockRangeByHoursOffsets(l1ChainId, 24 * 7, 0); - logger.debug({ - at: "Finalizer#LineaL1ToL2Finalizer", - message: "Linea MessageSent event filter", - fromBlock, - toBlock, - }); - const searchConfig: EventSearchConfig = { - fromBlock, - toBlock, - maxBlockLookBack: CHAIN_MAX_BLOCK_LOOKBACK[l1ChainId] || 10_000, + fromBlock: l1SpokePoolClient.eventSearchConfig.fromBlock, + toBlock: l1SpokePoolClient.eventSearchConfig.toBlock, + maxBlockLookBack: l1SpokePoolClient.eventSearchConfig.maxBlockLookBack, }; const [wethAndRelayEvents, tokenBridgeEvents, usdcBridgeEvents] = await Promise.all([ @@ -100,7 +90,7 @@ export async function lineaL1ToL2Finalizer( const messageStatus = await getL1ToL2MessageStatusUsingCustomProvider( l2MessageServiceContract, _messageHash, - _spokePoolClient.spokePool.provider + l2SpokePoolClient.spokePool.provider ); return { messageSender: _from,