github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/consensus/hotstuff/notifications/log_consumer.go (about) 1 package notifications 2 3 import ( 4 "time" 5 6 "github.com/rs/zerolog" 7 8 "github.com/onflow/flow-go/consensus/hotstuff" 9 "github.com/onflow/flow-go/consensus/hotstuff/model" 10 "github.com/onflow/flow-go/model/flow" 11 "github.com/onflow/flow-go/utils/logging" 12 ) 13 14 // LogConsumer is an implementation of the notifications consumer that logs a 15 // message for each event. 16 type LogConsumer struct { 17 log zerolog.Logger 18 } 19 20 var _ hotstuff.Consumer = (*LogConsumer)(nil) 21 var _ hotstuff.TimeoutAggregationConsumer = (*LogConsumer)(nil) 22 var _ hotstuff.VoteAggregationConsumer = (*LogConsumer)(nil) 23 24 func NewLogConsumer(log zerolog.Logger) *LogConsumer { 25 lc := &LogConsumer{ 26 log: log, 27 } 28 return lc 29 } 30 31 func (lc *LogConsumer) OnEventProcessed() { 32 lc.log.Debug().Msg("event processed") 33 } 34 35 func (lc *LogConsumer) OnStart(currentView uint64) { 36 lc.log.Debug().Uint64("cur_view", currentView).Msg("starting event handler") 37 } 38 39 func (lc *LogConsumer) OnBlockIncorporated(block *model.Block) { 40 lc.logBasicBlockData(lc.log.Debug(), block). 41 Msg("block incorporated") 42 } 43 44 func (lc *LogConsumer) OnFinalizedBlock(block *model.Block) { 45 lc.logBasicBlockData(lc.log.Debug(), block). 46 Msg("block finalized") 47 } 48 49 func (lc *LogConsumer) OnInvalidBlockDetected(err flow.Slashable[model.InvalidProposalError]) { 50 invalidBlock := err.Message.InvalidProposal.Block 51 lc.log.Warn(). 52 Str(logging.KeySuspicious, "true"). 53 Hex("origin_id", err.OriginID[:]). 54 Uint64("block_view", invalidBlock.View). 55 Hex("proposer_id", invalidBlock.ProposerID[:]). 56 Hex("block_id", invalidBlock.BlockID[:]). 57 Uint64("qc_block_view", invalidBlock.QC.View). 58 Hex("qc_block_id", invalidBlock.QC.BlockID[:]). 59 Msgf("invalid block detected: %s", err.Message.Error()) 60 } 61 62 func (lc *LogConsumer) OnDoubleProposeDetected(block *model.Block, alt *model.Block) { 63 lc.log.Warn(). 64 Str(logging.KeySuspicious, "true"). 65 Uint64("block_view", block.View). 66 Hex("block_id", block.BlockID[:]). 67 Hex("alt_id", alt.BlockID[:]). 68 Hex("proposer_id", block.ProposerID[:]). 69 Msg("double proposal detected") 70 } 71 72 func (lc *LogConsumer) OnReceiveProposal(currentView uint64, proposal *model.Proposal) { 73 logger := lc.logBasicBlockData(lc.log.Debug(), proposal.Block). 74 Uint64("cur_view", currentView) 75 lastViewTC := proposal.LastViewTC 76 if lastViewTC != nil { 77 logger. 78 Uint64("last_view_tc_view", lastViewTC.View). 79 Uint64("last_view_tc_newest_qc_view", lastViewTC.NewestQC.View). 80 Hex("last_view_tc_newest_qc_block_id", logging.ID(lastViewTC.NewestQC.BlockID)) 81 } 82 83 logger.Msg("processing proposal") 84 } 85 86 func (lc *LogConsumer) OnReceiveQc(currentView uint64, qc *flow.QuorumCertificate) { 87 lc.log.Debug(). 88 Uint64("cur_view", currentView). 89 Uint64("qc_view", qc.View). 90 Hex("qc_block_id", logging.ID(qc.BlockID)). 91 Msg("processing QC") 92 } 93 94 func (lc *LogConsumer) OnReceiveTc(currentView uint64, tc *flow.TimeoutCertificate) { 95 lc.log.Debug(). 96 Uint64("cur_view", currentView). 97 Uint64("tc_view", tc.View). 98 Uint64("newest_qc_view", tc.NewestQC.View). 99 Hex("newest_qc_block_id", logging.ID(tc.NewestQC.BlockID)). 100 Msg("processing TC") 101 } 102 103 func (lc *LogConsumer) OnPartialTc(currentView uint64, partialTc *hotstuff.PartialTcCreated) { 104 logger := lc.log.With(). 105 Uint64("cur_view", currentView). 106 Uint64("view", partialTc.View). 107 Uint64("qc_view", partialTc.NewestQC.View). 108 Hex("qc_block_id", logging.ID(partialTc.NewestQC.BlockID)) 109 110 lastViewTC := partialTc.LastViewTC 111 if lastViewTC != nil { 112 logger. 113 Uint64("last_view_tc_view", lastViewTC.View). 114 Uint64("last_view_tc_newest_qc_view", lastViewTC.NewestQC.View). 115 Hex("last_view_tc_newest_qc_block_id", logging.ID(lastViewTC.NewestQC.BlockID)) 116 } 117 118 log := logger.Logger() 119 log.Debug().Msg("processing partial TC") 120 } 121 122 func (lc *LogConsumer) OnLocalTimeout(currentView uint64) { 123 lc.log.Debug(). 124 Uint64("cur_view", currentView). 125 Msg("processing local timeout") 126 } 127 128 func (lc *LogConsumer) OnViewChange(oldView, newView uint64) { 129 lc.log.Debug(). 130 Uint64("old_view", oldView). 131 Uint64("new_view", newView). 132 Msg("entered new view") 133 } 134 135 func (lc *LogConsumer) OnQcTriggeredViewChange(oldView uint64, newView uint64, qc *flow.QuorumCertificate) { 136 lc.log.Debug(). 137 Uint64("qc_view", qc.View). 138 Hex("qc_block_id", qc.BlockID[:]). 139 Uint64("old_view", oldView). 140 Uint64("new_view", newView). 141 Msg("QC triggered view change") 142 } 143 144 func (lc *LogConsumer) OnTcTriggeredViewChange(oldView uint64, newView uint64, tc *flow.TimeoutCertificate) { 145 lc.log.Debug(). 146 Uint64("tc_view", tc.View). 147 Uint64("tc_newest_qc_view", tc.NewestQC.View). 148 Uint64("new_view", newView). 149 Uint64("old_view", oldView). 150 Msg("TC triggered view change") 151 } 152 153 func (lc *LogConsumer) OnStartingTimeout(info model.TimerInfo) { 154 lc.log.Debug(). 155 Uint64("timeout_view", info.View). 156 Time("timeout_cutoff", info.StartTime.Add(info.Duration)). 157 Msg("timeout started") 158 } 159 160 func (lc *LogConsumer) OnVoteProcessed(vote *model.Vote) { 161 lc.log.Debug(). 162 Hex("block_id", vote.BlockID[:]). 163 Uint64("block_view", vote.View). 164 Hex("recipient_id", vote.SignerID[:]). 165 Msg("processed valid HotStuff vote") 166 } 167 168 func (lc *LogConsumer) OnTimeoutProcessed(timeout *model.TimeoutObject) { 169 log := timeout.LogContext(lc.log).Logger() 170 log.Debug().Msg("processed valid timeout object") 171 } 172 173 func (lc *LogConsumer) OnCurrentViewDetails(currentView, finalizedView uint64, currentLeader flow.Identifier) { 174 lc.log.Info(). 175 Uint64("view", currentView). 176 Uint64("finalized_view", finalizedView). 177 Hex("current_leader", currentLeader[:]). 178 Msg("current view details") 179 } 180 181 func (lc *LogConsumer) OnDoubleVotingDetected(vote *model.Vote, alt *model.Vote) { 182 lc.log.Warn(). 183 Str(logging.KeySuspicious, "true"). 184 Uint64("vote_view", vote.View). 185 Hex("voted_block_id", vote.BlockID[:]). 186 Hex("alt_id", alt.BlockID[:]). 187 Hex("voter_id", vote.SignerID[:]). 188 Msg("double vote detected") 189 } 190 191 func (lc *LogConsumer) OnInvalidVoteDetected(err model.InvalidVoteError) { 192 lc.log.Warn(). 193 Str(logging.KeySuspicious, "true"). 194 Uint64("vote_view", err.Vote.View). 195 Hex("voted_block_id", err.Vote.BlockID[:]). 196 Hex("voter_id", err.Vote.SignerID[:]). 197 Msgf("invalid vote detected: %s", err.Error()) 198 } 199 200 func (lc *LogConsumer) OnVoteForInvalidBlockDetected(vote *model.Vote, proposal *model.Proposal) { 201 lc.log.Warn(). 202 Str(logging.KeySuspicious, "true"). 203 Uint64("vote_view", vote.View). 204 Hex("voted_block_id", vote.BlockID[:]). 205 Hex("voter_id", vote.SignerID[:]). 206 Hex("proposer_id", proposal.Block.ProposerID[:]). 207 Msg("vote for invalid proposal detected") 208 } 209 210 func (lc *LogConsumer) OnDoubleTimeoutDetected(timeout *model.TimeoutObject, alt *model.TimeoutObject) { 211 lc.log.Warn(). 212 Str(logging.KeySuspicious, "true"). 213 Uint64("timeout_view", timeout.View). 214 Hex("signer_id", logging.ID(timeout.SignerID)). 215 Hex("timeout_id", logging.ID(timeout.ID())). 216 Hex("alt_id", logging.ID(alt.ID())). 217 Msg("double timeout detected") 218 } 219 220 func (lc *LogConsumer) OnInvalidTimeoutDetected(err model.InvalidTimeoutError) { 221 log := err.Timeout.LogContext(lc.log).Logger() 222 log.Warn(). 223 Str(logging.KeySuspicious, "true"). 224 Msgf("invalid timeout detected: %s", err.Error()) 225 } 226 227 func (lc *LogConsumer) logBasicBlockData(loggerEvent *zerolog.Event, block *model.Block) *zerolog.Event { 228 loggerEvent. 229 Uint64("block_view", block.View). 230 Hex("block_id", logging.ID(block.BlockID)). 231 Hex("proposer_id", logging.ID(block.ProposerID)). 232 Hex("payload_hash", logging.ID(block.PayloadHash)). 233 Uint64("qc_view", block.QC.View). 234 Hex("qc_block_id", logging.ID(block.QC.BlockID)) 235 236 return loggerEvent 237 } 238 239 func (lc *LogConsumer) OnTcConstructedFromTimeouts(tc *flow.TimeoutCertificate) { 240 lc.log.Debug(). 241 Uint64("tc_view", tc.View). 242 Uint64("newest_qc_view", tc.NewestQC.View). 243 Hex("newest_qc_block_id", tc.NewestQC.BlockID[:]). 244 Msg("TC constructed") 245 } 246 247 func (lc *LogConsumer) OnPartialTcCreated(view uint64, newestQC *flow.QuorumCertificate, lastViewTC *flow.TimeoutCertificate) { 248 lc.log.Debug(). 249 Uint64("view", view). 250 Uint64("newest_qc_view", newestQC.View). 251 Hex("newest_qc_block_id", newestQC.BlockID[:]). 252 Bool("has_last_view_tc", lastViewTC != nil). 253 Msg("partial TC constructed") 254 } 255 256 func (lc *LogConsumer) OnNewQcDiscovered(qc *flow.QuorumCertificate) { 257 lc.log.Debug(). 258 Uint64("qc_view", qc.View). 259 Hex("qc_block_id", qc.BlockID[:]). 260 Msg("new QC discovered") 261 } 262 263 func (lc *LogConsumer) OnNewTcDiscovered(tc *flow.TimeoutCertificate) { 264 lc.log.Debug(). 265 Uint64("tc_view", tc.View). 266 Uint64("newest_qc_view", tc.NewestQC.View). 267 Hex("newest_qc_block_id", tc.NewestQC.BlockID[:]). 268 Msg("new TC discovered") 269 } 270 271 func (lc *LogConsumer) OnOwnVote(blockID flow.Identifier, view uint64, sigData []byte, recipientID flow.Identifier) { 272 lc.log.Debug(). 273 Hex("block_id", blockID[:]). 274 Uint64("block_view", view). 275 Hex("recipient_id", recipientID[:]). 276 Msg("publishing HotStuff vote") 277 } 278 279 func (lc *LogConsumer) OnOwnTimeout(timeout *model.TimeoutObject) { 280 log := timeout.LogContext(lc.log).Logger() 281 log.Debug().Msg("publishing HotStuff timeout object") 282 } 283 284 func (lc *LogConsumer) OnOwnProposal(header *flow.Header, targetPublicationTime time.Time) { 285 lc.log.Debug(). 286 Str("chain_id", header.ChainID.String()). 287 Uint64("block_height", header.Height). 288 Uint64("block_view", header.View). 289 Hex("block_id", logging.Entity(header)). 290 Hex("parent_id", header.ParentID[:]). 291 Hex("payload_hash", header.PayloadHash[:]). 292 Time("timestamp", header.Timestamp). 293 Hex("parent_signer_indices", header.ParentVoterIndices). 294 Time("target_publication_time", targetPublicationTime). 295 Msg("publishing HotStuff block proposal") 296 } 297 298 func (lc *LogConsumer) OnQcConstructedFromVotes(qc *flow.QuorumCertificate) { 299 lc.log.Info(). 300 Uint64("view", qc.View). 301 Hex("block_id", qc.BlockID[:]). 302 Msg("QC constructed from votes") 303 }