@@ -71,7 +71,7 @@ async function updateSparkRound (pgPool, contract, newRoundIndex, recordTelemetr
7171 const meridianContractAddress = await contract . getAddress ( )
7272
7373 if ( roundStartEpoch === undefined ) {
74- roundStartEpoch = await getRoundStartEpoch ( contract , meridianRoundIndex )
74+ roundStartEpoch = await getRoundStartEpochWithBackoff ( contract , meridianRoundIndex )
7575 }
7676
7777 const pgClient = await pgPool . connect ( )
@@ -329,17 +329,46 @@ async function defineTasksForRound (pgClient, sparkRoundNumber, taskCount) {
329329 ] )
330330}
331331
332+ // Exponentially look at more blocks to handle the case when we have an outage
333+ // and the rounds are not advanced frequently enough, while keeping the happy
334+ // path performant.
335+ export async function getRoundStartEpochWithBackoff (
336+ contract ,
337+ roundIndex ,
338+ maxAttempts = 5
339+ ) {
340+ for ( let attempt = 0 ; attempt < maxAttempts ; attempt ++ ) {
341+ try {
342+ return await getRoundStartEpoch (
343+ contract ,
344+ roundIndex ,
345+ 50 * ( 2 ** attempt )
346+ )
347+ } catch ( err ) {
348+ if ( attempt < maxAttempts ) {
349+ console . warn ( 'Failed to get round start epoch, retrying...' , {
350+ err,
351+ attempt,
352+ maxAttempts,
353+ roundIndex
354+ } )
355+ } else {
356+ throw err
357+ }
358+ }
359+ }
360+ }
361+
332362/**
333363 * @param {MeridianContract } contract
334364 * @param {bigint } roundIndex
335365 * @returns {Promise<number> } Filecoin Epoch (ETH block number) when the SPARK round started
336366 */
337- export async function getRoundStartEpoch ( contract , roundIndex ) {
367+ export async function getRoundStartEpoch ( contract , roundIndex , blocks ) {
338368 assert . strictEqual ( typeof roundIndex , 'bigint' , `roundIndex must be a bigint, received: ${ typeof roundIndex } ` )
369+ assert . strictEqual ( typeof blocks , 'number' , `blocks must be a number, received: ${ typeof blocks } ` )
339370
340- // Look at more blocks than should be necessary to handle the case when we have an outage and
341- // the rounds are not advanced frequently enough.
342- const recentRoundStartEvents = ( await contract . queryFilter ( 'RoundStart' , - 500 ) )
371+ const recentRoundStartEvents = ( await contract . queryFilter ( 'RoundStart' , - blocks ) )
343372 . map ( ( { blockNumber, args } ) => ( { blockNumber, roundIndex : args [ 0 ] } ) )
344373
345374 const roundStart = recentRoundStartEvents . find ( e => e . roundIndex === roundIndex )
0 commit comments