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

Flexible Port Binding for Transfer Module #6011

Merged
merged 10 commits into from
Apr 17, 2020
27 changes: 12 additions & 15 deletions x/ibc/20-transfer/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,11 @@ import (
"github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types"
)

// GenesisState is currently only used to ensure that the InitGenesis gets run
// by the module manager
type GenesisState struct {
Version string `json:"version,omitempty" yaml:"version,omitempty"`
}

func DefaultGenesis() GenesisState {
return GenesisState{
Version: types.Version,
}
}

// InitGenesis sets distribution information for genesis
func InitGenesis(ctx sdk.Context, keeper Keeper) {
// InitGenesis binds to portid from genesis state
func InitGenesis(ctx sdk.Context, keeper Keeper, state types.GenesisState) {
// transfer module binds to the transfer port on InitChain
// and claims the returned capability
err := keeper.BindPort(ctx, types.PortID)
err := keeper.BindPort(ctx, state.PortID)
if err != nil {
panic(fmt.Sprintf("could not claim port capability: %v", err))
}
Expand All @@ -33,3 +21,12 @@ func InitGenesis(ctx sdk.Context, keeper Keeper) {
panic(fmt.Sprintf("%s module account has not been set", types.GetModuleAccountName()))
}
}

// ExportGenesis exports transfer module's portID into its geneis state
func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
portID := keeper.GetPort(ctx)

return types.GenesisState{
PortID: portID,
}
}
10 changes: 10 additions & 0 deletions x/ibc/20-transfer/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,20 @@ func (k Keeper) ChanCloseInit(ctx sdk.Context, portID, channelID string) error {
// BindPort defines a wrapper function for the ort Keeper's function in
// order to expose it to module's InitGenesis function
func (k Keeper) BindPort(ctx sdk.Context, portID string) error {
// Set the portID into our store so we can retrieve it later
store := ctx.KVStore(k.storeKey)
store.Set([]byte(types.PortKey), []byte(portID))

cap := k.portKeeper.BindPort(ctx, portID)
return k.ClaimCapability(ctx, cap, porttypes.PortPath(portID))
}

// GetPort returns the portID for the transfer module. Used in ExportGenesis
func (k Keeper) GetPort(ctx sdk.Context) string {
store := ctx.KVStore(k.storeKey)
return string(store.Get([]byte(types.PortKey)))
}

// ClaimCapability allows the transfer module that can claim a capability that IBC module
// passes to it
func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capability.Capability, name string) error {
Expand Down
26 changes: 17 additions & 9 deletions x/ibc/20-transfer/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
// DefaultGenesis returns default genesis state as raw bytes for the ibc
// transfer module.
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
return cdc.MustMarshalJSON(DefaultGenesis())
return cdc.MustMarshalJSON(types.DefaultGenesis())
}

// ValidateGenesis performs genesis state validation for the ibc transfer module.
Expand Down Expand Up @@ -111,14 +111,18 @@ func (am AppModule) NewQuerierHandler() sdk.Querier {

// InitGenesis performs genesis initialization for the ibc transfer module. It returns
// no validator updates.
func (am AppModule) InitGenesis(ctx sdk.Context, _ codec.JSONMarshaler, _ json.RawMessage) []abci.ValidatorUpdate {
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data json.RawMessage) []abci.ValidatorUpdate {
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
var genesisState types.GenesisState
cdc.MustUnmarshalJSON(data, &genesisState)

// check if the IBC transfer module account is set
InitGenesis(ctx, am.keeper)
InitGenesis(ctx, am.keeper, genesisState)
return []abci.ValidatorUpdate{}
}

func (am AppModule) ExportGenesis(ctx sdk.Context, _ codec.JSONMarshaler) json.RawMessage {
return nil
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler) json.RawMessage {
gs := ExportGenesis(ctx, am.keeper)
return cdc.MustMarshalJSON(gs)
}

// BeginBlock implements the AppModule interface
Expand All @@ -144,8 +148,10 @@ func (am AppModule) OnChanOpenInit(
) error {
// TODO: Enforce ordering, currently relayers use ORDERED channels

if counterparty.PortID != types.PortID {
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "counterparty has invalid portid. expected: %s, got %s", types.PortID, counterparty.PortID)
// Require portID is the portID transfer module is bound to
boundPort := am.keeper.GetPort(ctx)
if boundPort != portID {
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort)
}

if version != types.Version {
Expand Down Expand Up @@ -174,8 +180,10 @@ func (am AppModule) OnChanOpenTry(
) error {
// TODO: Enforce ordering, currently relayers use ORDERED channels

if counterparty.PortID != types.PortID {
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "counterparty has invalid portid. expected: %s, got %s", types.PortID, counterparty.PortID)
// Require portID is the portID transfer module is bound to
boundPort := am.keeper.GetPort(ctx)
if boundPort != portID {
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort)
}

if version != types.Version {
Expand Down
1 change: 1 addition & 0 deletions x/ibc/20-transfer/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var ModuleCdc = codec.New()
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterConcrete(MsgTransfer{}, "ibc/transfer/MsgTransfer", nil)
cdc.RegisterConcrete(FungibleTokenPacketData{}, "ibc/transfer/PacketDataTransfer", nil)
cdc.RegisterConcrete(GenesisState{}, "ibc/transfer/GenesisState", nil)
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
}

func init() {
Expand Down
13 changes: 13 additions & 0 deletions x/ibc/20-transfer/types/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package types

// GenesisState is currently only used to ensure that the InitGenesis gets run
// by the module manager
type GenesisState struct {
PortID string `json:"portid" yaml:"portid"`
}

func DefaultGenesis() GenesisState {
return GenesisState{
PortID: PortID,
}
}
5 changes: 4 additions & 1 deletion x/ibc/20-transfer/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const (
// module supports
Version = "ics20-1"

// PortID that transfer module binds to
// Default PortID that transfer module binds to
PortID = "transfer"

// StoreKey is the store key string for IBC transfer
Expand All @@ -26,6 +26,9 @@ const (
// RouterKey is the message route for IBC transfer
RouterKey = ModuleName

// Key to store portID in our store
PortKey = "portID"

// QuerierRoute is the querier route for IBC transfer
QuerierRoute = ModuleName
)
Expand Down