@@ -23,13 +23,12 @@ func DropHistory(
2323 db * gorm.DB ,
2424 intervalSeconds , checkInterval uint64 ,
2525 client * chain.Client ,
26- startBlockNumber uint64 ,
2726) {
2827 for {
2928 logger .Infof ("starting DropHistory iteration" )
3029
3130 startTime := time .Now ()
32- err := dropHistoryIteration (ctx , db , intervalSeconds , client , startBlockNumber )
31+ err := dropHistoryIteration (ctx , db , intervalSeconds , client )
3332 if err == nil {
3433 duration := time .Since (startTime )
3534 logger .Infof ("finished DropHistory iteration in %v" , duration )
@@ -52,22 +51,15 @@ var deleteOrder = []interface{}{
5251const deleteBatchSize = 1000
5352
5453func dropHistoryIteration (
55- ctx context.Context , db * gorm.DB , intervalSeconds uint64 , client * chain.Client , startBlockNumber uint64 ,
54+ ctx context.Context , db * gorm.DB , intervalSeconds uint64 , client * chain.Client ,
5655) error {
57- lastBlockTime , lastBlockNumber , err := getBlockTimestamp (ctx , nil , client )
56+ lastBlockTime , _ , err := getBlockTimestamp (ctx , nil , client )
5857 if err != nil {
5958 return errors .Wrap (err , "Failed to get the latest time" )
6059 }
6160
6261 db = db .WithContext (ctx )
63-
6462 deleteStartTime := lastBlockTime - intervalSeconds
65- deleteStartBlock , err := getNearestBlockByTimestamp (
66- ctx , deleteStartTime , db , client , startBlockNumber , lastBlockNumber ,
67- )
68- if err != nil {
69- return errors .Wrap (err , "Failed to get the nearest block by timestamp" )
70- }
7163
7264 // Delete in specified order to not break foreign keys.
7365 for _ , entity := range deleteOrder {
@@ -76,10 +68,19 @@ func dropHistoryIteration(
7668 }
7769 }
7870
79- if err := updateStateIfLower (db , FirstDatabaseIndexState , deleteStartBlock , deleteStartTime ); err != nil {
71+ var firstBlock Block
72+ err = db .Order ("number ASC" ).First (& firstBlock ).Error
73+ if errors .Is (err , gorm .ErrRecordNotFound ) {
74+ return nil
75+ }
76+ if err != nil {
77+ return errors .Wrap (err , "find first surviving block" )
78+ }
79+
80+ if err := updateStateIfLower (db , FirstDatabaseIndexState , firstBlock .Number , firstBlock .Timestamp ); err != nil {
8081 return errors .Wrap (err , "Failed to update state in the DB" )
8182 }
82- if err := updateStateIfLower (db , FirstDatabaseFSPEventIndexState , deleteStartBlock , deleteStartTime ); err != nil {
83+ if err := updateStateIfLower (db , FirstDatabaseFSPEventIndexState , firstBlock . Number , firstBlock . Timestamp ); err != nil {
8384 return errors .Wrap (err , "Failed to update FSP event state in the DB" )
8485 }
8586
@@ -157,88 +158,3 @@ func getBlockTimestamp(ctx context.Context, index *big.Int, client *chain.Client
157158
158159 return block .Time (), block .Number ().Uint64 (), nil
159160}
160-
161- func getNearestBlockByTimestamp (
162- ctx context.Context ,
163- timestamp uint64 ,
164- db * gorm.DB ,
165- client * chain.Client ,
166- startBlockNumber uint64 ,
167- lastBlockNumber uint64 ,
168- ) (uint64 , error ) {
169- // First try to find a block in the DB with a timestamp close to the requested one.
170- // If that fails, we fall back to doing a binary search on the chain.
171- blockNumber , err := getNearestBlockByTimestampFromDB (ctx , timestamp , db )
172- if err != nil {
173- logger .Debugf ("failed to get the nearest block by timestamp from DB, will fall back to RPC binary search. err: %s" , err )
174- }
175-
176- // A blocknumber of 0 means that no block was found in the DB.
177- if blockNumber != 0 {
178- return blockNumber , nil
179- }
180-
181- return chain .GetNearestBlockByTimestampFromChain (ctx , timestamp , client , startBlockNumber , lastBlockNumber )
182- }
183-
184- const maxBlockTimeDiff = time .Minute
185-
186- func validateNearestDBBlockTimestamp (blockTime , timestamp uint64 ) (bool , error ) {
187- if blockTime < timestamp {
188- return false , errors .Errorf (
189- "unexpected block time %d, expected at least %d" ,
190- blockTime , timestamp ,
191- )
192- }
193-
194- blockTimeDiff := time .Duration (blockTime - timestamp ) * time .Second
195- if blockTimeDiff > maxBlockTimeDiff {
196- // This is expected on initial runs or whenever the DB only contains a
197- // much newer window of blocks than the requested history-drop cutoff.
198- // In that case we should quietly fall back to RPC binary search.
199- return false , nil
200- }
201-
202- return true , nil
203- }
204-
205- func getNearestBlockByTimestampFromDB (ctx context.Context , timestamp uint64 , db * gorm.DB ) (uint64 , error ) {
206- // First try to find a block in the DB with a similar timestamp.
207- block , err := boff .RetryWithMaxElapsed (
208- ctx ,
209- func () (* Block , error ) {
210- // First try to find a block in the DB with a similar timestamp.
211- block := new (Block )
212- err := db .Where ("timestamp >= ?" , timestamp ).Order ("timestamp ASC" ).First (block ).Error
213-
214- if err == nil {
215- return block , nil
216- }
217-
218- if errors .Is (err , gorm .ErrRecordNotFound ) {
219- return nil , nil
220- }
221-
222- return nil , err
223- },
224- "getNearestBlockByTimestampFromDB" ,
225- )
226- if err != nil {
227- return 0 , errors .Wrap (err , "getNearestBlockByTimestampFromDB" )
228- }
229-
230- // Block not found in the DB.
231- if block == nil || block .Number == 0 {
232- return 0 , nil
233- }
234-
235- useBlock , err := validateNearestDBBlockTimestamp (block .Timestamp , timestamp )
236- if err != nil {
237- return 0 , errors .Wrapf (err , "invalid DB block %d" , block .Number )
238- }
239- if ! useBlock {
240- return 0 , nil
241- }
242-
243- return block .Number , nil
244- }
0 commit comments