Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better OnAcknowledgementPacket handling #1114

Closed
3 tasks
joe-bowman opened this issue Mar 13, 2022 · 4 comments · Fixed by #1122
Closed
3 tasks

Better OnAcknowledgementPacket handling #1114

joe-bowman opened this issue Mar 13, 2022 · 4 comments · Fixed by #1122

Comments

@joe-bowman
Copy link
Contributor

Summary

The docs at https://github.com/cosmos/ibc-go/blob/main/docs/apps/interchain-accounts/auth-modules.md suggest that decoding the Acknowledgement is as simple as:

Begin by unmarshaling the acknowledgement into sdk.TxMsgData

(N.B. channeltypes here refers to github.com/cosmos/ibc-go/v3/modules/core/04-channel/types)

However, the acknowledgement byte slice that is referred to is not an sdk.TxMsgData but the JSON-encoded Response field from channeltypes.Acknowledgement - either a channeltypes.Acknowledgement_Result or channeltypes.Acknowledgement_Error`.

This needs to be unmarshalled from JSON (cannot be done using the Keeper's Codec; so unintuitively we have to use json.Unmarshal - unless there is a better way?) before we can proto.Unmarshal the actual bytestring the docs allude to.

Problem Definition

Docs / spec do not reflect reality.

Proposal

Not sure - but docs/spec should reflect reality.

The manual unmarshalling of the Acknowledgement struct feels clumsy - maybe there ought to be a NewAcknowledgementFromResponse() helper in channeltypes (or have this handled internally and have OnAcknowledgementPacket acknowledgement argument of type channeltypes.Acknowledgement so we just have to called GetResult() or GetError() as appropriate).


For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged/assigned
@joe-bowman
Copy link
Contributor Author

For reference, this is currently required to handle Acknowledgements - this differs from my interpretation of the docs:

// OnAcknowledgementPacket implements the IBCModule interface
func (im IBCModule) OnAcknowledgementPacket(
	ctx sdk.Context,
	packet channeltypes.Packet,
	acknowledgement []byte,
	relayer sdk.AccAddress,
) error {
	ack := channeltypes.Acknowledgement_Result{}
	err := json.Unmarshal(acknowledgement, &ack)
	if err != nil {
		im.keeper.Logger(ctx).Error("Unable to unmarshal acknowledgement result", "error", err, "data", acknowledgement)
		return err
	}
	txMsgData := &sdk.TxMsgData{}
	err = proto.Unmarshal(ack.Result, txMsgData)
	if err != nil {
		im.keeper.Logger(ctx).Error("Unable to unmarshal acknowledgement", "error", err, "ack", ack.Result)
		return err
	}
	for _, msgData := range txMsgData.Data {
		switch msgData.MsgType {
		case ...
                }
        }
}

@colin-axner
Copy link
Contributor

Nice catch and thanks for opening the issue. The docs are incomplete/incorrect.

This:

if err := proto.Unmarshal(ack.Acknowledgement(), txMsgData); err != nil {

should be

if err := proto.Unmarshal(ack.Result, txMsgData); err != nil {

like you reference.

cannot be done using the Keeper's Codec

IBC modules typically have access to a keeper (see that the ica demo repo does). It is a little clumsy, but you can move this code into a keeper.OnAcknowledgementPacket() to get access to the codec. This explanation should also be added to the docs (although I guess using json.Unmarshal should be fine?)

@crodriguezvega
Copy link
Contributor

@joe-bowman we have also tried this ourselves now (for SDK 0.45.x) in the interchain-account-demo repo, in case you want to have a look.

@joe-bowman
Copy link
Contributor Author

joe-bowman commented Mar 16, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants