diff --git a/src/clients/BundleDataClient/BundleDataClient.ts b/src/clients/BundleDataClient/BundleDataClient.ts index 2971f928..5a62d49a 100644 --- a/src/clients/BundleDataClient/BundleDataClient.ts +++ b/src/clients/BundleDataClient/BundleDataClient.ts @@ -29,7 +29,6 @@ import { getImpliedBundleBlockRanges, isSlowFill, mapAsync, - relayFillStatus, bnUint32Max, } from "../../utils"; import { BigNumber } from "ethers"; @@ -1125,8 +1124,7 @@ export class BundleDataClient { ) { // If we haven't seen a fill matching this deposit, then we need to rule out that it was filled a long time ago // by checkings its on-chain fill status. - const fillStatus = await relayFillStatus( - spokePoolClients[destinationChainId].spokePool, + const fillStatus = await spokePoolClients[destinationChainId].relayFillStatus( deposit, // We can assume that in production // the block ranges passed into this function would never contain blocks where the spoke pool client @@ -1313,8 +1311,8 @@ export class BundleDataClient { const startBlockForChain = Math.min(_startBlockForChain, spokePoolClient.latestBlockSearched); const endBlockForChain = Math.min(_endBlockForChain, spokePoolClient.latestBlockSearched); const [startTime, endTime] = [ - Number((await spokePoolClient.spokePool.provider.getBlock(startBlockForChain)).timestamp), - Number((await spokePoolClient.spokePool.provider.getBlock(endBlockForChain)).timestamp), + await spokePoolClient.getTimestampForBlock(startBlockForChain), + await spokePoolClient.getTimestampForBlock(endBlockForChain), ]; // Sanity checks: assert(endTime >= startTime, "End time should be greater than start time."); diff --git a/src/clients/SpokePoolClient.ts b/src/clients/SpokePoolClient.ts index f82490c3..1ad3dcf0 100644 --- a/src/clients/SpokePoolClient.ts +++ b/src/clients/SpokePoolClient.ts @@ -25,6 +25,7 @@ import { Deposit, DepositWithBlock, Fill, + FillStatus, FillWithBlock, FilledV3RelayEvent, RealizedLpFee, @@ -883,4 +884,33 @@ export class SpokePoolClient extends BaseAbstractClient { this.configStoreClient?.isChainLiteChainAtTimestamp(deposit.destinationChainId, deposit.quoteTimestamp) ?? false ); } + + public async getTimestampForBlock(blockTag: number): Promise { + const block = await this.spokePool.provider.getBlock(blockTag); + return Number(block.timestamp); + } + + /** + * Find the amount filled for a deposit at a particular block. + * @param relayData Deposit information that is used to complete a fill. + * @param blockTag Block tag (numeric or "latest") to query at. + * @returns The amount filled for the specified deposit at the requested block (or latest). + */ + public async relayFillStatus( + relayData: RelayData, + blockTag?: number | "latest", + destinationChainId?: number + ): Promise { + destinationChainId ??= this.chainId; + const hash = getRelayDataHash(relayData, destinationChainId!); + const _fillStatus = await this.spokePool.fillStatuses(hash, { blockTag }); + const fillStatus = Number(_fillStatus); + if (![FillStatus.Unfilled, FillStatus.RequestedSlowFill, FillStatus.Filled].includes(fillStatus)) { + const { originChainId, depositId } = relayData; + throw new Error( + `relayFillStatus: Unexpected fillStatus for ${originChainId} deposit ${depositId} (${fillStatus})` + ); + } + return fillStatus; + } } diff --git a/src/utils/SpokeUtils.ts b/src/utils/SpokeUtils.ts index 554b777f..de840fc7 100644 --- a/src/utils/SpokeUtils.ts +++ b/src/utils/SpokeUtils.ts @@ -244,32 +244,6 @@ export function getRelayHashFromEvent(e: Deposit | Fill | SlowFillRequest): stri return getRelayDataHash(e, e.destinationChainId); } -/** - * Find the amount filled for a deposit at a particular block. - * @param spokePool SpokePool contract instance. - * @param relayData Deposit information that is used to complete a fill. - * @param blockTag Block tag (numeric or "latest") to query at. - * @returns The amount filled for the specified deposit at the requested block (or latest). - */ -export async function relayFillStatus( - spokePool: Contract, - relayData: RelayData, - blockTag?: number | "latest", - destinationChainId?: number -): Promise { - destinationChainId ??= await spokePool.chainId(); - const hash = getRelayDataHash(relayData, destinationChainId!); - const _fillStatus = await spokePool.fillStatuses(hash, { blockTag }); - const fillStatus = Number(_fillStatus); - - if (![FillStatus.Unfilled, FillStatus.RequestedSlowFill, FillStatus.Filled].includes(fillStatus)) { - const { originChainId, depositId } = relayData; - throw new Error(`relayFillStatus: Unexpected fillStatus for ${originChainId} deposit ${depositId} (${fillStatus})`); - } - - return fillStatus; -} - export async function fillStatusArray( spokePool: Contract, relayData: RelayData[], @@ -316,11 +290,12 @@ export async function fillStatusArray( * @returns The block number at which the relay was completed, or undefined. */ export async function findFillBlock( - spokePool: Contract, + spokePoolClient: SpokePoolClient, relayData: RelayData, lowBlockNumber: number, highBlockNumber?: number ): Promise { + const { spokePool } = spokePoolClient; const { provider } = spokePool; highBlockNumber ??= await provider.getBlockNumber(); assert(highBlockNumber > lowBlockNumber, `Block numbers out of range (${lowBlockNumber} > ${highBlockNumber})`); @@ -340,8 +315,8 @@ export async function findFillBlock( // Make sure the relay war completed within the block range supplied by the caller. const [initialFillStatus, finalFillStatus] = ( await Promise.all([ - relayFillStatus(spokePool, relayData, lowBlockNumber, destinationChainId), - relayFillStatus(spokePool, relayData, highBlockNumber, destinationChainId), + spokePoolClient.relayFillStatus(relayData, lowBlockNumber, destinationChainId), + spokePoolClient.relayFillStatus(relayData, highBlockNumber, destinationChainId), ]) ).map(Number); @@ -359,7 +334,7 @@ export async function findFillBlock( // Find the leftmost block where filledAmount equals the deposit amount. do { const midBlockNumber = Math.floor((highBlockNumber + lowBlockNumber) / 2); - const fillStatus = await relayFillStatus(spokePool, relayData, midBlockNumber, destinationChainId); + const fillStatus = await spokePoolClient.relayFillStatus(relayData, midBlockNumber, destinationChainId); if (fillStatus === FillStatus.Filled) { highBlockNumber = midBlockNumber;