github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/apps/27-interchain-accounts/controller/ibc_middleware.go (about) 1 package controller 2 3 import ( 4 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 5 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 6 capabilitytypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types" 7 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/27-interchain-accounts/controller/keeper" 8 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/27-interchain-accounts/controller/types" 9 icatypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/27-interchain-accounts/types" 10 channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types" 11 porttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/05-port/types" 12 ibcexported "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported" 13 ) 14 15 var _ porttypes.Middleware = &IBCMiddleware{} 16 17 // IBCMiddleware implements the ICS26 callbacks for the fee middleware given the 18 // ICA controller keeper and the underlying application. 19 type IBCMiddleware struct { 20 app porttypes.IBCModule 21 keeper keeper.Keeper 22 } 23 24 // IBCMiddleware creates a new IBCMiddleware given the associated keeper and underlying application 25 func NewIBCMiddleware(app porttypes.IBCModule, k keeper.Keeper) porttypes.Middleware { 26 internal := IBCMiddleware{ 27 app: app, 28 keeper: k, 29 } 30 return internal 31 } 32 33 // OnChanOpenInit implements the IBCMiddleware interface 34 // 35 // Interchain Accounts is implemented to act as middleware for connected authentication modules on 36 // the controller side. The connected modules may not change the controller side portID or 37 // version. They will be allowed to perform custom logic without changing 38 // the parameters stored within a channel struct. 39 func (im IBCMiddleware) OnChanOpenInit( 40 ctx sdk.Context, 41 order channeltypes.Order, 42 connectionHops []string, 43 portID string, 44 channelID string, 45 chanCap *capabilitytypes.Capability, 46 counterparty channeltypes.Counterparty, 47 version string, 48 ) (string, error) { 49 if !im.keeper.IsControllerEnabled(ctx) { 50 return version, types.ErrControllerSubModuleDisabled 51 } 52 53 version, err := im.keeper.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version) 54 if err != nil { 55 return version, err 56 } 57 58 // call underlying app's OnChanOpenInit callback with the passed in version 59 // the version returned is discarded as the ica-auth module does not have permission to edit the version string. 60 // ics27 will always return the version string containing the Metadata struct which is created during the `RegisterInterchainAccount` call. 61 if _, err := im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version); err != nil { 62 return "", err 63 } 64 65 return version, nil 66 } 67 68 // OnChanOpenTry implements the IBCMiddleware interface 69 func (im IBCMiddleware) OnChanOpenTry( 70 ctx sdk.Context, 71 order channeltypes.Order, 72 connectionHops []string, 73 portID, 74 channelID string, 75 chanCap *capabilitytypes.Capability, 76 counterparty channeltypes.Counterparty, 77 version string, 78 counterpartyVersion string, 79 ) (string, error) { 80 return "", sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") 81 } 82 83 // OnChanOpenAck implements the IBCMiddleware interface 84 // 85 // Interchain Accounts is implemented to act as middleware for connected authentication modules on 86 // the controller side. The connected modules may not change the portID or 87 // version. They will be allowed to perform custom logic without changing 88 // the parameters stored within a channel struct. 89 func (im IBCMiddleware) OnChanOpenAck( 90 ctx sdk.Context, 91 portID, 92 channelID string, 93 counterpartyChannelID string, 94 counterpartyVersion string, 95 ) error { 96 if !im.keeper.IsControllerEnabled(ctx) { 97 return types.ErrControllerSubModuleDisabled 98 } 99 100 if err := im.keeper.OnChanOpenAck(ctx, portID, channelID, counterpartyVersion); err != nil { 101 return err 102 } 103 104 // call underlying app's OnChanOpenAck callback with the counterparty app version. 105 return im.app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) 106 } 107 108 // OnChanOpenAck implements the IBCMiddleware interface 109 func (im IBCMiddleware) OnChanOpenConfirm( 110 ctx sdk.Context, 111 portID, 112 channelID string, 113 ) error { 114 return sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") 115 } 116 117 // OnChanCloseInit implements the IBCMiddleware interface 118 func (im IBCMiddleware) OnChanCloseInit( 119 ctx sdk.Context, 120 portID, 121 channelID string, 122 ) error { 123 // Disallow user-initiated channel closing for interchain account channels 124 return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") 125 } 126 127 // OnChanCloseConfirm implements the IBCMiddleware interface 128 func (im IBCMiddleware) OnChanCloseConfirm( 129 ctx sdk.Context, 130 portID, 131 channelID string, 132 ) error { 133 return im.keeper.OnChanCloseConfirm(ctx, portID, channelID) 134 } 135 136 // OnRecvPacket implements the IBCMiddleware interface 137 func (im IBCMiddleware) OnRecvPacket( 138 ctx sdk.Context, 139 packet channeltypes.Packet, 140 _ sdk.AccAddress, 141 ) ibcexported.Acknowledgement { 142 err := sdkerrors.Wrapf(icatypes.ErrInvalidChannelFlow, "cannot receive packet on controller chain") 143 ack := channeltypes.NewErrorAcknowledgementV4(err) 144 keeper.EmitAcknowledgementEvent(ctx, packet, ack, err) 145 return ack 146 } 147 148 // OnAcknowledgementPacket implements the IBCMiddleware interface 149 func (im IBCMiddleware) OnAcknowledgementPacket( 150 ctx sdk.Context, 151 packet channeltypes.Packet, 152 acknowledgement []byte, 153 relayer sdk.AccAddress, 154 ) error { 155 if !im.keeper.IsControllerEnabled(ctx) { 156 return types.ErrControllerSubModuleDisabled 157 } 158 159 // call underlying app's OnAcknowledgementPacket callback. 160 return im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) 161 } 162 163 // OnTimeoutPacket implements the IBCMiddleware interface 164 func (im IBCMiddleware) OnTimeoutPacket( 165 ctx sdk.Context, 166 packet channeltypes.Packet, 167 relayer sdk.AccAddress, 168 ) error { 169 if !im.keeper.IsControllerEnabled(ctx) { 170 return types.ErrControllerSubModuleDisabled 171 } 172 173 if err := im.keeper.OnTimeoutPacket(ctx, packet); err != nil { 174 return err 175 } 176 177 return im.app.OnTimeoutPacket(ctx, packet, relayer) 178 } 179 180 // SendPacket implements the ICS4 Wrapper interface 181 func (im IBCMiddleware) SendPacket( 182 ctx sdk.Context, 183 chanCap *capabilitytypes.Capability, 184 packet ibcexported.PacketI, 185 ) error { 186 panic("SendPacket not supported for ICA controller module. Please use SendTx") 187 } 188 189 // WriteAcknowledgement implements the ICS4 Wrapper interface 190 func (im IBCMiddleware) WriteAcknowledgement( 191 ctx sdk.Context, 192 chanCap *capabilitytypes.Capability, 193 packet ibcexported.PacketI, 194 ack ibcexported.Acknowledgement, 195 ) error { 196 panic("WriteAcknowledgement not supported for ICA controller module") 197 } 198 199 // GetAppVersion returns the interchain accounts metadata. 200 func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { 201 return im.keeper.GetAppVersion(ctx, portID, channelID) 202 } 203 204 func (im IBCMiddleware) NegotiateAppVersion(ctx sdk.Context, order channeltypes.Order, connectionID string, portID string, counterparty channeltypes.Counterparty, proposedVersion string) (version string, err error) { 205 return version, nil 206 }