Skip to content

Commit 3f73ac6

Browse files
authored
Merge pull request #86 from neutron-org/fix/relayer-fails-on-not-found-query
2 parents 6da0eb9 + d384500 commit 3f73ac6

File tree

12 files changed

+440
-95
lines changed

12 files changed

+440
-95
lines changed

.tool-versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
golang 1.21
1+
golang 1.21.3

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ generate-openapi:
2626

2727
install:
2828
go install -ldflags '$(ldflags)' -a ./cmd/neutron_query_relayer
29+
30+
mocks:
31+
@echo "Regenerate mocks..."
32+
go generate ./...

cmd/neutron_query_relayer/cmd/start.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cmd
22

33
import (
44
"context"
5+
relaysubscriber "github.com/neutron-org/neutron-query-relayer/internal/subscriber"
56
"log"
67
"os"
78
"os/signal"
@@ -92,7 +93,7 @@ func startRelayer() {
9293
submittedTxsTasksQueue = make(chan relay.PendingSubmittedTxInfo)
9394
)
9495

95-
subscriber, err := app.NewDefaultSubscriber(cfg, logRegistry)
96+
subscriber, err := relaysubscriber.NewDefaultSubscriber(cfg, logRegistry)
9697
if err != nil {
9798
logger.Fatal("Failed to get NewDefaultSubscriber", zap.Error(err))
9899
}

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ require (
1616
github.com/go-openapi/strfmt v0.21.3
1717
github.com/go-openapi/swag v0.22.3
1818
github.com/go-openapi/validate v0.21.0
19+
github.com/golang/mock v1.6.0
1920
github.com/gorilla/mux v1.8.1
2021
github.com/kelseyhightower/envconfig v1.4.0
2122
github.com/neutron-org/neutron v1.0.5-0.20231128122544-e605ed3db438
2223
github.com/neutron-org/neutron-logger v0.0.0-20221027125151-535167f2dd73
2324
github.com/prometheus/client_golang v1.16.0
2425
github.com/spf13/cobra v1.8.0
26+
github.com/stretchr/testify v1.8.4
2527
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d
28+
go.uber.org/mock v0.2.0
2629
go.uber.org/zap v1.24.0
2730
)
2831

@@ -112,7 +115,6 @@ require (
112115
github.com/gogo/protobuf v1.3.3 // indirect
113116
github.com/golang/glog v1.1.2 // indirect
114117
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
115-
github.com/golang/mock v1.6.0 // indirect
116118
github.com/golang/protobuf v1.5.3 // indirect
117119
github.com/golang/snappy v0.0.4 // indirect
118120
github.com/google/btree v1.1.2 // indirect
@@ -186,7 +188,6 @@ require (
186188
github.com/spf13/jwalterweatherman v1.1.0 // indirect
187189
github.com/spf13/pflag v1.0.5 // indirect
188190
github.com/spf13/viper v1.16.0 // indirect
189-
github.com/stretchr/testify v1.8.4 // indirect
190191
github.com/subosito/gotenv v1.4.2 // indirect
191192
github.com/tendermint/go-amino v0.16.0 // indirect
192193
github.com/tidwall/btree v1.6.0 // indirect

internal/app/app.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,9 @@ import (
2020
nlogger "github.com/neutron-org/neutron-logger"
2121
"github.com/neutron-org/neutron-query-relayer/internal/config"
2222
"github.com/neutron-org/neutron-query-relayer/internal/raw"
23-
"github.com/neutron-org/neutron-query-relayer/internal/registry"
2423
"github.com/neutron-org/neutron-query-relayer/internal/relay"
25-
"github.com/neutron-org/neutron-query-relayer/internal/subscriber"
26-
relaysubscriber "github.com/neutron-org/neutron-query-relayer/internal/subscriber"
2724
"github.com/neutron-org/neutron-query-relayer/internal/subscriber/querier/client/query"
2825
"github.com/neutron-org/neutron-query-relayer/internal/txsubmitchecker"
29-
neutrontypes "github.com/neutron-org/neutron/x/interchainqueries/types"
3026
)
3127

3228
var (
@@ -56,30 +52,6 @@ var (
5652
rtyErr = retry.LastErrorOnly(true)
5753
)
5854

59-
func NewDefaultSubscriber(cfg config.NeutronQueryRelayerConfig, logRegistry *nlogger.Registry) (relay.Subscriber, error) {
60-
watchedMsgTypes := []neutrontypes.InterchainQueryType{neutrontypes.InterchainQueryTypeKV}
61-
if cfg.AllowTxQueries {
62-
watchedMsgTypes = append(watchedMsgTypes, neutrontypes.InterchainQueryTypeTX)
63-
}
64-
65-
subscriber, err := relaysubscriber.NewSubscriber(
66-
&subscriber.SubscriberConfig{
67-
RPCAddress: cfg.NeutronChain.RPCAddr,
68-
RESTAddress: cfg.NeutronChain.RESTAddr,
69-
Timeout: cfg.NeutronChain.Timeout,
70-
ConnectionID: cfg.NeutronChain.ConnectionID,
71-
WatchedTypes: watchedMsgTypes,
72-
Registry: registry.New(cfg.Registry),
73-
},
74-
logRegistry.Get(SubscriberContext),
75-
)
76-
if err != nil {
77-
return nil, fmt.Errorf("failed to create a NewSubscriber: %s", err)
78-
}
79-
80-
return subscriber, nil
81-
}
82-
8355
func NewDefaultTxSubmitChecker(cfg config.NeutronQueryRelayerConfig, logRegistry *nlogger.Registry,
8456
storage relay.Storage) (relay.TxSubmitChecker, error) {
8557
neutronClient, err := raw.NewRPCClient(cfg.NeutronChain.RPCAddr, cfg.NeutronChain.Timeout)

internal/subscriber/attributes.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,22 @@ const (
1616
// eventAttr is the key of the tendermint's event attribute that contains the kind of event.
1717
eventAttr = "tm.event"
1818

19-
// connectionIdAttr is the key of the Neutron's custom message event's attribute that contains the
19+
// ConnectionIdAttr is the key of the Neutron's custom message event's attribute that contains the
2020
// connectionID of the event's ActiveQuery.
21-
connectionIdAttr = eventTypePrefix + "." + types.AttributeKeyConnectionID
22-
// queryIdAttr is the key of the Neutron's custom message event's attribute that contains the
21+
ConnectionIdAttr = eventTypePrefix + "." + types.AttributeKeyConnectionID
22+
// QueryIdAttr is the key of the Neutron's custom message event's attribute that contains the
2323
// incoming ICQ ID.
24-
queryIdAttr = eventTypePrefix + "." + types.AttributeKeyQueryID
25-
// kvKeyAttr is the key of the Neutron's custom message event's attribute that contains the KV
24+
QueryIdAttr = eventTypePrefix + "." + types.AttributeKeyQueryID
25+
// KvKeyAttr is the key of the Neutron's custom message event's attribute that contains the KV
2626
// values for the incoming KV ICQ.
27-
kvKeyAttr = eventTypePrefix + "." + types.AttributeKeyKVQuery
28-
// transactionsFilterAttr is the key of the Neutron's custom message event's attribute that
27+
KvKeyAttr = eventTypePrefix + "." + types.AttributeKeyKVQuery
28+
// TransactionsFilterAttr is the key of the Neutron's custom message event's attribute that
2929
// contains the transaction filter value for the incoming TX ICQ.
30-
transactionsFilterAttr = eventTypePrefix + "." + types.AttributeTransactionsFilterQuery
31-
// typeAttr is the key of the Neutron's custom message event's attribute that contains the type
30+
TransactionsFilterAttr = eventTypePrefix + "." + types.AttributeTransactionsFilterQuery
31+
// TypeAttr is the key of the Neutron's custom message event's attribute that contains the type
3232
// of the incoming ICQ.
33-
typeAttr = eventTypePrefix + "." + types.AttributeKeyQueryType
34-
// ownerAttr is the key of the Neutron's custom message event's attribute that contains the
33+
TypeAttr = eventTypePrefix + "." + types.AttributeKeyQueryType
34+
// OwnerAttr is the key of the Neutron's custom message event's attribute that contains the
3535
// address of the ICQ owner.
36-
ownerAttr = eventTypePrefix + "." + types.AttributeKeyOwner
36+
OwnerAttr = eventTypePrefix + "." + types.AttributeKeyOwner
3737
)

internal/subscriber/clients.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package subscriber
2+
3+
import (
4+
"context"
5+
ctypes "github.com/cometbft/cometbft/rpc/core/types"
6+
"github.com/neutron-org/neutron-query-relayer/internal/subscriber/querier/client/query"
7+
)
8+
9+
type RpcHttpClient interface {
10+
Start() error
11+
Subscribe(ctx context.Context, subscriber string, query string, outCapacity ...int) (out <-chan ctypes.ResultEvent, err error)
12+
Status(ctx context.Context) (*ctypes.ResultStatus, error)
13+
Unsubscribe(ctx context.Context, subscriber, query string) error
14+
}
15+
16+
type RestHttpQuery interface {
17+
NeutronInterchainQueriesRegisteredQuery(params *query.NeutronInterchainQueriesRegisteredQueryParams, opts ...query.ClientOption) (*query.NeutronInterchainQueriesRegisteredQueryOK, error)
18+
NeutronInterchainQueriesRegisteredQueries(params *query.NeutronInterchainQueriesRegisteredQueriesParams, opts ...query.ClientOption) (*query.NeutronInterchainQueriesRegisteredQueriesOK, error)
19+
}

internal/subscriber/subscriber.go

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,30 @@ package subscriber
33
import (
44
"context"
55
"fmt"
6+
nlogger "github.com/neutron-org/neutron-logger"
7+
"github.com/neutron-org/neutron-query-relayer/internal/app"
8+
"github.com/neutron-org/neutron-query-relayer/internal/config"
9+
"github.com/neutron-org/neutron-query-relayer/internal/relay"
610
"sync"
711
"time"
812

13+
"github.com/neutron-org/neutron-query-relayer/internal/registry"
14+
915
instrumenters "github.com/neutron-org/neutron-query-relayer/internal/metrics"
1016

11-
"github.com/cometbft/cometbft/rpc/client/http"
1217
tmtypes "github.com/cometbft/cometbft/rpc/core/types"
1318
"go.uber.org/zap"
1419

1520
rg "github.com/neutron-org/neutron-query-relayer/internal/registry"
16-
restclient "github.com/neutron-org/neutron-query-relayer/internal/subscriber/querier/client"
1721
neutrontypes "github.com/neutron-org/neutron/x/interchainqueries/types"
1822
)
1923

2024
var (
2125
unsubscribeTimeout = time.Second * 5
2226
)
2327

24-
// SubscriberConfig contains configurable fields for the Subscriber.
25-
type SubscriberConfig struct {
26-
// RPCAddress represents the address for RPC calls to the chain.
27-
RPCAddress string
28-
// RESTAddress represents the address for REST calls to the chain.
29-
RESTAddress string
30-
// Timeout defines time limit for requests executed by the Subscriber.
31-
Timeout time.Duration
28+
// Config contains configurable fields for the Subscriber.
29+
type Config struct {
3230
// ConnectionID is the Neutron's side connection ID used to filter out queries.
3331
ConnectionID string
3432
// WatchedTypes is the list of query types to be observed and handled.
@@ -38,24 +36,50 @@ type SubscriberConfig struct {
3836
Registry *rg.Registry
3937
}
4038

41-
// NewSubscriber creates a new Subscriber instance ready to subscribe to Neutron events.
42-
func NewSubscriber(
43-
cfg *SubscriberConfig,
44-
logger *zap.Logger,
45-
) (*Subscriber, error) {
39+
func NewDefaultSubscriber(cfg config.NeutronQueryRelayerConfig, logRegistry *nlogger.Registry) (relay.Subscriber, error) {
40+
watchedMsgTypes := []neutrontypes.InterchainQueryType{neutrontypes.InterchainQueryTypeKV}
41+
if cfg.AllowTxQueries {
42+
watchedMsgTypes = append(watchedMsgTypes, neutrontypes.InterchainQueryTypeTX)
43+
}
44+
4645
// rpcClient is used to subscribe to Neutron events.
47-
rpcClient, err := newRPCClient(cfg.RPCAddress, cfg.Timeout)
46+
rpcClient, err := NewRPCClient(cfg.NeutronChain.RPCAddr, cfg.NeutronChain.Timeout)
4847
if err != nil {
49-
return nil, fmt.Errorf("could not create new tendermint rpcClient: %w", err)
50-
}
51-
if err = rpcClient.Start(); err != nil {
52-
return nil, fmt.Errorf("could not start tendermint rpcClient: %w", err)
48+
return nil, fmt.Errorf("could not create new tendermint rpcClient for Subscriber: %w", err)
5349
}
5450

5551
// restClient is used to retrieve registered queries from Neutron.
56-
restClient, err := newRESTClient(cfg.RESTAddress, cfg.Timeout)
52+
restClient, err := NewRESTClient(cfg.NeutronChain.RESTAddr, cfg.NeutronChain.Timeout)
53+
if err != nil {
54+
return nil, fmt.Errorf("failed to get NewRESTClient for Subscriber: %w", err)
55+
}
56+
57+
sub, err := NewSubscriber(
58+
&Config{
59+
ConnectionID: cfg.NeutronChain.ConnectionID,
60+
WatchedTypes: watchedMsgTypes,
61+
Registry: registry.New(cfg.Registry),
62+
},
63+
rpcClient,
64+
restClient.Query,
65+
logRegistry.Get(app.SubscriberContext),
66+
)
5767
if err != nil {
58-
return nil, fmt.Errorf("failed to get newRESTClient: %w", err)
68+
return nil, fmt.Errorf("failed to create a NewSubscriber: %s", err)
69+
}
70+
71+
return sub, nil
72+
}
73+
74+
// NewSubscriber creates a new Subscriber instance ready to subscribe to Neutron events.
75+
func NewSubscriber(
76+
cfg *Config,
77+
rpcClient RpcHttpClient,
78+
restClient RestHttpQuery,
79+
logger *zap.Logger,
80+
) (*Subscriber, error) {
81+
if err := rpcClient.Start(); err != nil {
82+
return nil, fmt.Errorf("could not start tendermint rpcClient: %w", err)
5983
}
6084

6185
// Contains the types of queries that we are ready to serve (KV / TX).
@@ -65,8 +89,8 @@ func NewSubscriber(
6589
}
6690

6791
return &Subscriber{
68-
rpcClient: rpcClient,
69-
restClient: restClient,
92+
rpcClient: rpcClient,
93+
restClientQuery: restClient,
7094

7195
connectionID: cfg.ConnectionID,
7296
registry: cfg.Registry,
@@ -81,13 +105,12 @@ func NewSubscriber(
81105
// filters them in accordance with the Registry configuration and watchedTypes, and provides a
82106
// stream of split to KV and TX messages.
83107
type Subscriber struct {
84-
rpcClient *http.HTTP // Used to subscribe to events
85-
restClient *restclient.HTTPAPIConsole // Used to run Neutron-specific queries using the REST
86-
87-
connectionID string
88-
registry *rg.Registry
89-
logger *zap.Logger
90-
watchedTypes map[neutrontypes.InterchainQueryType]struct{}
108+
rpcClient RpcHttpClient // Used to subscribe to events
109+
restClientQuery RestHttpQuery // Used to run Neutron-specific queries using the REST
110+
connectionID string
111+
registry *rg.Registry
112+
logger *zap.Logger
113+
watchedTypes map[neutrontypes.InterchainQueryType]struct{}
91114

92115
activeQueries map[string]*neutrontypes.RegisteredQuery
93116
}
@@ -183,10 +206,10 @@ func (s *Subscriber) processUpdateEvent(ctx context.Context, event tmtypes.Resul
183206
// There can be multiple events of the same type associated with our connection id in a
184207
// single tmtypes.ResultEvent value. We need to process all of them.
185208
var events = event.Events
186-
for idx := range events[connectionIdAttr] {
209+
for idx := range events[ConnectionIdAttr] {
187210
var (
188-
owner = events[ownerAttr][idx]
189-
queryID = events[queryIdAttr][idx]
211+
owner = events[OwnerAttr][idx]
212+
queryID = events[QueryIdAttr][idx]
190213
)
191214
if !s.isWatchedAddress(owner) {
192215
s.logger.Debug("Skipping query (wrong owner)", zap.String("owner", owner),
@@ -197,7 +220,8 @@ func (s *Subscriber) processUpdateEvent(ctx context.Context, event tmtypes.Resul
197220
// Load all information about the neutronQuery directly from Neutron.
198221
neutronQuery, err := s.getNeutronRegisteredQuery(ctx, queryID)
199222
if err != nil {
200-
return fmt.Errorf("failed to getNeutronRegisteredQuery: %w", err)
223+
s.logger.Debug("Skipping query (could not find by id, probably removed)", zap.String("queryId", queryID))
224+
continue
201225
}
202226

203227
if !s.isWatchedMsgType(neutronQuery.QueryType) {
@@ -228,9 +252,9 @@ func (s *Subscriber) processRemoveEvent(event tmtypes.ResultEvent) error {
228252
// There can be multiple events of the same type associated with our connection id in a
229253
// single tmtypes.ResultEvent value. We need to process all of them.
230254
var events = event.Events
231-
for idx := range events[connectionIdAttr] {
255+
for idx := range events[ConnectionIdAttr] {
232256
var (
233-
queryID = events[queryIdAttr][idx]
257+
queryID = events[QueryIdAttr][idx]
234258
)
235259

236260
// Delete the query from the active queries list.

0 commit comments

Comments
 (0)