github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/state/protocol/inmem/snapshot.go (about) 1 package inmem 2 3 import ( 4 "fmt" 5 6 "github.com/onflow/flow-go/consensus/hotstuff/model" 7 "github.com/onflow/flow-go/model/flow" 8 "github.com/onflow/flow-go/model/flow/filter" 9 "github.com/onflow/flow-go/state/protocol" 10 "github.com/onflow/flow-go/state/protocol/protocol_state/kvstore" 11 ) 12 13 // Snapshot is a memory-backed implementation of protocol.Snapshot. The snapshot 14 // data is stored in the embedded encodable snapshot model, which defines the 15 // canonical structure of an encoded snapshot for the purposes of serialization. 16 type Snapshot struct { 17 enc EncodableSnapshot 18 } 19 20 var _ protocol.Snapshot = (*Snapshot)(nil) 21 22 func (s Snapshot) Head() (*flow.Header, error) { 23 return s.enc.Head, nil 24 } 25 26 func (s Snapshot) QuorumCertificate() (*flow.QuorumCertificate, error) { 27 return s.enc.QuorumCertificate, nil 28 } 29 30 func (s Snapshot) Identities(selector flow.IdentityFilter[flow.Identity]) (flow.IdentityList, error) { 31 protocolState, err := s.EpochProtocolState() 32 if err != nil { 33 return nil, fmt.Errorf("could not access protocol state: %w", err) 34 } 35 return protocolState.Identities().Filter(selector), nil 36 } 37 38 func (s Snapshot) Identity(nodeID flow.Identifier) (*flow.Identity, error) { 39 // filter identities at snapshot for node ID 40 identities, err := s.Identities(filter.HasNodeID[flow.Identity](nodeID)) 41 if err != nil { 42 return nil, fmt.Errorf("could not get identities: %w", err) 43 } 44 45 // check if node ID is part of identities 46 if len(identities) == 0 { 47 return nil, protocol.IdentityNotFoundError{NodeID: nodeID} 48 } 49 return identities[0], nil 50 } 51 52 func (s Snapshot) Commit() (flow.StateCommitment, error) { 53 return s.enc.LatestSeal.FinalState, nil 54 } 55 56 func (s Snapshot) SealedResult() (*flow.ExecutionResult, *flow.Seal, error) { 57 return s.enc.LatestResult, s.enc.LatestSeal, nil 58 } 59 60 func (s Snapshot) SealingSegment() (*flow.SealingSegment, error) { 61 return s.enc.SealingSegment, nil 62 } 63 64 func (s Snapshot) Descendants() ([]flow.Identifier, error) { 65 // canonical snapshots don't have any descendants 66 return nil, nil 67 } 68 69 func (s Snapshot) Phase() (flow.EpochPhase, error) { 70 epochProtocolState, err := s.EpochProtocolState() 71 if err != nil { 72 return flow.EpochPhaseUndefined, fmt.Errorf("could not get epoch protocol state: %w", err) 73 } 74 return epochProtocolState.EpochPhase(), nil 75 } 76 77 func (s Snapshot) RandomSource() ([]byte, error) { 78 return model.BeaconSignature(s.enc.QuorumCertificate) 79 } 80 81 func (s Snapshot) Epochs() protocol.EpochQuery { 82 return Epochs{ 83 entry: *s.enc.SealingSegment.LatestProtocolStateEntry().EpochEntry, 84 } 85 } 86 87 func (s Snapshot) Params() protocol.GlobalParams { 88 return Params{s.enc.Params} 89 } 90 91 func (s Snapshot) Encodable() EncodableSnapshot { 92 return s.enc 93 } 94 95 func (s Snapshot) EpochProtocolState() (protocol.DynamicProtocolState, error) { 96 entry := s.enc.SealingSegment.LatestProtocolStateEntry() 97 return NewDynamicProtocolStateAdapter(entry.EpochEntry, s.Params()), nil 98 } 99 100 func (s Snapshot) ProtocolState() (protocol.KVStoreReader, error) { 101 entry := s.enc.SealingSegment.LatestProtocolStateEntry() 102 return kvstore.VersionedDecode(entry.KVStore.Version, entry.KVStore.Data) 103 } 104 105 func (s Snapshot) VersionBeacon() (*flow.SealedVersionBeacon, error) { 106 return s.enc.SealedVersionBeacon, nil 107 } 108 109 func SnapshotFromEncodable(enc EncodableSnapshot) *Snapshot { 110 return &Snapshot{ 111 enc: enc, 112 } 113 }