Skip to content

Commit

Permalink
integration test updates
Browse files Browse the repository at this point in the history
  • Loading branch information
wllmshao committed Feb 5, 2025
1 parent 8bf51e9 commit eff3efa
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 34 deletions.
19 changes: 10 additions & 9 deletions tests/integration/distribution.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,15 +563,16 @@ func (s *CCVTestSuite) TestIBCTransferMiddleware() {
false,
true,
},
{
"IBC packet sender isn't a consumer chain",
func(ctx sdk.Context, keeper *providerkeeper.Keeper, bankKeeper icstestingutils.TestBankKeeper) {
// make the sender consumer chain impossible to identify
packet.DestinationChannel = "CorruptedChannelId"
},
false,
false,
},
// This test no longer works because the channel ID fails the channel validation check in ibc v9
// {
// "IBC packet sender isn't a consumer chain",
// func(ctx sdk.Context, keeper *providerkeeper.Keeper, bankKeeper icstestingutils.TestBankKeeper) {
// // make the sender consumer chain impossible to identify
// packet.DestinationChannel = "CorruptedChannelId"
// },
// false,
// false,
// },
{
"IBC Transfer recipient is not the consumer rewards pool address",
func(ctx sdk.Context, keeper *providerkeeper.Keeper, bankKeeper icstestingutils.TestBankKeeper) {
Expand Down
8 changes: 6 additions & 2 deletions tests/integration/query_providerinfo_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package integration

import "strings"

// TestQueryProviderInfo tests the results of GetProviderInfo method.
// @Long Description@
// * Set up a CCV channel and send an empty VSC packet.
Expand All @@ -17,6 +19,8 @@ func (s *CCVTestSuite) TestQueryProviderInfo() {
s.Require().Equal(chainInfo.Consumer.ClientID, "07-tendermint-0")
s.Require().Equal(chainInfo.Provider.ConnectionID, "connection-0")
s.Require().Equal(chainInfo.Consumer.ConnectionID, "connection-0")
s.Require().Equal(chainInfo.Provider.ChannelID, "channel-0")
s.Require().Equal(chainInfo.Consumer.ChannelID, "channel-0")
// s.Require().Equal(chainInfo.Provider.ChannelID, "channel-0")
// s.Require().Equal(chainInfo.Consumer.ChannelID, "channel-0") // these channels no longer seem to be always channel-0 after ibc v9 upgrade
s.Require().True(strings.HasPrefix(chainInfo.Provider.ChannelID, "channel-"))
s.Require().True(strings.HasPrefix(chainInfo.Consumer.ChannelID, "channel-"))
}
80 changes: 57 additions & 23 deletions x/ccv/types/denom_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (

// The code in this file is removed in ibc v9. It is copied from ibc v8 to here in order to support the migration to v9

// ReceiverChainIsSource returns true if the denomination originally came
// from the receiving chain and false otherwise.
func ReceiverChainIsSource(sourcePort, sourceChannel, denom string) bool {
// The prefix passed in should contain the SourcePort and SourceChannel.
// If the receiver chain originally sent the token to the sender chain
Expand All @@ -31,61 +33,89 @@ func ReceiverChainIsSource(sourcePort, sourceChannel, denom string) bool {
return strings.HasPrefix(denom, voucherPrefix)
}

// GetDenomPrefix returns the receiving denomination prefix
func GetDenomPrefix(portID, channelID string) string {
return fmt.Sprintf("%s/%s/", portID, channelID)
}

// GetPrefixedDenom returns the denomination with the portID and channelID prefixed
func GetPrefixedDenom(portID, channelID, baseDenom string) string {
return fmt.Sprintf("%s/%s/%s", portID, channelID, baseDenom)
}

// DenomTrace contains the base denomination for ICS20 fungible tokens and the
// source tracing information path.
type DenomTrace struct {
Path string
BaseDenom string
// path defines the chain of port/channel identifiers used for tracing the
// source of the fungible token.
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
// base denomination of the relayed fungible token.
BaseDenom string `protobuf:"bytes,2,opt,name=base_denom,json=baseDenom,proto3" json:"base_denom,omitempty"`
}

const DenomPrefix = "ibc"

// ParseDenomTrace parses a string with the ibc prefix (denom trace) and the base denomination
// into a DenomTrace type.
//
// Examples:
//
// - "portidone/channel-0/uatom" => DenomTrace{Path: "portidone/channel-0", BaseDenom: "uatom"}
// - "portidone/channel-0/portidtwo/channel-1/uatom" => DenomTrace{Path: "portidone/channel-0/portidtwo/channel-1", BaseDenom: "uatom"}
// - "portidone/channel-0/gamm/pool/1" => DenomTrace{Path: "portidone/channel-0", BaseDenom: "gamm/pool/1"}
// - "gamm/pool/1" => DenomTrace{Path: "", BaseDenom: "gamm/pool/1"}
// - "uatom" => DenomTrace{Path: "", BaseDenom: "uatom"}
func ParseDenomTrace(rawDenom string) DenomTrace {
denomSplit := strings.Split(rawDenom, "/")

if denomSplit[0] == rawDenom {
return DenomTrace{
Path: "",
BaseDenom: rawDenom,
}
}

path, baseDenom := extractPathAndBaseFromFullDenom(denomSplit)
return DenomTrace{
Path: path,
BaseDenom: baseDenom,
}
}

// Hash returns the hex bytes of the SHA256 hash of the DenomTrace fields using the following formula:
//
// hash = sha256(tracePath + "/" + baseDenom)
func (dt DenomTrace) Hash() tmbytes.HexBytes {
hash := sha256.Sum256([]byte(dt.GetFullDenomPath()))
return hash[:]
}

// GetPrefix returns the receiving denomination prefix composed by the trace info and a separator.
func (dt DenomTrace) GetPrefix() string {
return dt.Path + "/"
}

func (dt DenomTrace) GetFullDenomPath() string {
if dt.Path == "" {
return dt.BaseDenom
}
return dt.GetPrefix() + dt.BaseDenom
}

// IBCDenom a coin denomination for an ICS20 fungible token in the format
// 'ibc/{hash(tracePath + baseDenom)}'. If the trace is empty, it will return the base denomination.
func (dt DenomTrace) IBCDenom() string {
if dt.Path != "" {
return fmt.Sprintf("%s/%s", DenomPrefix, dt.Hash())
}
return dt.BaseDenom
}

func ParseDenomTrace(rawDenom string) DenomTrace {
denomSplit := strings.Split(rawDenom, "/")

if denomSplit[0] == rawDenom {
return DenomTrace{
Path: "",
BaseDenom: rawDenom,
}
}

path, baseDenom := extractPathAndBaseFromFullDenom(denomSplit)
return DenomTrace{
Path: path,
BaseDenom: baseDenom,
// GetFullDenomPath returns the full denomination according to the ICS20 specification:
// tracePath + "/" + baseDenom
// If there exists no trace then the base denomination is returned.
func (dt DenomTrace) GetFullDenomPath() string {
if dt.Path == "" {
return dt.BaseDenom
}
return dt.GetPrefix() + dt.BaseDenom
}

// extractPathAndBaseFromFullDenom returns the trace path and the base denom from
// the elements that constitute the complete denom.
func extractPathAndBaseFromFullDenom(fullDenomItems []string) (string, string) {
var (
pathSlice []string
Expand Down Expand Up @@ -117,6 +147,10 @@ func extractPathAndBaseFromFullDenom(fullDenomItems []string) (string, string) {
return path, baseDenom
}

// ValidateIBCDenom validates that the given denomination is either:
//
// - A valid base denomination (eg: 'uatom' or 'gamm/pool/1' as in https://github.com/cosmos/ibc-go/issues/894)
// - A valid fungible token representation (i.e 'ibc/{hash}') per ADR 001 https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-001-coin-source-tracing.md
func ValidateIBCDenom(denom string) error {
if err := sdk.ValidateDenom(denom); err != nil {
return err
Expand Down

0 comments on commit eff3efa

Please sign in to comment.