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 }