mirror of https://github.com/certusone/wasmd.git
Properly charge gas on sub-queries, tests pass
This commit is contained in:
parent
b97c87212c
commit
ea5ae47ffd
2
go.mod
2
go.mod
|
@ -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
2
go.sum
|
@ -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=
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue