From ba00fc7eded970b3e682c5b5601d0bbf09087588 Mon Sep 17 00:00:00 2001 From: Paul Noel Date: Mon, 30 Oct 2023 10:37:30 -0500 Subject: [PATCH] watcher: handle near missing blocks --- watcher/src/utils/near.ts | 2 + watcher/src/watchers/NearArchiveWatcher.ts | 57 +++++++++++++++++----- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/watcher/src/utils/near.ts b/watcher/src/utils/near.ts index 886971cb..12fecd80 100644 --- a/watcher/src/utils/near.ts +++ b/watcher/src/utils/near.ts @@ -24,6 +24,7 @@ export const getNearProvider = async (rpc: string): Promise => { return provider; }; +// This function can definitely throw. export async function getTimestampByBlock( provider: Provider, blockHeight: number @@ -32,6 +33,7 @@ export async function getTimestampByBlock( return block.header.timestamp; } +// This function can definitely throw. export async function fetchBlockByBlockId( provider: Provider, blockHeight: BlockId diff --git a/watcher/src/watchers/NearArchiveWatcher.ts b/watcher/src/watchers/NearArchiveWatcher.ts index f726ffeb..18fa8f40 100644 --- a/watcher/src/watchers/NearArchiveWatcher.ts +++ b/watcher/src/watchers/NearArchiveWatcher.ts @@ -16,7 +16,6 @@ import { isWormholePublishEventLog, } from '../utils/near'; import { Watcher } from './Watcher'; -import { sleep } from '@wormhole-foundation/wormhole-monitor-common'; export class NearArchiveWatcher extends Watcher { provider: Provider | null = null; @@ -39,22 +38,58 @@ export class NearArchiveWatcher extends Watcher { } async getMessagesForBlocks(fromBlock: number, toBlock: number): Promise { - // assume toBlock was retrieved from getFinalizedBlockNumber and is finalized - this.logger.info(`fetching info for blocks ${fromBlock} to ${toBlock}`); + const origFromBlock = fromBlock; + const origToBlock = toBlock; + this.logger.info(`fetching info for blocks ${origFromBlock} to ${origToBlock}`); const provider = await this.getProvider(); - const fromBlockTimestamp: number = await getTimestampByBlock(provider, fromBlock); + // Do the following in a while loop until a fromBlock has been found. + let fromBlockTimestamp: number = 0; + let done: boolean = false; + while (!done) { + try { + fromBlockTimestamp = await getTimestampByBlock(provider, fromBlock); + done = true; + } catch (e) { + // Logging this to help with troubleshooting. + this.logger.debug(e); + this.logger.error('getMessagesForBlocks(): Error fetching from block', fromBlock); + fromBlock++; + if (fromBlock > toBlock) { + this.logger.error( + `Unable to fetch timestamp for fromBlock in range ${origFromBlock} - ${origToBlock}` + ); + throw new Error( + `Unable to fetch timestamp for fromBlock in range ${origFromBlock} - ${origToBlock}` + ); + } + } + } if (fromBlockTimestamp === 0) { - this.logger.error(`Unable to fetch timestamp for block ${fromBlock}`); + this.logger.error(`Unable to fetch timestamp for fromBlock ${fromBlock}`); throw new Error(`Unable to fetch timestamp for fromBlock ${fromBlock}`); } let toBlockInfo: BlockResult = {} as BlockResult; - try { - toBlockInfo = await fetchBlockByBlockId(provider, toBlock); - } catch (e) { - // Logging this to help with troubleshooting. - this.logger.error('getMessagesForBlocks(): Error fetching block', e); - throw e; + done = false; + while (!done) { + try { + toBlockInfo = await fetchBlockByBlockId(provider, toBlock); + done = true; + } catch (e) { + // Logging this to help with troubleshooting. + this.logger.debug(e); + this.logger.error('getMessagesForBlocks(): Error fetching toBlock', toBlock); + toBlock--; + if (toBlock < fromBlock) { + this.logger.error( + `Unable to fetch block info for toBlock in range ${origFromBlock} - ${origToBlock}` + ); + throw new Error( + `Unable to fetch block info for toBlock in range ${origFromBlock} - ${origToBlock}` + ); + } + } } + this.logger.info(`Actual block range: ${fromBlock} - ${toBlock}`); const transactions: Transaction[] = await getTransactionsByAccountId( CONTRACTS.MAINNET.near.core, this.maximumBatchSize,