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  }