Skip to content

Commit

Permalink
IBC mapping for tokenfactory denoms
Browse files Browse the repository at this point in the history
  • Loading branch information
codehans authored and antstalepresh committed Jul 23, 2024
1 parent 91169d1 commit daedc9f
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 34 deletions.
2 changes: 1 addition & 1 deletion modules/apps/transfer/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ corresponding to the counterparty channel. Any timeout set to 0 is disabled.`),
return err
}

if !strings.HasPrefix(coin.Denom, "ibc/") {
if !strings.HasPrefix(coin.Denom, "ibc/") && !strings.HasPrefix(coin.Denom, "factory/") {
denomTrace := types.ParseDenomTrace(coin.Denom)
coin.Denom = denomTrace.IBCDenom()
}
Expand Down
8 changes: 4 additions & 4 deletions modules/apps/transfer/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,10 @@ func (suite *KeeperTestSuite) TestParams() {
expPass bool
}{
// it is not possible to set invalid booleans
{"success: set params false-false", types.NewParams(false, false), true},
{"success: set params false-true", types.NewParams(false, true), true},
{"success: set params true-false", types.NewParams(true, false), true},
{"success: set params true-true", types.NewParams(true, true), true},
{"success: set params false-false", types.NewParams(false, false, "factory"), true},
{"success: set params false-true", types.NewParams(false, true, "factory"), true},
{"success: set params true-false", types.NewParams(true, false, "factory"), true},
{"success: set params true-true", types.NewParams(true, true, "factory"), true},
}

for _, tc := range testCases {
Expand Down
25 changes: 18 additions & 7 deletions modules/apps/transfer/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ func (k Keeper) sendTransfer(
return 0, err
}

prefix := k.GetParams(ctx).SlashPrefix
if prefix != "" && strings.HasPrefix(fullDenomPath, prefix+"/") {
fullDenomPath = strings.ReplaceAll(fullDenomPath, "/", ":")
}

} else {
labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "false"))

Expand Down Expand Up @@ -205,14 +210,20 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t
unprefixedDenom := data.Denom[len(voucherPrefix):]

// coin denomination used in sending from the escrow address
denom := unprefixedDenom

// The denomination used to send the coins is either the native denom or the hash of the path
// if the denomination is not native.
denomTrace := types.ParseDenomTrace(unprefixedDenom)
if !denomTrace.IsNativeDenom() {
denom = denomTrace.IBCDenom()
var denom string
prefix := k.GetParams(ctx).SlashPrefix
if prefix != "" && strings.HasPrefix(unprefixedDenom, prefix+":") {
denom = strings.ReplaceAll(unprefixedDenom, ":", "/")
} else {
denom = unprefixedDenom
// The denomination used to send the coins is either the native denom or the hash of the path
// if the denomination is not native.
denomTrace := types.ParseDenomTrace(unprefixedDenom)
if denomTrace.Path != "" {
denom = denomTrace.IBCDenom()
}
}

token := sdk.NewCoin(denom, transferAmount)

if k.bankKeeper.BlockedAddr(receiver) {
Expand Down
12 changes: 11 additions & 1 deletion modules/apps/transfer/simulation/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ func RadomEnabled(r *rand.Rand) bool {
return r.Int63n(101) <= 75
}

func RandomPrefix(r *rand.Rand) string {
return simtypes.RandStringOfLength(r, 10)
}

// RandomizedGenState generates a random GenesisState for transfer.
func RandomizedGenState(simState *module.SimulationState) {
var portID string
Expand All @@ -40,10 +44,16 @@ func RandomizedGenState(simState *module.SimulationState) {
func(r *rand.Rand) { receiveEnabled = RadomEnabled(r) },
)

var slashPrefix string
simState.AppParams.GetOrGenerate(
string(types.KeySlashPrefix), &slashPrefix, simState.Rand,
func(r *rand.Rand) { slashPrefix = RandomPrefix(r) },
)

transferGenesis := types.GenesisState{
PortId: portID,
DenomTraces: types.Traces{},
Params: types.NewParams(sendEnabled, receiveEnabled),
Params: types.NewParams(sendEnabled, receiveEnabled, slashPrefix),
}

bz, err := json.MarshalIndent(&transferGenesis, "", " ")
Expand Down
7 changes: 5 additions & 2 deletions modules/apps/transfer/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ const (
DefaultSendEnabled = true
// DefaultReceiveEnabled enabled
DefaultReceiveEnabled = true
// DefaultSlashPrefix factory
DefaultSlashPrefix = "factory"
)

// NewParams creates a new parameter configuration for the ibc transfer module
func NewParams(enableSend, enableReceive bool) Params {
func NewParams(enableSend, enableReceive bool, slashPrefix string) Params {
return Params{
SendEnabled: enableSend,
ReceiveEnabled: enableReceive,
SlashPrefix: slashPrefix,
}
}

// DefaultParams is the default parameter configuration for the ibc-transfer module
func DefaultParams() Params {
return NewParams(DefaultSendEnabled, DefaultReceiveEnabled)
return NewParams(DefaultSendEnabled, DefaultReceiveEnabled, DefaultSlashPrefix)
}
36 changes: 36 additions & 0 deletions modules/apps/transfer/types/params_legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ package types

import (
"fmt"
"strings"

sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
)

Expand All @@ -17,6 +19,8 @@ var (
KeySendEnabled = []byte("SendEnabled")
// KeyReceiveEnabled is store's key for ReceiveEnabled Params
KeyReceiveEnabled = []byte("ReceiveEnabled")
// KeySlashPrefix is store's key for SlashPrefix Params
KeySlashPrefix = []byte("SlashPrefix")
)

// ParamKeyTable type declaration for parameters
Expand All @@ -29,9 +33,23 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
return paramtypes.ParamSetPairs{
paramtypes.NewParamSetPair(KeySendEnabled, &p.SendEnabled, validateEnabledTypeLegacy),
paramtypes.NewParamSetPair(KeyReceiveEnabled, &p.ReceiveEnabled, validateEnabledTypeLegacy),
paramtypes.NewParamSetPair(KeySlashPrefix, &p.SlashPrefix, validatePrefixLegacy),
}
}

// Validate all ibc-transfer module parameters
func (p Params) Validate() error {
if err := validateEnabledTypeLegacy(p.SendEnabled); err != nil {
return err
}

if err := validatePrefixLegacy(p.SlashPrefix); err != nil {
return err
}

return validateEnabledTypeLegacy(p.ReceiveEnabled)
}

func validateEnabledTypeLegacy(i interface{}) error {
_, ok := i.(bool)
if !ok {
Expand All @@ -40,3 +58,21 @@ func validateEnabledTypeLegacy(i interface{}) error {

return nil
}

func validatePrefixLegacy(i interface{}) error {
p, ok := i.(string)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}

err := sdk.ValidateDenom(p)
if err != nil {
return err
}

if strings.Contains(p, "/") {
return fmt.Errorf("invalid parameter type: %T", i)
}

return nil
}
15 changes: 15 additions & 0 deletions modules/apps/transfer/types/params_legacy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package types_test

import (
"testing"

"github.com/stretchr/testify/require"

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

func TestValidateParams(t *testing.T) {
require.NoError(t, types.DefaultParams().Validate())
require.NoError(t, types.NewParams(true, false, "factory").Validate())
require.Error(t, types.NewParams(true, false, "factory/").Validate())
}
95 changes: 77 additions & 18 deletions modules/apps/transfer/types/transfer.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion proto/ibc/applications/transfer/v1/transfer.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ syntax = "proto3";

package ibc.applications.transfer.v1;

import "gogoproto/gogo.proto";

option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types";

// DenomTrace contains the base denomination for ICS20 fungible tokens and the
Expand All @@ -24,5 +26,9 @@ message Params {
bool send_enabled = 1;
// receive_enabled enables or disables all cross-chain token transfers to this
// chain.
bool receive_enabled = 2;
bool receive_enabled = 2 [(gogoproto.moretags) = "yaml:\"receive_enabled\""];
// In order to provide backward compatibility with IBC transfers to other
// IBCv3 chains, we can provide a prefix for denoms containing `/` so that they
// are escaped on send and receive with `:`
string slash_prefix = 3 [(gogoproto.moretags) = "yaml:\"slash_prefix\""];
}

0 comments on commit daedc9f

Please sign in to comment.