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 }