Skip to content

Commit

Permalink
Ensure query isolation (#611)
Browse files Browse the repository at this point in the history
* Ensure query isolation

* Review feedback
  • Loading branch information
alpe authored Sep 14, 2021
1 parent 454576a commit a447ee0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
31 changes: 31 additions & 0 deletions x/wasm/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1652,6 +1652,37 @@ func TestReply(t *testing.T) {
}
}

func TestQueryIsolation(t *testing.T) {
ctx, keepers := CreateTestInput(t, false, SupportedFeatures)
k := keepers.WasmKeeper
var mock wasmtesting.MockWasmer
wasmtesting.MakeInstantiable(&mock)
example := SeedNewContractInstance(t, ctx, keepers, &mock)
WithQueryHandlerDecorator(func(other WasmVMQueryHandler) WasmVMQueryHandler {
return WasmVMQueryHandlerFn(func(ctx sdk.Context, caller sdk.AccAddress, request wasmvmtypes.QueryRequest) ([]byte, error) {
if request.Custom == nil {
return other.HandleQuery(ctx, caller, request)
}
// here we write to DB which should not be persisted
ctx.KVStore(k.storeKey).Set([]byte(`set_in_query`), []byte(`this_is_allowed`))
return nil, nil
})
}).apply(k)

// when
mock.ReplyFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, reply wasmvmtypes.Reply, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
_, err := querier.Query(wasmvmtypes.QueryRequest{
Custom: []byte(`{}`),
}, 1_000_000)
require.NoError(t, err)
return &wasmvmtypes.Response{}, 0, nil
}
em := sdk.NewEventManager()
_, gotErr := k.reply(ctx.WithEventManager(em), example.Contract, wasmvmtypes.Reply{})
require.NoError(t, gotErr)
assert.Nil(t, ctx.KVStore(k.storeKey).Get([]byte(`set_in_query`)))
}

func TestBuildContractAddress(t *testing.T) {
specs := map[string]struct {
srcCodeID uint64
Expand Down
9 changes: 5 additions & 4 deletions x/wasm/keeper/query_plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,16 @@ type GRPCQueryRouter interface {
var _ wasmvmtypes.Querier = QueryHandler{}

func (q QueryHandler) Query(request wasmvmtypes.QueryRequest, gasLimit uint64) ([]byte, error) {
// set a limit for a subctx
// set a limit for a subCtx
sdkGas := q.gasRegister.FromWasmVMGas(gasLimit)
subctx := q.Ctx.WithGasMeter(sdk.NewGasMeter(sdkGas))
// discard all changes/ events in subCtx by not committing the cached context
subCtx, _ := q.Ctx.WithGasMeter(sdk.NewGasMeter(sdkGas)).CacheContext()

// make sure we charge the higher level context even on panic
defer func() {
q.Ctx.GasMeter().ConsumeGas(subctx.GasMeter().GasConsumed(), "contract sub-query")
q.Ctx.GasMeter().ConsumeGas(subCtx.GasMeter().GasConsumed(), "contract sub-query")
}()
return q.Plugins.HandleQuery(subctx, q.Caller, request)
return q.Plugins.HandleQuery(subCtx, q.Caller, request)
}

func (q QueryHandler) GasConsumed() uint64 {
Expand Down

0 comments on commit a447ee0

Please sign in to comment.