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 }