Skip to content

Commit 9f6de6d

Browse files
jwasingerkaralabe
andcommitted
eth/downloader: return nil from cleanStales if the latest filled hashnis non-existent or different than the corresponding skeleton header. add test case that beacon syncs a chain, beacon syncs to a separate fork
Co-authored-by: Péter Szilágyi <[email protected]>
1 parent ee00779 commit 9f6de6d

File tree

3 files changed

+17
-50
lines changed

3 files changed

+17
-50
lines changed

eth/downloader/downloader.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ func New(stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, lightchai
235235
syncStartBlock: chain.CurrentSnapBlock().Number.Uint64(),
236236
}
237237
// Create the post-merge skeleton syncer and start the process
238-
dl.skeleton = newSkeleton(chain, stateDb, dl.peers, dropPeer, newBeaconBackfiller(dl, success))
238+
dl.skeleton = newSkeleton(stateDb, dl.peers, dropPeer, newBeaconBackfiller(dl, success))
239239

240240
go dl.stateFetcher()
241241
return dl
@@ -498,7 +498,6 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd *
498498
if number < oldest.Number.Uint64() {
499499
count := int(oldest.Number.Uint64() - number) // it's capped by fsMinFullBlocks
500500
headers := d.readHeaderRange(oldest, count)
501-
fmt.Printf("readHeaderRange, oldest=%x, oldest num=%d, count=%d\n", oldest.Hash(), oldest.Number, count)
502501
if len(headers) == count {
503502
pivot = headers[len(headers)-1]
504503
log.Warn("Retrieved pivot header from local", "number", pivot.Number, "hash", pivot.Hash(), "latest", latest.Number, "oldest", oldest.Number)

eth/downloader/skeleton.go

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ type headerRequest struct {
141141
cancel chan struct{} // Channel to track sync cancellation
142142
stale chan struct{} // Channel to signal the request was dropped
143143

144-
head uint64 // Head number of the requested batch of headers
145-
chain BlockChain
144+
head uint64 // Head number of the requested batch of headers
146145
}
147146

148147
// headerResponse is an already verified remote response to a header request.
@@ -202,7 +201,6 @@ type backfiller interface {
202201
type skeleton struct {
203202
db ethdb.Database // Database backing the skeleton
204203
filler backfiller // Chain syncer suspended/resumed by head events
205-
chain BlockChain
206204

207205
peers *peerSet // Set of peers we can sync from
208206
idles map[string]*peerConnection // Set of idle peers in the current sync cycle
@@ -229,7 +227,7 @@ type skeleton struct {
229227

230228
// newSkeleton creates a new sync skeleton that tracks a potentially dangling
231229
// header chain until it's linked into an existing set of blocks.
232-
func newSkeleton(chain BlockChain, db ethdb.Database, peers *peerSet, drop peerDropFn, filler backfiller) *skeleton {
230+
func newSkeleton(db ethdb.Database, peers *peerSet, drop peerDropFn, filler backfiller) *skeleton {
233231
sk := &skeleton{
234232
db: db,
235233
filler: filler,
@@ -239,7 +237,6 @@ func newSkeleton(chain BlockChain, db ethdb.Database, peers *peerSet, drop peerD
239237
headEvents: make(chan *headUpdate),
240238
terminate: make(chan chan error),
241239
terminated: make(chan struct{}),
242-
chain: chain,
243240
}
244241
go sk.startup()
245242
return sk
@@ -349,7 +346,7 @@ func (s *skeleton) Sync(head *types.Header, final *types.Header, force bool) err
349346
// sync is the internal version of Sync that executes a single sync cycle, either
350347
// until some termination condition is reached, or until the current cycle merges
351348
// with a previously aborted run.
352-
func (s *skeleton) sync(head *types.Header) (header *types.Header, err error) {
349+
func (s *skeleton) sync(head *types.Header) (*types.Header, error) {
353350
// If we're continuing a previous merge interrupt, just access the existing
354351
// old state without initing from disk.
355352
if head == nil {
@@ -390,27 +387,6 @@ func (s *skeleton) sync(head *types.Header) (header *types.Header, err error) {
390387
log.Error("Latest filled block is not available")
391388
return
392389
}
393-
// if the skeleton just linked up and the current snap/full block is within
394-
// the range of the skeleton, the skeleton forked
395-
newlyLinked :=
396-
rawdb.HasHeader(s.db, s.progress.Subchains[0].Next, s.progress.Subchains[0].Tail-1) &&
397-
rawdb.HasBody(s.db, s.progress.Subchains[0].Next, s.progress.Subchains[0].Tail-1) &&
398-
rawdb.HasReceipts(s.db, s.progress.Subchains[0].Next, s.progress.Subchains[0].Tail-1) && !linked
399-
if newlyLinked && filled.Number.Uint64() >= s.progress.Subchains[0].Tail {
400-
// TODO: this could also happen if the skeleton was reverted back to a block already in the filled history?
401-
// ^probably/definitely not but need to verify
402-
403-
// revert the chain to the shared ancestor
404-
ancestor, err := s.findSkeletonAncestor(filled)
405-
if err != nil {
406-
log.Crit("Failed to find skeleton ancestor", "err", err)
407-
}
408-
if err = s.chain.SetHead(ancestor); err != nil {
409-
log.Crit("Failed to rewind chain", "err", err)
410-
}
411-
filled = s.chain.CurrentSnapBlock()
412-
}
413-
414390
// If something was filled, try to delete stale sync helpers. If
415391
// unsuccessful, warn the user, but not much else we can do (it's
416392
// a programming error, just let users report an issue and don't
@@ -1156,6 +1132,16 @@ func (s *skeleton) cleanStales(filled *types.Header) error {
11561132
if number+1 == s.progress.Subchains[0].Tail {
11571133
return nil
11581134
}
1135+
// If the latest fill was on a different subchain, it means the backfiller
1136+
// was interrupted before it got to do any meaningful work, no cleanup
1137+
header := rawdb.ReadSkeletonHeader(s.db, filled.Number.Uint64())
1138+
if header == nil {
1139+
log.Debug("Filled header outside of skeleton range", "number", number, "head", s.progress.Subchains[0].Head, "tail", s.progress.Subchains[0].Tail)
1140+
return nil
1141+
} else if header.Hash() != filled.Hash() {
1142+
log.Debug("Filled header on different sidechain", "number", number, "filled", filled.Hash(), "skeleton", header.Hash())
1143+
return nil
1144+
}
11591145
var (
11601146
start uint64
11611147
end uint64
@@ -1270,21 +1256,3 @@ func (s *skeleton) Bounds() (head *types.Header, tail *types.Header, final *type
12701256
func (s *skeleton) Header(number uint64) *types.Header {
12711257
return rawdb.ReadSkeletonHeader(s.db, number)
12721258
}
1273-
1274-
// find the common ancestor header of the skeleton chain and the snap block
1275-
func (s *skeleton) findSkeletonAncestor(filledHeader *types.Header) (uint64, error) {
1276-
for {
1277-
if filledHeader.Hash() == s.Header(filledHeader.Number.Uint64()).Hash() {
1278-
return filledHeader.Number.Uint64(), nil
1279-
}
1280-
if filledHeader.Number.Uint64() == s.progress.Subchains[0].Tail-1 {
1281-
if filledHeader.Hash() == s.progress.Subchains[0].Next {
1282-
return filledHeader.Number.Uint64(), nil
1283-
}
1284-
break
1285-
}
1286-
filledHeader = s.chain.GetHeaderByHash(filledHeader.ParentHash)
1287-
}
1288-
log.Crit("absolutely should not happen: the chain of the filled header and the skeleton chain must have a common ancestor")
1289-
return 0, nil
1290-
}

eth/downloader/skeleton_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ func TestSkeletonSyncInit(t *testing.T) {
368368
// Create a skeleton sync and run a cycle
369369
wait := make(chan struct{})
370370

371-
skeleton := newSkeleton(nil, db, newPeerSet(), nil, newHookedBackfiller())
371+
skeleton := newSkeleton(db, newPeerSet(), nil, newHookedBackfiller())
372372
skeleton.syncStarting = func() { close(wait) }
373373
skeleton.Sync(tt.head, nil, true)
374374

@@ -482,7 +482,7 @@ func TestSkeletonSyncExtend(t *testing.T) {
482482
// Create a skeleton sync and run a cycle
483483
wait := make(chan struct{})
484484

485-
skeleton := newSkeleton(nil, db, newPeerSet(), nil, newHookedBackfiller())
485+
skeleton := newSkeleton(db, newPeerSet(), nil, newHookedBackfiller())
486486
skeleton.syncStarting = func() { close(wait) }
487487
skeleton.Sync(tt.head, nil, true)
488488

@@ -858,7 +858,7 @@ func TestSkeletonSyncRetrievals(t *testing.T) {
858858
}
859859
}
860860
// Create a skeleton sync and run a cycle
861-
skeleton := newSkeleton(nil, db, peerset, drop, filler)
861+
skeleton := newSkeleton(db, peerset, drop, filler)
862862
skeleton.Sync(tt.head, nil, true)
863863

864864
var progress skeletonProgress

0 commit comments

Comments
 (0)