Skip to content

Commit

Permalink
feat(08-wasm): querier plugins implemented (#5345)
Browse files Browse the repository at this point in the history
* imp: moved gas to internal

* fix: fixed compiler complaints

* feat: added 'QueryRouter' interface

* imp: passing the queryRouter to keeper

* Revert "fix: fixed compiler complaints"

This reverts commit 208e314.

* Revert "imp: moved gas to internal"

This reverts commit b45b605.

* fix(test): fixed keeper_test.go

* imp: initial querier template

* imp: moved querier to types

* fix: compiler complaints

* imp: removed querier from keeper

* feat: including default querier

* imp: added options

* feat: querier implemented fully

* docs: improved godocs

* imp: improved the querier

* style: improved styling of querier

* fix: fixed options

* fix: fixed options not being passed with config

* style: renamed variables

* imp: added review items

* imp: review items

* imp: set and get query plugins made private

* docs: added more godocs

* fix: default plugin not set

* imp: review items

* docs: added a godoc

---------

Co-authored-by: Carlos Rodriguez <carlos@interchain.io>
  • Loading branch information
srdtrk and Carlos Rodriguez authored Dec 12, 2023
1 parent 3e1998f commit e2bcb77
Show file tree
Hide file tree
Showing 13 changed files with 574 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package ibcwasm
import (
wasmvm "github.com/CosmWasm/wasmvm"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"

"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
)

var _ WasmEngine = (*wasmvm.VM)(nil)
Expand Down Expand Up @@ -115,3 +118,14 @@ type WasmEngine interface {
// Unpin is idempotent.
Unpin(checksum wasmvm.Checksum) error
}

type QueryRouter interface {
// Route returns the GRPCQueryHandler for a given query route path or nil
// if not found
Route(path string) baseapp.GRPCQueryHandler
}

type QueryPluginsI interface {
// HandleQuery will route the query to the correct plugin and return the result
HandleQuery(ctx sdk.Context, caller string, request wasmvmtypes.QueryRequest) ([]byte, error)
}
17 changes: 0 additions & 17 deletions modules/light-clients/08-wasm/internal/ibcwasm/querier.go

This file was deleted.

37 changes: 24 additions & 13 deletions modules/light-clients/08-wasm/internal/ibcwasm/wasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ package ibcwasm
import (
"errors"

wasmvm "github.com/CosmWasm/wasmvm"

"cosmossdk.io/collections"
storetypes "cosmossdk.io/core/store"
)

var (
vm WasmEngine

querier wasmvm.Querier
queryRouter QueryRouter
queryPlugins QueryPluginsI

// state management
Schema collections.Schema
Expand All @@ -36,19 +35,31 @@ func GetVM() WasmEngine {
return vm
}

// SetQuerier sets the custom wasm query handle for the 08-wasm module.
// If wasmQuerier is nil a default querier is used that return always an error for any query.
func SetQuerier(wasmQuerier wasmvm.Querier) {
if wasmQuerier == nil {
querier = &defaultQuerier{}
} else {
querier = wasmQuerier
// SetQueryRouter sets the custom wasm query router for the 08-wasm module.
// Panics if the queryRouter is nil.
func SetQueryRouter(router QueryRouter) {
if router == nil {
panic(errors.New("query router must be not nil"))
}
queryRouter = router
}

// GetQueryRouter returns the custom wasm query router for the 08-wasm module.
func GetQueryRouter() QueryRouter {
return queryRouter
}

// SetQueryPlugins sets the current query plugins
func SetQueryPlugins(plugins QueryPluginsI) {
if plugins == nil {
panic(errors.New("query plugins must be not nil"))
}
queryPlugins = plugins
}

// GetQuerier returns the custom wasm query handler for the 08-wasm module.
func GetQuerier() wasmvm.Querier {
return querier
// GetQueryPlugins returns the current query plugins
func GetQueryPlugins() QueryPluginsI {
return queryPlugins
}

// SetupWasmStoreService sets up the 08-wasm module's collections.
Expand Down
34 changes: 19 additions & 15 deletions modules/light-clients/08-wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ import (

storetypes "cosmossdk.io/core/store"
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/log"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/internal/ibcwasm"
"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
"github.com/cosmos/ibc-go/v8/modules/core/exported"
)

// Keeper defines the 08-wasm keeper
Expand All @@ -44,7 +42,8 @@ func NewKeeperWithVM(
clientKeeper types.ClientKeeper,
authority string,
vm ibcwasm.WasmEngine,
querier wasmvm.Querier,
queryRouter ibcwasm.QueryRouter,
opts ...Option,
) Keeper {
if clientKeeper == nil {
panic(errors.New("client keeper must be not nil"))
Expand All @@ -62,16 +61,25 @@ func NewKeeperWithVM(
panic(errors.New("authority must be non-empty"))
}

ibcwasm.SetVM(vm)
ibcwasm.SetQuerier(querier)
ibcwasm.SetupWasmStoreService(storeService)

return Keeper{
keeper := &Keeper{
cdc: cdc,
storeService: storeService,
clientKeeper: clientKeeper,
authority: authority,
}

// set query plugins to ensure there is a non-nil query plugin
// regardless of what options the user provides
ibcwasm.SetQueryPlugins(types.NewDefaultQueryPlugins())
for _, opt := range opts {
opt.apply(keeper)
}

ibcwasm.SetVM(vm)
ibcwasm.SetQueryRouter(queryRouter)
ibcwasm.SetupWasmStoreService(storeService)

return *keeper
}

// NewKeeperWithConfig creates a new Keeper instance with the provided Wasm configuration.
Expand All @@ -83,26 +91,22 @@ func NewKeeperWithConfig(
clientKeeper types.ClientKeeper,
authority string,
wasmConfig types.WasmConfig,
querier wasmvm.Querier,
queryRouter ibcwasm.QueryRouter,
opts ...Option,
) Keeper {
vm, err := wasmvm.NewVM(wasmConfig.DataDir, wasmConfig.SupportedCapabilities, types.ContractMemoryLimit, wasmConfig.ContractDebugMode, types.MemoryCacheSize)
if err != nil {
panic(fmt.Errorf("failed to instantiate new Wasm VM instance: %v", err))
}

return NewKeeperWithVM(cdc, storeService, clientKeeper, authority, vm, querier)
return NewKeeperWithVM(cdc, storeService, clientKeeper, authority, vm, queryRouter, opts...)
}

// GetAuthority returns the 08-wasm module's authority.
func (k Keeper) GetAuthority() string {
return k.authority
}

// Logger returns a module-specific logger.
func (Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName)
}

func (Keeper) storeWasmCode(ctx sdk.Context, code []byte, storeFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error)) ([]byte, error) {
var err error
if types.IsGzip(code) {
Expand Down
25 changes: 20 additions & 5 deletions modules/light-clients/08-wasm/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
GetSimApp(suite.chainA).IBCKeeper.ClientKeeper,
GetSimApp(suite.chainA).WasmClientKeeper.GetAuthority(),
ibcwasm.GetVM(),
nil,
GetSimApp(suite.chainA).GRPCQueryRouter(),
)
},
true,
Expand All @@ -173,7 +173,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
GetSimApp(suite.chainA).IBCKeeper.ClientKeeper,
"", // authority
ibcwasm.GetVM(),
nil,
GetSimApp(suite.chainA).GRPCQueryRouter(),
)
},
false,
Expand All @@ -188,7 +188,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
nil, // client keeper,
GetSimApp(suite.chainA).WasmClientKeeper.GetAuthority(),
ibcwasm.GetVM(),
nil,
GetSimApp(suite.chainA).GRPCQueryRouter(),
)
},
false,
Expand All @@ -203,7 +203,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
GetSimApp(suite.chainA).IBCKeeper.ClientKeeper,
GetSimApp(suite.chainA).WasmClientKeeper.GetAuthority(),
nil,
nil,
GetSimApp(suite.chainA).GRPCQueryRouter(),
)
},
false,
Expand All @@ -218,12 +218,27 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
GetSimApp(suite.chainA).IBCKeeper.ClientKeeper,
GetSimApp(suite.chainA).WasmClientKeeper.GetAuthority(),
ibcwasm.GetVM(),
nil,
GetSimApp(suite.chainA).GRPCQueryRouter(),
)
},
false,
errors.New("store service must be not nil"),
},
{
"failure: nil query router",
func() {
keeper.NewKeeperWithVM(
GetSimApp(suite.chainA).AppCodec(),
runtime.NewKVStoreService(GetSimApp(suite.chainA).GetKey(types.StoreKey)),
GetSimApp(suite.chainA).IBCKeeper.ClientKeeper,
GetSimApp(suite.chainA).WasmClientKeeper.GetAuthority(),
ibcwasm.GetVM(),
nil,
)
},
false,
errors.New("query router must be not nil"),
},
}

for _, tc := range testCases {
Expand Down
2 changes: 1 addition & 1 deletion modules/light-clients/08-wasm/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (m Migrator) MigrateChecksums(ctx sdk.Context) error {
return err
}

m.keeper.Logger(ctx).Info("successfully migrated Checksums to collections")
types.Logger(ctx).Info("successfully migrated Checksums to collections")
return nil
}

Expand Down
32 changes: 32 additions & 0 deletions modules/light-clients/08-wasm/keeper/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package keeper

import (
"errors"

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/internal/ibcwasm"
"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
)

// Option is an extension point to instantiate keeper with non default values
type Option interface {
apply(*Keeper)
}

type optsFn func(*Keeper)

func (f optsFn) apply(keeper *Keeper) {
f(keeper)
}

// WithQueryPlugins is an optional constructor parameter to pass custom query plugins for wasmVM requests.
// Missing fields will be filled with default queriers.
func WithQueryPlugins(plugins *types.QueryPlugins) Option {
return optsFn(func(_ *Keeper) {
currentPlugins, ok := ibcwasm.GetQueryPlugins().(*types.QueryPlugins)
if !ok {
panic(errors.New("invalid query plugins type"))
}
newPlugins := currentPlugins.Merge(plugins)
ibcwasm.SetQueryPlugins(&newPlugins)
})
}
Loading

0 comments on commit e2bcb77

Please sign in to comment.