Skip to content
New issue

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

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

Already on GitHub? # to your account

fix: skip emission of unpopulated memo field in ics20 (backport #2651) #2653

Merged
merged 3 commits into from
Nov 3, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### State Machine Breaking

* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty).
* (27-interchain-accounts) [\#2580](https://github.com/cosmos/ibc-go/issues/2580) Removing port prefix requirement from the ICA host channel handshake
* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`.

Expand Down
33 changes: 33 additions & 0 deletions modules/apps/transfer/types/codec.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package types

import (
"bytes"

"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/msgservice"
"github.com/gogo/protobuf/jsonpb"
"github.com/gogo/protobuf/proto"
)

// RegisterLegacyAminoCodec registers the necessary x/ibc transfer interfaces and concrete types
Expand Down Expand Up @@ -39,3 +43,32 @@ func init() {
RegisterLegacyAminoCodec(amino)
amino.Seal()
}

// mustProtoMarshalJSON provides an auxiliary function to return Proto3 JSON encoded
// bytes of a message.
// NOTE: Copied from https://github.com/cosmos/cosmos-sdk/blob/971c542453e0972ef1dfc5a80159ad5049c7211c/codec/json.go
// and modified in order to allow `EmitDefaults` to be set to false for ics20 packet marshalling.
// This allows for the introduction of the memo field to be backwards compatible.
func mustProtoMarshalJSON(msg proto.Message) []byte {
anyResolver := codectypes.NewInterfaceRegistry()

// EmitDefaults is set to false to prevent marshalling of unpopulated fields (memo)
// OrigName and the anyResovler match the fields the original SDK function would expect
// in order to minimize changes.

// OrigName is true since there is no particular reason to use camel case
// The any resolver is empty, but provided anyways.
jm := &jsonpb.Marshaler{OrigName: true, EmitDefaults: false, AnyResolver: anyResolver}

err := codectypes.UnpackInterfaces(msg, codectypes.ProtoJSONPacker{JSONPBMarshaler: jm})
if err != nil {
panic(err)
}

buf := new(bytes.Buffer)
if err := jm.Marshal(buf, msg); err != nil {
panic(err)
}

return buf.Bytes()
}
25 changes: 25 additions & 0 deletions modules/apps/transfer/types/codec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package types_test

import (
"strings"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
)

// TestMustMarshalProtoJSON tests that the memo field is only emitted (marshalled) if it is populated
func (suite *TypesTestSuite) TestMustMarshalProtoJSON() {
memo := "memo"
packetData := types.NewFungibleTokenPacketData(sdk.DefaultBondDenom, "1", suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), memo)

bz := packetData.GetBytes()
exists := strings.Contains(string(bz), memo)
suite.Require().True(exists)

packetData.Memo = ""

bz = packetData.GetBytes()
exists = strings.Contains(string(bz), memo)
suite.Require().False(exists)
}
2 changes: 1 addition & 1 deletion modules/apps/transfer/types/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ func (ftpd FungibleTokenPacketData) ValidateBasic() error {

// GetBytes is a helper for serialising
func (ftpd FungibleTokenPacketData) GetBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&ftpd))
return sdk.MustSortJSON(mustProtoMarshalJSON(&ftpd))
}