11import dayjs from 'dayjs'
22import duration from 'dayjs/plugin/duration'
33import utc from 'dayjs/plugin/utc'
4+ import { base } from 'viem/chains'
45
56import { Block , Context } from '@processor'
67
@@ -9,6 +10,7 @@ dayjs.extend(utc)
910
1011const SECONDS_PER_WEEK = dayjs . duration ( { weeks : 1 } ) . asSeconds ( )
1112const SECONDS_PER_DAY = dayjs . duration ( { days : 1 } ) . asSeconds ( )
13+ const SECONDS_PER_HOUR = dayjs . duration ( { hours : 1 } ) . asSeconds ( )
1214const SECONDS_PER_MINUTE = 60
1315
1416// It's OK that these are only calculated at launch.
@@ -27,9 +29,9 @@ const getFrequency = (blockRate: number, timestamp: number) => {
2729 } else if ( timestamp < oneWeekAgo ) {
2830 return ( SECONDS_PER_DAY / blockRate / 4 ) ^ 0 // Older than one week ago
2931 } else if ( timestamp < oneDayAgo ) {
30- return ( SECONDS_PER_DAY / blockRate / 12 ) ^ 0 // Older than one day ago
32+ return ( ( SECONDS_PER_MINUTE * 30 ) / blockRate ) ^ 0 // Older than one day ago
3133 } else if ( timestamp < oneHourAgo ) {
32- return ( ( SECONDS_PER_MINUTE * 30 ) / blockRate ) ^ 0 // Older than one hour ago
34+ return ( ( SECONDS_PER_MINUTE * 15 ) / blockRate ) ^ 0 // Older than one hour ago
3335 } else if ( timestamp < fifteenMinutesAgo ) {
3436 return ( ( SECONDS_PER_MINUTE * 5 ) / blockRate ) ^ 0 // Older than 15 minutes ago
3537 } else {
@@ -40,46 +42,40 @@ const getFrequency = (blockRate: number, timestamp: number) => {
4042export const blockFrequencyTracker = ( params : { from : number } ) => {
4143 return ( ctx : Context , block : Block ) => {
4244 if ( block . header . height < params . from ) return
43- const frequency : number = getFrequency (
44- ctx . blockRate ,
45- block . header . timestamp ,
46- )
47- return block . header . height % frequency === 0
45+ const frequency = getFrequency ( ctx . blockRate , block . header . timestamp )
46+ return block . header . height % frequency === 0 || isAerodromeImportantBlock ( ctx , block )
4847 }
4948}
5049
5150export const blockFrequencyUpdater = ( params : { from : number } ) => {
52- return async (
53- ctx : Context ,
54- fn : ( ctx : Context , block : Block ) => Promise < void > ,
55- ) => {
51+ const tracker = blockFrequencyTracker ( params )
52+ return async ( ctx : Context , fn : ( ctx : Context , block : Block ) => Promise < void > ) => {
5653 if ( ! ctx . blocks . length ) return
5754 if ( ctx . blocks [ ctx . blocks . length - 1 ] . header . height < params . from ) {
5855 // No applicable blocks in current context.
5956 return
6057 }
61- let frequency : number = getFrequency (
62- ctx . blockRate ,
63- ctx . blocks [ 0 ] . header . timestamp ,
64- )
65- for (
66- let i = ctx . blocks . findIndex (
67- ( b ) =>
68- b . header . height % frequency === 0 && b . header . height >= params . from ,
69- ) ;
70- i < ctx . blocks . length ;
71- i += frequency
72- ) {
73- const block = ctx . blocks [ i ]
74- if ( ! block ) break
75- if ( block . header . height % frequency !== 0 ) {
76- throw new Error (
77- 'This should never happen. Ensure you are passing all blocks through here.' ,
78- )
58+ for ( let i = 0 ; i < ctx . blocks . length ; i ++ ) {
59+ if ( tracker ( ctx , ctx . blocks [ i ] ) ) {
60+ await fn ( ctx , ctx . blocks [ i ] )
7961 }
80- await fn ( ctx , block )
81- frequency = getFrequency ( ctx . blockRate , block . header . timestamp )
82- i -= ctx . blocks [ i ] . header . height % frequency
8362 }
8463 }
8564}
65+
66+ // This came around so we can have good historical snapshots of data during Aerodrome epoch flips.
67+ export const isAerodromeImportantBlock = ( ctx : Context , block : Block ) => {
68+ if ( ctx . chain . id !== base . id ) return false
69+ if ( block . header . height < 17819702 ) return false
70+ const lastBlockWeek = Math . floor ( ( block . header . timestamp / 1000 - ctx . blockRate ) / SECONDS_PER_WEEK )
71+ const blockWeek = Math . floor ( block . header . timestamp / 1000 / SECONDS_PER_WEEK )
72+ if ( blockWeek !== lastBlockWeek ) return true
73+
74+ const nextBlockWeek = Math . floor ( ( block . header . timestamp / 1000 + ctx . blockRate ) / SECONDS_PER_WEEK )
75+ if ( blockWeek !== nextBlockWeek ) return true
76+
77+ const secondOfWeek = Math . floor ( block . header . timestamp / 1000 ) % SECONDS_PER_WEEK
78+ const lastBlockHourOfWeek = Math . floor ( ( secondOfWeek - ctx . blockRate ) / SECONDS_PER_HOUR )
79+ const hourOfWeek = Math . floor ( secondOfWeek / SECONDS_PER_HOUR )
80+ return lastBlockHourOfWeek === 0 && hourOfWeek === 1
81+ }
0 commit comments