github.com/badrootd/celestia-core@v0.0.0-20240305091328-aa4207a4b25d/state/txindex/kv/utils.go (about)

     1  package kv
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/badrootd/celestia-core/libs/pubsub/query"
     7  	"github.com/badrootd/celestia-core/state/indexer"
     8  	"github.com/badrootd/celestia-core/types"
     9  	"github.com/google/orderedcode"
    10  )
    11  
    12  type HeightInfo struct {
    13  	heightRange     indexer.QueryRange
    14  	height          int64
    15  	heightEqIdx     int
    16  	onlyHeightRange bool
    17  	onlyHeightEq    bool
    18  }
    19  
    20  // IntInSlice returns true if a is found in the list.
    21  func intInSlice(a int, list []int) bool {
    22  	for _, b := range list {
    23  		if b == a {
    24  			return true
    25  		}
    26  	}
    27  	return false
    28  }
    29  
    30  func dedupMatchEvents(conditions []query.Condition) ([]query.Condition, bool) {
    31  	var dedupConditions []query.Condition
    32  	matchEvents := false
    33  	for i, c := range conditions {
    34  		if c.CompositeKey == types.MatchEventKey {
    35  			// Match events should be added only via RPC as the very first query condition
    36  			if i == 0 && c.Op == query.OpEqual && c.Operand.(int64) == 1 {
    37  				dedupConditions = append(dedupConditions, c)
    38  				matchEvents = true
    39  			}
    40  		} else {
    41  			dedupConditions = append(dedupConditions, c)
    42  		}
    43  
    44  	}
    45  	return dedupConditions, matchEvents
    46  }
    47  
    48  func ParseEventSeqFromEventKey(key []byte) (int64, error) {
    49  	var (
    50  		compositeKey, typ, eventValue string
    51  		height                        int64
    52  		eventSeq                      int64
    53  	)
    54  
    55  	remaining, err := orderedcode.Parse(string(key), &compositeKey, &eventValue, &height, &typ, &eventSeq)
    56  	if err != nil {
    57  		return 0, fmt.Errorf("failed to parse event key: %w", err)
    58  	}
    59  
    60  	if len(remaining) != 0 {
    61  		return 0, fmt.Errorf("unexpected remainder in key: %s", remaining)
    62  	}
    63  
    64  	return eventSeq, nil
    65  }
    66  
    67  func dedupHeight(conditions []query.Condition) (dedupConditions []query.Condition, heightInfo HeightInfo) {
    68  	heightInfo.heightEqIdx = -1
    69  	found := false
    70  	heightRangeExists := false
    71  	var heightCondition []query.Condition
    72  	heightInfo.onlyHeightEq = true
    73  	heightInfo.onlyHeightRange = true
    74  	for _, c := range conditions {
    75  		if c.CompositeKey == types.TxHeightKey {
    76  			if c.Op == query.OpEqual {
    77  				if heightRangeExists || found {
    78  					continue
    79  				} else {
    80  					found = true
    81  					heightCondition = append(heightCondition, c)
    82  					heightInfo.height = c.Operand.(int64)
    83  				}
    84  			} else {
    85  				heightInfo.onlyHeightEq = false
    86  				heightRangeExists = true
    87  				dedupConditions = append(dedupConditions, c)
    88  			}
    89  		} else {
    90  			if c.CompositeKey != types.MatchEventKey {
    91  				heightInfo.onlyHeightRange = false
    92  				heightInfo.onlyHeightEq = false
    93  			}
    94  			dedupConditions = append(dedupConditions, c)
    95  		}
    96  	}
    97  	if !heightRangeExists && len(heightCondition) != 0 {
    98  		heightInfo.heightEqIdx = len(dedupConditions)
    99  		heightInfo.onlyHeightRange = false
   100  		dedupConditions = append(dedupConditions, heightCondition...)
   101  	} else {
   102  		// If we found a range make sure we set the height idx to -1 as the height equality
   103  		// will be removed
   104  		heightInfo.heightEqIdx = -1
   105  		heightInfo.height = 0
   106  		heightInfo.onlyHeightEq = false
   107  	}
   108  	return dedupConditions, heightInfo
   109  }
   110  
   111  func checkHeightConditions(heightInfo HeightInfo, keyHeight int64) bool {
   112  	if heightInfo.heightRange.Key != "" {
   113  		if !checkBounds(heightInfo.heightRange, keyHeight) {
   114  			return false
   115  		}
   116  	} else {
   117  		if heightInfo.height != 0 && keyHeight != heightInfo.height {
   118  			return false
   119  		}
   120  	}
   121  	return true
   122  }