github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/state/indexer/block/kv/util.go (about) 1 package kv 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "math/big" 7 "strconv" 8 9 "github.com/google/orderedcode" 10 11 "github.com/badrootd/nibiru-cometbft/libs/pubsub/query" 12 "github.com/badrootd/nibiru-cometbft/state/indexer" 13 "github.com/badrootd/nibiru-cometbft/types" 14 ) 15 16 type HeightInfo struct { 17 heightRange indexer.QueryRange 18 height int64 19 heightEqIdx int 20 onlyHeightRange bool 21 onlyHeightEq bool 22 } 23 24 func intInSlice(a int, list []int) bool { 25 for _, b := range list { 26 if b == a { 27 return true 28 } 29 } 30 31 return false 32 } 33 34 func int64FromBytes(bz []byte) int64 { 35 v, _ := binary.Varint(bz) 36 return v 37 } 38 39 func int64ToBytes(i int64) []byte { 40 buf := make([]byte, binary.MaxVarintLen64) 41 n := binary.PutVarint(buf, i) 42 return buf[:n] 43 } 44 45 func heightKey(height int64) ([]byte, error) { 46 return orderedcode.Append( 47 nil, 48 types.BlockHeightKey, 49 height, 50 ) 51 } 52 53 func eventKey(compositeKey, typ, eventValue string, height int64, eventSeq int64) ([]byte, error) { 54 return orderedcode.Append( 55 nil, 56 compositeKey, 57 eventValue, 58 height, 59 typ, 60 eventSeq, 61 ) 62 } 63 64 func parseValueFromPrimaryKey(key []byte) (string, error) { 65 var ( 66 compositeKey string 67 height int64 68 ) 69 70 remaining, err := orderedcode.Parse(string(key), &compositeKey, &height) 71 if err != nil { 72 return "", fmt.Errorf("failed to parse event key: %w", err) 73 } 74 75 if len(remaining) != 0 { 76 return "", fmt.Errorf("unexpected remainder in key: %s", remaining) 77 } 78 79 return strconv.FormatInt(height, 10), nil 80 } 81 82 func parseValueFromEventKey(key []byte) (string, error) { 83 var ( 84 compositeKey, typ, eventValue string 85 height int64 86 ) 87 88 _, err := orderedcode.Parse(string(key), &compositeKey, &eventValue, &height, &typ) 89 if err != nil { 90 return "", fmt.Errorf("failed to parse event key: %w", err) 91 } 92 93 return eventValue, nil 94 } 95 96 func parseHeightFromEventKey(key []byte) (int64, error) { 97 var ( 98 compositeKey, typ, eventValue string 99 height int64 100 ) 101 102 _, err := orderedcode.Parse(string(key), &compositeKey, &eventValue, &height, &typ) 103 if err != nil { 104 return -1, fmt.Errorf("failed to parse event key: %w", err) 105 } 106 107 return height, nil 108 } 109 110 func parseEventSeqFromEventKey(key []byte) (int64, error) { 111 var ( 112 compositeKey, typ, eventValue string 113 height int64 114 eventSeq int64 115 ) 116 117 remaining, err := orderedcode.Parse(string(key), &compositeKey, &eventValue, &height, &typ) 118 if err != nil { 119 return 0, fmt.Errorf("failed to parse event key: %w", err) 120 } 121 122 // This is done to support previous versions that did not have event sequence in their key 123 if len(remaining) != 0 { 124 remaining, err = orderedcode.Parse(remaining, &eventSeq) 125 if err != nil { 126 return 0, fmt.Errorf("failed to parse event key: %w", err) 127 } 128 if len(remaining) != 0 { 129 return 0, fmt.Errorf("unexpected remainder in key: %s", remaining) 130 } 131 } 132 133 return eventSeq, nil 134 } 135 136 // Remove all occurrences of height equality queries except one. While we are traversing the conditions, check whether the only condition in 137 // addition to match events is the height equality or height range query. At the same time, if we do have a height range condition 138 // ignore the height equality condition. If a height equality exists, place the condition index in the query and the desired height 139 // into the heightInfo struct 140 func dedupHeight(conditions []query.Condition) (dedupConditions []query.Condition, heightInfo HeightInfo, found bool) { 141 heightInfo.heightEqIdx = -1 142 heightRangeExists := false 143 var heightCondition []query.Condition 144 heightInfo.onlyHeightEq = true 145 heightInfo.onlyHeightRange = true 146 for _, c := range conditions { 147 if c.CompositeKey == types.BlockHeightKey { 148 if c.Op == query.OpEqual { 149 if found || heightRangeExists { 150 continue 151 } else { 152 heightCondition = append(heightCondition, c) 153 heightInfo.height = c.Operand.(*big.Int).Int64() // As height is assumed to always be int64 154 found = true 155 } 156 } else { 157 heightInfo.onlyHeightEq = false 158 heightRangeExists = true 159 dedupConditions = append(dedupConditions, c) 160 } 161 } else { 162 heightInfo.onlyHeightRange = false 163 heightInfo.onlyHeightEq = false 164 dedupConditions = append(dedupConditions, c) 165 } 166 } 167 if !heightRangeExists && len(heightCondition) != 0 { 168 heightInfo.heightEqIdx = len(dedupConditions) 169 heightInfo.onlyHeightRange = false 170 dedupConditions = append(dedupConditions, heightCondition...) 171 } else { 172 // If we found a range make sure we set the hegiht idx to -1 as the height equality 173 // will be removed 174 heightInfo.heightEqIdx = -1 175 heightInfo.height = 0 176 heightInfo.onlyHeightEq = false 177 found = false 178 } 179 return dedupConditions, heightInfo, found 180 } 181 182 func checkHeightConditions(heightInfo HeightInfo, keyHeight int64) bool { 183 if heightInfo.heightRange.Key != "" { 184 if !checkBounds(heightInfo.heightRange, big.NewInt(keyHeight)) { 185 return false 186 } 187 } else { 188 if heightInfo.height != 0 && keyHeight != heightInfo.height { 189 return false 190 } 191 } 192 return true 193 } 194 195 //nolint:unused,deadcode 196 func lookForHeight(conditions []query.Condition) (int64, bool, int) { 197 for i, c := range conditions { 198 if c.CompositeKey == types.BlockHeightKey && c.Op == query.OpEqual { 199 return c.Operand.(int64), true, i 200 } 201 } 202 203 return 0, false, -1 204 }