github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/sync/initial-sync/blocks_queue_utils.go (about)

     1  package initialsync
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	types "github.com/prysmaticlabs/eth2-types"
     8  )
     9  
    10  // resetWithBlocks removes all state machines, then re-adds enough machines to contain all provided
    11  // blocks (machines are set into stateDataParsed state, so that their content is immediately
    12  // consumable). It is assumed that blocks come in an ascending order.
    13  func (q *blocksQueue) resetFromFork(ctx context.Context, fork *forkData) error {
    14  	if fork == nil {
    15  		return errors.New("nil fork data")
    16  	}
    17  	if len(fork.blocks) == 0 {
    18  		return errors.New("no blocks to reset from")
    19  	}
    20  	firstBlock := fork.blocks[0].Block()
    21  	if firstBlock == nil || firstBlock.IsNil() {
    22  		return errors.New("invalid first block in fork data")
    23  	}
    24  
    25  	blocksPerRequest := q.blocksFetcher.blocksPerSecond
    26  	if err := q.smm.removeAllStateMachines(); err != nil {
    27  		return err
    28  	}
    29  	fsm := q.smm.addStateMachine(firstBlock.Slot())
    30  	fsm.pid = fork.peer
    31  	fsm.blocks = fork.blocks
    32  	fsm.state = stateDataParsed
    33  
    34  	// The rest of machines are in skipped state.
    35  	startSlot := firstBlock.Slot().Add(uint64(len(fork.blocks)))
    36  	for i := startSlot; i < startSlot.Add(blocksPerRequest*(lookaheadSteps-1)); i += types.Slot(blocksPerRequest) {
    37  		fsm := q.smm.addStateMachine(i)
    38  		fsm.state = stateSkipped
    39  	}
    40  	return nil
    41  }
    42  
    43  // resetFromSlot removes all state machines, and re-adds them starting with a given slot.
    44  // The last machine added relies on calculated non-skipped slot (to allow FSMs to jump over
    45  // long periods with skipped slots).
    46  func (q *blocksQueue) resetFromSlot(ctx context.Context, startSlot types.Slot) error {
    47  	// Shift start position of all the machines except for the last one.
    48  	blocksPerRequest := q.blocksFetcher.blocksPerSecond
    49  	if err := q.smm.removeAllStateMachines(); err != nil {
    50  		return err
    51  	}
    52  	for i := startSlot; i < startSlot.Add(blocksPerRequest*(lookaheadSteps-1)); i += types.Slot(blocksPerRequest) {
    53  		q.smm.addStateMachine(i)
    54  	}
    55  
    56  	// Replace the last (currently activated) state machine to start with best known non-skipped slot.
    57  	nonSkippedSlot, err := q.blocksFetcher.nonSkippedSlotAfter(ctx, startSlot.Add(blocksPerRequest*(lookaheadSteps-1)-1))
    58  	if err != nil {
    59  		return err
    60  	}
    61  	if q.mode == modeStopOnFinalizedEpoch {
    62  		if q.highestExpectedSlot < q.blocksFetcher.bestFinalizedSlot() {
    63  			q.highestExpectedSlot = q.blocksFetcher.bestFinalizedSlot()
    64  		}
    65  	} else {
    66  		if q.highestExpectedSlot < q.blocksFetcher.bestNonFinalizedSlot() {
    67  			q.highestExpectedSlot = q.blocksFetcher.bestNonFinalizedSlot()
    68  		}
    69  	}
    70  	if nonSkippedSlot > q.highestExpectedSlot {
    71  		nonSkippedSlot = startSlot.Add(blocksPerRequest * (lookaheadSteps - 1))
    72  	}
    73  	q.smm.addStateMachine(nonSkippedSlot)
    74  	return nil
    75  }