github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/state/protocol/events.go (about)

     1  package protocol
     2  
     3  import (
     4  	"github.com/onflow/flow-go/model/flow"
     5  )
     6  
     7  // Consumer defines a set of events that occur within the protocol state, that
     8  // can be propagated to other components via an implementation of this interface.
     9  // Collectively, these are referred to as "Protocol Events".
    10  //
    11  // Protocol events are delivered immediately after the database transaction
    12  // committing the corresponding state change completes successfully.
    13  // This means that events are delivered exactly once, while the system is running.
    14  // Events may not be delivered during crashes and restarts, but any missed events
    15  // are guaranteed to be reflected in the Protocol State upon restarting.
    16  // Components consuming protocol events which cannot tolerate missed events
    17  // must implement initialization logic which accounts for any missed events.
    18  //
    19  // EXAMPLE:
    20  // Suppose block A is finalized at height 100. If the BlockFinalized(A) event is
    21  // dropped due to a crash, then when the node restarts, the latest finalized block
    22  // in the Protocol State is guaranteed to be A.
    23  //
    24  // CAUTION: Protocol event subscriber callbacks are invoked synchronously in the
    25  // critical path of protocol state mutations. Most subscribers should immediately
    26  // spawn a goroutine to handle the notification to avoid blocking protocol state
    27  // progression, especially for frequent protocol events (eg. BlockFinalized).
    28  //
    29  // NOTE: the epoch-related callbacks are only called once the fork containing
    30  // the relevant event has been finalized.
    31  type Consumer interface {
    32  	// BlockFinalized is called when a block is finalized.
    33  	// Formally, this callback is informationally idempotent. I.e. the consumer
    34  	// of this callback must handle repeated calls for the same block.
    35  	BlockFinalized(block *flow.Header)
    36  
    37  	// BlockProcessable is called when a correct block is encountered that is
    38  	// ready to be processed (i.e. it is connected to the finalized chain and
    39  	// its source of randomness is available).
    40  	// BlockProcessable provides the block and a certifying QC. BlockProcessable is never emitted
    41  	// for the root block, as the root block is always processable.
    42  	// Formally, this callback is informationally idempotent. I.e. the consumer
    43  	// of this callback must handle repeated calls for the same block.
    44  	BlockProcessable(block *flow.Header, certifyingQC *flow.QuorumCertificate)
    45  
    46  	// EpochTransition is called when we transition to a new epoch. This is
    47  	// equivalent to the beginning of the new epoch's staking phase and the end
    48  	// of the previous epoch's epoch committed phase.
    49  	//
    50  	// The block parameter is the first block of the new epoch.
    51  	//
    52  	// NOTE: Only called once the transition has been finalized.
    53  	EpochTransition(newEpochCounter uint64, first *flow.Header)
    54  
    55  	// EpochSetupPhaseStarted is called when we begin the epoch setup phase for
    56  	// the current epoch. This is equivalent to the end of the epoch staking
    57  	// phase for the current epoch.
    58  	//
    59  	// Referencing the diagram below, the event is emitted when block b is finalized.
    60  	// The block parameter is the first block of the epoch setup phase (block b).
    61  	//
    62  	// |<-- Epoch N ------------------------------------------------->|
    63  	// |<-- StakingPhase -->|<-- SetupPhase -->|<-- CommittedPhase -->|
    64  	//                    ^--- block A - this block's execution result contains an EpochSetup event
    65  	//                      ^--- block b - contains seal for block A, first block of Setup phase
    66  	//                         ^--- block c - finalizes block b, triggers EpochSetupPhaseStarted event
    67  	//
    68  	// NOTE: Only called once the phase transition has been finalized.
    69  	EpochSetupPhaseStarted(currentEpochCounter uint64, first *flow.Header)
    70  
    71  	// EpochCommittedPhaseStarted is called when we begin the epoch committed phase
    72  	// for the current epoch. This is equivalent to the end of the epoch setup
    73  	// phase for the current epoch.
    74  	//
    75  	// Referencing the diagram below, the event is emitted when block e is finalized.
    76  	// The block parameter is the first block of the epoch committed phase (block e).
    77  	//
    78  	// |<-- Epoch N ------------------------------------------------->|
    79  	// |<-- StakingPhase -->|<-- SetupPhase -->|<-- CommittedPhase -->|
    80  	//                                       ^--- block D - this block's execution result contains an EpochCommit event
    81  	//                                         ^--- block e - contains seal for block D, first block of Committed phase
    82  	//                                            ^--- block f - finalizes block e, triggers EpochCommittedPhaseStarted event
    83  	//
    84  	// NOTE: Only called once the phase transition has been finalized.
    85  	EpochCommittedPhaseStarted(currentEpochCounter uint64, first *flow.Header)
    86  
    87  	// EpochEmergencyFallbackTriggered is called when epoch fallback mode [EFM] is triggered.
    88  	// Since EFM is a permanent, spork-scoped state, this event is triggered only once.
    89  	// After this event is triggered, no further epoch transitions will occur,
    90  	// no further epoch phase transitions will occur, and no further epoch-related
    91  	// related protocol events (the events defined in this interface) will be emitted.
    92  	EpochEmergencyFallbackTriggered()
    93  }