diff --git a/modules/apps/transfer/ibc_module.go b/modules/apps/transfer/ibc_module.go index ba13442a196..0eb7bfbc692 100644 --- a/modules/apps/transfer/ibc_module.go +++ b/modules/apps/transfer/ibc_module.go @@ -11,7 +11,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v9/modules/apps/transfer/internal/events" "github.com/cosmos/ibc-go/v9/modules/apps/transfer/keeper" "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types" @@ -181,7 +180,9 @@ func (im IBCModule) OnRecvPacket( // we are explicitly wrapping this emit event call in an anonymous function so that // the packet data is evaluated after it has been assigned a value. defer func() { - events.EmitOnRecvPacketEvent(ctx, data, ack, ackErr) + if err := im.keeper.EmitOnRecvPacketEvent(ctx, data, ack, ackErr); err != nil { + ack = channeltypes.NewErrorAcknowledgement(err) + } }() data, ackErr = types.UnmarshalPacketData(packet.GetData(), channelVersion) @@ -230,9 +231,7 @@ func (im IBCModule) OnAcknowledgementPacket( return err } - events.EmitOnAcknowledgementPacketEvent(ctx, data, ack) - - return nil + return im.keeper.EmitOnAcknowledgementPacketEvent(ctx, data, ack) } // OnTimeoutPacket implements the IBCModule interface @@ -252,8 +251,7 @@ func (im IBCModule) OnTimeoutPacket( return err } - events.EmitOnTimeoutEvent(ctx, data) - return nil + return im.keeper.EmitOnTimeoutEvent(ctx, data) } // OnChanUpgradeInit implements the IBCModule interface diff --git a/modules/apps/transfer/internal/events/events.go b/modules/apps/transfer/internal/events/events.go deleted file mode 100644 index b6e48282e3c..00000000000 --- a/modules/apps/transfer/internal/events/events.go +++ /dev/null @@ -1,150 +0,0 @@ -package events - -import ( - "context" - "encoding/json" - "strconv" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types" -) - -// EmitTransferEvent emits a ibc transfer event on successful transfers. -func EmitTransferEvent(ctx context.Context, sender, receiver string, tokens types.Tokens, memo string, forwardingHops []types.Hop) { - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - tokensStr := mustMarshalJSON(tokens) - forwardingHopsStr := mustMarshalJSON(forwardingHops) - - sdkCtx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - types.EventTypeTransfer, - sdk.NewAttribute(types.AttributeKeySender, sender), - sdk.NewAttribute(types.AttributeKeyReceiver, receiver), - sdk.NewAttribute(types.AttributeKeyTokens, tokensStr), - sdk.NewAttribute(types.AttributeKeyMemo, memo), - sdk.NewAttribute(types.AttributeKeyForwardingHops, forwardingHopsStr), - ), - sdk.NewEvent( - sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - ), - }) -} - -// EmitOnRecvPacketEvent emits a fungible token packet event in the OnRecvPacket callback -func EmitOnRecvPacketEvent(ctx context.Context, packetData types.FungibleTokenPacketDataV2, ack channeltypes.Acknowledgement, ackErr error) { - tokensStr := mustMarshalJSON(packetData.Tokens) - forwardingHopStr := mustMarshalJSON(packetData.Forwarding.Hops) - - eventAttributes := []sdk.Attribute{ - sdk.NewAttribute(types.AttributeKeySender, packetData.Sender), - sdk.NewAttribute(types.AttributeKeyReceiver, packetData.Receiver), - sdk.NewAttribute(types.AttributeKeyTokens, tokensStr), - sdk.NewAttribute(types.AttributeKeyMemo, packetData.Memo), - sdk.NewAttribute(types.AttributeKeyForwardingHops, forwardingHopStr), - sdk.NewAttribute(types.AttributeKeyAckSuccess, strconv.FormatBool(ack.Success())), - } - - if ackErr != nil { - eventAttributes = append(eventAttributes, sdk.NewAttribute(types.AttributeKeyAckError, ackErr.Error())) - } - - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - - sdkCtx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - types.EventTypePacket, - eventAttributes..., - ), - sdk.NewEvent( - sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - ), - }) -} - -// EmitOnAcknowledgementPacketEvent emits a fungible token packet event in the OnAcknowledgementPacket callback -func EmitOnAcknowledgementPacketEvent(ctx context.Context, packetData types.FungibleTokenPacketDataV2, ack channeltypes.Acknowledgement) { - tokensStr := mustMarshalJSON(packetData.Tokens) - forwardingHopsStr := mustMarshalJSON(packetData.Forwarding.Hops) - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - sdkCtx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - types.EventTypePacket, - sdk.NewAttribute(sdk.AttributeKeySender, packetData.Sender), - sdk.NewAttribute(types.AttributeKeyReceiver, packetData.Receiver), - sdk.NewAttribute(types.AttributeKeyTokens, tokensStr), - sdk.NewAttribute(types.AttributeKeyMemo, packetData.Memo), - sdk.NewAttribute(types.AttributeKeyForwardingHops, forwardingHopsStr), - sdk.NewAttribute(types.AttributeKeyAck, ack.String()), - ), - sdk.NewEvent( - sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - ), - }) - - switch resp := ack.Response.(type) { - case *channeltypes.Acknowledgement_Result: - sdkCtx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypePacket, - sdk.NewAttribute(types.AttributeKeyAckSuccess, string(resp.Result)), - ), - ) - case *channeltypes.Acknowledgement_Error: - sdkCtx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypePacket, - sdk.NewAttribute(types.AttributeKeyAckError, resp.Error), - ), - ) - } -} - -// EmitOnTimeoutEvent emits a fungible token packet event in the OnTimeoutPacket callback -func EmitOnTimeoutEvent(ctx context.Context, packetData types.FungibleTokenPacketDataV2) { - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - tokensStr := mustMarshalJSON(packetData.Tokens) - forwardingHopsStr := mustMarshalJSON(packetData.Forwarding.Hops) - - sdkCtx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - types.EventTypeTimeout, - sdk.NewAttribute(types.AttributeKeyReceiver, packetData.Sender), - sdk.NewAttribute(types.AttributeKeyRefundTokens, tokensStr), - sdk.NewAttribute(types.AttributeKeyMemo, packetData.Memo), - sdk.NewAttribute(types.AttributeKeyForwardingHops, forwardingHopsStr), - ), - sdk.NewEvent( - sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - ), - }) -} - -// EmitDenomEvent emits a denomination event in the OnRecv callback. -func EmitDenomEvent(ctx context.Context, token types.Token) { - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - denomStr := mustMarshalJSON(token.Denom) - - sdkCtx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeDenom, - sdk.NewAttribute(types.AttributeKeyDenomHash, token.Denom.Hash().String()), - sdk.NewAttribute(types.AttributeKeyDenom, denomStr), - ), - ) -} - -// mustMarshalJSON json marshals the given type and panics on failure. -func mustMarshalJSON(v any) string { - bz, err := json.Marshal(v) - if err != nil { - panic(err) - } - - return string(bz) -} diff --git a/modules/apps/transfer/keeper/events.go b/modules/apps/transfer/keeper/events.go new file mode 100644 index 00000000000..b797fcf1029 --- /dev/null +++ b/modules/apps/transfer/keeper/events.go @@ -0,0 +1,147 @@ +package keeper + +import ( + "context" + "encoding/json" + "strconv" + + "cosmossdk.io/core/event" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types" +) + +// EmitTransferEvent emits a ibc transfer event on successful transfers. +func (k Keeper) EmitTransferEvent(ctx context.Context, sender, receiver string, tokens types.Tokens, memo string, forwardingHops []types.Hop) error { + tokensStr := mustMarshalJSON(tokens) + forwardingHopsStr := mustMarshalJSON(forwardingHops) + + if err := k.EventService.EventManager(ctx).EmitKV( + types.EventTypeTransfer, + event.NewAttribute(types.AttributeKeySender, sender), + event.NewAttribute(types.AttributeKeyReceiver, receiver), + event.NewAttribute(types.AttributeKeyTokens, tokensStr), + event.NewAttribute(types.AttributeKeyMemo, memo), + event.NewAttribute(types.AttributeKeyForwardingHops, forwardingHopsStr), + ); err != nil { + return err + } + + return k.EventService.EventManager(ctx).EmitKV( + sdk.EventTypeMessage, + event.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + ) +} + +// EmitOnRecvPacketEvent emits a fungible token packet event in the OnRecvPacket callback +func (k Keeper) EmitOnRecvPacketEvent(ctx context.Context, packetData types.FungibleTokenPacketDataV2, ack channeltypes.Acknowledgement, ackErr error) error { + tokensStr := mustMarshalJSON(packetData.Tokens) + forwardingHopStr := mustMarshalJSON(packetData.Forwarding.Hops) + + eventAttributes := []event.Attribute{ + event.NewAttribute(types.AttributeKeySender, packetData.Sender), + event.NewAttribute(types.AttributeKeyReceiver, packetData.Receiver), + event.NewAttribute(types.AttributeKeyTokens, tokensStr), + event.NewAttribute(types.AttributeKeyMemo, packetData.Memo), + event.NewAttribute(types.AttributeKeyForwardingHops, forwardingHopStr), + event.NewAttribute(types.AttributeKeyAckSuccess, strconv.FormatBool(ack.Success())), + } + + if ackErr != nil { + eventAttributes = append(eventAttributes, event.NewAttribute(types.AttributeKeyAckError, ackErr.Error())) + } + + if err := k.EventService.EventManager(ctx).EmitKV( + types.EventTypePacket, + eventAttributes..., + ); err != nil { + return err + } + + return k.EventService.EventManager(ctx).EmitKV( + sdk.EventTypeMessage, + event.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + ) +} + +// EmitOnAcknowledgementPacketEvent emits a fungible token packet event in the OnAcknowledgementPacket callback +func (k Keeper) EmitOnAcknowledgementPacketEvent(ctx context.Context, packetData types.FungibleTokenPacketDataV2, ack channeltypes.Acknowledgement) error { + tokensStr := mustMarshalJSON(packetData.Tokens) + forwardingHopsStr := mustMarshalJSON(packetData.Forwarding.Hops) + + if err := k.EventService.EventManager(ctx).EmitKV( + types.EventTypePacket, + event.NewAttribute(sdk.AttributeKeySender, packetData.Sender), + event.NewAttribute(types.AttributeKeyReceiver, packetData.Receiver), + event.NewAttribute(types.AttributeKeyTokens, tokensStr), + event.NewAttribute(types.AttributeKeyMemo, packetData.Memo), + event.NewAttribute(types.AttributeKeyForwardingHops, forwardingHopsStr), + event.NewAttribute(types.AttributeKeyAck, ack.String()), + ); err != nil { + return err + } + + switch resp := ack.Response.(type) { + case *channeltypes.Acknowledgement_Result: + if err := k.EventService.EventManager(ctx).EmitKV( + types.EventTypePacket, + event.NewAttribute(types.AttributeKeyAckSuccess, string(resp.Result)), + ); err != nil { + return err + } + case *channeltypes.Acknowledgement_Error: + if err := k.EventService.EventManager(ctx).EmitKV( + types.EventTypePacket, + event.NewAttribute(types.AttributeKeyAckError, resp.Error), + ); err != nil { + return err + } + } + + return k.EventService.EventManager(ctx).EmitKV( + sdk.EventTypeMessage, + event.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + ) +} + +// EmitOnTimeoutEvent emits a fungible token packet event in the OnTimeoutPacket callback +func (k Keeper) EmitOnTimeoutEvent(ctx context.Context, packetData types.FungibleTokenPacketDataV2) error { + tokensStr := mustMarshalJSON(packetData.Tokens) + forwardingHopsStr := mustMarshalJSON(packetData.Forwarding.Hops) + + if err := k.EventService.EventManager(ctx).EmitKV( + types.EventTypeTimeout, + event.NewAttribute(types.AttributeKeyReceiver, packetData.Sender), + event.NewAttribute(types.AttributeKeyRefundTokens, tokensStr), + event.NewAttribute(types.AttributeKeyMemo, packetData.Memo), + event.NewAttribute(types.AttributeKeyForwardingHops, forwardingHopsStr), + ); err != nil { + return err + } + + return k.EventService.EventManager(ctx).EmitKV( + sdk.EventTypeMessage, + event.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + ) +} + +// EmitDenomEvent emits a denomination event in the OnRecv callback. +func (k Keeper) EmitDenomEvent(ctx context.Context, token types.Token) error { + return k.EventService.EventManager(ctx).EmitKV( + types.EventTypeDenom, + event.NewAttribute(types.AttributeKeyDenomHash, token.Denom.Hash().String()), + event.NewAttribute(types.AttributeKeyDenom, mustMarshalJSON(token.Denom)), + ) +} + +// mustMarshalJSON json marshals the given type and panics on failure. +func mustMarshalJSON(v any) string { + bz, err := json.Marshal(v) + if err != nil { + panic(err) + } + + return string(bz) +} diff --git a/modules/apps/transfer/keeper/relay.go b/modules/apps/transfer/keeper/relay.go index 98c7e992fdc..07043402a4c 100644 --- a/modules/apps/transfer/keeper/relay.go +++ b/modules/apps/transfer/keeper/relay.go @@ -10,7 +10,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v9/modules/apps/transfer/internal/events" "github.com/cosmos/ibc-go/v9/modules/apps/transfer/internal/telemetry" internaltypes "github.com/cosmos/ibc-go/v9/modules/apps/transfer/internal/types" "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" @@ -150,7 +149,9 @@ func (k Keeper) sendTransfer( return 0, err } - events.EmitTransferEvent(ctx, sender.String(), receiver, tokens, memo, hops) + if err := k.EmitTransferEvent(ctx, sender.String(), receiver, tokens, memo, hops); err != nil { + return 0, err + } telemetry.ReportTransfer(sourcePort, sourceChannel, destinationPort, destinationChannel, tokens) @@ -231,7 +232,9 @@ func (k Keeper) OnRecvPacket(ctx context.Context, packet channeltypes.Packet, da k.setDenomMetadata(ctx, token.Denom) } - events.EmitDenomEvent(ctx, token) + if err := k.EmitDenomEvent(ctx, token); err != nil { + return err + } voucher := sdk.NewCoin(voucherDenom, transferAmount)