@@ -69,9 +69,17 @@ var errSyncReorged = errors.New("sync reorged")
69
69
// might still be propagating.
70
70
var errTerminated = errors .New ("terminated" )
71
71
72
- // errReorgDenied is returned if an attempt is made to extend the beacon chain
73
- // with a new header, but it does not link up to the existing sync.
74
- var errReorgDenied = errors .New ("non-forced head reorg denied" )
72
+ // errChainReorged is an internal helper error to signal that the header chain
73
+ // of the current sync cycle was (partially) reorged.
74
+ var errChainReorged = errors .New ("chain reorged" )
75
+
76
+ // errChainGapped is an internal helper error to signal that the header chain
77
+ // of the current sync cycle is gaped with the one advertised by consensus client.
78
+ var errChainGapped = errors .New ("chain gapped" )
79
+
80
+ // errChainForked is an internal helper error to signal that the header chain
81
+ // of the current sync cycle is forked with the one advertised by consensus client.
82
+ var errChainForked = errors .New ("chain forked" )
75
83
76
84
func init () {
77
85
// Tuning parameters is nice, but the scratch space must be assignable in
@@ -271,9 +279,9 @@ func (s *skeleton) startup() {
271
279
newhead , err := s .sync (head )
272
280
switch {
273
281
case err == errSyncLinked :
274
- // Sync cycle linked up to the genesis block. Tear down the loop
275
- // and restart it so, it can properly notify the backfiller. Don't
276
- // account a new head.
282
+ // Sync cycle linked up to the genesis block, or the existent chain
283
+ // segment. Tear down the loop and restart it so, it can properly
284
+ // notify the backfiller. Don't account a new head.
277
285
head = nil
278
286
279
287
case err == errSyncMerged :
@@ -457,15 +465,16 @@ func (s *skeleton) sync(head *types.Header) (*types.Header, error) {
457
465
// we don't seamlessly integrate reorgs to keep things simple. If the
458
466
// network starts doing many mini reorgs, it might be worthwhile handling
459
467
// a limited depth without an error.
460
- if reorged := s .processNewHead (event .header , event .final , event . force ); reorged {
468
+ if err := s .processNewHead (event .header , event .final ); err != nil {
461
469
// If a reorg is needed, and we're forcing the new head, signal
462
470
// the syncer to tear down and start over. Otherwise, drop the
463
471
// non-force reorg.
464
472
if event .force {
465
473
event .errc <- nil // forced head reorg accepted
474
+ log .Info ("Restarting sync cycle" , "reason" , err )
466
475
return event .header , errSyncReorged
467
476
}
468
- event .errc <- errReorgDenied
477
+ event .errc <- err
469
478
continue
470
479
}
471
480
event .errc <- nil // head extension accepted
@@ -610,7 +619,7 @@ func (s *skeleton) saveSyncStatus(db ethdb.KeyValueWriter) {
610
619
// accepts and integrates it into the skeleton or requests a reorg. Upon reorg,
611
620
// the syncer will tear itself down and restart with a fresh head. It is simpler
612
621
// to reconstruct the sync state than to mutate it and hope for the best.
613
- func (s * skeleton ) processNewHead (head * types.Header , final * types.Header , force bool ) bool {
622
+ func (s * skeleton ) processNewHead (head * types.Header , final * types.Header ) error {
614
623
// If a new finalized block was announced, update the sync process independent
615
624
// of what happens with the sync head below
616
625
if final != nil {
@@ -631,26 +640,17 @@ func (s *skeleton) processNewHead(head *types.Header, final *types.Header, force
631
640
// once more, ignore it instead of tearing down sync for a noop.
632
641
if lastchain .Head == lastchain .Tail {
633
642
if current := rawdb .ReadSkeletonHeader (s .db , number ); current .Hash () == head .Hash () {
634
- return false
643
+ return nil
635
644
}
636
645
}
637
646
// Not a noop / double head announce, abort with a reorg
638
- if force {
639
- log .Warn ("Beacon chain reorged" , "tail" , lastchain .Tail , "head" , lastchain .Head , "newHead" , number )
640
- }
641
- return true
647
+ return fmt .Errorf ("%w, tail: %d, head: %d, newHead: %d" , errChainReorged , lastchain .Tail , lastchain .Head , number )
642
648
}
643
649
if lastchain .Head + 1 < number {
644
- if force {
645
- log .Warn ("Beacon chain gapped" , "head" , lastchain .Head , "newHead" , number )
646
- }
647
- return true
650
+ return fmt .Errorf ("%w, head: %d, newHead: %d" , errChainGapped , lastchain .Head , number )
648
651
}
649
652
if parent := rawdb .ReadSkeletonHeader (s .db , number - 1 ); parent .Hash () != head .ParentHash {
650
- if force {
651
- log .Warn ("Beacon chain forked" , "ancestor" , number - 1 , "hash" , parent .Hash (), "want" , head .ParentHash )
652
- }
653
- return true
653
+ return fmt .Errorf ("%w, ancestor: %d, hash: %s, want: %s" , errChainForked , number - 1 , parent .Hash (), head .ParentHash )
654
654
}
655
655
// New header seems to be in the last subchain range. Unwind any extra headers
656
656
// from the chain tip and insert the new head. We won't delete any trimmed
@@ -666,7 +666,7 @@ func (s *skeleton) processNewHead(head *types.Header, final *types.Header, force
666
666
if err := batch .Write (); err != nil {
667
667
log .Crit ("Failed to write skeleton sync status" , "err" , err )
668
668
}
669
- return false
669
+ return nil
670
670
}
671
671
672
672
// assignTasks attempts to match idle peers to pending header retrievals.
0 commit comments