CosmWasm / CosmWasm/wasmd

design: Why does consumeGas panic & not return an error?

Open
#1,771 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
416
Forks
538
PR merge metrics
No merged PRs in 30d

Description

[func (k Keeper) consumeRuntimeGas(ctx sdk.Context, gas uint64) ](https://github.com/CosmWasm/wasmd/blob/d0dde1a0f12c93507f5b0842968dd4588b5df043/x/wasm/keeper/keeper.go#L1111-L1118) panics in function calls such as [`Sudo`](https://github.com/CosmWasm/wasmd/blob/d0dde1a0f12c93507f5b0842968dd4588b5df043/x/wasm/keeper/keeper.go#L538-L541) calls even though an error for this function is thrown

For developers, this is unexpected behavior, especially when using a childCtx with a gas limit, expecting an error to be thrown.

It then required work around like the following from Juno with a `recover()`
```go
// Execute contract, recover from panic
func ExecuteContract(k wasmtypes.ContractOpsKeeper, childCtx sdk.Context, contractAddr sdk.AccAddress, msgBz []byte, err *error) {
// Recover from panic, return error
defer func() {
if recoveryError := recover(); recoveryError != nil {
// Determine error associated with panic
if isOutofGas, msg := IsOutOfGasError(recoveryError); isOutofGas {
*err = ErrOutOfGas.Wrapf("%s", msg)
} else {
*err = ErrContractExecutionPanic.Wrapf("%s", recoveryError)
}
}
}()

// Execute contract with sudo
_, *err = k.Sudo(childCtx, contractAddr, msgBz)
}

// Check if error is out of gas error
func IsOutOfGasError(err any) (bool, string) {
switch e := err.(type) {
case storetypes.ErrorOutOfGas:
return true, e.Descriptor
case storetypes.ErrorGasOverflow:
return true, e.Descriptor
default:
return false, ""
}
}
```

This just seems wrong given Sudo already returns an error, so persist a Gas error up?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.