docs: update event subscription documentation for new API (#8509)

Update the static documentation about event subscription to include the new
/events API, and to add more details about how queries work. Mention that the
streaming API is deprecated.
This commit is contained in:
M. J. Fromberger
2022-05-12 11:54:49 -07:00
committed by GitHub
parent 92811b9153
commit f9fa0a3228
2 changed files with 216 additions and 63 deletions

View File

@@ -2,74 +2,228 @@
order: 7
---
# Subscribing to events via Websocket
# Subscribing to Events
Tendermint emits different events, which you can subscribe to via
[Websocket](https://en.wikipedia.org/wiki/WebSocket). This can be useful
for third-party applications (for analysis) or for inspecting state.
A Tendermint node emits events about important state transitions during
consensus. These events can be queried by clients via the [RPC interface][rpc]
on nodes that enable it. The [list of supported event types][event-types] can
be found in the tendermint/types Go package.
[List of events](https://godoc.org/github.com/tendermint/tendermint/types#pkg-constants)
In Tendermint v0.36 there are two APIs to query events:
To connect to a node via websocket from the CLI, you can use a tool such as
[wscat](https://github.com/websockets/wscat) and run:
- The [**legacy streaming API**](#legacy-streaming-api), comprising the
`subscribe`, `unsubscribe`, and `unsubscribe_all` RPC methods over websocket.
- The [**event log API**](#event-log-api), comprising the `events` RPC method.
The legacy streaming API is deprecated in Tendermint v0.36, and will be removed
in Tendermint v0.37. Clients are strongly encouraged to migrate to the new
event log API as soon as is practical.
[rpc]: https://docs.tendermint.com/master/rpc
[event-types]: https://godoc.org/github.com/tendermint/tendermint/types#EventNewBlockValue
## Filter Queries
Event requests take a [filter query][query] parameter. A filter query is a
string that describes a subset of available event items to return. An empty
query matches all events; otherwise a query comprises one or more *terms*
comparing event metadata to target values.
For example, to select new block events, use the term:
```
tm.event = 'NewBlock'
```
Multiple terms can be combined with `AND` (case matters), for example to match
the transaction event with a given hash, use the query:
```
tm.event = 'Tx' AND tx.hash = 'EA7B33F'
```
Operands may be strings in single quotes (`'Tx'`), numbers (`45`), dates, or
timestamps.
The comparison operators include `=`, `<`, `<=`, `>`, `>=`, and `CONTAINS` (for
substring match). In addition, the `EXISTS` operator checks for the presence
of an attribute regardless of its value.
### Attributes
Tendermint implicitly defines a string-valued `tm.event` attribute for all
event types. Transaction items (type `Tx`) are also assigned `tx.hash`
(string), giving the hash of the transaction, and and `tx.height` (number)
giving the height of the block containing the transaction. For `NewBlock` and
`NewBlockHeader` events, Tendermint defines a `block.height` attribute giving
the height of the block.
Additional attributes can be provided by the application as [ABCI `Event`
records][abci-event] in response to the `FinalizeBlock` request. The full name
of the attribute in the query is formed by combining the `type` and attribute
`key` with a period.
For example, given the events
```go
[]abci.Event{{
Type: "reward",
Attributes: []abci.EventAttribute{
{Key: "address", Value: "cosmos1xyz012pdq"},
{Key: "amount", Value: "45.62"},
{Key: "balance", Value: "100.390001"},
},
}}
```
a query may refer to the names `reward.address`, `reward.amount`, and `reward.balance`, as in:
```
reward.address EXISTS AND reward.balance > 45
```
Certain application-specific metadata are also indexed for offline queries.
See [Indexing transactions](../app-dev/indexing-transactions.md) for more details.
[query]: https://godoc.org/github.com/tendermint/tendermint/internal/pubsub/query/syntax
[abci-event]: https://github.com/tendermint/tendermint/blob/master/proto/tendermint/abci/types.proto#L397
## Event Log API
Starting in Tendermint v0.36, when the `rpc.event-log-window-size`
configuration is enabled, the node maintains maintains a log of all events
within this operator-defined time window. This API supersedes the websocket
subscription API described below.
Clients can query these events can by long-polling the `/events` RPC method,
which returns the most recent items from the log that match the [request
parameters][reqevents]. Each item returned includes a cursor that marks its
location in the log. Cursors can be passed via the `before` and `after`
parameters to fetch events earlier in the log.
For example, this request:
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "events",
"params": {
"filter": {
"query": "tm.event = 'Tx' AND app.key = 'applesauce'"
},
"maxItems": 1,
"after": ""
}
}
```
will return a result similar to the following:
```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"items": [
{
"cursor": "16ee3d5e65be53d8-03d5",
"event": "Tx",
"data": {
"type": "tendermint/event/Tx",
"value": {
"height": 70,
"tx": "YXBwbGVzYXVjZT1zeXJ1cA==",
"result": {
"events": [
{
"type": "app",
"attributes": [
{
"key": "creator",
"value": "Cosmoshi Netowoko",
"index": true
},
{
"key": "key",
"value": "applesauce",
"index": true
},
{
"key": "index_key",
"value": "index is working",
"index": true
},
{
"key": "noindex_key",
"value": "index is working",
"index": false
}
]
}
]
}
}
}
}
],
"more": false,
"oldest": "16ee3d4c471c3b00-0001",
"newest": "16ee3d5f2e05a4e0-0400"
}
}
```
The `"items"` array gives the matching items (up to the requested
`"maxResults"`) in decreasing time order (i.e., newest to oldest). In this
case, there is only one result, but if there are additional results that were
not returned, the `"more"` flag will be true. Calling `/events` again with the
same query and `"after"` set to the cursor of the newest result (in this
example, `"16ee3d5e65be53d8-03d5"`) will fetch newer results.
Go clients can use the [`eventstream`][eventstream] package to simplify the use
of this method. The `eventstream.Stream` automatically handles polling for new
events, updating the cursor, and reporting any missed events.
[reqevents]: https://pkg.go.dev/github.com/tendermint/tendermint@master/rpc/coretypes#RequestEvents
[eventstream]: https://godoc.org/github.com/tendermint/tendermint/rpc/client/eventstream
## Legacy Streaming API
- **Note:** This API is deprecated in Tendermint v0.36, and will be removed in
Tendermint v0.37. New clients and existing use should use the [event log
API](#event-log-api) instead. See [ADR 075][adr075] for more details.
To subscribe to events in the streaming API, you must connect to the node RPC
service using a [websocket][ws]. From the command line you can use a tool such
as [wscat][wscat], for example:
```sh
wscat ws://127.0.0.1:26657/websocket
```
You can subscribe to any of the events above by calling the `subscribe` RPC
method via Websocket along with a valid query.
[ws]: https://en.wikipedia.org/wiki/WebSocket
[wscat]: https://github.com/websockets/wscat
To subscribe to events, call the `subscribe` JSON-RPC method method passing in
a [filter query][query] for the events you wish to receive:
```json
{
"jsonrpc": "2.0",
"method": "subscribe",
"id": 0,
"id": 1,
"params": {
"query": "tm.event='NewBlock'"
}
}
```
Check out [API docs](https://docs.tendermint.com/master/rpc/) for
more information on query syntax and other options.
The subscribe method returns an initial response confirming the subscription,
then sends additional JSON-RPC response messages containing the matching events
as they are published. The subscription continues until either the client
explicitly cancels the subscription (by calling `unsubscribe` or
`unsubscribe_all`) or until the websocket connection is terminated.
You can also use tags, given you had included them into DeliverTx
response, to query transaction results. See [Indexing
transactions](../app-dev/indexing-transactions.md) for details.
## ValidatorSetUpdates
When validator set changes, ValidatorSetUpdates event is published. The
event carries a list of pubkey/power pairs. The list is the same
Tendermint receives from ABCI application (see [EndBlock
section](https://github.com/tendermint/tendermint/blob/master/spec/abci/abci.md#endblock) in
the ABCI spec).
Response:
```json
{
"jsonrpc": "2.0",
"id": 0,
"result": {
"query": "tm.event='ValidatorSetUpdates'",
"data": {
"type": "tendermint/event/ValidatorSetUpdates",
"value": {
"validator_updates": [
{
"address": "09EAD022FD25DE3A02E64B0FE9610B1417183EE4",
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "ww0z4WaZ0Xg+YI10w43wTWbBmM3dpVza4mmSQYsd0ck="
},
"voting_power": "10",
"proposer_priority": "0"
}
]
}
}
}
}
```
[adr075]: https://tinyurl.com/adr075

View File

@@ -260,10 +260,9 @@ paths:
operationId: events
description: |
Fetch a batch of events posted by the consensus node and matching a
specified query.
specified query string.
The query grammar is defined in
https://godoc.org/github.com/tendermint/tendermint/internal/pubsub/query/syntax.
The query grammar is defined in [pubsub/query/syntax](https://godoc.org/github.com/tendermint/tendermint/internal/pubsub/query/syntax).
An empty query matches all events; otherwise a query comprises one or
more terms comparing event metadata to target values. For example, to
select new block events:
@@ -275,13 +274,13 @@ paths:
tm.event = 'Tx' AND tx.hash = 'EA7B33F'
The comparison operators include "=", "<", "<=", ">", ">=", and
"CONTAINS". Operands may be strings (in single quotes), numbers, dates,
or timestamps. In addition, the "EXISTS" operator allows you to check
The comparison operators include `=`, `<`, `<=`, `>`, `>=`, and
`CONTAINS`. Operands may be strings (in single quotes), numbers, dates,
or timestamps. In addition, the `EXISTS` operator allows you to check
for the presence of an attribute regardless of its value.
Tendermint defines a tm.event attribute for all events. Transactions
are also assigned tx.hash and tx.height attributes. Other attributes
Tendermint defines a `tm.event` attribute for all events. Transactions
are also assigned `tx.hash` and `tx.height` attributes. Other attributes
are provided by the application as ABCI Event records. The name of the
event in the query is formed by combining the type and attribute key
with a period. For example, given:
@@ -295,16 +294,16 @@ paths:
},
}}
the query may refer to the names "reward.address", "reward.amount", and
"reward.balance", as in:
the query may refer to the names`"reward.address`,`"reward.amount`, and
`reward.balance`, as in:
reward.address EXISTS AND reward.balance > 45
The node maintains a log of all events within an operator-defined time
window. The /events method returns the most recent items from the log
that match the query. Each item returned includes a cursor that marks
its location in the log. Cursors can be passed via the "before" and
"after" parameters to fetch events earlier in the log.
its location in the log. Cursors can be passed via the `before` and
`after` parameters to fetch events earlier in the log.
parameters:
- in: query
name: filter