cosmos / ibc-go

Inter-Blockchain Communication Protocol (IBC) implementation in Golang.
https://ibc.cosmos.network/
MIT License
542 stars 580 forks source link

Trimming events to contain essential attributes only #5901

Open colin-axner opened 6 months ago

colin-axner commented 6 months ago

Summary

As per request from Osmosis, sometimes we emit events which aren't essential or provide duplicate information. This issue is a placeholder to discuss potentially removing event attributes which do not provide useful benefits and cost more in usage.

02-client event trimming

The client type should be unnecessary as it is contained in the clientID. Maybe it is used in some workflow for querying events?

We should be able to remove the client type in all 02-client queries

04-channel event trimming

On recv packet, we emit all the information needed to reconstruct the packet, but the packet is provided as an argument to the MsgRecvPacket, see events. All that should really be necessary is the packet sequence and port/channel

The same is true for write acknowledgement, see events

In acknowledge packet events, I think we could just emit the packet id information (sequence, source port, source channel)

For timeout packet, I think we could do packet ID info (sequence, source port, source channel) + timeout info


For Admin Use

colin-axner commented 6 months ago

A very minimal recv packet event could look like this:

// emitRecvPacketEvent emits a receive packet event. It will be emitted both the first time a packet
// is received for a certain sequence and for all duplicate receives.
func emitRecvPacketEvent(ctx sdk.Context, packet types.Packet, channel types.Channel) {
    ctx.EventManager().EmitEvents(sdk.Events{
        sdk.NewEvent(
            types.EventTypeRecvPacket,
            sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())),
            sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()),
            sdk.NewAttribute(types.AttributeKeyDstChannel, packet.GetDestChannel()),
        ),
        sdk.NewEvent(
            sdk.EventTypeMessage,
            sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
        ),
    })
}

and for write acknowledgement:

// emitWriteAcknowledgementEvent emits an event that the relayer can query for
func emitWriteAcknowledgementEvent(ctx sdk.Context, packet types.Packet, channel types.Channel, acknowledgement []byte) {
    ctx.EventManager().EmitEvents(sdk.Events{
        sdk.NewEvent(
            types.EventTypeWriteAck,
            sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())),
            sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()),
            sdk.NewAttribute(types.AttributeKeyDstChannel, packet.GetDestChannel()),
            sdk.NewAttribute(types.AttributeKeyAck, string(acknowledgement)), //nolint:staticcheck // DEPRECATED
            sdk.NewAttribute(types.AttributeKeyAckHex, hex.EncodeToString(acknowledgement)),
        ),
        sdk.NewEvent(
            sdk.EventTypeMessage,
            sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
        ),
    })
}

and for acknowledge packet:

// emitAcknowledgePacketEvent emits an acknowledge packet event. It will be emitted both the first time
// a packet is acknowledged for a certain sequence and for all duplicate acknowledgements.
func emitAcknowledgePacketEvent(ctx sdk.Context, packet types.Packet, channel types.Channel) {
    ctx.EventManager().EmitEvents(sdk.Events{
        sdk.NewEvent(
            types.EventTypeAcknowledgePacket,
            sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())),
            sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()),
            sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()),
        ),
        sdk.NewEvent(
            sdk.EventTypeMessage,
            sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
        ),
    })
}

and for timeout packet

// emitTimeoutPacketEvent emits a timeout packet event. It will be emitted both the first time a packet
// is timed out for a certain sequence and for all duplicate timeouts.
func emitTimeoutPacketEvent(ctx sdk.Context, packet types.Packet, channel types.Channel) {
    ctx.EventManager().EmitEvents(sdk.Events{
        sdk.NewEvent(
            types.EventTypeTimeoutPacket,
            sdk.NewAttribute(types.AttributeKeyTimeoutHeight, packet.GetTimeoutHeight().String()),
            sdk.NewAttribute(types.AttributeKeyTimeoutTimestamp, fmt.Sprintf("%d", packet.GetTimeoutTimestamp())),
            sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())),
            sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()),
            sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()),
        ),
        sdk.NewEvent(
            sdk.EventTypeMessage,
            sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
        ),
    })
}
colin-axner commented 6 months ago

The most effective starting point is to try to remove the redundant packet data emissions in the recv packet flow (currently emitted 4 times)

colin-axner commented 2 months ago

requires https://github.com/informalsystems/hermes/issues/4078