github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/storage/badger/operation/cluster.go (about)

     1  package operation
     2  
     3  import (
     4  	"github.com/dgraph-io/badger/v2"
     5  
     6  	"github.com/onflow/flow-go/model/flow"
     7  )
     8  
     9  // This file implements storage functions for chain state book-keeping of
    10  // collection node cluster consensus. In contrast to the corresponding functions
    11  // for regular consensus, these functions include the cluster ID in order to
    12  // support storing multiple chains, for example during epoch switchover.
    13  
    14  // IndexClusterBlockHeight inserts a block number to block ID mapping for
    15  // the given cluster.
    16  func IndexClusterBlockHeight(clusterID flow.ChainID, number uint64, blockID flow.Identifier) func(*badger.Txn) error {
    17  	return insert(makePrefix(codeFinalizedCluster, clusterID, number), blockID)
    18  }
    19  
    20  // LookupClusterBlockHeight retrieves a block ID by number for the given cluster
    21  func LookupClusterBlockHeight(clusterID flow.ChainID, number uint64, blockID *flow.Identifier) func(*badger.Txn) error {
    22  	return retrieve(makePrefix(codeFinalizedCluster, clusterID, number), blockID)
    23  }
    24  
    25  // InsertClusterFinalizedHeight inserts the finalized boundary for the given cluster.
    26  func InsertClusterFinalizedHeight(clusterID flow.ChainID, number uint64) func(*badger.Txn) error {
    27  	return insert(makePrefix(codeClusterHeight, clusterID), number)
    28  }
    29  
    30  // UpdateClusterFinalizedHeight updates the finalized boundary for the given cluster.
    31  func UpdateClusterFinalizedHeight(clusterID flow.ChainID, number uint64) func(*badger.Txn) error {
    32  	return update(makePrefix(codeClusterHeight, clusterID), number)
    33  }
    34  
    35  // RetrieveClusterFinalizedHeight retrieves the finalized boundary for the given cluster.
    36  func RetrieveClusterFinalizedHeight(clusterID flow.ChainID, number *uint64) func(*badger.Txn) error {
    37  	return retrieve(makePrefix(codeClusterHeight, clusterID), number)
    38  }
    39  
    40  // IndexReferenceBlockByClusterBlock inserts the reference block ID for the given
    41  // cluster block ID. While each cluster block specifies a reference block in its
    42  // payload, we maintain this additional lookup for performance reasons.
    43  func IndexReferenceBlockByClusterBlock(clusterBlockID, refID flow.Identifier) func(*badger.Txn) error {
    44  	return insert(makePrefix(codeClusterBlockToRefBlock, clusterBlockID), refID)
    45  }
    46  
    47  // LookupReferenceBlockByClusterBlock looks up the reference block ID for the given
    48  // cluster block ID. While each cluster block specifies a reference block in its
    49  // payload, we maintain this additional lookup for performance reasons.
    50  func LookupReferenceBlockByClusterBlock(clusterBlockID flow.Identifier, refID *flow.Identifier) func(*badger.Txn) error {
    51  	return retrieve(makePrefix(codeClusterBlockToRefBlock, clusterBlockID), refID)
    52  }
    53  
    54  // IndexClusterBlockByReferenceHeight indexes a cluster block ID by its reference
    55  // block height. The cluster block ID is included in the key for more efficient
    56  // traversal. Only finalized cluster blocks should be included in this index.
    57  // The key looks like: <prefix 0:1><ref_height 1:9><cluster_block_id 9:41>
    58  func IndexClusterBlockByReferenceHeight(refHeight uint64, clusterBlockID flow.Identifier) func(*badger.Txn) error {
    59  	return insert(makePrefix(codeRefHeightToClusterBlock, refHeight, clusterBlockID), nil)
    60  }
    61  
    62  // LookupClusterBlocksByReferenceHeightRange traverses the ref_height->cluster_block
    63  // index and returns any finalized cluster blocks which have a reference block with
    64  // height in the given range. This is used to avoid including duplicate transaction
    65  // when building or validating a new collection.
    66  func LookupClusterBlocksByReferenceHeightRange(start, end uint64, clusterBlockIDs *[]flow.Identifier) func(*badger.Txn) error {
    67  	startPrefix := makePrefix(codeRefHeightToClusterBlock, start)
    68  	endPrefix := makePrefix(codeRefHeightToClusterBlock, end)
    69  	prefixLen := len(startPrefix)
    70  
    71  	return iterate(startPrefix, endPrefix, func() (checkFunc, createFunc, handleFunc) {
    72  		check := func(key []byte) bool {
    73  			clusterBlockIDBytes := key[prefixLen:]
    74  			var clusterBlockID flow.Identifier
    75  			copy(clusterBlockID[:], clusterBlockIDBytes)
    76  			*clusterBlockIDs = append(*clusterBlockIDs, clusterBlockID)
    77  
    78  			// the info we need is stored in the key, never process the value
    79  			return false
    80  		}
    81  		return check, nil, nil
    82  	}, withPrefetchValuesFalse)
    83  }