Skip to content

Commit 95855d7

Browse files
authored
Merge pull request #87 from stafiprotocol/main
feat: add query IDs filter
2 parents 3f73ac6 + 2070b36 commit 95855d7

File tree

8 files changed

+463
-16
lines changed

8 files changed

+463
-16
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ RELAYER_TARGET_CHAIN_DEBUG=true
2020
RELAYER_TARGET_CHAIN_OUTPUT_FORMAT=json
2121

2222
RELAYER_REGISTRY_ADDRESSES=neutron14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s5c2epq
23+
RELAYER_REGISTRY_QUERY_IDS=
2324

2425
RELAYER_ALLOW_TX_QUERIES=true
2526
RELAYER_ALLOW_KV_CALLBACKS=true

.env.example.dev

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ RELAYER_TARGET_CHAIN_OUTPUT_FORMAT=json
3434
RELAYER_TARGET_CHAIN_SIGN_MODE_STR=direct
3535

3636
RELAYER_REGISTRY_ADDRESSES=
37+
RELAYER_REGISTRY_QUERY_IDS=
3738

3839
RELAYER_ALLOW_TX_QUERIES=true
3940
RELAYER_ALLOW_KV_CALLBACKS=true

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ Relayer:
9898
| `RELAYER_TARGET_CHAIN_DEBUG ` | `bool` | flag to run target chain provider in debug mode | optional |
9999
| `RELAYER_TARGET_CHAIN_OUTPUT_FORMAT` | `json` or `yaml` | target chain provider output format | optional |
100100
| `RELAYER_REGISTRY_ADDRESSES` | `string` | a list of comma-separated smart-contract addresses for which the relayer processes interchain queries | required |
101+
| `RELAYER_REGISTRY_QUERY_IDS` | `string` | a list of comma-separated query IDs which complements to `RELAYER_REGISTRY_ADDRESSES` to further filter out interchain queries being processed | optional |
101102
| `RELAYER_ALLOW_TX_QUERIES` | `bool` | if true relayer will process tx queries (if `false`, relayer will drop them) | required |
102103
| `RELAYER_ALLOW_KV_CALLBACKS` | `bool` | if `true`, will pass proofs as sudo callbacks to contracts | required |
103104
| `RELAYER_MIN_KV_UPDATE_PERIOD` | `uint` | minimal period of queries execution and submission (not less than `n` blocks) | optional |

internal/registry/registry.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,53 @@ package registry
33
// RegistryConfig represents the config structure for the Registry.
44
type RegistryConfig struct {
55
Addresses []string
6+
QueryIDs []uint64 `envconfig:"QUERY_IDS"`
67
}
78

89
// New instantiates a new *Registry based on the cfg.
910
func New(cfg *RegistryConfig) *Registry {
1011
r := &Registry{
1112
addresses: make(map[string]struct{}, len(cfg.Addresses)),
13+
queryIDs: make(map[uint64]struct{}, len(cfg.QueryIDs)),
1214
}
1315
for _, addr := range cfg.Addresses {
1416
r.addresses[addr] = struct{}{}
1517
}
18+
for _, queryID := range cfg.QueryIDs {
19+
r.queryIDs[queryID] = struct{}{}
20+
}
1621
return r
1722
}
1823

19-
// Registry is the relayer's watch list registry. It contains a list of addresses, and the relayer
20-
// only works with interchain queries that are under these addresses' ownership.
24+
// Registry is the relayer's watch list registry. It contains a list of addresses and a list of queryIDs,
25+
// and the relayer only works with interchain queries that are under these addresses' ownership and match the queryIDs.
2126
type Registry struct {
2227
addresses map[string]struct{}
28+
queryIDs map[uint64]struct{}
2329
}
2430

25-
// IsEmpty returns true if the registry addresses list is empty.
26-
func (r *Registry) IsEmpty() bool {
31+
// IsAddressesEmpty returns true if the registry addresses list is empty.
32+
func (r *Registry) IsAddressesEmpty() bool {
2733
return len(r.addresses) == 0
2834
}
2935

30-
// Contains returns true if the addr is in the registry.
31-
func (r *Registry) Contains(addr string) bool {
36+
// IsQueryIDsEmpty returns true if the registry queryIDs list is empty.
37+
func (r *Registry) IsQueryIDsEmpty() bool {
38+
return len(r.queryIDs) == 0
39+
}
40+
41+
// ContainsAddress returns true if the addr is in the registry.
42+
func (r *Registry) ContainsAddress(addr string) bool {
3243
_, ex := r.addresses[addr]
3344
return ex
3445
}
3546

47+
// ContainsQueryID returns true if the queryID is in the registry.
48+
func (r *Registry) ContainsQueryID(queryID uint64) bool {
49+
_, ex := r.queryIDs[queryID]
50+
return ex
51+
}
52+
3653
func (r *Registry) GetAddresses() []string {
3754
var out []string
3855
for addr := range r.addresses {

internal/registry/registry_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package registry_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/neutron-org/neutron-query-relayer/internal/registry"
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestRegistryWithEmptyAddressesAndEmptyQueryIDs(t *testing.T) {
11+
cfg := registry.RegistryConfig{}
12+
r := registry.New(&cfg)
13+
assert.True(t, r.IsAddressesEmpty())
14+
assert.True(t, r.IsQueryIDsEmpty())
15+
16+
assert.False(t, r.ContainsAddress("not_exist_address"))
17+
assert.False(t, r.ContainsQueryID(0))
18+
assert.False(t, r.ContainsQueryID(1))
19+
assert.Equal(t, []string(nil), r.GetAddresses())
20+
}
21+
22+
func TestRegistryWithAddressesAndEmptyQueryIDs(t *testing.T) {
23+
cfg := registry.RegistryConfig{
24+
Addresses: []string{"exist_address", "exist_address2"},
25+
}
26+
r := registry.New(&cfg)
27+
assert.False(t, r.IsAddressesEmpty())
28+
assert.True(t, r.ContainsAddress("exist_address"))
29+
assert.False(t, r.ContainsAddress("not_exist_address"))
30+
assert.ElementsMatch(t, []string{"exist_address", "exist_address2"}, r.GetAddresses())
31+
}
32+
33+
func TestRegistryWithAddressesAndQueryIDs(t *testing.T) {
34+
cfg := registry.RegistryConfig{
35+
Addresses: []string{"exist_address", "exist_address2"},
36+
QueryIDs: []uint64{0, 1},
37+
}
38+
r := registry.New(&cfg)
39+
assert.False(t, r.IsAddressesEmpty())
40+
assert.False(t, r.IsQueryIDsEmpty())
41+
assert.True(t, r.ContainsAddress("exist_address"))
42+
assert.False(t, r.ContainsAddress("not_exist_address"))
43+
assert.True(t, r.ContainsQueryID(0))
44+
assert.True(t, r.ContainsQueryID(1))
45+
assert.False(t, r.ContainsQueryID(2))
46+
}
47+
48+
func TestRegistryWithEmptyAddressesAndQueryIDs(t *testing.T) {
49+
cfg := registry.RegistryConfig{
50+
QueryIDs: []uint64{0, 1},
51+
}
52+
r := registry.New(&cfg)
53+
assert.True(t, r.IsAddressesEmpty())
54+
assert.False(t, r.IsQueryIDsEmpty())
55+
assert.False(t, r.ContainsAddress("not_exist_address"))
56+
assert.True(t, r.ContainsQueryID(0))
57+
assert.True(t, r.ContainsQueryID(1))
58+
assert.False(t, r.ContainsQueryID(2))
59+
}

internal/subscriber/subscriber.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ package subscriber
33
import (
44
"context"
55
"fmt"
6+
"strconv"
7+
"sync"
8+
"time"
9+
610
nlogger "github.com/neutron-org/neutron-logger"
711
"github.com/neutron-org/neutron-query-relayer/internal/app"
812
"github.com/neutron-org/neutron-query-relayer/internal/config"
913
"github.com/neutron-org/neutron-query-relayer/internal/relay"
10-
"sync"
11-
"time"
1214

1315
"github.com/neutron-org/neutron-query-relayer/internal/registry"
1416

@@ -31,8 +33,8 @@ type Config struct {
3133
ConnectionID string
3234
// WatchedTypes is the list of query types to be observed and handled.
3335
WatchedTypes []neutrontypes.InterchainQueryType
34-
// Registry is a watch list registry. It contains a list of addresses, and the Subscriber only
35-
// works with interchain queries and events that are under these addresses' ownership.
36+
// Registry is a watch list registry. It contains a list of addresses and a list of queryIDs, and the Subscriber only
37+
// works with interchain queries and events that are under ownership of these addresses and match the queryIDs.
3638
Registry *rg.Registry
3739
}
3840

@@ -216,6 +218,16 @@ func (s *Subscriber) processUpdateEvent(ctx context.Context, event tmtypes.Resul
216218
zap.String("query_id", queryID))
217219
continue
218220
}
221+
queryIDNumber, err := strconv.ParseUint(queryID, 10, 64)
222+
if err != nil {
223+
return fmt.Errorf("failed to parse queryID: %w", err)
224+
}
225+
226+
if !s.isWatchedQueryID(queryIDNumber) {
227+
s.logger.Debug("Skipping query (wrong queryID)", zap.String("owner", owner),
228+
zap.String("query_id", queryID))
229+
continue
230+
}
219231

220232
// Load all information about the neutronQuery directly from Neutron.
221233
neutronQuery, err := s.getNeutronRegisteredQuery(ctx, queryID)

0 commit comments

Comments
 (0)