Properly charge gas in keeper

This commit is contained in:
Ethan Frey
2020-07-27 13:44:18 +02:00
parent fa5d338509
commit f74e077a27
3 changed files with 20 additions and 8 deletions

View File

@@ -399,8 +399,6 @@ func (k Keeper) GetContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress)
func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error) {
ctx.GasMeter().ConsumeGas(InstanceCost, "Loading CosmWasm module: query")
ctx = ctx.WithGasMeter(sdk.NewGasMeter(k.queryGasLimit))
codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr)
if err != nil {
return nil, err

View File

@@ -144,6 +144,8 @@ func queryContractState(ctx sdk.Context, bech, queryMethod string, req abci.Requ
// this returns a serialized json object
resultData = keeper.QueryRaw(ctx, contractAddr, req.Data)
case QueryMethodContractStateSmart:
// we enforce a subjective gas limit on all queries to avoid infinite loops
ctx = ctx.WithGasMeter(sdk.NewGasMeter(keeper.queryGasLimit))
// this returns raw bytes (must be base64-encoded)
return keeper.QuerySmart(ctx, contractAddr, req.Data)
default:

View File

@@ -34,19 +34,28 @@ type recurseResponse struct {
}
func TestGasCostOnQuery(t *testing.T) {
const (
GasNoWork uint64 = InstanceCost + 2_756
// Note: about 100 SDK gas (10k wasmer gas) for each round of sha256
GasWork50 uint64 = InstanceCost + 8_464
)
cases := map[string]struct {
gasLimit uint64
msg Recurse
gasLimit uint64
msg Recurse
expectedGas uint64
}{
"no recursion, no work": {
gasLimit: 400_000,
msg: Recurse{},
gasLimit: 400_000,
msg: Recurse{},
expectedGas: GasNoWork,
},
"no recursion, some work": {
gasLimit: 400_000,
msg: Recurse{
Work: 5, // 5 rounds of sha256 inside the contract
Work: 50, // 50 rounds of sha256 inside the contract
},
expectedGas: GasWork50,
},
}
@@ -96,12 +105,15 @@ func TestGasCostOnQuery(t *testing.T) {
err = json.Unmarshal(data, &resp)
require.NoError(t, err)
// TODO: assert result? - now just that it is 32 byte sha256 hash (or contractAddr if no hash)
// assert result is 32 byte sha256 hash (if hashed), or contractAddr if not
if recurse.Work == 0 {
assert.Equal(t, len(resp.Hashed), len(creator.String()))
} else {
assert.Equal(t, len(resp.Hashed), 32)
}
// check the gas is what we expected
assert.Equal(t, tc.expectedGas, ctx.GasMeter().GasConsumed())
})
}
}