Skip to content

Commit

Permalink
Use query routes in async_icq (#67)
Browse files Browse the repository at this point in the history
* better gas management

* better test

* lint

* lint
  • Loading branch information
nicolaslara authored and jtieri committed Jul 26, 2023
1 parent f5dd047 commit f359340
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 5 deletions.
7 changes: 4 additions & 3 deletions modules/async-icq/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/cosmos/ibc-apps/modules/async-icq/v4/types"
"github.com/tendermint/tendermint/libs/log"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -28,14 +29,14 @@ type Keeper struct {

scopedKeeper capabilitykeeper.ScopedKeeper

querier sdk.Queryable
queryRouter *baseapp.GRPCQueryRouter
}

// NewKeeper creates a new interchain query Keeper instance
func NewKeeper(
cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace,
ics4Wrapper types.ICS4Wrapper, channelKeeper types.ChannelKeeper, portKeeper types.PortKeeper,
scopedKeeper capabilitykeeper.ScopedKeeper, querier sdk.Queryable,
scopedKeeper capabilitykeeper.ScopedKeeper, queryRouter *baseapp.GRPCQueryRouter,
) Keeper {
// set KeyTable if it has not already been set
if !paramSpace.HasKeyTable() {
Expand All @@ -50,7 +51,7 @@ func NewKeeper(
channelKeeper: channelKeeper,
portKeeper: portKeeper,
scopedKeeper: scopedKeeper,
querier: querier,
queryRouter: queryRouter,
}
}

Expand Down
16 changes: 15 additions & 1 deletion modules/async-icq/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,23 @@ func (k Keeper) executeQuery(ctx sdk.Context, reqs []abci.RequestQuery) ([]byte,
return nil, err
}

resp := k.querier.Query(req)
route := k.queryRouter.Route(req.Path)
if route == nil {
return nil, errors.Wrapf(sdkerrors.ErrUnauthorized, "no route found for: %s", req.Path)
}

resp, err := route(ctx, abci.RequestQuery{
Data: req.Data,
Path: req.Path,
})
if err != nil {
return nil, err
}

// Remove non-deterministic fields from response
resps[i] = abci.ResponseQuery{
// Codespace is not currently part of consensus, but it will probablyy be added in the future
// Codespace: resp.Codespace,
Code: resp.Code,
Index: resp.Index,
Key: resp.Key,
Expand Down
88 changes: 88 additions & 0 deletions modules/async-icq/keeper/relay_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package keeper_test

import (
"fmt"

"github.com/cosmos/ibc-apps/modules/async-icq/v4/testing/simapp"
"github.com/cosmos/ibc-apps/modules/async-icq/v4/types"
abcitypes "github.com/tendermint/tendermint/abci/types"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"

clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
Expand Down Expand Up @@ -180,3 +184,87 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() {
})
}
}

func (suite *KeeperTestSuite) TestOutOfGasOnSlowQueries() {
path := NewICQPath(suite.chainA, suite.chainB)
suite.coordinator.SetupConnections(path)

err := SetupICQPath(path)
suite.Require().NoError(err)

q := banktypes.QueryAllBalancesRequest{
Address: suite.chainB.SenderAccount.GetAddress().String(),
Pagination: &query.PageRequest{
Offset: 0,
Limit: 100_000_000,
},
}
reqs := []abcitypes.RequestQuery{
{
Path: "/cosmos.bank.v1beta1.Query/AllBalances",
Data: simapp.GetSimApp(suite.chainB).AppCodec().MustMarshal(&q),
},
}
data, err := types.SerializeCosmosQuery(reqs)
suite.Require().NoError(err)

icqPacketData := types.InterchainQueryPacketData{
Data: data,
}
packetData := icqPacketData.GetBytes()

params := types.NewParams(true, []string{"/cosmos.bank.v1beta1.Query/AllBalances"})
simapp.GetSimApp(suite.chainB).ICQKeeper.SetParams(suite.chainB.GetContext(), params)

packet := channeltypes.NewPacket(
packetData,
suite.chainA.SenderAccount.GetSequence(),
path.EndpointA.ChannelConfig.PortID,
path.EndpointA.ChannelID,
path.EndpointB.ChannelConfig.PortID,
path.EndpointB.ChannelID,
clienttypes.NewHeight(1, 100),
0,
)

ctx := suite.chainB.GetContext()
ctx = ctx.WithGasMeter(sdk.NewGasMeter(2000))
// enough gas for this small query, but not for the larger one. This one should work
_, err = simapp.GetSimApp(suite.chainB).ICQKeeper.OnRecvPacket(ctx, packet)
suite.Require().NoError(err)

// fund account with 10_000 denoms
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
for i := 0; i < 10_000; i++ {
denom := fmt.Sprintf("denom%d", i)
err = simapp.GetSimApp(suite.chainB).BankKeeper.MintCoins(ctx, minttypes.ModuleName, sdk.NewCoins(sdk.NewInt64Coin(denom, 10)))
suite.Require().NoError(err)
err = simapp.GetSimApp(suite.chainB).BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, suite.chainB.SenderAccount.GetAddress(), sdk.NewCoins(sdk.NewInt64Coin(denom, 10)))
suite.Require().NoError(err)

}

// We need to call NextBlock() so that the context is committed. This doesn't matter as much anymore,
// but previous versions didn't pass the context to the query, so the test would've picked the previous
// block's data
suite.chainB.NextBlock()
ctx = suite.chainB.GetContext()

packet = channeltypes.NewPacket(
packetData,
suite.chainA.SenderAccount.GetSequence(),
path.EndpointA.ChannelConfig.PortID,
path.EndpointA.ChannelID,
path.EndpointB.ChannelConfig.PortID,
path.EndpointB.ChannelID,
clienttypes.NewHeight(1, 100),
0,
)
//

// and this one should panic
suite.Assert().Panics(func() {
ctx = ctx.WithGasMeter(sdk.NewGasMeter(2000))
_, _ = simapp.GetSimApp(suite.chainB).ICQKeeper.OnRecvPacket(ctx, packet)
}, "out of gas")
}
2 changes: 1 addition & 1 deletion modules/async-icq/testing/simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func NewSimApp(
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
scopedICQKeeper,
app.BaseApp, // may be replaced
app.BaseApp.GRPCQueryRouter(),
)

// Create IBC Router
Expand Down

0 comments on commit f359340

Please sign in to comment.