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
281 lines
9 KiB
Go
281 lines
9 KiB
Go
package controller
|
|
|
|
import (
|
|
"errors"
|
|
|
|
errorsmod "cosmossdk.io/errors"
|
|
|
|
sdk "git.cw.tr/mukan-network/mukan-sdk/types"
|
|
|
|
"git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/controller/keeper"
|
|
"git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/controller/types"
|
|
icatypes "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/types"
|
|
clienttypes "git.cw.tr/mukan-network/mukan-ibc/modules/core/02-client/types"
|
|
channeltypes "git.cw.tr/mukan-network/mukan-ibc/modules/core/04-channel/types"
|
|
porttypes "git.cw.tr/mukan-network/mukan-ibc/modules/core/05-port/types"
|
|
ibcerrors "git.cw.tr/mukan-network/mukan-ibc/modules/core/errors"
|
|
ibcexported "git.cw.tr/mukan-network/mukan-ibc/modules/core/exported"
|
|
)
|
|
|
|
var (
|
|
_ porttypes.Middleware = (*IBCMiddleware)(nil)
|
|
_ porttypes.PacketDataUnmarshaler = (*IBCMiddleware)(nil)
|
|
)
|
|
|
|
// IBCMiddleware implements the ICS26 callbacks for the controller middleware given the
|
|
// ICA controller keeper and the underlying application.
|
|
type IBCMiddleware struct {
|
|
app porttypes.IBCModule
|
|
keeper keeper.Keeper
|
|
}
|
|
|
|
// NewIBCMiddleware creates a new IBCMiddleware given the associated keeper.
|
|
// The underlying application is set to nil and authentication is assumed to
|
|
// be performed by a Cosmos SDK module that sends messages to controller message server.
|
|
func NewIBCMiddleware(k keeper.Keeper) IBCMiddleware {
|
|
return IBCMiddleware{
|
|
app: nil,
|
|
keeper: k,
|
|
}
|
|
}
|
|
|
|
// NewIBCMiddlewareWithAuth creates a new IBCMiddleware given the associated keeper and underlying application
|
|
func NewIBCMiddlewareWithAuth(app porttypes.IBCModule, k keeper.Keeper) IBCMiddleware {
|
|
return IBCMiddleware{
|
|
app: app,
|
|
keeper: k,
|
|
}
|
|
}
|
|
|
|
// OnChanOpenInit implements the IBCMiddleware interface
|
|
//
|
|
// Interchain Accounts is implemented to act as middleware for connected authentication modules on
|
|
// the controller side. The connected modules may not change the controller side portID or
|
|
// version. They will be allowed to perform custom logic without changing
|
|
// the parameters stored within a channel struct.
|
|
func (im IBCMiddleware) OnChanOpenInit(
|
|
ctx sdk.Context,
|
|
order channeltypes.Order,
|
|
connectionHops []string,
|
|
portID string,
|
|
channelID string,
|
|
counterparty channeltypes.Counterparty,
|
|
version string,
|
|
) (string, error) {
|
|
if !im.keeper.GetParams(ctx).ControllerEnabled {
|
|
return "", types.ErrControllerSubModuleDisabled
|
|
}
|
|
|
|
version, err := im.keeper.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, counterparty, version)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// call underlying app's OnChanOpenInit callback with the passed in version
|
|
// the version returned is discarded as the ica-auth module does not have permission to edit the version string.
|
|
// ics27 will always return the version string containing the Metadata struct which is created during the `RegisterInterchainAccount` call.
|
|
if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, portID, connectionHops[0]) {
|
|
if _, err := im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, counterparty, version); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
return version, nil
|
|
}
|
|
|
|
// OnChanOpenTry implements the IBCMiddleware interface
|
|
func (IBCMiddleware) OnChanOpenTry(
|
|
ctx sdk.Context,
|
|
order channeltypes.Order,
|
|
connectionHops []string,
|
|
portID,
|
|
channelID string,
|
|
counterparty channeltypes.Counterparty,
|
|
counterpartyVersion string,
|
|
) (string, error) {
|
|
return "", errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain")
|
|
}
|
|
|
|
// OnChanOpenAck implements the IBCMiddleware interface
|
|
//
|
|
// Interchain Accounts is implemented to act as middleware for connected authentication modules on
|
|
// the controller side. The connected modules may not change the portID or
|
|
// version. They will be allowed to perform custom logic without changing
|
|
// the parameters stored within a channel struct.
|
|
func (im IBCMiddleware) OnChanOpenAck(
|
|
ctx sdk.Context,
|
|
portID,
|
|
channelID string,
|
|
counterpartyChannelID string,
|
|
counterpartyVersion string,
|
|
) error {
|
|
if !im.keeper.GetParams(ctx).ControllerEnabled {
|
|
return types.ErrControllerSubModuleDisabled
|
|
}
|
|
|
|
if err := im.keeper.OnChanOpenAck(ctx, portID, channelID, counterpartyVersion); err != nil {
|
|
return err
|
|
}
|
|
|
|
connectionID, err := im.keeper.GetConnectionID(ctx, portID, channelID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// call underlying app's OnChanOpenAck callback with the counterparty app version.
|
|
if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, portID, connectionID) {
|
|
return im.app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// OnChanOpenConfirm implements the IBCMiddleware interface
|
|
func (IBCMiddleware) OnChanOpenConfirm(
|
|
ctx sdk.Context,
|
|
portID,
|
|
channelID string,
|
|
) error {
|
|
return errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain")
|
|
}
|
|
|
|
// OnChanCloseInit implements the IBCMiddleware interface
|
|
func (IBCMiddleware) OnChanCloseInit(
|
|
ctx sdk.Context,
|
|
portID,
|
|
channelID string,
|
|
) error {
|
|
// Disallow user-initiated channel closing for interchain account channels
|
|
return errorsmod.Wrap(ibcerrors.ErrInvalidRequest, "user cannot close channel")
|
|
}
|
|
|
|
// OnChanCloseConfirm implements the IBCMiddleware interface
|
|
func (im IBCMiddleware) OnChanCloseConfirm(
|
|
ctx sdk.Context,
|
|
portID,
|
|
channelID string,
|
|
) error {
|
|
if err := im.keeper.OnChanCloseConfirm(ctx, portID, channelID); err != nil {
|
|
return err
|
|
}
|
|
|
|
connectionID, err := im.keeper.GetConnectionID(ctx, portID, channelID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, portID, connectionID) {
|
|
return im.app.OnChanCloseConfirm(ctx, portID, channelID)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// OnRecvPacket implements the IBCMiddleware interface
|
|
func (IBCMiddleware) OnRecvPacket(
|
|
ctx sdk.Context,
|
|
_ string,
|
|
packet channeltypes.Packet,
|
|
_ sdk.AccAddress,
|
|
) ibcexported.Acknowledgement {
|
|
err := errorsmod.Wrapf(icatypes.ErrInvalidChannelFlow, "cannot receive packet on controller chain")
|
|
ack := channeltypes.NewErrorAcknowledgement(err)
|
|
keeper.EmitAcknowledgementEvent(ctx, packet, ack, err)
|
|
return ack
|
|
}
|
|
|
|
// OnAcknowledgementPacket implements the IBCMiddleware interface
|
|
func (im IBCMiddleware) OnAcknowledgementPacket(
|
|
ctx sdk.Context,
|
|
channelVersion string,
|
|
packet channeltypes.Packet,
|
|
acknowledgement []byte,
|
|
relayer sdk.AccAddress,
|
|
) error {
|
|
if !im.keeper.GetParams(ctx).ControllerEnabled {
|
|
return types.ErrControllerSubModuleDisabled
|
|
}
|
|
|
|
connectionID, err := im.keeper.GetConnectionID(ctx, packet.GetSourcePort(), packet.GetSourceChannel())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// call underlying app's OnAcknowledgementPacket callback.
|
|
if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, packet.GetSourcePort(), connectionID) {
|
|
return im.app.OnAcknowledgementPacket(ctx, channelVersion, packet, acknowledgement, relayer)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// OnTimeoutPacket implements the IBCMiddleware interface
|
|
func (im IBCMiddleware) OnTimeoutPacket(
|
|
ctx sdk.Context,
|
|
channelVersion string,
|
|
packet channeltypes.Packet,
|
|
relayer sdk.AccAddress,
|
|
) error {
|
|
if !im.keeper.GetParams(ctx).ControllerEnabled {
|
|
return types.ErrControllerSubModuleDisabled
|
|
}
|
|
|
|
if err := im.keeper.OnTimeoutPacket(ctx, packet); err != nil {
|
|
return err
|
|
}
|
|
|
|
connectionID, err := im.keeper.GetConnectionID(ctx, packet.GetSourcePort(), packet.GetSourceChannel())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, packet.GetSourcePort(), connectionID) {
|
|
return im.app.OnTimeoutPacket(ctx, channelVersion, packet, relayer)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SendPacket implements the ICS4 Wrapper interface
|
|
func (IBCMiddleware) SendPacket(
|
|
ctx sdk.Context,
|
|
sourcePort string,
|
|
sourceChannel string,
|
|
timeoutHeight clienttypes.Height,
|
|
timeoutTimestamp uint64,
|
|
data []byte,
|
|
) (uint64, error) {
|
|
panic(errors.New("SendPacket not supported for ICA controller module. Please use SendTx"))
|
|
}
|
|
|
|
// WriteAcknowledgement implements the ICS4 Wrapper interface
|
|
func (IBCMiddleware) WriteAcknowledgement(
|
|
ctx sdk.Context,
|
|
packet ibcexported.PacketI,
|
|
ack ibcexported.Acknowledgement,
|
|
) error {
|
|
panic(errors.New("WriteAcknowledgement not supported for ICA controller module"))
|
|
}
|
|
|
|
// GetAppVersion returns the interchain accounts metadata.
|
|
func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) {
|
|
return im.keeper.GetAppVersion(ctx, portID, channelID)
|
|
}
|
|
|
|
// UnmarshalPacketData attempts to unmarshal the provided packet data bytes
|
|
// into an InterchainAccountPacketData. This function implements the optional
|
|
// PacketDataUnmarshaler interface required for ADR 008 support.
|
|
func (im IBCMiddleware) UnmarshalPacketData(ctx sdk.Context, portID string, channelID string, bz []byte) (any, string, error) {
|
|
var data icatypes.InterchainAccountPacketData
|
|
err := data.UnmarshalJSON(bz)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
|
|
version, ok := im.GetAppVersion(ctx, portID, channelID)
|
|
if !ok {
|
|
return nil, "", errorsmod.Wrapf(ibcerrors.ErrNotFound, "app version not found for port %s and channel %s", portID, channelID)
|
|
}
|
|
|
|
return data, version, nil
|
|
}
|