diff --git a/x/wasm/internal/keeper/keeper.go b/x/wasm/internal/keeper/keeper.go index 4a560f4..8e47d7b 100644 --- a/x/wasm/internal/keeper/keeper.go +++ b/x/wasm/internal/keeper/keeper.go @@ -28,7 +28,7 @@ import ( // Rough timing have 88k gas at 90us, which is equal to 1k sdk gas... (one read) // // Please not that all gas prices returned to the wasmer engine should have this multiplied -var GasMultiplier uint64 = 100 +const GasMultiplier uint64 = 100 // MaxGas for a contract is 10 billion wasmer gas (enforced in rust to prevent overflow) // The limit for v0.9.3 is defined here: https://github.com/CosmWasm/cosmwasm/blob/v0.9.3/packages/vm/src/backends/singlepass.rs#L15-L23 @@ -573,6 +573,10 @@ func gasForContract(ctx sdk.Context) uint64 { func consumeGas(ctx sdk.Context, gas uint64) { consumed := gas / GasMultiplier ctx.GasMeter().ConsumeGas(consumed, "wasm contract") + // throw OutOfGas error if we ran out (got exactly to zero due to better limit enforcing) + if ctx.GasMeter().IsOutOfGas() { + panic(sdk.ErrorOutOfGas{"Wasmer function execution"}) + } } // generates a contract address from codeID + instanceID diff --git a/x/wasm/internal/keeper/keeper_test.go b/x/wasm/internal/keeper/keeper_test.go index 0128680..128b27e 100644 --- a/x/wasm/internal/keeper/keeper_test.go +++ b/x/wasm/internal/keeper/keeper_test.go @@ -710,11 +710,18 @@ func TestExecuteWithCpuLoop(t *testing.T) { ctx = ctx.WithGasMeter(sdk.NewGasMeter(gasLimit)) require.Equal(t, uint64(0), ctx.GasMeter().GasConsumed()) - // this must fail + // ensure we get an out of gas panic + defer func() { + r := recover() + require.NotNil(t, r) + _, ok := r.(sdk.ErrorOutOfGas) + require.True(t, ok, "%v", r) + }() + + // this should throw out of gas exception (panic) _, err = keeper.Execute(ctx, addr, fred, []byte(`{"cpu_loop":{}}`), nil) - assert.Error(t, err) - // make sure gas ran out - require.Equal(t, gasLimit, ctx.GasMeter().GasConsumed()) + require.True(t, false, "We must panic before this line") + } func TestExecuteWithStorageLoop(t *testing.T) { @@ -755,16 +762,12 @@ func TestExecuteWithStorageLoop(t *testing.T) { defer func() { r := recover() require.NotNil(t, r) - // TODO: ensure it is out of gas error _, ok := r.(sdk.ErrorOutOfGas) require.True(t, ok, "%v", r) }() // this should throw out of gas exception (panic) _, err = keeper.Execute(ctx, addr, fred, []byte(`{"storage_loop":{}}`), nil) - // these are points for "out of gas", but why not a panic? - require.Equal(t, gasLimit, ctx.GasMeter().GasConsumed()) - require.Error(t, err) require.True(t, false, "We must panic before this line") }