99 "flare-ftso-indexer/internal/core"
1010 "flare-ftso-indexer/internal/database"
1111 "flare-ftso-indexer/internal/ready"
12+ "math/big"
1213 "time"
1314
1415 "github.com/flare-foundation/go-flare-common/pkg/logger"
@@ -22,6 +23,7 @@ func RunIndexer(
2223 db * gorm.DB ,
2324 ethClient * chain.Client ,
2425 resolver * contracts.ContractResolver ,
26+ chainID * big.Int ,
2527) error {
2628 logger .Infof (
2729 "Starting indexer in FSP mode: history_epochs=%d, fsp_tx_lookback_seconds=%d, collect_transactions=%d, collect_logs=%d" ,
@@ -49,9 +51,10 @@ func RunIndexer(
4951 return errors .Wrap (err , "FSP startup backfill fatal error" )
5052 }
5153
52- historyDropSeconds := historyDropHeuristicSeconds (cfg .Indexer .HistoryEpochs )
54+ historyDropSeconds := historyDropHeuristicSeconds (chainID , cfg .Indexer .HistoryEpochs )
5355 logger .Infof (
54- "Using FSP history drop: history_epochs=%d, derived retention=%ds (%.2f days)" ,
56+ "Using FSP history drop: chain_id=%s, history_epochs=%d, derived retention=%ds (%.2f days)" ,
57+ chainID ,
5558 cfg .Indexer .HistoryEpochs ,
5659 historyDropSeconds ,
5760 float64 (historyDropSeconds )/ (24 * 60 * 60 ),
@@ -89,12 +92,27 @@ func RunIndexer(
8992 return nil
9093}
9194
92- func historyDropHeuristicSeconds (historyEpochs uint64 ) uint64 {
93- // Over-estimation heuristic: history_epochs * 3.5 days + 14 days.
94- const (
95- baseRetentionSeconds = uint64 ((14 * 24 * time .Hour ) / time .Second )
96- retentionPerEpochSeconds = uint64 ((84 * time .Hour ) / time .Second )
97- )
95+ // historyDropHeuristicSeconds derives the retention window used by history drop
96+ // from the number of FSP reward epochs that must remain indexable. It keeps three extra
97+ // reward epochs worth of history to cover the metadata event windows required by the
98+ // oldest indexed reward epoch + extra buffer for potentially extended epochs.
99+ func historyDropHeuristicSeconds (chainId * big.Int , historyEpochs uint64 ) uint64 {
100+ return (historyEpochs + 4 ) * rewardEpochSecondsFor (chainId )
101+ }
98102
99- return baseRetentionSeconds + historyEpochs * retentionPerEpochSeconds
103+ // rewardEpochSecondsByChain is the reward-epoch duration per network.
104+ // Mainnets run 3.5d epochs; testnets run 6h.
105+ var rewardEpochSecondsByChain = map [chain.ChainID ]uint64 {
106+ chain .ChainIDFlare : uint64 ((84 * time .Hour ) / time .Second ),
107+ chain .ChainIDSongbird : uint64 ((84 * time .Hour ) / time .Second ),
108+ chain .ChainIDCoston : uint64 ((6 * time .Hour ) / time .Second ),
109+ chain .ChainIDCoston2 : uint64 ((6 * time .Hour ) / time .Second ),
110+ }
111+
112+ func rewardEpochSecondsFor (chainID * big.Int ) uint64 {
113+ chainIDInt := chain .ChainIDFromBigInt (chainID )
114+ if v , ok := rewardEpochSecondsByChain [chainIDInt ]; ok {
115+ return v
116+ }
117+ return rewardEpochSecondsByChain [chain .ChainIDFlare ]
100118}
0 commit comments