diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 30303008a..844dc8696 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -40,3 +40,4 @@ IMPROVEMENTS: BUG FIXES: - [mempool] No longer possible to fill up linked list without getting caching benefits [#2180](https://github.com/tendermint/tendermint/issues/2180) +- [state] kv store index tx.height to support search diff --git a/state/txindex/kv/kv.go b/state/txindex/kv/kv.go index 707325929..363ab1193 100644 --- a/state/txindex/kv/kv.go +++ b/state/txindex/kv/kv.go @@ -89,6 +89,11 @@ func (txi *TxIndex) AddBatch(b *txindex.Batch) error { } } + // index tx by height + if txi.indexAllTags || cmn.StringInSlice(types.TxHeightKey, txi.tagsToIndex) { + storeBatch.Set(keyForHeight(result), hash) + } + // index tx by hash rawBytes, err := cdc.MarshalBinaryBare(result) if err != nil { @@ -114,6 +119,11 @@ func (txi *TxIndex) Index(result *types.TxResult) error { } } + // index tx by height + if txi.indexAllTags || cmn.StringInSlice(types.TxHeightKey, txi.tagsToIndex) { + b.Set(keyForHeight(result), hash) + } + // index tx by hash rawBytes, err := cdc.MarshalBinaryBare(result) if err != nil { @@ -153,12 +163,6 @@ func (txi *TxIndex) Search(q *query.Query) ([]*types.TxResult, error) { // conditions to skip because they're handled before "everything else" skipIndexes := make([]int, 0) - // if there is a height condition ("tx.height=3"), extract it for faster lookups - height, heightIndex := lookForHeight(conditions) - if heightIndex >= 0 { - skipIndexes = append(skipIndexes, heightIndex) - } - // extract ranges // 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. @@ -176,6 +180,9 @@ func (txi *TxIndex) Search(q *query.Query) ([]*types.TxResult, error) { } } + // if there is a height condition ("tx.height=3"), extract it + height := lookForHeight(conditions) + // for all other conditions for i, c := range conditions { if cmn.IntInSlice(i, skipIndexes) { @@ -218,13 +225,13 @@ func lookForHash(conditions []query.Condition) (hash []byte, err error, ok bool) return } -func lookForHeight(conditions []query.Condition) (height int64, index int) { - for i, c := range conditions { +func lookForHeight(conditions []query.Condition) (height int64) { + for _, c := range conditions { if c.Tag == types.TxHeightKey { - return c.Operand.(int64), i + return c.Operand.(int64) } } - return 0, -1 + return 0 } // special map to hold range conditions @@ -421,6 +428,10 @@ func keyForTag(tag cmn.KVPair, result *types.TxResult) []byte { return []byte(fmt.Sprintf("%s/%s/%d/%d", tag.Key, tag.Value, result.Height, result.Index)) } +func keyForHeight(result *types.TxResult) []byte { + return []byte(fmt.Sprintf("%s/%d/%d/%d", types.TxHeightKey, result.Height, result.Height, result.Index)) +} + /////////////////////////////////////////////////////////////////////////////// // Utils