Skip to content

Commit

Permalink
eth/downloader: fix a crash if the beacon chain is reduced in length
Browse files Browse the repository at this point in the history
  • Loading branch information
karalabe committed Jan 11, 2022
1 parent 51c47ad commit 4f75778
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
25 changes: 19 additions & 6 deletions eth/downloader/beaconsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package downloader

import (
"fmt"
"sync"
"sync/atomic"
"time"
Expand Down Expand Up @@ -136,24 +137,36 @@ func (d *Downloader) BeaconSync(mode SyncMode, head *types.Header) error {
// none of the head links match), we do a binary search to find the ancestor.
func (d *Downloader) findBeaconAncestor() uint64 {
// Figure out the current local head position
var head *types.Header
var chainHead *types.Header

switch d.getMode() {
case FullSync:
head = d.blockchain.CurrentBlock().Header()
chainHead = d.blockchain.CurrentBlock().Header()
case SnapSync:
head = d.blockchain.CurrentFastBlock().Header()
chainHead = d.blockchain.CurrentFastBlock().Header()
default:
head = d.lightchain.CurrentHeader()
chainHead = d.lightchain.CurrentHeader()
}
number := head.Number.Uint64()
number := chainHead.Number.Uint64()

// If the head is present in the skeleton chain, return that
if head.Hash() == d.skeleton.Header(number).Hash() {
if chainHead.Hash() == d.skeleton.Header(number).Hash() {
return number
}
// Head header not present, binary search to find the ancestor
start, end := uint64(0), number

beaconHead, err := d.skeleton.Head()
if err != nil {
panic(fmt.Sprintf("failed to read skeleton head: %v", err)) // can't reach this method without a head
}
if number := beaconHead.Number.Uint64(); end > number {
// This shouldn't really happen in a healty network, but if the consensus
// clients feeds us a shorter chain as the canonical, we should not attempt
// to access non-existent skeleton items.
log.Warn("Beacon head lower than local chain", "beacon", number, "local", end)
end = number
}
for start+1 < end {
// Split our chain interval in two, and request the hash to cross check
check := (start + end) / 2
Expand Down
2 changes: 1 addition & 1 deletion eth/downloader/skeleton.go
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ func (s *skeleton) processResponse(res *headerResponse) bool {
// Note, the method will not use the internal state of the skeleton, but will
// rather blindly pull stuff from the database. This is fine, because the back-
// filler will only run when the skeleton chain is fully downloaded and stable.
// There might be new heads appended, but those are stomic from the perspective
// There might be new heads appended, but those are atomic from the perspective
// of this method. Any head reorg will first tear down the backfiller and only
// then make the modification.
func (s *skeleton) Head() (*types.Header, error) {
Expand Down

0 comments on commit 4f75778

Please sign in to comment.