From e81d655287b645c7fda593a64392100c80b47847 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 12 Sep 2023 11:30:04 +0200 Subject: [PATCH 1/3] Start rework channel query --- x/wasm/keeper/query_plugins.go | 42 +++---- x/wasm/keeper/query_plugins_test.go | 129 ---------------------- x/wasm/keeper/wasmtesting/mock_keepers.go | 18 +-- x/wasm/types/expected_keepers.go | 2 +- 4 files changed, 32 insertions(+), 159 deletions(-) diff --git a/x/wasm/keeper/query_plugins.go b/x/wasm/keeper/query_plugins.go index 36290cad95..0ed8c57196 100644 --- a/x/wasm/keeper/query_plugins.go +++ b/x/wasm/keeper/query_plugins.go @@ -249,27 +249,29 @@ func IBCQuerier(wasm contractMetaDataSource, channelKeeper types.ChannelKeeper) } if request.ListChannels != nil { portID := request.ListChannels.PortID - channels := make(wasmvmtypes.IBCChannels, 0) - channelKeeper.IterateChannels(ctx, func(ch channeltypes.IdentifiedChannel) bool { - // it must match the port and be in open state - if (portID == "" || portID == ch.PortId) && ch.State == channeltypes.OPEN { - newChan := wasmvmtypes.IBCChannel{ - Endpoint: wasmvmtypes.IBCEndpoint{ - PortID: ch.PortId, - ChannelID: ch.ChannelId, - }, - CounterpartyEndpoint: wasmvmtypes.IBCEndpoint{ - PortID: ch.Counterparty.PortId, - ChannelID: ch.Counterparty.ChannelId, - }, - Order: ch.Ordering.String(), - Version: ch.Version, - ConnectionID: ch.ConnectionHops[0], - } - channels = append(channels, newChan) + if portID == "" { + portID = wasm.GetContractInfo(ctx, caller).IBCPortID + } + gotChannels := channelKeeper.GetAllChannelsWithPortPrefix(ctx, portID) + channels := make(wasmvmtypes.IBCChannels, 0, len(gotChannels)) + for _, ch := range gotChannels { + if ch.State != channeltypes.OPEN { + continue } - return false - }) + channels = append(channels, wasmvmtypes.IBCChannel{ + Endpoint: wasmvmtypes.IBCEndpoint{ + PortID: ch.PortId, + ChannelID: ch.ChannelId, + }, + CounterpartyEndpoint: wasmvmtypes.IBCEndpoint{ + PortID: ch.Counterparty.PortId, + ChannelID: ch.Counterparty.ChannelId, + }, + Order: ch.Ordering.String(), + Version: ch.Version, + ConnectionID: ch.ConnectionHops[0], + }) + } res := wasmvmtypes.ListChannelsResponse{ Channels: channels, } diff --git a/x/wasm/keeper/query_plugins_test.go b/x/wasm/keeper/query_plugins_test.go index d8e94ce8f9..89438be1d6 100644 --- a/x/wasm/keeper/query_plugins_test.go +++ b/x/wasm/keeper/query_plugins_test.go @@ -40,59 +40,6 @@ import ( ) func TestIBCQuerier(t *testing.T) { - myExampleChannels := []channeltypes.IdentifiedChannel{ - // this is returned - { - State: channeltypes.OPEN, - Ordering: channeltypes.ORDERED, - Counterparty: channeltypes.Counterparty{ - PortId: "counterPartyPortID", - ChannelId: "counterPartyChannelID", - }, - ConnectionHops: []string{"one"}, - Version: "v1", - PortId: "myPortID", - ChannelId: "myChannelID", - }, - // this is filtered out - { - State: channeltypes.INIT, - Ordering: channeltypes.UNORDERED, - Counterparty: channeltypes.Counterparty{ - PortId: "foobar", - }, - ConnectionHops: []string{"one"}, - Version: "initversion", - PortId: "initPortID", - ChannelId: "initChannelID", - }, - // this is returned - { - State: channeltypes.OPEN, - Ordering: channeltypes.UNORDERED, - Counterparty: channeltypes.Counterparty{ - PortId: "otherCounterPartyPortID", - ChannelId: "otherCounterPartyChannelID", - }, - ConnectionHops: []string{"other", "second"}, - Version: "otherVersion", - PortId: "otherPortID", - ChannelId: "otherChannelID", - }, - // this is filtered out - { - State: channeltypes.CLOSED, - Ordering: channeltypes.ORDERED, - Counterparty: channeltypes.Counterparty{ - PortId: "super", - ChannelId: "duper", - }, - ConnectionHops: []string{"no-more"}, - Version: "closedVersion", - PortId: "closedPortID", - ChannelId: "closedChannelID", - }, - } specs := map[string]struct { srcQuery *wasmvmtypes.IBCQuery wasmKeeper *mockWasmQueryKeeper @@ -112,82 +59,6 @@ func TestIBCQuerier(t *testing.T) { channelKeeper: &wasmtesting.MockChannelKeeper{}, expJSONResult: `{"port_id":"myIBCPortID"}`, }, - "query list channels - all": { - srcQuery: &wasmvmtypes.IBCQuery{ - ListChannels: &wasmvmtypes.ListChannelsQuery{}, - }, - channelKeeper: &wasmtesting.MockChannelKeeper{ - IterateChannelsFn: wasmtesting.MockChannelKeeperIterator(myExampleChannels), - }, - expJSONResult: `{ - "channels": [ - { - "endpoint": { - "port_id": "myPortID", - "channel_id": "myChannelID" - }, - "counterparty_endpoint": { - "port_id": "counterPartyPortID", - "channel_id": "counterPartyChannelID" - }, - "order": "ORDER_ORDERED", - "version": "v1", - "connection_id": "one" - }, - { - "endpoint": { - "port_id": "otherPortID", - "channel_id": "otherChannelID" - }, - "counterparty_endpoint": { - "port_id": "otherCounterPartyPortID", - "channel_id": "otherCounterPartyChannelID" - }, - "order": "ORDER_UNORDERED", - "version": "otherVersion", - "connection_id": "other" - } - ] -}`, - }, - "query list channels - filtered": { - srcQuery: &wasmvmtypes.IBCQuery{ - ListChannels: &wasmvmtypes.ListChannelsQuery{ - PortID: "otherPortID", - }, - }, - channelKeeper: &wasmtesting.MockChannelKeeper{ - IterateChannelsFn: wasmtesting.MockChannelKeeperIterator(myExampleChannels), - }, - expJSONResult: `{ - "channels": [ - { - "endpoint": { - "port_id": "otherPortID", - "channel_id": "otherChannelID" - }, - "counterparty_endpoint": { - "port_id": "otherCounterPartyPortID", - "channel_id": "otherCounterPartyChannelID" - }, - "order": "ORDER_UNORDERED", - "version": "otherVersion", - "connection_id": "other" - } - ] -}`, - }, - "query list channels - filtered empty": { - srcQuery: &wasmvmtypes.IBCQuery{ - ListChannels: &wasmvmtypes.ListChannelsQuery{ - PortID: "none-existing", - }, - }, - channelKeeper: &wasmtesting.MockChannelKeeper{ - IterateChannelsFn: wasmtesting.MockChannelKeeperIterator(myExampleChannels), - }, - expJSONResult: `{"channels": []}`, - }, "query channel": { srcQuery: &wasmvmtypes.IBCQuery{ Channel: &wasmvmtypes.ChannelQuery{ diff --git a/x/wasm/keeper/wasmtesting/mock_keepers.go b/x/wasm/keeper/wasmtesting/mock_keepers.go index f405869761..8cae741855 100644 --- a/x/wasm/keeper/wasmtesting/mock_keepers.go +++ b/x/wasm/keeper/wasmtesting/mock_keepers.go @@ -11,12 +11,12 @@ import ( ) type MockChannelKeeper struct { - GetChannelFn func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) - GetNextSequenceSendFn func(ctx sdk.Context, portID, channelID string) (uint64, bool) - ChanCloseInitFn func(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error - GetAllChannelsFn func(ctx sdk.Context) []channeltypes.IdentifiedChannel - IterateChannelsFn func(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) - SetChannelFn func(ctx sdk.Context, portID, channelID string, channel channeltypes.Channel) + GetChannelFn func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) + GetNextSequenceSendFn func(ctx sdk.Context, portID, channelID string) (uint64, bool) + ChanCloseInitFn func(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error + GetAllChannelsFn func(ctx sdk.Context) []channeltypes.IdentifiedChannel + SetChannelFn func(ctx sdk.Context, portID, channelID string, channel channeltypes.Channel) + GetAllChannelsWithPortPrefixFn func(ctx sdk.Context, portPrefix string) []channeltypes.IdentifiedChannel } func (m *MockChannelKeeper) GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) { @@ -47,11 +47,11 @@ func (m *MockChannelKeeper) ChanCloseInit(ctx sdk.Context, portID, channelID str return m.ChanCloseInitFn(ctx, portID, channelID, chanCap) } -func (m *MockChannelKeeper) IterateChannels(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) { - if m.IterateChannelsFn == nil { +func (m *MockChannelKeeper) GetAllChannelsWithPortPrefix(ctx sdk.Context, portPrefix string) []channeltypes.IdentifiedChannel { + if m.GetAllChannelsWithPortPrefixFn == nil { panic("not expected to be called") } - m.IterateChannelsFn(ctx, cb) + return m.GetAllChannelsWithPortPrefixFn(ctx, portPrefix) } func (m *MockChannelKeeper) SetChannel(ctx sdk.Context, portID, channelID string, channel channeltypes.Channel) { diff --git a/x/wasm/types/expected_keepers.go b/x/wasm/types/expected_keepers.go index 7f6e8a444f..720baaaaf4 100644 --- a/x/wasm/types/expected_keepers.go +++ b/x/wasm/types/expected_keepers.go @@ -82,8 +82,8 @@ type ChannelKeeper interface { GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) ChanCloseInit(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error GetAllChannels(ctx sdk.Context) (channels []channeltypes.IdentifiedChannel) - IterateChannels(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) SetChannel(ctx sdk.Context, portID, channelID string, channel channeltypes.Channel) + GetAllChannelsWithPortPrefix(ctx sdk.Context, portPrefix string) []channeltypes.IdentifiedChannel } // ICS4Wrapper defines the method for an IBC data package to be submitted. From 177c0a9218139d17be5f346b0c0510df5cb2e9a4 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Wed, 13 Sep 2023 15:20:26 +0200 Subject: [PATCH 2/3] Test channels query --- .../keeper/query_plugin_integration_test.go | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/x/wasm/keeper/query_plugin_integration_test.go b/x/wasm/keeper/query_plugin_integration_test.go index 496643bbd3..d35a18096a 100644 --- a/x/wasm/keeper/query_plugin_integration_test.go +++ b/x/wasm/keeper/query_plugin_integration_test.go @@ -9,6 +9,7 @@ import ( wasmvmtypes "github.com/CosmWasm/wasmvm/types" "github.com/cosmos/gogoproto/proto" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -642,6 +643,180 @@ func TestDistributionQuery(t *testing.T) { } } +func TestIBCListChannelsQuery(t *testing.T) { + cdc := MakeEncodingConfig(t).Codec + pCtx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc)), WithQueryPlugins(reflectPlugins())) + keeper := keepers.WasmKeeper + example := InstantiateReflectExampleContract(t, pCtx, keepers) + // add an ibc port for testing + myIBCPortID := "myValidPortID" + cInfo := keeper.GetContractInfo(pCtx, example.Contract) + cInfo.IBCPortID = myIBCPortID + keeper.storeContractInfo(pCtx, example.Contract, cInfo) + // store a random channel to be ignored in queries + unusedChan := channeltypes.Channel{ + State: channeltypes.OPEN, + Ordering: channeltypes.UNORDERED, + Counterparty: channeltypes.Counterparty{ + PortId: "counterPartyPortID", + ChannelId: "counterPartyChannelID", + }, + ConnectionHops: []string{"any"}, + Version: "any", + } + keepers.IBCKeeper.ChannelKeeper.SetChannel(pCtx, "nonContractPortID", "channel-99", unusedChan) + + // mixed channel examples for testing + myExampleChannels := []channeltypes.Channel{ + { + State: channeltypes.OPEN, + Ordering: channeltypes.ORDERED, + Counterparty: channeltypes.Counterparty{ + PortId: "counterPartyPortID", + ChannelId: "counterPartyChannelID", + }, + ConnectionHops: []string{"one"}, + Version: "v1", + }, + { + State: channeltypes.INIT, + Ordering: channeltypes.UNORDERED, + Counterparty: channeltypes.Counterparty{ + PortId: "foobar", + }, + ConnectionHops: []string{"one"}, + Version: "initversion", + }, + { + State: channeltypes.OPEN, + Ordering: channeltypes.UNORDERED, + Counterparty: channeltypes.Counterparty{ + PortId: "otherCounterPartyPortID", + ChannelId: "otherCounterPartyChannelID", + }, + ConnectionHops: []string{"other", "second"}, + Version: "otherVersion", + }, + { + State: channeltypes.CLOSED, + Ordering: channeltypes.ORDERED, + Counterparty: channeltypes.Counterparty{ + PortId: "super", + ChannelId: "duper", + }, + ConnectionHops: []string{"no-more"}, + Version: "closedVersion", + }, + } + + withChannelsStored := func(portID string, channels ...channeltypes.Channel) func(t *testing.T, ctx sdk.Context) sdk.Context { + return func(t *testing.T, ctx sdk.Context) sdk.Context { + for i, v := range channels { + keepers.IBCKeeper.ChannelKeeper.SetChannel(ctx, portID, fmt.Sprintf("channel-%d", i), v) + } + return ctx + } + } + noopSetup := func(t *testing.T, ctx sdk.Context) sdk.Context { return ctx } + + specs := map[string]struct { + setup func(t *testing.T, ctx sdk.Context) sdk.Context + query *wasmvmtypes.IBCQuery + expErr bool + assert func(t *testing.T, d []byte) + }{ + "only open channels - portID empty": { + setup: withChannelsStored(myIBCPortID, myExampleChannels...), + query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{}}, + assert: func(t *testing.T, d []byte) { + rsp := unmarshalReflect[wasmvmtypes.ListChannelsResponse](t, d) + exp := wasmvmtypes.ListChannelsResponse{Channels: []wasmvmtypes.IBCChannel{ + { + Endpoint: wasmvmtypes.IBCEndpoint{PortID: myIBCPortID, ChannelID: "channel-0"}, + CounterpartyEndpoint: wasmvmtypes.IBCEndpoint{ + PortID: "counterPartyPortID", + ChannelID: "counterPartyChannelID", + }, + Order: channeltypes.ORDERED.String(), + Version: "v1", + ConnectionID: "one", + }, { + Endpoint: wasmvmtypes.IBCEndpoint{PortID: myIBCPortID, ChannelID: "channel-2"}, + CounterpartyEndpoint: wasmvmtypes.IBCEndpoint{ + PortID: "otherCounterPartyPortID", + ChannelID: "otherCounterPartyChannelID", + }, + Order: channeltypes.UNORDERED.String(), + Version: "otherVersion", + ConnectionID: "other", + }, + }} + assert.Equal(t, exp, rsp) + }, + }, + "open channels - portID set to non contract addr": { + setup: withChannelsStored("OtherPortID", myExampleChannels...), + query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{PortID: "OtherPortID"}}, + assert: func(t *testing.T, d []byte) { + rsp := unmarshalReflect[wasmvmtypes.ListChannelsResponse](t, d) + exp := wasmvmtypes.ListChannelsResponse{Channels: []wasmvmtypes.IBCChannel{ + { + Endpoint: wasmvmtypes.IBCEndpoint{PortID: "OtherPortID", ChannelID: "channel-0"}, + CounterpartyEndpoint: wasmvmtypes.IBCEndpoint{ + PortID: "counterPartyPortID", + ChannelID: "counterPartyChannelID", + }, + Order: channeltypes.ORDERED.String(), + Version: "v1", + ConnectionID: "one", + }, { + Endpoint: wasmvmtypes.IBCEndpoint{PortID: "OtherPortID", ChannelID: "channel-2"}, + CounterpartyEndpoint: wasmvmtypes.IBCEndpoint{ + PortID: "otherCounterPartyPortID", + ChannelID: "otherCounterPartyChannelID", + }, + Order: channeltypes.UNORDERED.String(), + Version: "otherVersion", + ConnectionID: "other", + }, + }} + assert.Equal(t, exp, rsp) + }, + }, + "no channels": { + setup: noopSetup, + query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{}}, + assert: func(t *testing.T, d []byte) { + rsp := unmarshalReflect[wasmvmtypes.ListChannelsResponse](t, d) + assert.Empty(t, rsp.Channels) + }, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + ctx, _ := pCtx.CacheContext() + ctx = spec.setup(t, ctx) + + // when + queryBz := mustMarshal(t, testdata.ReflectQueryMsg{ + Chain: &testdata.ChainQuery{ + Request: &wasmvmtypes.QueryRequest{IBC: spec.query}, + }, + }) + simpleRes, gotErr := keeper.QuerySmart(ctx, example.Contract, queryBz) + if spec.expErr { + require.Error(t, gotErr) + return + } + // then + require.NoError(t, gotErr) + var rsp testdata.ChainResponse + mustUnmarshal(t, simpleRes, &rsp) + spec.assert(t, rsp.Data) + }) + } +} + func unmarshalReflect[T any](t *testing.T, d []byte) T { var v T mustUnmarshal(t, d, &v) From d5fa2780c1474fa6398c468ae21d6b01a3b45772 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Wed, 13 Sep 2023 16:31:41 +0200 Subject: [PATCH 3/3] Handle query for non ibc contracts --- .../keeper/query_plugin_integration_test.go | 48 ++++++++++++------- x/wasm/keeper/query_plugins.go | 41 ++++++++-------- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/x/wasm/keeper/query_plugin_integration_test.go b/x/wasm/keeper/query_plugin_integration_test.go index d35a18096a..83dea003b0 100644 --- a/x/wasm/keeper/query_plugin_integration_test.go +++ b/x/wasm/keeper/query_plugin_integration_test.go @@ -647,12 +647,13 @@ func TestIBCListChannelsQuery(t *testing.T) { cdc := MakeEncodingConfig(t).Codec pCtx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc)), WithQueryPlugins(reflectPlugins())) keeper := keepers.WasmKeeper - example := InstantiateReflectExampleContract(t, pCtx, keepers) + nonIbcExample := InstantiateReflectExampleContract(t, pCtx, keepers) + ibcExample := InstantiateReflectExampleContract(t, pCtx, keepers) // add an ibc port for testing myIBCPortID := "myValidPortID" - cInfo := keeper.GetContractInfo(pCtx, example.Contract) + cInfo := keeper.GetContractInfo(pCtx, ibcExample.Contract) cInfo.IBCPortID = myIBCPortID - keeper.storeContractInfo(pCtx, example.Contract, cInfo) + keeper.storeContractInfo(pCtx, ibcExample.Contract, cInfo) // store a random channel to be ignored in queries unusedChan := channeltypes.Channel{ State: channeltypes.OPEN, @@ -720,14 +721,16 @@ func TestIBCListChannelsQuery(t *testing.T) { noopSetup := func(t *testing.T, ctx sdk.Context) sdk.Context { return ctx } specs := map[string]struct { - setup func(t *testing.T, ctx sdk.Context) sdk.Context - query *wasmvmtypes.IBCQuery - expErr bool - assert func(t *testing.T, d []byte) + setup func(t *testing.T, ctx sdk.Context) sdk.Context + contract sdk.AccAddress + query *wasmvmtypes.IBCQuery + expErr bool + assert func(t *testing.T, d []byte) }{ - "only open channels - portID empty": { - setup: withChannelsStored(myIBCPortID, myExampleChannels...), - query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{}}, + "open channels - with query portID empty": { + contract: ibcExample.Contract, + setup: withChannelsStored(myIBCPortID, myExampleChannels...), + query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{}}, assert: func(t *testing.T, d []byte) { rsp := unmarshalReflect[wasmvmtypes.ListChannelsResponse](t, d) exp := wasmvmtypes.ListChannelsResponse{Channels: []wasmvmtypes.IBCChannel{ @@ -754,9 +757,10 @@ func TestIBCListChannelsQuery(t *testing.T) { assert.Equal(t, exp, rsp) }, }, - "open channels - portID set to non contract addr": { - setup: withChannelsStored("OtherPortID", myExampleChannels...), - query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{PortID: "OtherPortID"}}, + "open channels - with query portID passed": { + contract: ibcExample.Contract, + setup: withChannelsStored("OtherPortID", myExampleChannels...), + query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{PortID: "OtherPortID"}}, assert: func(t *testing.T, d []byte) { rsp := unmarshalReflect[wasmvmtypes.ListChannelsResponse](t, d) exp := wasmvmtypes.ListChannelsResponse{Channels: []wasmvmtypes.IBCChannel{ @@ -783,9 +787,19 @@ func TestIBCListChannelsQuery(t *testing.T) { assert.Equal(t, exp, rsp) }, }, - "no channels": { - setup: noopSetup, - query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{}}, + "non ibc contract - with query portID empty": { + contract: nonIbcExample.Contract, + setup: withChannelsStored(myIBCPortID, myExampleChannels...), + query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{}}, + assert: func(t *testing.T, d []byte) { + rsp := unmarshalReflect[wasmvmtypes.ListChannelsResponse](t, d) + assert.Nil(t, rsp.Channels) + }, + }, + "no matching channels": { + contract: ibcExample.Contract, + setup: noopSetup, + query: &wasmvmtypes.IBCQuery{ListChannels: &wasmvmtypes.ListChannelsQuery{}}, assert: func(t *testing.T, d []byte) { rsp := unmarshalReflect[wasmvmtypes.ListChannelsResponse](t, d) assert.Empty(t, rsp.Channels) @@ -803,7 +817,7 @@ func TestIBCListChannelsQuery(t *testing.T) { Request: &wasmvmtypes.QueryRequest{IBC: spec.query}, }, }) - simpleRes, gotErr := keeper.QuerySmart(ctx, example.Contract, queryBz) + simpleRes, gotErr := keeper.QuerySmart(ctx, spec.contract, queryBz) if spec.expErr { require.Error(t, gotErr) return diff --git a/x/wasm/keeper/query_plugins.go b/x/wasm/keeper/query_plugins.go index 0ed8c57196..c0d332f1ec 100644 --- a/x/wasm/keeper/query_plugins.go +++ b/x/wasm/keeper/query_plugins.go @@ -249,28 +249,31 @@ func IBCQuerier(wasm contractMetaDataSource, channelKeeper types.ChannelKeeper) } if request.ListChannels != nil { portID := request.ListChannels.PortID - if portID == "" { + if portID == "" { // then fallback to contract port address portID = wasm.GetContractInfo(ctx, caller).IBCPortID } - gotChannels := channelKeeper.GetAllChannelsWithPortPrefix(ctx, portID) - channels := make(wasmvmtypes.IBCChannels, 0, len(gotChannels)) - for _, ch := range gotChannels { - if ch.State != channeltypes.OPEN { - continue + var channels wasmvmtypes.IBCChannels + if portID != "" { // then return empty list for non ibc contracts; no channels possible + gotChannels := channelKeeper.GetAllChannelsWithPortPrefix(ctx, portID) + channels = make(wasmvmtypes.IBCChannels, 0, len(gotChannels)) + for _, ch := range gotChannels { + if ch.State != channeltypes.OPEN { + continue + } + channels = append(channels, wasmvmtypes.IBCChannel{ + Endpoint: wasmvmtypes.IBCEndpoint{ + PortID: ch.PortId, + ChannelID: ch.ChannelId, + }, + CounterpartyEndpoint: wasmvmtypes.IBCEndpoint{ + PortID: ch.Counterparty.PortId, + ChannelID: ch.Counterparty.ChannelId, + }, + Order: ch.Ordering.String(), + Version: ch.Version, + ConnectionID: ch.ConnectionHops[0], + }) } - channels = append(channels, wasmvmtypes.IBCChannel{ - Endpoint: wasmvmtypes.IBCEndpoint{ - PortID: ch.PortId, - ChannelID: ch.ChannelId, - }, - CounterpartyEndpoint: wasmvmtypes.IBCEndpoint{ - PortID: ch.Counterparty.PortId, - ChannelID: ch.Counterparty.ChannelId, - }, - Order: ch.Ordering.String(), - Version: ch.Version, - ConnectionID: ch.ConnectionHops[0], - }) } res := wasmvmtypes.ListChannelsResponse{ Channels: channels,