diff --git a/Makefile b/Makefile index 6a72834842..63a66b3f92 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ IGNORE_CHECK_GO=false install_rocksdb_version:=$(ROCKSDB_VERSION) -Version=v1.6.7.6 +Version=v1.6.7.7 CosmosSDK=v0.39.2 Tendermint=v0.33.9 Iavl=v0.14.3 diff --git a/libs/tendermint/state/txindex/kv/kv.go b/libs/tendermint/state/txindex/kv/kv.go index 42e1fbdc32..a8abcbfbba 100644 --- a/libs/tendermint/state/txindex/kv/kv.go +++ b/libs/tendermint/state/txindex/kv/kv.go @@ -21,6 +21,8 @@ import ( const ( tagKeySeparator = "/" + defaultTimeOut = 5 * time.Second + maxQueryRange = 256 ) var _ txindex.TxIndexer = (*TxIndex)(nil) @@ -227,12 +229,17 @@ func (txi *TxIndex) Search(ctx context.Context, q *query.Query) ([]*types.TxResu // if both upper and lower bounds exist, it's better to get them in order not // no iterate over kvs that are not within range. ranges, rangeIndexes := lookForRanges(conditions) + ctx, cancel := context.WithTimeout(ctx, defaultTimeOut) + defer cancel() if len(ranges) > 0 { skipIndexes = append(skipIndexes, rangeIndexes...) for _, r := range ranges { if !hashesInitialized { - filteredHashes = txi.matchRange(ctx, r, startKey(r.key), filteredHashes, true) + filteredHashes, err = txi.matchRange(ctx, r, startKey(r.key), filteredHashes, true) + if err != nil { + return []*types.TxResult{}, err + } hashesInitialized = true // Ignore any remaining conditions if the first condition resulted @@ -241,7 +248,16 @@ func (txi *TxIndex) Search(ctx context.Context, q *query.Query) ([]*types.TxResu break } } else { - filteredHashes = txi.matchRange(ctx, r, startKey(r.key), filteredHashes, false) + filteredHashes, err = txi.matchRange(ctx, r, startKey(r.key), filteredHashes, false) + if err != nil { + return []*types.TxResult{}, err + } + } + // Potentially exit early. + select { + case <-ctx.Done(): + return []*types.TxResult{}, errors.New("request processing timeout, optimize request filter conditions parameter") + default: } } } @@ -511,11 +527,11 @@ func (txi *TxIndex) matchRange( startKey []byte, filteredHashes map[string][]byte, firstRun bool, -) map[string][]byte { +) (map[string][]byte, error) { // A previous match was attempted but resulted in no matches, so we return // no matches (assuming AND operand). if !firstRun && len(filteredHashes) == 0 { - return filteredHashes + return filteredHashes, nil } tmpHashes := make(map[string][]byte) @@ -527,13 +543,22 @@ func (txi *TxIndex) matchRange( panic(err) } defer it.Close() - + count := 0 LOOP: for ; it.Valid(); it.Next() { + if count > maxQueryRange { + return nil, errors.New("request processing more than max query range, optimize request filter conditions parameter") + } + count++ + // Potentially exit early. + select { + case <-ctx.Done(): + return nil, errors.New("request processing timeout, optimize request filter conditions parameter") + default: + } if !isTagKey(it.Key()) { continue } - if _, ok := r.AnyBound().(int64); ok { v, err := strconv.ParseInt(extractValueFromKey(it.Key()), 10, 64) if err != nil { @@ -561,12 +586,7 @@ LOOP: // } } - // Potentially exit early. - select { - case <-ctx.Done(): - break - default: - } + } if len(tmpHashes) == 0 || firstRun { @@ -577,7 +597,7 @@ LOOP: // return no matches (assuming AND operand). // // 2. A previous match was not attempted, so we return all results. - return tmpHashes + return tmpHashes, nil } // Remove/reduce matches in filteredHashes that were not found in this @@ -595,7 +615,7 @@ LOOP: } } - return filteredHashes + return filteredHashes, nil } ///////////////////////////////////////////////////////////////////////////////