Properly charge gas on sub-queries, tests pass

This commit is contained in:
Ethan Frey 2020-07-29 22:08:34 +02:00
parent b97c87212c
commit ea5ae47ffd
4 changed files with 22 additions and 18 deletions

2
go.mod
View File

@ -3,7 +3,7 @@ module github.com/CosmWasm/wasmd
go 1.13
require (
github.com/CosmWasm/go-cosmwasm v0.10.0-alpha3
github.com/CosmWasm/go-cosmwasm v0.10.0-alpha3.0.20200729195610-18b861d95ddb
github.com/cosmos/cosmos-sdk v0.39.1-0.20200727135228-9d00f712e334
github.com/golang/mock v1.4.3 // indirect
github.com/google/gofuzz v1.0.0

2
go.sum
View File

@ -13,6 +13,8 @@ github.com/CosmWasm/go-cosmwasm v0.10.0-alpha2 h1:k069wQF0f24w3A52mjR3AK6AfkuvQ5
github.com/CosmWasm/go-cosmwasm v0.10.0-alpha2/go.mod h1:gAFCwllx97ejI+m9SqJQrmd2SBW7HA0fOjvWWJjM2uc=
github.com/CosmWasm/go-cosmwasm v0.10.0-alpha3 h1:+LJxN6oHNdHDoB9JT8v6Zh373MvBbFkKoikSnh4GGWM=
github.com/CosmWasm/go-cosmwasm v0.10.0-alpha3/go.mod h1:gAFCwllx97ejI+m9SqJQrmd2SBW7HA0fOjvWWJjM2uc=
github.com/CosmWasm/go-cosmwasm v0.10.0-alpha3.0.20200729195610-18b861d95ddb h1:JHeFb9Dle3c3RvXkxZbo6YURaS3aQf+7zdUn5P3TP04=
github.com/CosmWasm/go-cosmwasm v0.10.0-alpha3.0.20200729195610-18b861d95ddb/go.mod h1:gAFCwllx97ejI+m9SqJQrmd2SBW7HA0fOjvWWJjM2uc=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=

View File

@ -2,8 +2,6 @@ package keeper
import (
"encoding/json"
"fmt"
wasmTypes "github.com/CosmWasm/go-cosmwasm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
@ -18,26 +16,30 @@ type QueryHandler struct {
var _ wasmTypes.Querier = QueryHandler{}
func (q QueryHandler) Query(request wasmTypes.QueryRequest, gasLimit uint64) (res []byte, err error) {
func (q QueryHandler) Query(request wasmTypes.QueryRequest, gasLimit uint64) ([]byte, error) {
// set a limit for a subctx
sdkGas := gasLimit / GasMultiplier
fmt.Printf("Sdk gas %d, wasmer gas: %d\n", sdkGas, gasLimit)
subctx := q.Ctx.WithGasMeter(sdk.NewGasMeter(gasLimit / GasMultiplier))
res, err = nil, wasmTypes.Unknown{}
subctx := q.Ctx.WithGasMeter(sdk.NewGasMeter(sdkGas))
// make sure we charge the higher level context even on panic
defer func() {
q.Ctx.GasMeter().ConsumeGas(subctx.GasMeter().GasConsumed(), "contract sub-query")
}()
// do the query
if request.Bank != nil {
res, err = q.Plugins.Bank(subctx, request.Bank)
return q.Plugins.Bank(subctx, request.Bank)
}
if request.Custom != nil {
res, err = q.Plugins.Custom(subctx, request.Custom)
return q.Plugins.Custom(subctx, request.Custom)
}
if request.Staking != nil {
res, err = q.Plugins.Staking(subctx, request.Staking)
return q.Plugins.Staking(subctx, request.Staking)
}
if request.Wasm != nil {
res, err = q.Plugins.Wasm(subctx, request.Wasm)
return q.Plugins.Wasm(subctx, request.Wasm)
}
fmt.Printf("charged: %d\n", subctx.GasMeter().GasConsumed())
q.Ctx.GasMeter().ConsumeGas(subctx.GasMeter().GasConsumed(), "contract sub-query")
return res, err
return nil, wasmTypes.Unknown{}
}
func (q QueryHandler) GasConsumed() uint64 {

View File

@ -35,7 +35,6 @@ type recurseResponse struct {
Hashed []byte `json:"hashed"`
}
// number os wasm queries called from a contract
var totalWasmQueryCounter int
@ -228,7 +227,8 @@ func TestGasOnExternalQuery(t *testing.T) {
if tc.expectPanic {
require.Panics(t, func() {
// this should run out of gas
_, _ = NewQuerier(keeper)(ctx, path, req)
_, err := NewQuerier(keeper)(ctx, path, req)
t.Logf("%v", err)
})
} else {
// otherwise, make sure we get a good success
@ -280,7 +280,7 @@ func TestLimitRecursiveQueryGas(t *testing.T) {
expectedGas: GasWork2k + 5*(GasWork2k+GasReturnHashed),
},
// this is where we expect an error...
// it has enough gas to run 4 times and die on the 5th
// it has enough gas to run 4 times and die on the 5th (4th time dispatching to sub-contract)
// however, if we don't charge the cpu gas before sub-dispatching, we can recurse over 20 times
// TODO: figure out how to asset how deep it went
"deep recursion, should die on 5th level": {
@ -289,7 +289,7 @@ func TestLimitRecursiveQueryGas(t *testing.T) {
Depth: 50,
Work: 2000,
},
expectQueriesFromContract: 5,
expectQueriesFromContract: 4,
expectOutOfGas: true,
},
}