Some checks failed
CodeQL / Analyze (push) Waiting to run
golangci-lint / lint (push) Waiting to run
Tests / Code Coverage / build (amd64) (push) Waiting to run
Tests / Code Coverage / build (arm64) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[additional-args:-tags="test_e2e" name:e2e path:./e2e]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:08-wasm path:./modules/light-clients/08-wasm]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:ibc-go path:.]) (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (push) Has been cancelled
61 lines
2.3 KiB
Go
61 lines
2.3 KiB
Go
package internal
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
errorsmod "cosmossdk.io/errors"
|
|
storetypes "cosmossdk.io/store/types"
|
|
|
|
sdk "git.cw.tr/mukan-network/mukan-sdk/types"
|
|
|
|
"git.cw.tr/mukan-network/mukan-ibc/modules/apps/callbacks/types"
|
|
)
|
|
|
|
// ProcessCallback executes the callbackExecutor and reverts contract changes if the callbackExecutor fails.
|
|
//
|
|
// Error Precedence and Returns:
|
|
// - oogErr: Takes the highest precedence. If the callback runs out of gas, an error wrapped with types.ErrCallbackOutOfGas is returned.
|
|
// - panicErr: Takes the second-highest precedence. If a panic occurs and it is not propagated, an error wrapped with types.ErrCallbackPanic is returned.
|
|
// - callbackErr: If the callbackExecutor returns an error, it is returned as-is.
|
|
//
|
|
// panics if
|
|
// - the contractExecutor panics for any reason, and the callbackType is SendPacket, or
|
|
// - the contractExecutor runs out of gas and the relayer has not reserved gas grater than or equal to
|
|
// CommitGasLimit.
|
|
func ProcessCallback(
|
|
ctx sdk.Context, callbackType types.CallbackType,
|
|
callbackData types.CallbackData, callbackExecutor func(sdk.Context) error,
|
|
) (err error) {
|
|
cachedCtx, writeFn := ctx.CacheContext()
|
|
cachedCtx = cachedCtx.WithGasMeter(storetypes.NewGasMeter(callbackData.ExecutionGasLimit))
|
|
|
|
defer func() {
|
|
// consume the minimum of g.consumed and g.limit
|
|
ctx.GasMeter().ConsumeGas(cachedCtx.GasMeter().GasConsumedToLimit(), fmt.Sprintf("ibc %s callback", callbackType))
|
|
|
|
// recover from all panics except during SendPacket callbacks
|
|
if r := recover(); r != nil {
|
|
if callbackType == types.CallbackTypeSendPacket {
|
|
panic(r)
|
|
}
|
|
err = errorsmod.Wrapf(types.ErrCallbackPanic, "ibc %s callback panicked with: %v", callbackType, r)
|
|
}
|
|
|
|
// if the callback ran out of gas and the relayer has not reserved enough gas, then revert the state
|
|
if cachedCtx.GasMeter().IsPastLimit() {
|
|
if callbackData.AllowRetry() {
|
|
panic(storetypes.ErrorOutOfGas{Descriptor: fmt.Sprintf("ibc %s callback out of gas; commitGasLimit: %d", callbackType, callbackData.CommitGasLimit)})
|
|
}
|
|
err = errorsmod.Wrapf(types.ErrCallbackOutOfGas, "ibc %s callback out of gas", callbackType)
|
|
}
|
|
|
|
// allow the transaction to be committed, continuing the packet lifecycle
|
|
}()
|
|
|
|
err = callbackExecutor(cachedCtx)
|
|
if err == nil {
|
|
writeFn()
|
|
}
|
|
|
|
return err
|
|
}
|