github.com/koko1123/flow-go-1@v0.29.6/consensus/hotstuff/pacemaker.go (about)

     1  package hotstuff
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/koko1123/flow-go-1/consensus/hotstuff/model"
     7  	"github.com/koko1123/flow-go-1/model/flow"
     8  )
     9  
    10  // PaceMaker for HotStuff. The component is passive in that it only reacts to method calls.
    11  // The PaceMaker does not perform state transitions on its own. Timeouts are emitted through
    12  // channels. Each timeout has its own dedicated channel, which is garbage collected after the
    13  // respective state has been passed. It is the EventHandler's responsibility to pick up
    14  // timeouts from the currently active TimeoutChannel process them first and subsequently inform the
    15  // PaceMaker about processing the timeout. Specifically, the intended usage pattern for the
    16  // TimeoutChannels is as follows:
    17  //
    18  // • Each time the PaceMaker starts a new timeout, it created a new TimeoutChannel
    19  //
    20  // • The channel for the CURRENTLY ACTIVE timeout is returned by PaceMaker.TimeoutChannel()
    21  //
    22  //   - Each time the EventHandler processes an event, the EventHandler might call into PaceMaker
    23  //     potentially resulting in a state transition and the PaceMaker starting a new timeout
    24  //
    25  //   - Hence, after processing any event, EventHandler should retrieve the current TimeoutChannel
    26  //     from the PaceMaker.
    27  //
    28  // For Example:
    29  //
    30  //	for {
    31  //		timeoutChannel := el.eventHandler.TimeoutChannel()
    32  //		select {
    33  //		   case <-timeoutChannel:
    34  //		    	el.eventHandler.OnLocalTimeout()
    35  //		   case <other events>
    36  //		}
    37  //	}
    38  type PaceMaker interface {
    39  
    40  	// CurView returns the current view.
    41  	CurView() uint64
    42  
    43  	// UpdateCurViewWithQC will check if the given QC will allow PaceMaker to fast
    44  	// forward to QC.view+1. If PaceMaker incremented the current View, a NewViewEvent will be returned.
    45  	UpdateCurViewWithQC(qc *flow.QuorumCertificate) (*model.NewViewEvent, bool)
    46  
    47  	// UpdateCurViewWithBlock will check if the given block will allow PaceMaker to fast forward
    48  	// to the BlockProposal's view. If yes, the PaceMaker will update it's internal value for
    49  	// CurView and return a NewViewEvent.
    50  	//
    51  	// The parameter `nextPrimary` indicates to the PaceMaker whether or not this replica is the
    52  	// primary for the NEXT view taking block.view as reference.
    53  	// True corresponds to this replica being the next primary.
    54  	UpdateCurViewWithBlock(block *model.Block, isLeaderForNextView bool) (*model.NewViewEvent, bool)
    55  
    56  	// TimeoutChannel returns the timeout channel for the CURRENTLY ACTIVE timeout.
    57  	// Each time the pace maker starts a new timeout, this channel is replaced.
    58  	TimeoutChannel() <-chan time.Time
    59  
    60  	// OnTimeout is called when a timeout, which was previously created by the PaceMaker, has
    61  	// looped through the event loop. When used correctly, OnTimeout will always return
    62  	// a NewViewEvent.
    63  	// It is the responsibility of the calling code to ensure that NO STALE timeouts are
    64  	// delivered to the PaceMaker.
    65  	OnTimeout() *model.NewViewEvent
    66  
    67  	// Start starts the PaceMaker (i.e. the timeout for the configured starting value for view).
    68  	Start()
    69  
    70  	// BlockRateDelay
    71  	BlockRateDelay() time.Duration
    72  }