github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/consensus/hotstuff/consumer.go (about)

     1  package hotstuff
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/onflow/flow-go/consensus/hotstuff/model"
     7  	"github.com/onflow/flow-go/model/flow"
     8  )
     9  
    10  // ProposalViolationConsumer consumes outbound notifications about HotStuff-protocol violations.
    11  // Such notifications are produced by the active consensus participants and consensus follower.
    12  //
    13  // Implementations must:
    14  //   - be concurrency safe
    15  //   - be non-blocking
    16  //   - handle repetition of the same events (with some processing overhead).
    17  type ProposalViolationConsumer interface {
    18  	// OnInvalidBlockDetected notifications are produced by components that have detected
    19  	// that a block proposal is invalid and need to report it.
    20  	// Most of the time such block can be detected by calling Validator.ValidateProposal.
    21  	// Prerequisites:
    22  	// Implementation must be concurrency safe; Non-blocking;
    23  	// and must handle repetition of the same events (with some processing overhead).
    24  	OnInvalidBlockDetected(err flow.Slashable[model.InvalidProposalError])
    25  
    26  	// OnDoubleProposeDetected notifications are produced by the Finalization Logic
    27  	// whenever a double block proposal (equivocation) was detected.
    28  	// Equivocation occurs when the same leader proposes two different blocks for the same view.
    29  	// Prerequisites:
    30  	// Implementation must be concurrency safe; Non-blocking;
    31  	// and must handle repetition of the same events (with some processing overhead).
    32  	OnDoubleProposeDetected(*model.Block, *model.Block)
    33  }
    34  
    35  // VoteAggregationViolationConsumer consumes outbound notifications about HotStuff-protocol violations specifically
    36  // invalid votes during processing.
    37  // Such notifications are produced by the Vote Aggregation logic.
    38  //
    39  // Implementations must:
    40  //   - be concurrency safe
    41  //   - be non-blocking
    42  //   - handle repetition of the same events (with some processing overhead).
    43  type VoteAggregationViolationConsumer interface {
    44  	// OnDoubleVotingDetected notifications are produced by the Vote Aggregation logic
    45  	// whenever a double voting (same voter voting for different blocks at the same view) was detected.
    46  	// Prerequisites:
    47  	// Implementation must be concurrency safe; Non-blocking;
    48  	// and must handle repetition of the same events (with some processing overhead).
    49  	OnDoubleVotingDetected(*model.Vote, *model.Vote)
    50  
    51  	// OnInvalidVoteDetected notifications are produced by the Vote Aggregation logic
    52  	// whenever an invalid vote was detected.
    53  	// Prerequisites:
    54  	// Implementation must be concurrency safe; Non-blocking;
    55  	// and must handle repetition of the same events (with some processing overhead).
    56  	OnInvalidVoteDetected(err model.InvalidVoteError)
    57  
    58  	// OnVoteForInvalidBlockDetected notifications are produced by the Vote Aggregation logic
    59  	// whenever vote for invalid proposal was detected.
    60  	// Prerequisites:
    61  	// Implementation must be concurrency safe; Non-blocking;
    62  	// and must handle repetition of the same events (with some processing overhead).
    63  	OnVoteForInvalidBlockDetected(vote *model.Vote, invalidProposal *model.Proposal)
    64  }
    65  
    66  // TimeoutAggregationViolationConsumer consumes outbound notifications about Active Pacemaker violations specifically
    67  // invalid timeouts during processing.
    68  // Such notifications are produced by the Timeout Aggregation logic.
    69  //
    70  // Implementations must:
    71  //   - be concurrency safe
    72  //   - be non-blocking
    73  //   - handle repetition of the same events (with some processing overhead).
    74  type TimeoutAggregationViolationConsumer interface {
    75  	// OnDoubleTimeoutDetected notifications are produced by the Timeout Aggregation logic
    76  	// whenever a double timeout (same replica producing two different timeouts at the same view) was detected.
    77  	// Prerequisites:
    78  	// Implementation must be concurrency safe; Non-blocking;
    79  	// and must handle repetition of the same events (with some processing overhead).
    80  	OnDoubleTimeoutDetected(*model.TimeoutObject, *model.TimeoutObject)
    81  
    82  	// OnInvalidTimeoutDetected notifications are produced by the Timeout Aggregation logic
    83  	// whenever an invalid timeout was detected.
    84  	// Prerequisites:
    85  	// Implementation must be concurrency safe; Non-blocking;
    86  	// and must handle repetition of the same events (with some processing overhead).
    87  	OnInvalidTimeoutDetected(err model.InvalidTimeoutError)
    88  }
    89  
    90  // FinalizationConsumer consumes outbound notifications produced by the logic tracking
    91  // forks and finalization. Such notifications are produced by the active consensus
    92  // participants, and generally potentially relevant to the larger node. The notifications
    93  // are emitted in the order in which the finalization algorithm makes the respective steps.
    94  //
    95  // Implementations must:
    96  //   - be concurrency safe
    97  //   - be non-blocking
    98  //   - handle repetition of the same events (with some processing overhead).
    99  type FinalizationConsumer interface {
   100  	// OnBlockIncorporated notifications are produced by the Finalization Logic
   101  	// whenever a block is incorporated into the consensus state.
   102  	// Prerequisites:
   103  	// Implementation must be concurrency safe; Non-blocking;
   104  	// and must handle repetition of the same events (with some processing overhead).
   105  	OnBlockIncorporated(*model.Block)
   106  
   107  	// OnFinalizedBlock notifications are produced by the Finalization Logic whenever
   108  	// a block has been finalized. They are emitted in the order the blocks are finalized.
   109  	// Prerequisites:
   110  	// Implementation must be concurrency safe; Non-blocking;
   111  	// and must handle repetition of the same events (with some processing overhead).
   112  	OnFinalizedBlock(*model.Block)
   113  }
   114  
   115  // ParticipantConsumer consumes outbound notifications produced by consensus participants
   116  // actively proposing blocks, voting, collecting & aggregating votes to QCs, and participating in
   117  // the pacemaker (sending timeouts, collecting & aggregating timeouts to TCs).
   118  // Implementations must:
   119  //   - be concurrency safe
   120  //   - be non-blocking
   121  //   - handle repetition of the same events (with some processing overhead).
   122  type ParticipantConsumer interface {
   123  	// OnEventProcessed notifications are produced by the EventHandler when it is done processing
   124  	// and hands control back to the EventLoop to wait for the next event.
   125  	// Prerequisites:
   126  	// Implementation must be concurrency safe; Non-blocking;
   127  	// and must handle repetition of the same events (with some processing overhead).
   128  	OnEventProcessed()
   129  
   130  	// OnStart notifications are produced by the EventHandler when it starts blocks recovery and
   131  	// prepares for handling incoming events from EventLoop.
   132  	// Prerequisites:
   133  	// Implementation must be concurrency safe; Non-blocking;
   134  	// and must handle repetition of the same events (with some processing overhead).
   135  	OnStart(currentView uint64)
   136  
   137  	// OnReceiveProposal notifications are produced by the EventHandler when it starts processing a block.
   138  	// Prerequisites:
   139  	// Implementation must be concurrency safe; Non-blocking;
   140  	// and must handle repetition of the same events (with some processing overhead).
   141  	OnReceiveProposal(currentView uint64, proposal *model.Proposal)
   142  
   143  	// OnReceiveQc notifications are produced by the EventHandler when it starts processing a
   144  	// QuorumCertificate [QC] constructed by the node's internal vote aggregator.
   145  	// Prerequisites:
   146  	// Implementation must be concurrency safe; Non-blocking;
   147  	// and must handle repetition of the same events (with some processing overhead).
   148  	OnReceiveQc(currentView uint64, qc *flow.QuorumCertificate)
   149  
   150  	// OnReceiveTc notifications are produced by the EventHandler when it starts processing a
   151  	// TimeoutCertificate [TC]  constructed by the node's internal timeout aggregator.
   152  	// Prerequisites:
   153  	// Implementation must be concurrency safe; Non-blocking;
   154  	// and must handle repetition of the same events (with some processing overhead).
   155  	OnReceiveTc(currentView uint64, tc *flow.TimeoutCertificate)
   156  
   157  	// OnPartialTc notifications are produced by the EventHandler when it starts processing partial TC
   158  	// constructed by local timeout aggregator.
   159  	// Prerequisites:
   160  	// Implementation must be concurrency safe; Non-blocking;
   161  	// and must handle repetition of the same events (with some processing overhead).
   162  	OnPartialTc(currentView uint64, partialTc *PartialTcCreated)
   163  
   164  	// OnLocalTimeout notifications are produced by the EventHandler when it reacts to expiry of round duration timer.
   165  	// Such a notification indicates that the PaceMaker's timeout was processed by the system.
   166  	// Prerequisites:
   167  	// Implementation must be concurrency safe; Non-blocking;
   168  	// and must handle repetition of the same events (with some processing overhead).
   169  	OnLocalTimeout(currentView uint64)
   170  
   171  	// OnViewChange notifications are produced by PaceMaker when it transitions to a new view
   172  	// based on processing a QC or TC. The arguments specify the oldView (first argument),
   173  	// and the newView to which the PaceMaker transitioned (second argument).
   174  	// Prerequisites:
   175  	// Implementation must be concurrency safe; Non-blocking;
   176  	// and must handle repetition of the same events (with some processing overhead).
   177  	OnViewChange(oldView, newView uint64)
   178  
   179  	// OnQcTriggeredViewChange notifications are produced by PaceMaker when it moves to a new view
   180  	// based on processing a QC. The arguments specify the qc (first argument), which triggered
   181  	// the view change, and the newView to which the PaceMaker transitioned (second argument).
   182  	// Prerequisites:
   183  	// Implementation must be concurrency safe; Non-blocking;
   184  	// and must handle repetition of the same events (with some processing overhead).
   185  	OnQcTriggeredViewChange(oldView uint64, newView uint64, qc *flow.QuorumCertificate)
   186  
   187  	// OnTcTriggeredViewChange notifications are produced by PaceMaker when it moves to a new view
   188  	// based on processing a TC. The arguments specify the tc (first argument), which triggered
   189  	// the view change, and the newView to which the PaceMaker transitioned (second argument).
   190  	// Prerequisites:
   191  	// Implementation must be concurrency safe; Non-blocking;
   192  	// and must handle repetition of the same events (with some processing overhead).
   193  	OnTcTriggeredViewChange(oldView uint64, newView uint64, tc *flow.TimeoutCertificate)
   194  
   195  	// OnStartingTimeout notifications are produced by PaceMaker. Such a notification indicates that the
   196  	// PaceMaker is now waiting for the system to (receive and) process blocks or votes.
   197  	// The specific timeout type is contained in the TimerInfo.
   198  	// Prerequisites:
   199  	// Implementation must be concurrency safe; Non-blocking;
   200  	// and must handle repetition of the same events (with some processing overhead).
   201  	OnStartingTimeout(model.TimerInfo)
   202  
   203  	// OnCurrentViewDetails notifications are produced by the EventHandler during the course of a view with auxiliary information.
   204  	// These notifications are generally not produced for all views (for example skipped views).
   205  	// These notifications are guaranteed to be produced for all views we enter after fully processing a message.
   206  	// Example 1:
   207  	//   - We are in view 8. We process a QC with view 10, causing us to enter view 11.
   208  	//   - Then this notification will be produced for view 11.
   209  	// Example 2:
   210  	//   - We are in view 8. We process a proposal with view 10, which contains a TC for view 9 and TC.NewestQC for view 8.
   211  	//   - The QC would allow us to enter view 9 and the TC would allow us to enter view 10,
   212  	//     so after fully processing the message we are in view 10.
   213  	//   - Then this notification will be produced for view 10, but not view 9
   214  	// Prerequisites:
   215  	// Implementation must be concurrency safe; Non-blocking;
   216  	// and must handle repetition of the same events (with some processing overhead).
   217  	OnCurrentViewDetails(currentView, finalizedView uint64, currentLeader flow.Identifier)
   218  }
   219  
   220  // VoteCollectorConsumer consumes outbound notifications produced by HotStuff's vote aggregation
   221  // component. These events are primarily intended for the HotStuff-internal state machine (EventHandler),
   222  // but might also be relevant to the larger node in which HotStuff is running.
   223  //
   224  // Implementations must:
   225  //   - be concurrency safe
   226  //   - be non-blocking
   227  //   - handle repetition of the same events (with some processing overhead).
   228  type VoteCollectorConsumer interface {
   229  	// OnQcConstructedFromVotes notifications are produced by the VoteAggregator
   230  	// component, whenever it constructs a QC from votes.
   231  	// Prerequisites:
   232  	// Implementation must be concurrency safe; Non-blocking;
   233  	// and must handle repetition of the same events (with some processing overhead).
   234  	OnQcConstructedFromVotes(*flow.QuorumCertificate)
   235  
   236  	// OnVoteProcessed notifications are produced by the Vote Aggregation logic, each time
   237  	// we successfully ingest a valid vote.
   238  	// Prerequisites:
   239  	// Implementation must be concurrency safe; Non-blocking;
   240  	// and must handle repetition of the same events (with some processing overhead).
   241  	OnVoteProcessed(vote *model.Vote)
   242  }
   243  
   244  // TimeoutCollectorConsumer consumes outbound notifications produced by HotStuff's timeout aggregation
   245  // component. These events are primarily intended for the HotStuff-internal state machine (EventHandler),
   246  // but might also be relevant to the larger node in which HotStuff is running.
   247  //
   248  // Caution: the events are not strictly ordered by increasing views!
   249  // The notifications are emitted by concurrent processing logic. Over larger time scales, the
   250  // emitted events are for statistically increasing views. However, on short time scales there
   251  // are _no_ monotonicity guarantees w.r.t. the events' views.
   252  //
   253  // Implementations must:
   254  //   - be concurrency safe
   255  //   - be non-blocking
   256  //   - handle repetition of the same events (with some processing overhead).
   257  type TimeoutCollectorConsumer interface {
   258  	// OnTcConstructedFromTimeouts notifications are produced by the TimeoutProcessor
   259  	// component, whenever it constructs a TC based on TimeoutObjects from a
   260  	// supermajority of consensus participants.
   261  	// Prerequisites:
   262  	// Implementation must be concurrency safe; Non-blocking;
   263  	// and must handle repetition of the same events (with some processing overhead).
   264  	OnTcConstructedFromTimeouts(certificate *flow.TimeoutCertificate)
   265  
   266  	// OnPartialTcCreated notifications are produced by the TimeoutProcessor
   267  	// component, whenever it collected TimeoutObjects from a superminority
   268  	// of consensus participants for a specific view. Along with the view, it
   269  	// reports the newest QC and TC (for previous view) discovered in process of
   270  	// timeout collection. Per convention, the newest QC is never nil, while
   271  	// the TC for the previous view might be nil.
   272  	// Prerequisites:
   273  	// Implementation must be concurrency safe; Non-blocking;
   274  	// and must handle repetition of the same events (with some processing overhead).
   275  	OnPartialTcCreated(view uint64, newestQC *flow.QuorumCertificate, lastViewTC *flow.TimeoutCertificate)
   276  
   277  	// OnNewQcDiscovered notifications are produced by the TimeoutCollector
   278  	// component, whenever it discovers new QC included in timeout object.
   279  	// Prerequisites:
   280  	// Implementation must be concurrency safe; Non-blocking;
   281  	// and must handle repetition of the same events (with some processing overhead).
   282  	OnNewQcDiscovered(certificate *flow.QuorumCertificate)
   283  
   284  	// OnNewTcDiscovered notifications are produced by the TimeoutCollector
   285  	// component, whenever it discovers new TC included in timeout object.
   286  	// Prerequisites:
   287  	// Implementation must be concurrency safe; Non-blocking;
   288  	// and must handle repetition of the same events (with some processing overhead).
   289  	OnNewTcDiscovered(certificate *flow.TimeoutCertificate)
   290  
   291  	// OnTimeoutProcessed notifications are produced by the Timeout Aggregation logic,
   292  	// each time we successfully ingest a valid timeout.
   293  	// Prerequisites:
   294  	// Implementation must be concurrency safe; Non-blocking;
   295  	// and must handle repetition of the same events (with some processing overhead).
   296  	OnTimeoutProcessed(timeout *model.TimeoutObject)
   297  }
   298  
   299  // CommunicatorConsumer consumes outbound notifications produced by HotStuff and it's components.
   300  // Notifications allow the HotStuff core algorithm to communicate with the other actors of the consensus process.
   301  // Implementations must:
   302  //   - be concurrency safe
   303  //   - be non-blocking
   304  //   - handle repetition of the same events (with some processing overhead).
   305  type CommunicatorConsumer interface {
   306  	// OnOwnVote notifies about intent to send a vote for the given parameters to the specified recipient.
   307  	// Prerequisites:
   308  	// Implementation must be concurrency safe; Non-blocking;
   309  	// and must handle repetition of the same events (with some processing overhead).
   310  	OnOwnVote(blockID flow.Identifier, view uint64, sigData []byte, recipientID flow.Identifier)
   311  
   312  	// OnOwnTimeout notifies about intent to broadcast the given timeout object(TO) to all actors of the consensus process.
   313  	// Prerequisites:
   314  	// Implementation must be concurrency safe; Non-blocking;
   315  	// and must handle repetition of the same events (with some processing overhead).
   316  	OnOwnTimeout(timeout *model.TimeoutObject)
   317  
   318  	// OnOwnProposal notifies about intent to broadcast the given block proposal to all actors of
   319  	// the consensus process.
   320  	// delay is to hold the proposal before broadcasting it. Useful to control the block production rate.
   321  	// Prerequisites:
   322  	// Implementation must be concurrency safe; Non-blocking;
   323  	// and must handle repetition of the same events (with some processing overhead).
   324  	OnOwnProposal(proposal *flow.Header, targetPublicationTime time.Time)
   325  }
   326  
   327  // FollowerConsumer consumes outbound notifications produced by consensus followers.
   328  // It is a subset of the notifications produced by consensus participants.
   329  // Implementations must:
   330  //   - be concurrency safe
   331  //   - be non-blocking
   332  //   - handle repetition of the same events (with some processing overhead).
   333  type FollowerConsumer interface {
   334  	ProposalViolationConsumer
   335  	FinalizationConsumer
   336  }
   337  
   338  // Consumer consumes outbound notifications produced by consensus participants.
   339  // Notifications are consensus-internal state changes which are potentially relevant to
   340  // the larger node in which HotStuff is running. The notifications are emitted
   341  // in the order in which the HotStuff algorithm makes the respective steps.
   342  //
   343  // Implementations must:
   344  //   - be concurrency safe
   345  //   - be non-blocking
   346  //   - handle repetition of the same events (with some processing overhead).
   347  type Consumer interface {
   348  	FollowerConsumer
   349  	CommunicatorConsumer
   350  	ParticipantConsumer
   351  }
   352  
   353  // VoteAggregationConsumer consumes outbound notifications produced by Vote Aggregation logic.
   354  // It is a subset of the notifications produced by consensus participants.
   355  // Implementations must:
   356  //   - be concurrency safe
   357  //   - be non-blocking
   358  //   - handle repetition of the same events (with some processing overhead).
   359  type VoteAggregationConsumer interface {
   360  	VoteAggregationViolationConsumer
   361  	VoteCollectorConsumer
   362  }
   363  
   364  // TimeoutAggregationConsumer consumes outbound notifications produced by Vote Aggregation logic.
   365  // It is a subset of the notifications produced by consensus participants.
   366  // Implementations must:
   367  //   - be concurrency safe
   368  //   - be non-blocking
   369  //   - handle repetition of the same events (with some processing overhead).
   370  type TimeoutAggregationConsumer interface {
   371  	TimeoutAggregationViolationConsumer
   372  	TimeoutCollectorConsumer
   373  }