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  }