design: Why does consumeGas panic & not return an error?
Reecepbcups opened this issue · 0 comments
Reecepbcups commented
func (k Keeper) consumeRuntimeGas(ctx sdk.Context, gas uint64) panics in function calls such as Sudo
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()
// 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?