Skip to content

Commit 47f427e

Browse files
Jerónimo AlbiAlex Johnsontbruyellelumtis
authored
docs: add cosmostxcollector package docs (ignite#2940)
* docs: add `cosmostxcollector` package docs * chore: fix broken english phrases :) Co-authored-by: Thomas Bruyelle <thomas.bruyelle@gmail.com> * chore: add extra comment on default sorting, paging and filtering * chore: fix english Co-authored-by: Lucas Bertrand <lucas.bertrand.22@gmail.com> * chore: use Cosmos' event contants for the query examples Co-authored-by: Thomas Bruyelle <thomas.bruyelle@gmail.com> Co-authored-by: Alex Johnson <alex@shmeeload.xyz> Co-authored-by: Thomas Bruyelle <thomas.bruyelle@gmail.com> Co-authored-by: Lucas Bertrand <lucas.bertrand.22@gmail.com>
1 parent 47f2f78 commit 47f427e

File tree

5 files changed

+211
-6
lines changed

5 files changed

+211
-6
lines changed

docs/docs/clients/_category_.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"label": "Clients",
3-
"position": 5,
3+
"position": 6,
44
"link": null
5-
}
5+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"label": "Contributing to Ignite CLI docs",
3-
"position": 7,
3+
"position": 8,
44
"link": null
5-
}
5+
}

docs/docs/network/_category_.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"label": "Network",
3-
"position": 6,
3+
"position": 7,
44
"link": null
5-
}
5+
}

docs/docs/packages/_category_.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"label": "Packages",
3+
"position": 5,
4+
"link": null
5+
}
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
sidebar_position: 0
3+
title: cosmostxcollector
4+
slug: /packages/cosmostxcollector
5+
---
6+
7+
# cosmostxcollector
8+
9+
The package implements support for collecting transactions and events from Cosmos blockchains
10+
into a data backend and it also adds support for querying the collected data.
11+
12+
## Transaction and event data collecting
13+
14+
Transactions and events can be collected using the `cosmostxcollector.Collector` type. This
15+
type uses a `cosmosclient.Client` instance to fetch the data from each block and a data backend
16+
adapter to save the data.
17+
18+
### Data backend adapters
19+
20+
Data backend adapters are used to query and save the collected data into different types of data
21+
backends and must implement the `cosmostxcollector.adapter.Adapter` interface.
22+
23+
An adapter for PostgreSQL is already implemented in `cosmostxcollector.adapter.postgres.Adapter`.
24+
This is the one used in the examples.
25+
26+
### Example: Data collection
27+
28+
The data collection example assumes that there is a PostgreSQL database running in the local
29+
environment containing an empty database named "cosmos".
30+
31+
The required database tables will be created automatically by the collector the first time it is run.
32+
33+
When the application is run it will fetch all the transactions and events starting from one of the
34+
recent blocks until the current block height and populate the database:
35+
36+
```go
37+
package main
38+
39+
import (
40+
"context"
41+
"log"
42+
43+
"github.com/ignite/cli/ignite/pkg/clictx"
44+
"github.com/ignite/cli/ignite/pkg/cosmosclient"
45+
"github.com/ignite/cli/ignite/pkg/cosmostxcollector"
46+
"github.com/ignite/cli/ignite/pkg/cosmostxcollector/adapter/postgres"
47+
)
48+
49+
const (
50+
// Name of a local PostgreSQL database
51+
dbName = "cosmos"
52+
53+
// Cosmos RPC address
54+
rpcAddr = "https://rpc.cosmos.network:443"
55+
)
56+
57+
func collect(ctx context.Context, db postgres.Adapter) error {
58+
// Make sure that the data backend schema is up to date
59+
if err = db.Init(ctx); err != nil {
60+
return err
61+
}
62+
63+
// Init the Cosmos client
64+
client, err := cosmosclient.New(ctx, cosmosclient.WithNodeAddress(rpcAddr))
65+
if err != nil {
66+
return err
67+
}
68+
69+
// Get the latest block height
70+
latestHeight, err := client.LatestBlockHeight(ctx)
71+
if err != nil {
72+
return err
73+
}
74+
75+
// Collect transactions and events starting from a block height.
76+
// The collector stops at the latest height available at the time of the call.
77+
collector := cosmostxcollector.New(db, client)
78+
if err := collector.Collect(ctx, latestHeight-50); err != nil {
79+
return err
80+
}
81+
82+
return nil
83+
}
84+
85+
func main() {
86+
ctx := clictx.From(context.Background())
87+
88+
// Init an adapter for a local PostgreSQL database running with the default values
89+
params := map[string]string{"sslmode": "disable"}
90+
db, err := postgres.NewAdapter(dbName, postgres.WithParams(params))
91+
if err != nil {
92+
log.Fatal(err)
93+
}
94+
95+
if err := collect(ctx, db); err != nil {
96+
log.Fatal(err)
97+
}
98+
}
99+
```
100+
101+
## Queries
102+
103+
Collected data can be queried through the data backend adapters using event queries or
104+
cursor-based queries.
105+
106+
Queries support sorting, paging and filtering by using different options during creation.
107+
The cursor-based ones also support the selection of specific fields or properties and also
108+
passing arguments in cases where the query is a function.
109+
110+
By default no sorting, filtering nor paging is applied to the queries.
111+
112+
### Event queries
113+
114+
The event queries return events and their attributes as `[]cosmostxcollector.query.Event`.
115+
116+
### Example: Query events
117+
118+
The example reads transfer events from Cosmos' bank module and paginates the results.
119+
120+
```go
121+
import (
122+
"context"
123+
124+
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
125+
"github.com/ignite/cli/ignite/pkg/cosmostxcollector/adapter/postgres"
126+
"github.com/ignite/cli/ignite/pkg/cosmostxcollector/query"
127+
)
128+
129+
func queryBankTransferEvents(ctx context.Context, db postgres.Adapter) ([]query.Event, error) {
130+
// Create an event query that returns events of type "transfer"
131+
qry := query.NewEventQuery(
132+
query.WithFilters(
133+
// Filter transfer events from Cosmos' bank module
134+
postgres.FilterByEventType(banktypes.EventTypeTransfer),
135+
),
136+
query.WithPageSize(10),
137+
query.AtPage(1),
138+
)
139+
140+
// Execute the query
141+
return db.QueryEvents(ctx, qry)
142+
}
143+
```
144+
145+
### Cursor-based queries
146+
147+
This type of queries is meant to be used in contexts where the Event queries are not
148+
useful.
149+
150+
Cursor-based queries can query a single "entity" which can be a table, view or function
151+
in relational databases or a collection or function in non relational data backends.
152+
153+
The result of these types of queries is a cursor that implements the `cosmostxcollector.query.Cursor`
154+
interface.
155+
156+
### Example: Query events using cursors
157+
158+
```go
159+
import (
160+
"context"
161+
162+
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
163+
"github.com/ignite/cli/ignite/pkg/cosmostxcollector/adapter/postgres"
164+
"github.com/ignite/cli/ignite/pkg/cosmostxcollector/query"
165+
)
166+
167+
func queryBankTransferEventIDs(ctx context.Context, db postgres.Adapter) (ids []int64, err error) {
168+
// Create a query that returns the IDs for events of type "transfer"
169+
qry := query.New(
170+
"event",
171+
query.Fields("id"),
172+
query.WithFilters(
173+
// Filter transfer events from Cosmos' bank module
174+
postgres.NewFilter("type", banktypes.EventTypeTransfer),
175+
),
176+
query.WithPageSize(10),
177+
query.AtPage(1),
178+
query.SortByFields(query.SortOrderAsc, "id"),
179+
)
180+
181+
// Execute the query
182+
cr, err := db.Query(ctx, qry)
183+
if err != nil {
184+
return nil, err
185+
}
186+
187+
// Read the results
188+
for cr.Next() {
189+
var eventID int64
190+
191+
if err := cr.Scan(&eventID); err != nil {
192+
return nil, err
193+
}
194+
195+
ids = append(ids, eventID)
196+
}
197+
198+
return ids, nil
199+
}
200+
```

0 commit comments

Comments
 (0)