623 lines
23 KiB
Go
623 lines
23 KiB
Go
package keeper
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/armon/go-metrics"
|
|
"github.com/cosmos/cosmos-sdk/telemetry"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
|
|
connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types"
|
|
channel "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel"
|
|
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types"
|
|
porttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/05-port/types"
|
|
)
|
|
|
|
var _ clienttypes.MsgServer = Keeper{}
|
|
var _ connectiontypes.MsgServer = Keeper{}
|
|
var _ channeltypes.MsgServer = Keeper{}
|
|
|
|
// CreateClient defines a rpc handler method for MsgCreateClient.
|
|
func (k Keeper) CreateClient(goCtx context.Context, msg *clienttypes.MsgCreateClient) (*clienttypes.MsgCreateClientResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
clientState, err := clienttypes.UnpackClientState(msg.ClientState)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
consensusState, err := clienttypes.UnpackConsensusState(msg.ConsensusState)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err = k.ClientKeeper.CreateClient(ctx, msg.ClientId, clientState, consensusState); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ctx.EventManager().EmitEvents(sdk.Events{
|
|
sdk.NewEvent(
|
|
clienttypes.EventTypeCreateClient,
|
|
sdk.NewAttribute(clienttypes.AttributeKeyClientID, msg.ClientId),
|
|
sdk.NewAttribute(clienttypes.AttributeKeyClientType, clientState.ClientType()),
|
|
sdk.NewAttribute(clienttypes.AttributeKeyConsensusHeight, clientState.GetLatestHeight().String()),
|
|
),
|
|
sdk.NewEvent(
|
|
sdk.EventTypeMessage,
|
|
sdk.NewAttribute(sdk.AttributeKeyModule, clienttypes.AttributeValueCategory),
|
|
),
|
|
})
|
|
|
|
return &clienttypes.MsgCreateClientResponse{}, nil
|
|
}
|
|
|
|
// UpdateClient defines a rpc handler method for MsgUpdateClient.
|
|
func (k Keeper) UpdateClient(goCtx context.Context, msg *clienttypes.MsgUpdateClient) (*clienttypes.MsgUpdateClientResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
header, err := clienttypes.UnpackHeader(msg.Header)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err = k.ClientKeeper.UpdateClient(ctx, msg.ClientId, header); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ctx.EventManager().EmitEvent(
|
|
sdk.NewEvent(
|
|
sdk.EventTypeMessage,
|
|
sdk.NewAttribute(sdk.AttributeKeyModule, clienttypes.AttributeValueCategory),
|
|
),
|
|
)
|
|
|
|
return &clienttypes.MsgUpdateClientResponse{}, nil
|
|
}
|
|
|
|
// UpgradeClient defines a rpc handler method for MsgUpgradeClient.
|
|
func (k Keeper) UpgradeClient(goCtx context.Context, msg *clienttypes.MsgUpgradeClient) (*clienttypes.MsgUpgradeClientResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
upgradedClient, err := clienttypes.UnpackClientState(msg.ClientState)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := upgradedClient.Validate(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err = k.ClientKeeper.UpgradeClient(ctx, msg.ClientId, upgradedClient, msg.UpgradeHeight, msg.ProofUpgrade); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ctx.EventManager().EmitEvent(
|
|
sdk.NewEvent(
|
|
sdk.EventTypeMessage,
|
|
sdk.NewAttribute(sdk.AttributeKeyModule, clienttypes.AttributeValueCategory),
|
|
),
|
|
)
|
|
|
|
return &clienttypes.MsgUpgradeClientResponse{}, nil
|
|
}
|
|
|
|
// SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour.
|
|
func (k Keeper) SubmitMisbehaviour(goCtx context.Context, msg *clienttypes.MsgSubmitMisbehaviour) (*clienttypes.MsgSubmitMisbehaviourResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
misbehaviour, err := clienttypes.UnpackMisbehaviour(msg.Misbehaviour)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := k.ClientKeeper.CheckMisbehaviourAndUpdateState(ctx, misbehaviour); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "failed to process misbehaviour for IBC client")
|
|
}
|
|
|
|
ctx.EventManager().EmitEvent(
|
|
sdk.NewEvent(
|
|
clienttypes.EventTypeSubmitMisbehaviour,
|
|
sdk.NewAttribute(clienttypes.AttributeKeyClientID, msg.ClientId),
|
|
sdk.NewAttribute(clienttypes.AttributeKeyClientType, misbehaviour.ClientType()),
|
|
sdk.NewAttribute(clienttypes.AttributeKeyConsensusHeight, misbehaviour.GetHeight().String()),
|
|
),
|
|
)
|
|
|
|
return &clienttypes.MsgSubmitMisbehaviourResponse{}, nil
|
|
}
|
|
|
|
// ConnectionOpenInit defines a rpc handler method for MsgConnectionOpenInit.
|
|
func (k Keeper) ConnectionOpenInit(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenInit) (*connectiontypes.MsgConnectionOpenInitResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
if err := k.ConnectionKeeper.ConnOpenInit(
|
|
ctx, msg.ConnectionId, msg.ClientId, msg.Counterparty, msg.Version,
|
|
); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "connection handshake open init failed")
|
|
}
|
|
|
|
ctx.EventManager().EmitEvents(sdk.Events{
|
|
sdk.NewEvent(
|
|
connectiontypes.EventTypeConnectionOpenInit,
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.ConnectionId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyClientID, msg.ClientId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, msg.Counterparty.ConnectionId),
|
|
),
|
|
sdk.NewEvent(
|
|
sdk.EventTypeMessage,
|
|
sdk.NewAttribute(sdk.AttributeKeyModule, connectiontypes.AttributeValueCategory),
|
|
),
|
|
})
|
|
|
|
return &connectiontypes.MsgConnectionOpenInitResponse{}, nil
|
|
}
|
|
|
|
// ConnectionOpenTry defines a rpc handler method for MsgConnectionOpenTry.
|
|
func (k Keeper) ConnectionOpenTry(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenTry) (*connectiontypes.MsgConnectionOpenTryResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
targetClient, err := clienttypes.UnpackClientState(msg.ClientState)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrapf(err, "client in msg is not exported.ClientState. invalid client: %v.", targetClient)
|
|
}
|
|
|
|
if err := k.ConnectionKeeper.ConnOpenTry(
|
|
ctx, msg.DesiredConnectionId, msg.CounterpartyChosenConnectionId, msg.Counterparty, msg.ClientId, targetClient,
|
|
msg.CounterpartyVersions, msg.ProofInit, msg.ProofClient, msg.ProofConsensus,
|
|
msg.ProofHeight, msg.ConsensusHeight,
|
|
); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "connection handshake open try failed")
|
|
}
|
|
|
|
ctx.EventManager().EmitEvents(sdk.Events{
|
|
sdk.NewEvent(
|
|
connectiontypes.EventTypeConnectionOpenTry,
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.DesiredConnectionId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyClientID, msg.ClientId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, msg.Counterparty.ConnectionId),
|
|
),
|
|
sdk.NewEvent(
|
|
sdk.EventTypeMessage,
|
|
sdk.NewAttribute(sdk.AttributeKeyModule, connectiontypes.AttributeValueCategory),
|
|
),
|
|
})
|
|
|
|
return &connectiontypes.MsgConnectionOpenTryResponse{}, nil
|
|
}
|
|
|
|
// ConnectionOpenAck defines a rpc handler method for MsgConnectionOpenAck.
|
|
func (k Keeper) ConnectionOpenAck(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenAck) (*connectiontypes.MsgConnectionOpenAckResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
targetClient, err := clienttypes.UnpackClientState(msg.ClientState)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrapf(err, "client in msg is not exported.ClientState. invalid client: %v", targetClient)
|
|
}
|
|
|
|
if err := k.ConnectionKeeper.ConnOpenAck(
|
|
ctx, msg.ConnectionId, targetClient, msg.Version, msg.CounterpartyConnectionId,
|
|
msg.ProofTry, msg.ProofClient, msg.ProofConsensus,
|
|
msg.ProofHeight, msg.ConsensusHeight,
|
|
); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "connection handshake open ack failed")
|
|
}
|
|
|
|
connectionEnd, _ := k.ConnectionKeeper.GetConnection(ctx, msg.ConnectionId)
|
|
|
|
ctx.EventManager().EmitEvents(sdk.Events{
|
|
sdk.NewEvent(
|
|
connectiontypes.EventTypeConnectionOpenAck,
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.ConnectionId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyClientID, connectionEnd.ClientId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, connectionEnd.Counterparty.ClientId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, connectionEnd.Counterparty.ConnectionId),
|
|
),
|
|
sdk.NewEvent(
|
|
sdk.EventTypeMessage,
|
|
sdk.NewAttribute(sdk.AttributeKeyModule, connectiontypes.AttributeValueCategory),
|
|
),
|
|
})
|
|
|
|
return &connectiontypes.MsgConnectionOpenAckResponse{}, nil
|
|
}
|
|
|
|
// ConnectionOpenConfirm defines a rpc handler method for MsgConnectionOpenConfirm.
|
|
func (k Keeper) ConnectionOpenConfirm(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenConfirm) (*connectiontypes.MsgConnectionOpenConfirmResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
if err := k.ConnectionKeeper.ConnOpenConfirm(
|
|
ctx, msg.ConnectionId, msg.ProofAck, msg.ProofHeight,
|
|
); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "connection handshake open confirm failed")
|
|
}
|
|
|
|
connectionEnd, _ := k.ConnectionKeeper.GetConnection(ctx, msg.ConnectionId)
|
|
|
|
ctx.EventManager().EmitEvents(sdk.Events{
|
|
sdk.NewEvent(
|
|
connectiontypes.EventTypeConnectionOpenConfirm,
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.ConnectionId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyClientID, connectionEnd.ClientId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, connectionEnd.Counterparty.ClientId),
|
|
sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, connectionEnd.Counterparty.ConnectionId),
|
|
),
|
|
sdk.NewEvent(
|
|
sdk.EventTypeMessage,
|
|
sdk.NewAttribute(sdk.AttributeKeyModule, connectiontypes.AttributeValueCategory),
|
|
),
|
|
})
|
|
|
|
return &connectiontypes.MsgConnectionOpenConfirmResponse{}, nil
|
|
}
|
|
|
|
// ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit.
|
|
func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChannelOpenInit) (*channeltypes.MsgChannelOpenInitResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
// Lookup module by port capability
|
|
module, portCap, err := k.PortKeeper.LookupModuleByPort(ctx, msg.PortId)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
_, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
if err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.ChannelId, cap, msg.Channel.Counterparty, msg.Channel.Version); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "channel open init callback failed")
|
|
}
|
|
|
|
return &channeltypes.MsgChannelOpenInitResponse{}, nil
|
|
}
|
|
|
|
// ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry.
|
|
func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChannelOpenTry) (*channeltypes.MsgChannelOpenTryResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
// Lookup module by port capability
|
|
module, portCap, err := k.PortKeeper.LookupModuleByPort(ctx, msg.PortId)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
_, cap, err := channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, portCap, msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
if err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.DesiredChannelId, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "channel open try callback failed")
|
|
}
|
|
|
|
return &channeltypes.MsgChannelOpenTryResponse{}, nil
|
|
}
|
|
|
|
// ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck.
|
|
func (k Keeper) ChannelOpenAck(goCtx context.Context, msg *channeltypes.MsgChannelOpenAck) (*channeltypes.MsgChannelOpenAckResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
// Lookup module by channel capability
|
|
module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
if err = cbs.OnChanOpenAck(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyVersion); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "channel open ack callback failed")
|
|
}
|
|
|
|
_, err = channel.HandleMsgChannelOpenAck(ctx, k.ChannelKeeper, cap, msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &channeltypes.MsgChannelOpenAckResponse{}, nil
|
|
}
|
|
|
|
// ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm.
|
|
func (k Keeper) ChannelOpenConfirm(goCtx context.Context, msg *channeltypes.MsgChannelOpenConfirm) (*channeltypes.MsgChannelOpenConfirmResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
// Lookup module by channel capability
|
|
module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
if err = cbs.OnChanOpenConfirm(ctx, msg.PortId, msg.ChannelId); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "channel open confirm callback failed")
|
|
}
|
|
|
|
_, err = channel.HandleMsgChannelOpenConfirm(ctx, k.ChannelKeeper, cap, msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &channeltypes.MsgChannelOpenConfirmResponse{}, nil
|
|
}
|
|
|
|
// ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit.
|
|
func (k Keeper) ChannelCloseInit(goCtx context.Context, msg *channeltypes.MsgChannelCloseInit) (*channeltypes.MsgChannelCloseInitResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
// Lookup module by channel capability
|
|
module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
if err = cbs.OnChanCloseInit(ctx, msg.PortId, msg.ChannelId); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "channel close init callback failed")
|
|
}
|
|
|
|
_, err = channel.HandleMsgChannelCloseInit(ctx, k.ChannelKeeper, cap, msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &channeltypes.MsgChannelCloseInitResponse{}, nil
|
|
}
|
|
|
|
// ChannelCloseConfirm defines a rpc handler method for MsgChannelCloseConfirm.
|
|
func (k Keeper) ChannelCloseConfirm(goCtx context.Context, msg *channeltypes.MsgChannelCloseConfirm) (*channeltypes.MsgChannelCloseConfirmResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
// Lookup module by channel capability
|
|
module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
if err = cbs.OnChanCloseConfirm(ctx, msg.PortId, msg.ChannelId); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "channel close confirm callback failed")
|
|
}
|
|
|
|
_, err = channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, cap, msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &channeltypes.MsgChannelCloseConfirmResponse{}, nil
|
|
}
|
|
|
|
// RecvPacket defines a rpc handler method for MsgRecvPacket.
|
|
func (k Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacket) (*channeltypes.MsgRecvPacketResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
// Lookup module by channel capability
|
|
module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.DestinationPort, msg.Packet.DestinationChannel)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
// Perform TAO verification
|
|
if err := k.ChannelKeeper.RecvPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "receive packet verification failed")
|
|
}
|
|
|
|
// Perform application logic callback
|
|
_, ack, err := cbs.OnRecvPacket(ctx, msg.Packet)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "receive packet callback failed")
|
|
}
|
|
|
|
if err := k.ChannelKeeper.WriteReceipt(ctx, cap, msg.Packet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Set packet acknowledgement only if the acknowledgement is not nil.
|
|
// NOTE: IBC applications modules may call the WriteAcknowledgement asynchronously if the
|
|
// acknowledgement is nil.
|
|
if ack != nil {
|
|
if err := k.ChannelKeeper.WriteAcknowledgement(ctx, msg.Packet, ack); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
defer func() {
|
|
telemetry.IncrCounterWithLabels(
|
|
[]string{"tx", "msg", "ibc", msg.Type()},
|
|
1,
|
|
[]metrics.Label{
|
|
telemetry.NewLabel("source-port", msg.Packet.SourcePort),
|
|
telemetry.NewLabel("source-channel", msg.Packet.SourceChannel),
|
|
telemetry.NewLabel("destination-port", msg.Packet.DestinationPort),
|
|
telemetry.NewLabel("destination-channel", msg.Packet.DestinationChannel),
|
|
},
|
|
)
|
|
}()
|
|
|
|
return &channeltypes.MsgRecvPacketResponse{}, nil
|
|
}
|
|
|
|
// Timeout defines a rpc handler method for MsgTimeout.
|
|
func (k Keeper) Timeout(goCtx context.Context, msg *channeltypes.MsgTimeout) (*channeltypes.MsgTimeoutResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
// Lookup module by channel capability
|
|
module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.SourcePort, msg.Packet.SourceChannel)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
// Perform TAO verification
|
|
if err := k.ChannelKeeper.TimeoutPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight, msg.NextSequenceRecv); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "timeout packet verification failed")
|
|
}
|
|
|
|
// Perform application logic callback
|
|
_, err = cbs.OnTimeoutPacket(ctx, msg.Packet)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "timeout packet callback failed")
|
|
}
|
|
|
|
// Delete packet commitment
|
|
if err = k.ChannelKeeper.TimeoutExecuted(ctx, cap, msg.Packet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer func() {
|
|
telemetry.IncrCounterWithLabels(
|
|
[]string{"ibc", "timeout", "packet"},
|
|
1,
|
|
[]metrics.Label{
|
|
telemetry.NewLabel("source-port", msg.Packet.SourcePort),
|
|
telemetry.NewLabel("source-channel", msg.Packet.SourceChannel),
|
|
telemetry.NewLabel("destination-port", msg.Packet.DestinationPort),
|
|
telemetry.NewLabel("destination-channel", msg.Packet.DestinationChannel),
|
|
telemetry.NewLabel("timeout-type", "height"),
|
|
},
|
|
)
|
|
}()
|
|
|
|
return &channeltypes.MsgTimeoutResponse{}, nil
|
|
}
|
|
|
|
// TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose.
|
|
func (k Keeper) TimeoutOnClose(goCtx context.Context, msg *channeltypes.MsgTimeoutOnClose) (*channeltypes.MsgTimeoutOnCloseResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
// Lookup module by channel capability
|
|
module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.SourcePort, msg.Packet.SourceChannel)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
// Perform TAO verification
|
|
if err := k.ChannelKeeper.TimeoutOnClose(ctx, cap, msg.Packet, msg.Proof, msg.ProofClose, msg.ProofHeight, msg.NextSequenceRecv); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "timeout on close packet verification failed")
|
|
}
|
|
|
|
// Perform application logic callback
|
|
// NOTE: MsgTimeout and MsgTimeoutOnClose use the same "OnTimeoutPacket"
|
|
// application logic callback.
|
|
_, err = cbs.OnTimeoutPacket(ctx, msg.Packet)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "timeout packet callback failed")
|
|
}
|
|
|
|
// Delete packet commitment
|
|
if err = k.ChannelKeeper.TimeoutExecuted(ctx, cap, msg.Packet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer func() {
|
|
telemetry.IncrCounterWithLabels(
|
|
[]string{"ibc", "timeout", "packet"},
|
|
1,
|
|
[]metrics.Label{
|
|
telemetry.NewLabel("source-port", msg.Packet.SourcePort),
|
|
telemetry.NewLabel("source-channel", msg.Packet.SourceChannel),
|
|
telemetry.NewLabel("destination-port", msg.Packet.DestinationPort),
|
|
telemetry.NewLabel("destination-channel", msg.Packet.DestinationChannel),
|
|
telemetry.NewLabel("timeout-type", "channel-closed"),
|
|
},
|
|
)
|
|
}()
|
|
|
|
return &channeltypes.MsgTimeoutOnCloseResponse{}, nil
|
|
}
|
|
|
|
// Acknowledgement defines a rpc handler method for MsgAcknowledgement.
|
|
func (k Keeper) Acknowledgement(goCtx context.Context, msg *channeltypes.MsgAcknowledgement) (*channeltypes.MsgAcknowledgementResponse, error) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
// Lookup module by channel capability
|
|
module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.SourcePort, msg.Packet.SourceChannel)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
|
|
}
|
|
|
|
// Retrieve callbacks from router
|
|
cbs, ok := k.Router.GetRoute(module)
|
|
if !ok {
|
|
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)
|
|
}
|
|
|
|
// Perform TAO verification
|
|
if err := k.ChannelKeeper.AcknowledgePacket(ctx, msg.Packet, msg.Acknowledgement, msg.Proof, msg.ProofHeight); err != nil {
|
|
return nil, sdkerrors.Wrap(err, "acknowledge packet verification failed")
|
|
}
|
|
|
|
// Perform application logic callback
|
|
_, err = cbs.OnAcknowledgementPacket(ctx, msg.Packet, msg.Acknowledgement)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(err, "acknowledge packet callback failed")
|
|
}
|
|
|
|
// Delete packet commitment
|
|
if err = k.ChannelKeeper.AcknowledgementExecuted(ctx, cap, msg.Packet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer func() {
|
|
telemetry.IncrCounterWithLabels(
|
|
[]string{"tx", "msg", "ibc", msg.Type()},
|
|
1,
|
|
[]metrics.Label{
|
|
telemetry.NewLabel("source-port", msg.Packet.SourcePort),
|
|
telemetry.NewLabel("source-channel", msg.Packet.SourceChannel),
|
|
telemetry.NewLabel("destination-port", msg.Packet.DestinationPort),
|
|
telemetry.NewLabel("destination-channel", msg.Packet.DestinationChannel),
|
|
},
|
|
)
|
|
}()
|
|
|
|
return &channeltypes.MsgAcknowledgementResponse{}, nil
|
|
}
|