diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 30b253fbe..4324412aa 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -55,6 +55,8 @@ program](https://hackerone.com/tendermint). ``` - ID is unique for each request; - Request.ID is now optional. Notification is a Request without an ID. Previously ID="" or ID=0 were considered as notifications. + - [config] \#4046 Rename tag(s) to CompositeKey & places where tag is still present it was renamed to event or events. Find how a compositeKey is constructed [here](https://github.com/tendermint/tendermint/blob/6d05c531f7efef6f0619155cf10ae8557dd7832f/docs/app-dev/indexing-transactions.md) + - You will have to generate a new config for your Tendermint node(s) - Apps @@ -98,7 +100,7 @@ program](https://hackerone.com/tendermint). ### BUG FIXES: -- [rpc/lib] [\#4051](https://github.com/tendermint/tendermint/pull/4131) Fix RPC client, which was previously resolving https protocol to http (@yenkhoon) +- [rpc/lib][\#4051](https://github.com/tendermint/tendermint/pull/4131) Fix RPC client, which was previously resolving https protocol to http (@yenkhoon) - [rpc] [\#4141](https://github.com/tendermint/tendermint/pull/4141) JSONRPCClient: validate that Response.ID matches Request.ID - [rpc] [\#4141](https://github.com/tendermint/tendermint/pull/4141) WSClient: check for unsolicited responses - [types] [\4164](https://github.com/tendermint/tendermint/pull/4164) Prevent temporary power overflows on validator updates diff --git a/config/config.go b/config/config.go index 8efc41b98..2b33c580b 100644 --- a/config/config.go +++ b/config/config.go @@ -883,9 +883,15 @@ func (cfg *ConsensusConfig) ValidateBasic() error { //----------------------------------------------------------------------------- // TxIndexConfig - +// Remember that Event has the following structure: +// type: [ +// key: value, +// ... +// ] +// +// CompositeKeys are constructed by `type.key` // TxIndexConfig defines the configuration for the transaction indexer, -// including tags to index. +// including composite keys to index. type TxIndexConfig struct { // What indexer to use for transactions // @@ -895,30 +901,30 @@ type TxIndexConfig struct { // backed by key-value storage (defaults to levelDB; see DBBackend). Indexer string `mapstructure:"indexer"` - // Comma-separated list of tags to index (by default the only tag is "tx.hash") + // Comma-separated list of compositeKeys to index (by default the only key is "tx.hash") // - // You can also index transactions by height by adding "tx.height" tag here. + // You can also index transactions by height by adding "tx.height" key here. // - // It's recommended to index only a subset of tags due to possible memory + // It's recommended to index only a subset of keys due to possible memory // bloat. This is, of course, depends on the indexer's DB and the volume of // transactions. - IndexTags string `mapstructure:"index_tags"` + IndexKeys string `mapstructure:"index_keys"` - // When set to true, tells indexer to index all tags (predefined tags: - // "tx.hash", "tx.height" and all tags from DeliverTx responses). + // When set to true, tells indexer to index all compositeKeys (predefined keys: + // "tx.hash", "tx.height" and all keys from DeliverTx responses). // - // Note this may be not desirable (see the comment above). IndexTags has a - // precedence over IndexAllTags (i.e. when given both, IndexTags will be + // Note this may be not desirable (see the comment above). IndexKeys has a + // precedence over IndexAllKeys (i.e. when given both, IndexKeys will be // indexed). - IndexAllTags bool `mapstructure:"index_all_tags"` + IndexAllKeys bool `mapstructure:"index_all_keys"` } // DefaultTxIndexConfig returns a default configuration for the transaction indexer. func DefaultTxIndexConfig() *TxIndexConfig { return &TxIndexConfig{ Indexer: "kv", - IndexTags: "", - IndexAllTags: false, + IndexKeys: "", + IndexAllKeys: false, } } diff --git a/config/toml.go b/config/toml.go index a6599ff57..223991438 100644 --- a/config/toml.go +++ b/config/toml.go @@ -353,22 +353,27 @@ peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}" # 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). indexer = "{{ .TxIndex.Indexer }}" -# Comma-separated list of tags to index (by default the only tag is "tx.hash") +# Comma-separated list of compositeKeys to index (by default the only key is "tx.hash") +# Remember that Event has the following structure: type.key +# type: [ +# key: value, +# ... +# ] # -# You can also index transactions by height by adding "tx.height" tag here. +# You can also index transactions by height by adding "tx.height" key here. # -# It's recommended to index only a subset of tags due to possible memory +# It's recommended to index only a subset of keys due to possible memory # bloat. This is, of course, depends on the indexer's DB and the volume of # transactions. -index_tags = "{{ .TxIndex.IndexTags }}" +index_keys = "{{ .TxIndex.IndexKeys }}" -# When set to true, tells indexer to index all tags (predefined tags: -# "tx.hash", "tx.height" and all tags from DeliverTx responses). +# When set to true, tells indexer to index all compositeKeys (predefined keys: +# "tx.hash", "tx.height" and all keys from DeliverTx responses). # -# Note this may be not desirable (see the comment above). IndexTags has a -# precedence over IndexAllTags (i.e. when given both, IndexTags will be +# Note this may be not desirable (see the comment above). IndexKeys has a +# precedence over IndexAllKeys (i.e. when given both, IndexKeys will be # indexed). -index_all_tags = {{ .TxIndex.IndexAllTags }} +index_all_keys = {{ .TxIndex.IndexAllKeys }} ##### instrumentation configuration options ##### [instrumentation] diff --git a/docs/app-dev/indexing-transactions.md b/docs/app-dev/indexing-transactions.md index 55fb014c3..31ff737e1 100644 --- a/docs/app-dev/indexing-transactions.md +++ b/docs/app-dev/indexing-transactions.md @@ -10,12 +10,23 @@ to their results. Events can be used to index transactions and blocks according to what happened during their execution. Note that the set of events returned for a block from `BeginBlock` and `EndBlock` are merged. In case both methods return the same -tag, only the value defined in `EndBlock` is used. +type, only the key-value pairs defined in `EndBlock` are used. Each event contains a type and a list of attributes, which are key-value pairs denoting something about what happened during the method's execution. For more details on `Events`, see the [ABCI](../spec/abci/abci.md) documentation. +An Event has a composite key associated with it. A `compositeKey` is constructed by its type and key separated by a dot. +For example: + +```json +"jack": [ + "account.number": 100 +] +``` + +would be equal to the composite key of `jack.account.number`. + Let's take a look at the `[tx_index]` config section: ```toml @@ -29,22 +40,22 @@ Let's take a look at the `[tx_index]` config section: # 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). indexer = "kv" -# Comma-separated list of tags to index (by default the only tag is "tx.hash") +# Comma-separated list of composite keys to index (by default the only key is "tx.hash") # -# You can also index transactions by height by adding "tx.height" tag here. +# You can also index transactions by height by adding "tx.height" key here. # -# It's recommended to index only a subset of tags due to possible memory +# It's recommended to index only a subset of keys due to possible memory # bloat. This is, of course, depends on the indexer's DB and the volume of # transactions. -index_tags = "" +index_keys = "" -# When set to true, tells indexer to index all tags (predefined tags: -# "tx.hash", "tx.height" and all tags from DeliverTx responses). +# When set to true, tells indexer to index all compositeKeys (predefined keys: +# "tx.hash", "tx.height" and all keys from DeliverTx responses). # -# Note this may be not desirable (see the comment above). IndexTags has a -# precedence over IndexAllTags (i.e. when given both, IndexTags will be +# Note this may be not desirable (see the comment above). Indexkeys has a +# precedence over IndexAllKeys (i.e. when given both, IndexKeys will be # indexed). -index_all_tags = false +index_all_keys = false ``` By default, Tendermint will index all transactions by their respective @@ -100,17 +111,17 @@ on query syntax and other options. ## Subscribing to Transactions -Clients can subscribe to transactions with the given tags via Websocket by providing +Clients can subscribe to transactions with the given tags via WebSocket by providing a query to `/subscribe` RPC endpoint. ```json { - "jsonrpc": "2.0", - "method": "subscribe", - "id": "0", - "params": { - "query": "account.name='igor'" - } + "jsonrpc": "2.0", + "method": "subscribe", + "id": "0", + "params": { + "query": "account.name='igor'" + } } ``` diff --git a/docs/tendermint-core/configuration.md b/docs/tendermint-core/configuration.md index ac2b2e09e..de6a86230 100644 --- a/docs/tendermint-core/configuration.md +++ b/docs/tendermint-core/configuration.md @@ -6,8 +6,7 @@ order: 3 Tendermint Core can be configured via a TOML file in `$TMHOME/config/config.toml`. Some of these parameters can be overridden by -command-line flags. For most users, the options in the `##### main base -configuration options #####` are intended to be modified while config options +command-line flags. For most users, the options in the `##### main base configuration options #####` are intended to be modified while config options further below are intended for advance power users. ## Options @@ -299,22 +298,27 @@ blocktime_iota = "1s" # 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). indexer = "kv" -# Comma-separated list of tags to index (by default the only tag is "tx.hash") +# Comma-separated list of compositeKeys to index (by default the only key is "tx.hash") +# Remember that Event has the following structure: type.key +# type: [ +# key: value, +# ... +# ] # -# You can also index transactions by height by adding "tx.height" tag here. +# You can also index transactions by height by adding "tx.height" event here. # -# It's recommended to index only a subset of tags due to possible memory +# It's recommended to index only a subset of keys due to possible memory # bloat. This is, of course, depends on the indexer's DB and the volume of # transactions. -index_tags = "" +index_keys = "" -# When set to true, tells indexer to index all tags (predefined tags: -# "tx.hash", "tx.height" and all tags from DeliverTx responses). +# When set to true, tells indexer to index all compositeKeys (predefined keys: +# "tx.hash", "tx.height" and all keys from DeliverTx responses). # -# Note this may be not desirable (see the comment above). IndexTags has a -# precedence over IndexAllTags (i.e. when given both, IndexTags will be +# Note this may be not desirable (see the comment above). IndexEvents has a +# precedence over IndexAllEvents (i.e. when given both, IndexEvents will be # indexed). -index_all_tags = false +index_all_keys = false ##### instrumentation configuration options ##### [instrumentation] diff --git a/docs/tendermint-core/running-in-production.md b/docs/tendermint-core/running-in-production.md index bc6fc7b3d..f1954cbea 100644 --- a/docs/tendermint-core/running-in-production.md +++ b/docs/tendermint-core/running-in-production.md @@ -21,10 +21,10 @@ Tendermint keeps multiple distinct databases in the `$TMROOT/data`: - `state.db`: Stores the current blockchain state (ie. height, validators, consensus params). Only grows if consensus params or validators change. Also used to temporarily store intermediate results during block processing. -- `tx_index.db`: Indexes txs (and their results) by tx hash and by DeliverTx result tags. +- `tx_index.db`: Indexes txs (and their results) by tx hash and by DeliverTx result events. By default, Tendermint will only index txs by their hash, not by their DeliverTx -result tags. See [indexing transactions](../app-dev/indexing-transactions.md) for +result events. See [indexing transactions](../app-dev/indexing-transactions.md) for details. There is no current strategy for pruning the databases. Consider reducing diff --git a/libs/pubsub/query/empty.go b/libs/pubsub/query/empty.go index 2c0d00095..b86b8d4e8 100644 --- a/libs/pubsub/query/empty.go +++ b/libs/pubsub/query/empty.go @@ -1,6 +1,6 @@ package query -// Empty query matches any set of tags. +// Empty query matches any set of events. type Empty struct { } diff --git a/libs/pubsub/query/query.go b/libs/pubsub/query/query.go index f59cb3904..247653394 100644 --- a/libs/pubsub/query/query.go +++ b/libs/pubsub/query/query.go @@ -29,12 +29,12 @@ type Query struct { parser *QueryParser } -// Condition represents a single condition within a query and consists of tag +// Condition represents a single condition within a query and consists of composite key // (e.g. "tx.gas"), operator (e.g. "=") and operand (e.g. "7"). type Condition struct { - Tag string - Op Operator - Operand interface{} + CompositeKey string + Op Operator + Operand interface{} } // New parses the given string and returns a query or error if the string is @@ -63,7 +63,7 @@ func (q *Query) String() string { return q.str } -// Operator is an operator that defines some kind of relation between tag and +// Operator is an operator that defines some kind of relation between composite key and // operand (equality, etc.). type Operator uint8 @@ -399,7 +399,7 @@ func matchValue(value string, op Operator, operand reflect.Value) (bool, error) case reflect.Struct: // time operandAsTime := operand.Interface().(time.Time) - // try our best to convert value from tags to time.Time + // try our best to convert value from events to time.Time var ( v time.Time err error diff --git a/libs/pubsub/query/query_test.go b/libs/pubsub/query/query_test.go index 07586eab8..d511e7fab 100644 --- a/libs/pubsub/query/query_test.go +++ b/libs/pubsub/query/query_test.go @@ -187,26 +187,26 @@ func TestConditions(t *testing.T) { { s: "tm.events.type='NewBlock'", conditions: []query.Condition{ - {Tag: "tm.events.type", Op: query.OpEqual, Operand: "NewBlock"}, + {CompositeKey: "tm.events.type", Op: query.OpEqual, Operand: "NewBlock"}, }, }, { s: "tx.gas > 7 AND tx.gas < 9", conditions: []query.Condition{ - {Tag: "tx.gas", Op: query.OpGreater, Operand: int64(7)}, - {Tag: "tx.gas", Op: query.OpLess, Operand: int64(9)}, + {CompositeKey: "tx.gas", Op: query.OpGreater, Operand: int64(7)}, + {CompositeKey: "tx.gas", Op: query.OpLess, Operand: int64(9)}, }, }, { s: "tx.time >= TIME 2013-05-03T14:45:00Z", conditions: []query.Condition{ - {Tag: "tx.time", Op: query.OpGreaterEqual, Operand: txTime}, + {CompositeKey: "tx.time", Op: query.OpGreaterEqual, Operand: txTime}, }, }, { s: "slashing EXISTS", conditions: []query.Condition{ - {Tag: "slashing", Op: query.OpExists}, + {CompositeKey: "slashing", Op: query.OpExists}, }, }, } diff --git a/libs/pubsub/subscription.go b/libs/pubsub/subscription.go index 40c97c9ee..cf3923584 100644 --- a/libs/pubsub/subscription.go +++ b/libs/pubsub/subscription.go @@ -16,7 +16,7 @@ var ( // A Subscription represents a client subscription for a particular query and // consists of three things: -// 1) channel onto which messages and tags are published +// 1) channel onto which messages and events are published // 2) channel which is closed if a client is too slow or choose to unsubscribe // 3) err indicating the reason for (2) type Subscription struct { @@ -35,7 +35,7 @@ func NewSubscription(outCapacity int) *Subscription { } } -// Out returns a channel onto which messages and tags are published. +// Out returns a channel onto which messages and events are published. // Unsubscribe/UnsubscribeAll does not close the channel to avoid clients from // receiving a nil message. func (s *Subscription) Out() <-chan Message { @@ -68,7 +68,7 @@ func (s *Subscription) cancel(err error) { close(s.cancelled) } -// Message glues data and tags together. +// Message glues data and events together. type Message struct { data interface{} events map[string][]string diff --git a/node/node.go b/node/node.go index eb81d5b0a..ffb94baf5 100644 --- a/node/node.go +++ b/node/node.go @@ -247,10 +247,10 @@ func createAndStartIndexerService(config *cfg.Config, dbProvider DBProvider, return nil, nil, err } switch { - case config.TxIndex.IndexTags != "": - txIndexer = kv.NewTxIndex(store, kv.IndexTags(splitAndTrimEmpty(config.TxIndex.IndexTags, ",", " "))) - case config.TxIndex.IndexAllTags: - txIndexer = kv.NewTxIndex(store, kv.IndexAllTags()) + case config.TxIndex.IndexKeys != "": + txIndexer = kv.NewTxIndex(store, kv.IndexEvents(splitAndTrimEmpty(config.TxIndex.IndexKeys, ",", " "))) + case config.TxIndex.IndexAllKeys: + txIndexer = kv.NewTxIndex(store, kv.IndexAllEvents()) default: txIndexer = kv.NewTxIndex(store) } diff --git a/rpc/client/rpc_test.go b/rpc/client/rpc_test.go index 6a7a802e2..50aa25209 100644 --- a/rpc/client/rpc_test.go +++ b/rpc/client/rpc_test.go @@ -452,14 +452,14 @@ func TestTxSearch(t *testing.T) { require.Nil(t, err, "%+v", err) require.Len(t, result.Txs, 0) - // query using a tag (see kvstore application) + // query using a compositeKey (see kvstore application) result, err = c.TxSearch("app.creator='Cosmoshi Netowoko'", false, 1, 30) require.Nil(t, err, "%+v", err) if len(result.Txs) == 0 { t.Fatal("expected a lot of transactions") } - // query using a tag (see kvstore application) and height + // query using a compositeKey (see kvstore application) and height result, err = c.TxSearch("app.creator='Cosmoshi Netowoko' AND tx.height<10000", true, 1, 30) require.Nil(t, err, "%+v", err) if len(result.Txs) == 0 { diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index 033015d11..a7df7994a 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -97,7 +97,7 @@ func createConfig() *cfg.Config { c.RPC.ListenAddress = rpc c.RPC.CORSAllowedOrigins = []string{"https://tendermint.com/"} c.RPC.GRPCListenAddress = grpc - c.TxIndex.IndexTags = "app.creator,tx.height" // see kvstore application + c.TxIndex.IndexKeys = "app.creator,tx.height" // see kvstore application return c } diff --git a/state/txindex/indexer_service.go b/state/txindex/indexer_service.go index 92bcf0639..e1c424734 100644 --- a/state/txindex/indexer_service.go +++ b/state/txindex/indexer_service.go @@ -29,7 +29,7 @@ func NewIndexerService(idr TxIndexer, eventBus *types.EventBus) *IndexerService } // OnStart implements cmn.Service by subscribing for all transactions -// and indexing them by tags. +// and indexing them by events. func (is *IndexerService) OnStart() error { // Use SubscribeUnbuffered here to ensure both subscriptions does not get // cancelled due to not pulling messages fast enough. Cause this might diff --git a/state/txindex/indexer_service_test.go b/state/txindex/indexer_service_test.go index cbb2a4161..6df7c984a 100644 --- a/state/txindex/indexer_service_test.go +++ b/state/txindex/indexer_service_test.go @@ -25,7 +25,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) { // tx indexer store := db.NewMemDB() - txIndexer := kv.NewTxIndex(store, kv.IndexAllTags()) + txIndexer := kv.NewTxIndex(store, kv.IndexAllEvents()) service := txindex.NewIndexerService(txIndexer, eventBus) service.SetLogger(log.TestingLogger()) diff --git a/state/txindex/kv/kv.go b/state/txindex/kv/kv.go index f7dce3348..5b8d82f87 100644 --- a/state/txindex/kv/kv.go +++ b/state/txindex/kv/kv.go @@ -27,31 +27,31 @@ var _ txindex.TxIndexer = (*TxIndex)(nil) // TxIndex is the simplest possible indexer, backed by key-value storage (levelDB). type TxIndex struct { - store dbm.DB - tagsToIndex []string - indexAllTags bool + store dbm.DB + compositeKeysToIndex []string + indexAllEvents bool } // NewTxIndex creates new KV indexer. func NewTxIndex(store dbm.DB, options ...func(*TxIndex)) *TxIndex { - txi := &TxIndex{store: store, tagsToIndex: make([]string, 0), indexAllTags: false} + txi := &TxIndex{store: store, compositeKeysToIndex: make([]string, 0), indexAllEvents: false} for _, o := range options { o(txi) } return txi } -// IndexTags is an option for setting which tags to index. -func IndexTags(tags []string) func(*TxIndex) { +// IndexEvents is an option for setting which composite keys to index. +func IndexEvents(compositeKeys []string) func(*TxIndex) { return func(txi *TxIndex) { - txi.tagsToIndex = tags + txi.compositeKeysToIndex = compositeKeys } } -// IndexAllTags is an option for indexing all tags. -func IndexAllTags() func(*TxIndex) { +// IndexAllEvents is an option for indexing all events. +func IndexAllEvents() func(*TxIndex) { return func(txi *TxIndex) { - txi.indexAllTags = true + txi.indexAllEvents = true } } @@ -91,7 +91,7 @@ func (txi *TxIndex) AddBatch(b *txindex.Batch) error { txi.indexEvents(result, hash, storeBatch) // index tx by height - if txi.indexAllTags || cmn.StringInSlice(types.TxHeightKey, txi.tagsToIndex) { + if txi.indexAllEvents || cmn.StringInSlice(types.TxHeightKey, txi.compositeKeysToIndex) { storeBatch.Set(keyForHeight(result), hash) } @@ -121,7 +121,7 @@ func (txi *TxIndex) Index(result *types.TxResult) error { txi.indexEvents(result, hash, b) // index tx by height - if txi.indexAllTags || cmn.StringInSlice(types.TxHeightKey, txi.tagsToIndex) { + if txi.indexAllEvents || cmn.StringInSlice(types.TxHeightKey, txi.compositeKeysToIndex) { b.Set(keyForHeight(result), hash) } @@ -150,7 +150,7 @@ func (txi *TxIndex) indexEvents(result *types.TxResult, hash []byte, store dbm.S } compositeTag := fmt.Sprintf("%s.%s", event.Type, string(attr.Key)) - if txi.indexAllTags || cmn.StringInSlice(compositeTag, txi.tagsToIndex) { + if txi.indexAllEvents || cmn.StringInSlice(compositeTag, txi.compositeKeysToIndex) { store.Set(keyForEvent(compositeTag, attr.Value, result), hash) } } @@ -260,7 +260,7 @@ func (txi *TxIndex) Search(q *query.Query) ([]*types.TxResult, error) { func lookForHash(conditions []query.Condition) (hash []byte, ok bool, err error) { for _, c := range conditions { - if c.Tag == types.TxHashKey { + if c.CompositeKey == types.TxHashKey { decoded, err := hex.DecodeString(c.Operand.(string)) return decoded, true, err } @@ -271,7 +271,7 @@ func lookForHash(conditions []query.Condition) (hash []byte, ok bool, err error) // lookForHeight returns a height if there is an "height=X" condition. func lookForHeight(conditions []query.Condition) (height int64) { for _, c := range conditions { - if c.Tag == types.TxHeightKey && c.Op == query.OpEqual { + if c.CompositeKey == types.TxHeightKey && c.Op == query.OpEqual { return c.Operand.(int64) } } @@ -340,9 +340,9 @@ func lookForRanges(conditions []query.Condition) (ranges queryRanges, indexes [] ranges = make(queryRanges) for i, c := range conditions { if isRangeOperation(c.Op) { - r, ok := ranges[c.Tag] + r, ok := ranges[c.CompositeKey] if !ok { - r = queryRange{key: c.Tag} + r = queryRange{key: c.CompositeKey} } switch c.Op { case query.OpGreater: @@ -356,7 +356,7 @@ func lookForRanges(conditions []query.Condition) (ranges queryRanges, indexes [] r.includeUpperBound = true r.upperBound = c.Operand } - ranges[c.Tag] = r + ranges[c.CompositeKey] = r indexes = append(indexes, i) } } @@ -404,7 +404,7 @@ func (txi *TxIndex) match( // XXX: startKey does not apply here. // For example, if startKey = "account.owner/an/" and search query = "account.owner CONTAINS an" // we can't iterate with prefix "account.owner/an/" because we might miss keys like "account.owner/Ulan/" - it := dbm.IteratePrefix(txi.store, startKey(c.Tag)) + it := dbm.IteratePrefix(txi.store, startKey(c.CompositeKey)) defer it.Close() for ; it.Valid(); it.Next() { @@ -491,7 +491,7 @@ LOOP: tmpHashes[string(it.Value())] = it.Value() } - // XXX: passing time in a ABCI Tags is not yet implemented + // XXX: passing time in a ABCI Events is not yet implemented // case time.Time: // v := strconv.ParseInt(extractValueFromKey(it.Key()), 10, 64) // if v == r.upperBound { @@ -554,9 +554,9 @@ func keyForHeight(result *types.TxResult) []byte { func startKeyForCondition(c query.Condition, height int64) []byte { if height > 0 { - return startKey(c.Tag, c.Operand, height) + return startKey(c.CompositeKey, c.Operand, height) } - return startKey(c.Tag, c.Operand) + return startKey(c.CompositeKey, c.Operand) } func startKey(fields ...interface{}) []byte { diff --git a/state/txindex/kv/kv_bench_test.go b/state/txindex/kv/kv_bench_test.go index 9c3442a01..834cf52e7 100644 --- a/state/txindex/kv/kv_bench_test.go +++ b/state/txindex/kv/kv_bench_test.go @@ -24,8 +24,8 @@ func BenchmarkTxSearch(b *testing.B) { b.Errorf("failed to create database: %s", err) } - allowedTags := []string{"transfer.address", "transfer.amount"} - indexer := NewTxIndex(db, IndexTags(allowedTags)) + allowedKeys := []string{"transfer.address", "transfer.amount"} + indexer := NewTxIndex(db, IndexEvents(allowedKeys)) for i := 0; i < 35000; i++ { events := []abci.Event{ diff --git a/state/txindex/kv/kv_test.go b/state/txindex/kv/kv_test.go index 189a9da61..4da251062 100644 --- a/state/txindex/kv/kv_test.go +++ b/state/txindex/kv/kv_test.go @@ -65,8 +65,8 @@ func TestTxIndex(t *testing.T) { } func TestTxSearch(t *testing.T) { - allowedTags := []string{"account.number", "account.owner", "account.date"} - indexer := NewTxIndex(db.NewMemDB(), IndexTags(allowedTags)) + allowedKeys := []string{"account.number", "account.owner", "account.date"} + indexer := NewTxIndex(db.NewMemDB(), IndexEvents(allowedKeys)) txResult := txResultWithEvents([]abci.Event{ {Type: "account", Attributes: []cmn.KVPair{{Key: []byte("number"), Value: []byte("1")}}}, @@ -84,11 +84,11 @@ func TestTxSearch(t *testing.T) { }{ // search by hash {fmt.Sprintf("tx.hash = '%X'", hash), 1}, - // search by exact match (one tag) + // search by exact match (one key) {"account.number = 1", 1}, - // search by exact match (two tags) + // search by exact match (two keys) {"account.number = 1 AND account.owner = 'Ivan'", 1}, - // search by exact match (two tags) + // search by exact match (two keys) {"account.number = 1 AND account.owner = 'Vlad'", 0}, {"account.owner = 'Vlad' AND account.number = 1", 0}, {"account.number >= 1 AND account.owner = 'Vlad'", 0}, @@ -103,17 +103,17 @@ func TestTxSearch(t *testing.T) { {"account.number >= 1", 1}, // search by range (upper bound) {"account.number <= 5", 1}, - // search using not allowed tag + // search using not allowed key {"not_allowed = 'boom'", 0}, // search for not existing tx result {"account.number >= 2 AND account.number <= 5", 0}, - // search using not existing tag + // search using not existing key {"account.date >= TIME 2013-05-03T14:45:00Z", 0}, // search using CONTAINS {"account.owner CONTAINS 'an'", 1}, // search for non existing value using CONTAINS {"account.owner CONTAINS 'Vlad'", 0}, - // search using the wrong tag (of numeric type) using CONTAINS + // search using the wrong key (of numeric type) using CONTAINS {"account.number CONTAINS 'Iv'", 0}, } @@ -132,8 +132,8 @@ func TestTxSearch(t *testing.T) { } func TestTxSearchDeprecatedIndexing(t *testing.T) { - allowedTags := []string{"account.number", "sender"} - indexer := NewTxIndex(db.NewMemDB(), IndexTags(allowedTags)) + allowedKeys := []string{"account.number", "sender"} + indexer := NewTxIndex(db.NewMemDB(), IndexEvents(allowedKeys)) // index tx using events indexing (composite key) txResult1 := txResultWithEvents([]abci.Event{ @@ -144,7 +144,7 @@ func TestTxSearchDeprecatedIndexing(t *testing.T) { err := indexer.Index(txResult1) require.NoError(t, err) - // index tx also using deprecated indexing (tag as key) + // index tx also using deprecated indexing (event as key) txResult2 := txResultWithEvents(nil) txResult2.Tx = types.Tx("HELLO WORLD 2") @@ -174,20 +174,20 @@ func TestTxSearchDeprecatedIndexing(t *testing.T) { {fmt.Sprintf("tx.hash = '%X'", hash1), []*types.TxResult{txResult1}}, // search by hash {fmt.Sprintf("tx.hash = '%X'", hash2), []*types.TxResult{txResult2}}, - // search by exact match (one tag) + // search by exact match (one key) {"account.number = 1", []*types.TxResult{txResult1}}, {"account.number >= 1 AND account.number <= 5", []*types.TxResult{txResult1}}, // search by range (lower bound) {"account.number >= 1", []*types.TxResult{txResult1}}, // search by range (upper bound) {"account.number <= 5", []*types.TxResult{txResult1}}, - // search using not allowed tag + // search using not allowed key {"not_allowed = 'boom'", []*types.TxResult{}}, // search for not existing tx result {"account.number >= 2 AND account.number <= 5", []*types.TxResult{}}, - // search using not existing tag + // search using not existing key {"account.date >= TIME 2013-05-03T14:45:00Z", []*types.TxResult{}}, - // search by deprecated tag + // search by deprecated key {"sender = 'addr1'", []*types.TxResult{txResult2}}, } @@ -202,8 +202,8 @@ func TestTxSearchDeprecatedIndexing(t *testing.T) { } func TestTxSearchOneTxWithMultipleSameTagsButDifferentValues(t *testing.T) { - allowedTags := []string{"account.number"} - indexer := NewTxIndex(db.NewMemDB(), IndexTags(allowedTags)) + allowedKeys := []string{"account.number"} + indexer := NewTxIndex(db.NewMemDB(), IndexEvents(allowedKeys)) txResult := txResultWithEvents([]abci.Event{ {Type: "account", Attributes: []cmn.KVPair{{Key: []byte("number"), Value: []byte("1")}}}, @@ -221,8 +221,8 @@ func TestTxSearchOneTxWithMultipleSameTagsButDifferentValues(t *testing.T) { } func TestTxSearchMultipleTxs(t *testing.T) { - allowedTags := []string{"account.number", "account.number.id"} - indexer := NewTxIndex(db.NewMemDB(), IndexTags(allowedTags)) + allowedKeys := []string{"account.number", "account.number.id"} + indexer := NewTxIndex(db.NewMemDB(), IndexEvents(allowedKeys)) // indexed first, but bigger height (to test the order of transactions) txResult := txResultWithEvents([]abci.Event{ @@ -256,7 +256,7 @@ func TestTxSearchMultipleTxs(t *testing.T) { err = indexer.Index(txResult3) require.NoError(t, err) - // indexed fourth (to test we don't include txs with similar tags) + // indexed fourth (to test we don't include txs with similar events) // https://github.com/tendermint/tendermint/issues/2908 txResult4 := txResultWithEvents([]abci.Event{ {Type: "account", Attributes: []cmn.KVPair{{Key: []byte("number.id"), Value: []byte("1")}}}, @@ -275,7 +275,7 @@ func TestTxSearchMultipleTxs(t *testing.T) { } func TestIndexAllTags(t *testing.T) { - indexer := NewTxIndex(db.NewMemDB(), IndexAllTags()) + indexer := NewTxIndex(db.NewMemDB(), IndexAllEvents()) txResult := txResultWithEvents([]abci.Event{ {Type: "account", Attributes: []cmn.KVPair{{Key: []byte("owner"), Value: []byte("Ivan")}}}, diff --git a/types/event_bus.go b/types/event_bus.go index 833e20fcf..7200a9a70 100644 --- a/types/event_bus.go +++ b/types/event_bus.go @@ -164,8 +164,8 @@ func (b *EventBus) PublishEventValidBlock(data EventDataRoundState) error { return b.Publish(EventValidBlock, data) } -// PublishEventTx publishes tx event with tags from Result. Note it will add -// predefined tags (EventTypeKey, TxHashKey). Existing tags with the same names +// PublishEventTx publishes tx event with events from Result. Note it will add +// predefined keys (EventTypeKey, TxHashKey). Existing events with the same keys // will be overwritten. func (b *EventBus) PublishEventTx(data EventDataTx) error { // no explicit deadline for publishing events @@ -173,7 +173,7 @@ func (b *EventBus) PublishEventTx(data EventDataTx) error { events := b.validateAndStringifyEvents(data.Result.Events, b.Logger.With("tx", data.Tx)) - // add predefined tags + // add predefined compositeKeys events[EventTypeKey] = append(events[EventTypeKey], EventTx) events[TxHashKey] = append(events[TxHashKey], fmt.Sprintf("%X", data.Tx.Hash())) events[TxHeightKey] = append(events[TxHeightKey], fmt.Sprintf("%d", data.Height)) diff --git a/types/event_bus_test.go b/types/event_bus_test.go index f7631b6d5..c56f2b244 100644 --- a/types/event_bus_test.go +++ b/types/event_bus_test.go @@ -29,7 +29,7 @@ func TestEventBusPublishEventTx(t *testing.T) { }, } - // PublishEventTx adds all these 3 tags, so the query below should work + // PublishEventTx adds 3 composite keys, so the query below should work query := fmt.Sprintf("tm.event='Tx' AND tx.height=1 AND tx.hash='%X' AND testType.baz=1", tx.Hash()) txsSub, err := eventBus.Subscribe(context.Background(), "test", tmquery.MustParse(query)) require.NoError(t, err) @@ -78,7 +78,7 @@ func TestEventBusPublishEventNewBlock(t *testing.T) { }, } - // PublishEventNewBlock adds the tm.event tag, so the query below should work + // PublishEventNewBlock adds the tm.event compositeKey, so the query below should work query := "tm.event='NewBlock' AND testType.baz=1 AND testType.foz=2" blocksSub, err := eventBus.Subscribe(context.Background(), "test", tmquery.MustParse(query)) require.NoError(t, err) @@ -225,7 +225,7 @@ func TestEventBusPublishEventNewBlockHeader(t *testing.T) { }, } - // PublishEventNewBlockHeader adds the tm.event tag, so the query below should work + // PublishEventNewBlockHeader adds the tm.event compositeKey, so the query below should work query := "tm.event='NewBlockHeader' AND testType.baz=1 AND testType.foz=2" headersSub, err := eventBus.Subscribe(context.Background(), "test", tmquery.MustParse(query)) require.NoError(t, err) diff --git a/types/events.go b/types/events.go index c679e7034..fb80db0f0 100644 --- a/types/events.go +++ b/types/events.go @@ -125,7 +125,7 @@ type EventDataValidatorSetUpdates struct { /////////////////////////////////////////////////////////////////////////////// const ( - // EventTypeKey is a reserved key, used to specify event type in tags. + // EventTypeKey is a reserved composite key for event name. EventTypeKey = "tm.event" // TxHashKey is a reserved key, used to specify transaction's hash. // see EventBus#PublishEventTx