@@ -464,22 +464,32 @@ func (self *LightChain) GetHeaderByNumberOdr(ctx context.Context, number uint64)
464
464
func (self * LightChain ) Config () * params.ChainConfig { return self .hc .Config () }
465
465
466
466
func (self * LightChain ) SyncCht (ctx context.Context ) bool {
467
+ // If we don't have a CHT indexer, abort
467
468
if self .odr .ChtIndexer () == nil {
468
469
return false
469
470
}
470
- headNum := self .CurrentHeader ().Number .Uint64 ()
471
- chtCount , _ , _ := self .odr .ChtIndexer ().Sections ()
472
- if headNum + 1 < chtCount * CHTFrequencyClient {
473
- num := chtCount * CHTFrequencyClient - 1
474
- header , err := GetHeaderByNumber (ctx , self .odr , num )
475
- if header != nil && err == nil {
476
- self .mu .Lock ()
477
- if self .hc .CurrentHeader ().Number .Uint64 () < header .Number .Uint64 () {
478
- self .hc .SetCurrentHeader (header )
479
- }
480
- self .mu .Unlock ()
481
- return true
471
+ // Ensure the remote CHT head is ahead of us
472
+ head := self .CurrentHeader ().Number .Uint64 ()
473
+ sections , _ , _ := self .odr .ChtIndexer ().Sections ()
474
+
475
+ latest := sections * CHTFrequencyClient - 1
476
+ if clique := self .hc .Config ().Clique ; clique != nil {
477
+ latest -= latest % clique .Epoch // epoch snapshot for clique
478
+ }
479
+ if head >= latest {
480
+ return false
481
+ }
482
+ // Retrieve the latest useful header and update to it
483
+ if header , err := GetHeaderByNumber (ctx , self .odr , latest ); header != nil && err == nil {
484
+ self .mu .Lock ()
485
+ defer self .mu .Unlock ()
486
+
487
+ // Ensure the chain didn't move past the latest block while retrieving it
488
+ if self .hc .CurrentHeader ().Number .Uint64 () < header .Number .Uint64 () {
489
+ log .Info ("Updated latest header based on CHT" , "number" , header .Number , "hash" , header .Hash ())
490
+ self .hc .SetCurrentHeader (header )
482
491
}
492
+ return true
483
493
}
484
494
return false
485
495
}
0 commit comments