diff --git a/modules/core/keeper/msg_server.go b/modules/core/keeper/msg_server.go index fe410471d63..ab9e583385c 100644 --- a/modules/core/keeper/msg_server.go +++ b/modules/core/keeper/msg_server.go @@ -500,6 +500,10 @@ func (k Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacke // Cache context so that we may discard state changes from callback if the acknowledgement is unsuccessful. cacheCtx, writeFn := ctx.CacheContext() ack := cbs.OnRecvPacket(cacheCtx, msg.Packet, relayer) + // This doesn't cause duplicate events to be emitted. + // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. + // Events from callback are emitted regardless of acknowledgement success + ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) if ack == nil || ack.Success() { // write application state changes for asynchronous and successful acknowledgements writeFn()