Skip to content

feat(core): retain raw packet payload on-chain for retrieval by packet hash#207

Draft
jinoosss wants to merge 2 commits into
mainfrom
feat/handle-packet-data-in-storage
Draft

feat(core): retain raw packet payload on-chain for retrieval by packet hash#207
jinoosss wants to merge 2 commits into
mainfrom
feat/handle-packet-data-in-storage

Conversation

@jinoosss

Copy link
Copy Markdown
Member

Summary

Large packet payloads overflow the event size limit: the packet_data
attribute emitted on PacketSend is truncated by downstream event consumers
(indexers/relayers), which then fail to parse the event. A real
TokenOrder/Batch payload routinely exceeds the limit because each ABI field
is padded to a 32-byte word, so the truncation is hit in normal operation, not
just edge cases.

This change retains the raw packet payload (packet.Data) in the core store,
keyed by the packet commitment hash, and exposes a getter so off-chain
consumers can fetch the full payload by hash instead of reading it from the
(truncated) event attribute. The packet_hash already emitted in every packet
event is the lookup key, so no new correlation data is needed.

Design

  • Key — packet commitment hash (CommitPacketHash). It is globally unique
    per packet and is already emitted as the packet_hash event attribute, so a
    consumer reads the intact packet_hash and queries the payload directly.
  • Store is a pure data layer. The Store exposes only Get/Set/Remove
    primitives over a dedicated bptree (SetPacketData, GetPacketData,
    RemovePacketData); it makes no lifecycle decisions, consistent with the
    store's existing "store and retrieve only — protocol logic lives in the impl"
    contract.
  • The impl (core/v1) owns the lifecycle.
    • SendPacket writes the payload right after CommitPacket.
    • markPacketAcknowledged removes it. Acknowledgement and timeout both funnel
      through markPacketAcknowledged, so this is the single retire point — the
      payload lives exactly while the packet is in flight, bounding state growth.
  • Reads are clones. Both SetPacketData and GetPacketData clone the byte
    slice, so stored state cannot be mutated through the caller's reference or
    across a realm boundary.

Public query

core.GetPacketData(packetHash) (string, error) returns the payload as a
0x-prefixed hex string — the same encoding as the packet_data event
attribute — so existing parsers work unchanged. It returns an error once the
packet has been retired (acknowledged/timed out) or if it was never sent from
this chain.

Off-chain usage:

1. Read packet_hash from the PacketSend event (not truncated).
2. gnokey query vm/qeval -data 'gno.land/r/onbloc/ibc/union/core.GetPacketData(H256{...})'
3. Receive the full packet_data hex (valid until ack/timeout).

Changes

  • core/store.gnopacketData bptree field + SetPacketData /
    GetPacketData / RemovePacketData primitives (realm-guarded, cloned).
  • core/types.gnoIStore gains the three primitives; ICore gains
    GetPacketData.
  • core/v1/packet.gnoSendPacket stores the payload; markPacketAcknowledged
    removes it (shared ack/timeout cleanup).
  • core/v1/getters.gno — impl GetPacketData passthrough.
  • core/getters.gno — public GetPacketData query returning 0x-hex.
  • core/errors.gnoErrPacketDataNotFound.

@github-actions github-actions Bot added the T-feature New functionality label Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants