From 54f86660449c47714000942f8d873a1c19afda46 Mon Sep 17 00:00:00 2001 From: Aditya Date: Sat, 18 Apr 2020 02:38:25 +0530 Subject: [PATCH] Flexible Port Binding for Transfer Module (#6011) * remove port check and move portID into genesis state * move GenesisState to types and implement ExportGenesis * fix build * store bound portID in transfer state * Update x/ibc/20-transfer/types/codec.go Co-authored-by: Christopher Goes Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- x/ibc/20-transfer/genesis.go | 27 ++++++++++++--------------- x/ibc/20-transfer/keeper/keeper.go | 10 ++++++++++ x/ibc/20-transfer/module.go | 26 +++++++++++++++++--------- x/ibc/20-transfer/types/genesis.go | 13 +++++++++++++ x/ibc/20-transfer/types/keys.go | 5 ++++- 5 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 x/ibc/20-transfer/types/genesis.go diff --git a/x/ibc/20-transfer/genesis.go b/x/ibc/20-transfer/genesis.go index eefeedd812..c91e2acf93 100644 --- a/x/ibc/20-transfer/genesis.go +++ b/x/ibc/20-transfer/genesis.go @@ -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)) } @@ -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, + } +} diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index 7ad7dae5da..1eb736eb5a 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -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 { diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index cbcfa779d0..b08785bf1a 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -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. @@ -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 { + 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 @@ -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 { @@ -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 { diff --git a/x/ibc/20-transfer/types/genesis.go b/x/ibc/20-transfer/types/genesis.go new file mode 100644 index 0000000000..1c81073f09 --- /dev/null +++ b/x/ibc/20-transfer/types/genesis.go @@ -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, + } +} diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go index 28f36745d6..1951f01461 100644 --- a/x/ibc/20-transfer/types/keys.go +++ b/x/ibc/20-transfer/types/keys.go @@ -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 @@ -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 )