diff --git a/packages/fault-detector/src/helpers.ts b/packages/fault-detector/src/helpers.ts index e590578d9830edfc1d21d81911958190a1fa85e2..4583d9134fb7b678fa6acaa35a84499fe5d993b7 100644 --- a/packages/fault-detector/src/helpers.ts +++ b/packages/fault-detector/src/helpers.ts @@ -1,4 +1,5 @@ import { Contract, BigNumber } from 'ethers' +import { Logger } from '@eth-optimism/common-ts' export interface OutputOracle<TSubmissionEventArgs> { contract: Contract @@ -39,7 +40,7 @@ const getCache = ( } => { if (!caches[address]) { caches[address] = { - highestBlock: 0, + highestBlock: -1, eventCache: new Map(), } } @@ -54,15 +55,28 @@ const getCache = ( * @param filter Event filter to use. */ export const updateOracleCache = async <TSubmissionEventArgs>( - oracle: OutputOracle<TSubmissionEventArgs> + oracle: OutputOracle<TSubmissionEventArgs>, + logger?: Logger ): Promise<void> => { const cache = getCache(oracle.contract.address) - let currentBlock = cache.highestBlock - const endingBlock = await oracle.contract.provider.getBlockNumber() - let step = endingBlock - currentBlock + const endBlock = await oracle.contract.provider.getBlockNumber() + logger?.info('visiting uncached oracle events for range', { + node: 'l1', + cachedTillBlock: cache.highestBlock, + latestBlock: endBlock, + }) + let failures = 0 - while (currentBlock < endingBlock) { + let currentBlock = cache.highestBlock + 1 + let step = endBlock - currentBlock + while (currentBlock < endBlock) { try { + logger?.info('polling events for range', { + node: 'l1', + startBlock: currentBlock, + blockRangeSize: step, + }) + const events = await oracle.contract.queryFilter( oracle.filter, currentBlock, @@ -83,7 +97,13 @@ export const updateOracleCache = async <TSubmissionEventArgs>( // Update the current block and increase the step size for the next iteration. currentBlock += step step = Math.ceil(step * 2) - } catch { + } catch (err) { + logger?.error('error fetching events', { + err, + node: 'l1', + section: 'getLogs', + }) + // Might happen if we're querying too large an event range. step = Math.floor(step / 2) @@ -97,13 +117,15 @@ export const updateOracleCache = async <TSubmissionEventArgs>( // We've failed 3 times in a row, we're probably stuck. if (failures >= 3) { + logger?.fatal('unable to fetch oracle events', { err }) throw new Error('failed to update event cache') } } } // Update the highest block. - cache.highestBlock = endingBlock + cache.highestBlock = endBlock + logger?.info('done caching oracle events') } /** @@ -115,7 +137,8 @@ export const updateOracleCache = async <TSubmissionEventArgs>( */ export const findEventForStateBatch = async <TSubmissionEventArgs>( oracle: OutputOracle<TSubmissionEventArgs>, - index: number + index: number, + logger?: Logger ): Promise<PartialEvent> => { const cache = getCache(oracle.contract.address) @@ -125,10 +148,12 @@ export const findEventForStateBatch = async <TSubmissionEventArgs>( } // Update the event cache if we don't have the event. - await updateOracleCache(oracle) + logger?.info('event not cached from index. warming cache...', { index }) + await updateOracleCache(oracle, logger) // Event better be in cache now! if (cache.eventCache[index] === undefined) { + logger?.fatal('expected event for index!', { index }) throw new Error(`unable to find event for batch ${index}`) } @@ -143,7 +168,8 @@ export const findEventForStateBatch = async <TSubmissionEventArgs>( */ export const findFirstUnfinalizedStateBatchIndex = async <TSubmissionEventArgs>( oracle: OutputOracle<TSubmissionEventArgs>, - fpw: number + fpw: number, + logger?: Logger ): Promise<number> => { const latestBlock = await oracle.contract.provider.getBlock('latest') const totalBatches = (await oracle.getTotalElements()).toNumber() @@ -153,7 +179,7 @@ export const findFirstUnfinalizedStateBatchIndex = async <TSubmissionEventArgs>( let hi = totalBatches while (lo !== hi) { const mid = Math.floor((lo + hi) / 2) - const event = await findEventForStateBatch(oracle, mid) + const event = await findEventForStateBatch(oracle, mid, logger) const block = await oracle.contract.provider.getBlock(event.blockNumber) if (block.timestamp + fpw < latestBlock.timestamp) {