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

feat(core, apps): 'PacketData' interface added and implemented #4200

Merged
merged 19 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
22 changes: 21 additions & 1 deletion modules/apps/27-interchain-accounts/types/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
"encoding/json"
"strings"
"time"

errorsmod "cosmossdk.io/errors"
Expand All @@ -12,7 +13,10 @@ import (
ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
)

var _ ibcexported.PacketDataProvider = (*InterchainAccountPacketData)(nil)
var (
_ ibcexported.PacketData = (*InterchainAccountPacketData)(nil)
_ ibcexported.PacketDataProvider = (*InterchainAccountPacketData)(nil)
)

// MaxMemoCharLength defines the maximum length for the InterchainAccountPacketData memo field
const MaxMemoCharLength = 256
Expand Down Expand Up @@ -70,6 +74,22 @@ func (ct CosmosTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
return nil
}

// GetPacketSender returns the sender address of the interchain accounts packet data.
// It is obtained from the source port ID by cutting off the ControllerPortPrefix.
// If the source port ID does not have the ControllerPortPrefix, then an empty string is returned.
//
// NOTE:
// - The sender address is set by the packet sender and may not have been validated a signature
// check if the packet sender isn't the interchain accounts module.
// - The sender address must only be used by modules on the sending chain.
func (InterchainAccountPacketData) GetPacketSender(sourcePortID string) string {
icaOwner, found := strings.CutPrefix(sourcePortID, ControllerPortPrefix)
if !found {
return ""
}
return icaOwner
}

// GetCustomPacketData interprets the memo field of the packet data as a JSON object
// and returns the value associated with the given key.
// If the key is missing or the memo is not properly formatted, then nil is returned.
Expand Down
29 changes: 29 additions & 0 deletions modules/apps/27-interchain-accounts/types/packet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,35 @@ func (suite *TypesTestSuite) TestValidateBasic() {
}
}

func (suite *TypesTestSuite) TestGetPacketSender() {
testCases := []struct {
name string
srcPortID string
expSender string
}{
{
"success: port id has prefix",
types.ControllerPortPrefix + ibctesting.TestAccAddress,
ibctesting.TestAccAddress,
},
{
"failure: missing prefix",
ibctesting.TestAccAddress,
"",
},
{
"failure: empty port id",
"",
"",
},
}

for _, tc := range testCases {
packetData := types.InterchainAccountPacketData{}
suite.Require().Equal(tc.expSender, packetData.GetPacketSender(tc.srcPortID))
}
}

func (suite *TypesTestSuite) TestPacketDataProvider() {
expCallbackAddr := ibctesting.TestAccAddress

Expand Down
16 changes: 15 additions & 1 deletion modules/apps/transfer/types/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import (
ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
)

var _ ibcexported.PacketDataProvider = (*FungibleTokenPacketData)(nil)
var (
_ ibcexported.PacketData = (*FungibleTokenPacketData)(nil)
_ ibcexported.PacketDataProvider = (*FungibleTokenPacketData)(nil)
)

var (
// DefaultRelativePacketTimeoutHeight is the default packet timeout height (in blocks) relative
Expand Down Expand Up @@ -69,6 +72,17 @@ func (ftpd FungibleTokenPacketData) GetBytes() []byte {
return sdk.MustSortJSON(mustProtoMarshalJSON(&ftpd))
}

// GetPacketSender returns the sender address embedded in the packet data.
//
// NOTE:
// - The sender address is set by the module which requested the packet to be sent,
// and this module may not have validated the sender address by a signature check.
// - The sender address must only be used by modules on the sending chain.
// - sourcePortID is not used in this implementation.
func (ftpd FungibleTokenPacketData) GetPacketSender(sourcePortID string) string {
return ftpd.Sender
}

// GetCustomPacketData interprets the memo field of the packet data as a JSON object
// and returns the value associated with the given key.
// If the key is missing or the memo is not properly formatted, then nil is returned.
Expand Down
12 changes: 12 additions & 0 deletions modules/apps/transfer/types/packet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ func TestFungibleTokenPacketDataValidateBasic(t *testing.T) {
}
}

func (suite *TypesTestSuite) TestGetPacketSender() {
packetData := types.FungibleTokenPacketData{
Denom: denom,
Amount: amount,
Sender: sender,
Receiver: receiver,
Memo: "",
}

suite.Require().Equal(sender, packetData.GetPacketSender(types.PortID))
}

func (suite *TypesTestSuite) TestPacketDataProvider() {
testCases := []struct {
name string
Expand Down
7 changes: 7 additions & 0 deletions modules/core/exported/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ type Acknowledgement interface {
Acknowledgement() []byte
}

// PacketData defines an optional interface which an application's packet data structure may implement.
type PacketData interface {
// GetPacketSender returns the sender address of the packet data.
// If the packet sender is unknown or undefined, an empty string should be returned.
GetPacketSender(sourcePortID string) string
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
}

// PacketDataProvider defines an optional interfaces for retrieving custom packet data stored on behalf of another application.
// An existing problem in the IBC middleware design is the inability for a middleware to define its own packet data type and insert packet sender provided information.
// A short term solution was introduced into several application's packet data to utilize a memo field to carry this information on behalf of another application.
Expand Down
Loading