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

     1  package protocol
     2  
     3  import (
     4  	"github.com/onflow/flow-go/model/flow"
     5  )
     6  
     7  // EpochQuery defines the different ways to query for epoch information
     8  // given a Snapshot. It only exists to simplify the main Snapshot interface.
     9  type EpochQuery interface {
    10  
    11  	// Current returns the current epoch as of this snapshot. All valid snapshots
    12  	// have a current epoch.
    13  	Current() Epoch
    14  
    15  	// Next returns the next epoch as of this snapshot. Valid snapshots must
    16  	// have a next epoch available after the transition to epoch setup phase.
    17  	//
    18  	// Returns invalid.Epoch with ErrNextEpochNotSetup in the case that this method
    19  	// is queried w.r.t. a snapshot within the flow.EpochPhaseStaking phase.
    20  	Next() Epoch
    21  
    22  	// Previous returns the previous epoch as of this snapshot. Valid snapshots
    23  	// must have a previous epoch for all epochs except that immediately after
    24  	// the root block - in other words, if a previous epoch exists, implementations
    25  	// must arrange to expose it here.
    26  	//
    27  	// Returns invalid.Epoch with ErrNoPreviousEpoch in the case that this method
    28  	// is queried w.r.t. a snapshot from the first epoch after the root block.
    29  	Previous() Epoch
    30  }
    31  
    32  // Epoch contains the information specific to a certain Epoch (defined
    33  // by the epoch Counter). Note that the Epoch preparation can differ along
    34  // different forks, since the emission of service events is fork-dependent.
    35  // Therefore, an epoch exists RELATIVE to the snapshot from which it was
    36  // queried.
    37  //
    38  // CAUTION: Clients must ensure to query epochs only for finalized blocks to
    39  // ensure they query finalized epoch information.
    40  //
    41  // An Epoch instance is constant and reports the identical information
    42  // even if progress is made later and more information becomes available in
    43  // subsequent blocks.
    44  //
    45  // Methods error if epoch preparation has not progressed far enough for
    46  // this information to be determined by a finalized block.
    47  //
    48  // TODO Epoch / Snapshot API Structure:  Currently Epoch and Snapshot APIs
    49  // are structured to allow chained queries to be used without error checking
    50  // at each call where errors might occur. Instead, errors are cached in the
    51  // resulting struct (eg. invalid.Epoch) until the query chain ends with a
    52  // function which can return an error. This has some negative effects:
    53  //  1. Cached intermediary errors result in more complex error handling
    54  //     a) each final call of the chained query needs to handle all intermediary errors, every time
    55  //     b) intermediary errors must be handled by dependencies on the final call of the query chain (eg. conversion functions)
    56  //  2. The error caching pattern encourages potentially dangerous snapshot query patterns
    57  //
    58  // See https://github.com/dapperlabs/flow-go/issues/6368 for details and proposal
    59  type Epoch interface {
    60  
    61  	// Counter returns the Epoch's counter.
    62  	// Error returns:
    63  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
    64  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
    65  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
    66  	Counter() (uint64, error)
    67  
    68  	// FirstView returns the first view of this epoch.
    69  	// Error returns:
    70  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
    71  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
    72  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
    73  	FirstView() (uint64, error)
    74  
    75  	// DKGPhase1FinalView returns the final view of DKG phase 1
    76  	// Error returns:
    77  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
    78  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
    79  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
    80  	DKGPhase1FinalView() (uint64, error)
    81  
    82  	// DKGPhase2FinalView returns the final view of DKG phase 2
    83  	// Error returns:
    84  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
    85  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
    86  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
    87  	DKGPhase2FinalView() (uint64, error)
    88  
    89  	// DKGPhase3FinalView returns the final view of DKG phase 3
    90  	// Error returns:
    91  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
    92  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
    93  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
    94  	DKGPhase3FinalView() (uint64, error)
    95  
    96  	// FinalView returns the largest view number which still belongs to this epoch.
    97  	// Error returns:
    98  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
    99  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   100  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   101  	FinalView() (uint64, error)
   102  
   103  	// TargetDuration returns the desired real-world duration for this epoch, in seconds.
   104  	// This target is specified by the FlowEpoch smart contract along the TargetEndTime in
   105  	// the EpochSetup event and used by the Cruise Control system to moderate the block rate.
   106  	// Error returns:
   107  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   108  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   109  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   110  	TargetDuration() (uint64, error)
   111  
   112  	// TargetEndTime returns the desired real-world end time for this epoch, represented as
   113  	// Unix Time (in units of seconds). This target is specified by the FlowEpoch smart contract in
   114  	// the EpochSetup event and used by the Cruise Control system to moderate the block rate.
   115  	// Error returns:
   116  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   117  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   118  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   119  	TargetEndTime() (uint64, error)
   120  
   121  	// RandomSource returns the underlying random source of this epoch.
   122  	// This source is currently generated by an on-chain contract using the
   123  	// UnsafeRandom() Cadence function.
   124  	// Error returns:
   125  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   126  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   127  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   128  	RandomSource() ([]byte, error)
   129  
   130  	// InitialIdentities returns the identities for this epoch as they were
   131  	// specified in the EpochSetup service event.
   132  	// Error returns:
   133  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   134  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   135  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   136  	InitialIdentities() (flow.IdentitySkeletonList, error)
   137  
   138  	// Clustering returns the cluster assignment for this epoch.
   139  	// Error returns:
   140  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   141  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   142  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   143  	Clustering() (flow.ClusterList, error)
   144  
   145  	// Cluster returns the detailed cluster information for the cluster with the
   146  	// given index, in this epoch.
   147  	// Error returns:
   148  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   149  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   150  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   151  	// * protocol.ErrClusterNotFound - if no cluster has the given index (index > len(clusters))
   152  	Cluster(index uint) (Cluster, error)
   153  
   154  	// ClusterByChainID returns the detailed cluster information for the cluster with
   155  	// the given chain ID, in this epoch
   156  	// Error returns:
   157  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   158  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   159  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   160  	// * protocol.ErrNextEpochNotCommitted - if epoch has not been committed yet
   161  	// * protocol.ErrClusterNotFound - if cluster is not found by the given chainID
   162  	ClusterByChainID(chainID flow.ChainID) (Cluster, error)
   163  
   164  	// DKG returns the result of the distributed key generation procedure.
   165  	// Error returns:
   166  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   167  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   168  	// * protocol.ErrNextEpochNotCommitted if epoch has not been committed yet
   169  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   170  	DKG() (DKG, error)
   171  
   172  	// FirstHeight returns the height of the first block of the epoch.
   173  	// The first block of an epoch E is defined as the block B with the lowest
   174  	// height so that: B.View >= E.FirstView
   175  	// The first block of an epoch is not defined until it is finalized.
   176  	// Error returns:
   177  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   178  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   179  	// * protocol.ErrNextEpochNotCommitted if epoch has not been committed yet
   180  	// * protocol.ErrUnknownEpochBoundary - if the first block of the epoch is unknown.
   181  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   182  	FirstHeight() (uint64, error)
   183  
   184  	// FinalHeight returns the height of the final block of the epoch.
   185  	// The final block of an epoch E is defined as the parent of the first
   186  	// block in epoch E+1 (see definition from FirstHeight).
   187  	// The final block of an epoch is not defined until its child is finalized.
   188  	// Error returns:
   189  	// * protocol.ErrNoPreviousEpoch - if the epoch represents a previous epoch which does not exist.
   190  	// * protocol.ErrNextEpochNotSetup - if the epoch represents a next epoch which has not been set up.
   191  	// * protocol.ErrNextEpochNotCommitted - if epoch has not been committed yet
   192  	// * protocol.ErrUnknownEpochBoundary - if the first block of the next epoch is unknown.
   193  	// * state.ErrUnknownSnapshotReference - if the epoch is queried from an unresolvable snapshot.
   194  	FinalHeight() (uint64, error)
   195  }