github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/state/protocol/snapshot.go (about) 1 package protocol 2 3 import ( 4 "github.com/onflow/flow-go/model/flow" 5 ) 6 7 // Snapshot represents an immutable snapshot of the protocol state 8 // at a specific block, denoted as the Head block. 9 // The Snapshot is fork-specific and only accounts for the information contained 10 // in blocks along this fork up to (including) Head. 11 // It allows us to read the parameters at the selected block in a deterministic manner. 12 // 13 // TODO Epoch / Snapshot API Structure: Currently Epoch and Snapshot APIs 14 // are structured to allow chained queries to be used without error checking 15 // at each call where errors might occur. Instead, errors are cached in the 16 // resulting struct (eg. invalid.Epoch) until the query chain ends with a 17 // function which can return an error. This has some negative effects: 18 // 1. Cached intermediary errors result in more complex error handling 19 // a) each final call of the chained query needs to handle all intermediary errors, every time 20 // b) intermediary errors must be handled by dependencies on the final call of the query chain (eg. conversion functions) 21 // 2. The error caching pattern encourages potentially dangerous snapshot query patterns 22 // 23 // See https://github.com/dapperlabs/flow-go/issues/6368 for details and proposal 24 // 25 // A snapshot with an unknown reference block will return state.ErrUnknownSnapshotReference for all methods. 26 // 27 // TODO document error returns 28 type Snapshot interface { 29 30 // Head returns the latest block at the selected point of the protocol state 31 // history. It can represent either a finalized or ambiguous block, 32 // depending on our selection criteria. Either way, it's the block on which 33 // we should build the next block in the context of the selected state. 34 // TODO document error returns 35 Head() (*flow.Header, error) 36 37 // QuorumCertificate returns a valid quorum certificate for the header at 38 // this snapshot, if one exists. 39 // Expected error returns: 40 // - storage.ErrNotFound is returned if the QC is unknown. 41 // - state.ErrUnknownSnapshotReference if the snapshot reference block is unknown 42 // All other errors should be treated as exceptions. 43 QuorumCertificate() (*flow.QuorumCertificate, error) 44 45 // Identities returns a list of identities at the selected point of the 46 // protocol state history. At the beginning of an epoch, this list includes 47 // identities from the previous epoch that are un-staking during the current 48 // epoch. At the end of an epoch, this includes identities scheduled to join 49 // in the next epoch but are not active yet. 50 // 51 // Identities are guaranteed to be returned in canonical order (flow.Canonical[flow.Identity]). 52 // 53 // It allows us to provide optional upfront filters which can be used by the 54 // implementation to speed up database lookups. 55 // TODO document error returns 56 Identities(selector flow.IdentityFilter[flow.Identity]) (flow.IdentityList, error) 57 58 // Identity attempts to retrieve the node with the given identifier at the 59 // selected point of the protocol state history. It will error if it doesn't exist. 60 // TODO document error returns 61 Identity(nodeID flow.Identifier) (*flow.Identity, error) 62 63 // SealedResult returns the most recent included seal as of this block and 64 // the corresponding execution result. The seal may have been included in a 65 // parent block, if this block is empty. If this block contains multiple 66 // seals, this returns the seal for the block with the greatest height. 67 // TODO document error returns 68 SealedResult() (*flow.ExecutionResult, *flow.Seal, error) 69 70 // Commit returns the state commitment of the most recently included seal 71 // as of this block. It represents the sealed state. 72 // TODO document error returns 73 Commit() (flow.StateCommitment, error) 74 75 // SealingSegment returns the chain segment such that the highest block 76 // is this snapshot's reference block and the lowest block 77 // is the most recently sealed block as of this snapshot (ie. the block 78 // referenced by LatestSeal). The segment is in ascending height order. 79 // 80 // TAIL <- B1 <- ... <- BN <- HEAD 81 // 82 // NOTE 1: TAIL is not always sealed by HEAD. In the case that the head of 83 // the snapshot contains no seals, TAIL must be sealed by the first ancestor 84 // of HEAD which contains any seal. 85 // 86 // NOTE 2: In the special case of a root snapshot generated for a spork, 87 // the sealing segment has exactly one block (the root block for the spork). 88 // For all other snapshots, the sealing segment contains at least 2 blocks. 89 // 90 // NOTE 3: It is often the case that a block inside the segment will contain 91 // an execution receipt in its payload that references an execution result 92 // missing from the payload. These missing execution results are stored on the 93 // flow.SealingSegment.ExecutionResults field. 94 // Expected errors during normal operations: 95 // - protocol.ErrSealingSegmentBelowRootBlock if sealing segment would stretch beyond the node's local history cut-off 96 // - protocol.UnfinalizedSealingSegmentError if sealing segment would contain unfinalized blocks (including orphaned blocks) 97 // - state.ErrUnknownSnapshotReference if the snapshot reference block is unknown 98 SealingSegment() (*flow.SealingSegment, error) 99 100 // Descendants returns the IDs of all descendants of the Head block. 101 // The IDs are ordered such that parents are included before their children. 102 // Since all blocks are fully validated before being inserted to the state, 103 // all returned blocks are validated. 104 // No errors are expected under normal operation. 105 Descendants() ([]flow.Identifier, error) 106 107 // RandomSource returns the source of randomness _for_ the snapshot's Head block. 108 // Note that the source of randomness for a block `H`, is contained in the 109 // QuorumCertificate [QC] for block `H` (QCs for H are distributed as part of child 110 // blocks, timeout messages or timeout certificates). While there might be different 111 // QCs for block H, they all yield exactly the same source of randomness (feature of 112 // threshold signatures used here). Therefore, it is a possibility that there is no 113 // QC known (yet) for the head block. 114 // NOTE: not to be confused with the epoch source of randomness! 115 // Expected error returns: 116 // - storage.ErrNotFound is returned if the QC is unknown. 117 // - state.ErrUnknownSnapshotReference if the snapshot reference block is unknown 118 // All other errors should be treated as exceptions. 119 RandomSource() ([]byte, error) 120 121 // Phase returns the epoch phase for the current epoch, as of the Head block. 122 // TODO document error returns 123 Phase() (flow.EpochPhase, error) 124 125 // Epochs returns a query object enabling querying detailed information about 126 // various epochs. 127 // 128 // For epochs that are in the future w.r.t. the Head block, some of Epoch's 129 // methods may return errors, since the Epoch Preparation Protocol may be 130 // in-progress and incomplete for the epoch. 131 // Returns invalid.Epoch with state.ErrUnknownSnapshotReference if snapshot reference block is unknown. 132 Epochs() EpochQuery 133 134 // Params returns global parameters of the state this snapshot is taken from. 135 // Returns invalid.Params with state.ErrUnknownSnapshotReference if snapshot reference block is unknown. 136 Params() GlobalParams 137 138 // EpochProtocolState returns the epoch part of dynamic protocol state that the Head block commits to. 139 // The compliance layer guarantees that only valid blocks are appended to the protocol state. 140 // Returns state.ErrUnknownSnapshotReference if snapshot reference block is unknown. 141 // All other errors should be treated as exceptions. 142 EpochProtocolState() (DynamicProtocolState, error) 143 144 // ProtocolState returns the dynamic protocol state that the Head block commits to. 145 // The compliance layer guarantees that only valid blocks are appended to the protocol state. 146 // Returns state.ErrUnknownSnapshotReference if snapshot reference block is unknown. 147 // All other errors should be treated as exceptions. 148 ProtocolState() (KVStoreReader, error) 149 150 // VersionBeacon returns the latest sealed version beacon. 151 // If no version beacon has been sealed so far during the current spork, returns nil. 152 // The latest VersionBeacon is only updated for finalized blocks. This means that, when 153 // querying an un-finalized fork, `VersionBeacon` will have the same value as querying 154 // the snapshot for the latest finalized block, even if a newer version beacon is included 155 // in a seal along the un-finalized fork. 156 VersionBeacon() (*flow.SealedVersionBeacon, error) 157 }