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