mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-24 20:37:17 +00:00
Handles case when no peers with finalized blocks are found (#6679)
* Handles case when no peers with finalized blocks are found * more tests * Merge branch 'master' into handle-zero-block-init-sync * Merge branch 'master' into handle-zero-block-init-sync
This commit is contained in:
parent
17f845dcb0
commit
4400321081
@ -461,7 +461,16 @@ func (f *blocksFetcher) nonSkippedSlotAfter(ctx context.Context, slot uint64) (u
|
||||
defer span.End()
|
||||
|
||||
headEpoch := helpers.SlotToEpoch(f.headFetcher.HeadSlot())
|
||||
epoch, peers := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
finalizedEpoch, peers := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
log.WithFields(logrus.Fields{
|
||||
"start": slot,
|
||||
"headEpoch": headEpoch,
|
||||
"finalizedEpoch": finalizedEpoch,
|
||||
}).Debug("Searching for non-skipped slot")
|
||||
// Exit early, if no peers with high enough finalized epoch are found.
|
||||
if finalizedEpoch <= headEpoch {
|
||||
return 0, errSlotIsTooHigh
|
||||
}
|
||||
var err error
|
||||
peers, err = f.filterPeers(peers, peersPercentagePerRequest)
|
||||
if err != nil {
|
||||
@ -511,7 +520,7 @@ func (f *blocksFetcher) nonSkippedSlotAfter(ctx context.Context, slot uint64) (u
|
||||
// Quickly find the close enough epoch where a non-empty slot definitely exists.
|
||||
// Only single random slot per epoch is checked - allowing to move forward relatively quickly.
|
||||
slot = slot + nonSkippedSlotsFullSearchEpochs*slotsPerEpoch
|
||||
upperBoundSlot := helpers.StartSlot(epoch + 1)
|
||||
upperBoundSlot := helpers.StartSlot(finalizedEpoch + 1)
|
||||
for ind := slot + 1; ind < upperBoundSlot; ind += (slotsPerEpoch * slotsPerEpoch) / 2 {
|
||||
start := ind + uint64(f.rand.Intn(int(slotsPerEpoch)))
|
||||
nextSlot, err := fetch(peers[pidInd%len(peers)], start, slotsPerEpoch/2, slotsPerEpoch)
|
||||
@ -534,7 +543,7 @@ func (f *blocksFetcher) nonSkippedSlotAfter(ctx context.Context, slot uint64) (u
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if nextSlot < slot || helpers.StartSlot(epoch+1) < nextSlot {
|
||||
if nextSlot < slot || helpers.StartSlot(finalizedEpoch+1) < nextSlot {
|
||||
return 0, errors.New("invalid range for non-skipped slot")
|
||||
}
|
||||
return nextSlot, nil
|
||||
|
@ -29,6 +29,7 @@ var (
|
||||
errQueueTakesTooLongToStop = errors.New("queue takes too long to stop")
|
||||
errInvalidInitialState = errors.New("invalid initial state")
|
||||
errInputNotFetchRequestParams = errors.New("input data is not type *fetchRequestParams")
|
||||
errNoPeersWithFinalizedBlocks = errors.New("no peers with finalized blocks are found")
|
||||
)
|
||||
|
||||
// blocksQueueConfig is a config to setup block queue service.
|
||||
@ -151,11 +152,16 @@ func (q *blocksQueue) loop() {
|
||||
fsm := q.smm.machines[key]
|
||||
if err := fsm.trigger(eventTick, nil); err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"event": eventTick,
|
||||
"epoch": helpers.SlotToEpoch(fsm.start),
|
||||
"start": fsm.start,
|
||||
"error": err.Error(),
|
||||
"highestExpectedSlot": q.highestExpectedSlot,
|
||||
"event": eventTick,
|
||||
"epoch": helpers.SlotToEpoch(fsm.start),
|
||||
"start": fsm.start,
|
||||
"error": err.Error(),
|
||||
}).Debug("Can not trigger event")
|
||||
if err == errNoPeersWithFinalizedBlocks {
|
||||
q.cancel()
|
||||
continue
|
||||
}
|
||||
}
|
||||
// Do garbage collection, and advance sliding window forward.
|
||||
if q.headFetcher.HeadSlot() >= fsm.start+blocksPerRequest-1 {
|
||||
@ -315,6 +321,11 @@ func (q *blocksQueue) onProcessSkippedEvent(ctx context.Context) eventHandlerFn
|
||||
return m.state, nil
|
||||
}
|
||||
|
||||
// Check if we have enough peers to progress, or sync needs to halt (due to no peers available).
|
||||
if q.blocksFetcher.bestFinalizedSlot() <= q.headFetcher.HeadSlot() {
|
||||
return stateSkipped, errNoPeersWithFinalizedBlocks
|
||||
}
|
||||
|
||||
// Shift start position of all the machines except for the last one.
|
||||
startSlot := q.headFetcher.HeadSlot() + 1
|
||||
blocksPerRequest := q.blocksFetcher.blocksPerSecond
|
||||
@ -326,8 +337,7 @@ func (q *blocksQueue) onProcessSkippedEvent(ctx context.Context) eventHandlerFn
|
||||
}
|
||||
|
||||
// Replace the last (currently activated) state machine.
|
||||
nonSkippedSlot, err := q.blocksFetcher.nonSkippedSlotAfter(
|
||||
ctx, startSlot+blocksPerRequest*(lookaheadSteps-1)-1)
|
||||
nonSkippedSlot, err := q.blocksFetcher.nonSkippedSlotAfter(ctx, startSlot+blocksPerRequest*(lookaheadSteps-1)-1)
|
||||
if err != nil {
|
||||
return stateSkipped, err
|
||||
}
|
||||
|
@ -32,6 +32,40 @@ func TestService_roundRobinSync(t *testing.T) {
|
||||
expectedBlockSlots []uint64
|
||||
peers []*peerData
|
||||
}{
|
||||
{
|
||||
name: "Single peer with no finalized blocks",
|
||||
currentSlot: 2,
|
||||
expectedBlockSlots: makeSequence(1, 2),
|
||||
peers: []*peerData{
|
||||
{
|
||||
blocks: makeSequence(1, 2),
|
||||
finalizedEpoch: 0,
|
||||
headSlot: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Multiple peers with no finalized blocks",
|
||||
currentSlot: 2,
|
||||
expectedBlockSlots: makeSequence(1, 2),
|
||||
peers: []*peerData{
|
||||
{
|
||||
blocks: makeSequence(1, 2),
|
||||
finalizedEpoch: 0,
|
||||
headSlot: 2,
|
||||
},
|
||||
{
|
||||
blocks: makeSequence(1, 2),
|
||||
finalizedEpoch: 0,
|
||||
headSlot: 2,
|
||||
},
|
||||
{
|
||||
blocks: makeSequence(1, 2),
|
||||
finalizedEpoch: 0,
|
||||
headSlot: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Single peer with all blocks",
|
||||
currentSlot: 131,
|
||||
|
Loading…
Reference in New Issue
Block a user