diff --git a/simapp/app.go b/simapp/app.go index 8e73e752217f..d2d82795c62f 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -176,6 +176,12 @@ func NewSimApp( app.subspaces[crisis.ModuleName] = app.ParamsKeeper.Subspace(crisis.DefaultParamspace) app.subspaces[evidence.ModuleName] = app.ParamsKeeper.Subspace(evidence.DefaultParamspace) + // add capability keeper and ScopeToModule for ibc module + app.CapabilityKeeper = capability.NewKeeper( + app.cdc, keys[capability.StoreKey], memKeys[capability.MemStoreKey], + ) + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibc.ModuleName) + // add keepers app.AccountKeeper = auth.NewAccountKeeper( appCodec, keys[auth.StoreKey], app.subspaces[auth.ModuleName], auth.ProtoBaseAccount, @@ -183,9 +189,6 @@ func NewSimApp( app.BankKeeper = bank.NewBaseKeeper( appCodec, keys[bank.StoreKey], app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(), ) - app.CapabilityKeeper = capability.NewKeeper( - app.cdc, keys[capability.StoreKey], memKeys[capability.MemStoreKey], - ) app.SupplyKeeper = supply.NewKeeper( appCodec, keys[supply.StoreKey], app.AccountKeeper, app.BankKeeper, maccPerms, ) @@ -236,7 +239,7 @@ func NewSimApp( ) app.IBCKeeper = ibc.NewKeeper( - app.cdc, keys[ibc.StoreKey], app.StakingKeeper, + app.cdc, keys[ibc.StoreKey], app.StakingKeeper, scopedIBCKeeper, ) transferCapKey := app.IBCKeeper.PortKeeper.BindPort(bank.ModuleName) diff --git a/x/ibc/04-channel/handler.go b/x/ibc/04-channel/handler.go index 6b602e08ec87..a55b302ad2ee 100644 --- a/x/ibc/04-channel/handler.go +++ b/x/ibc/04-channel/handler.go @@ -2,18 +2,19 @@ package channel import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit -func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenInit) (*sdk.Result, error) { - err := k.ChanOpenInit( +func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap capability.Capability, msg types.MsgChannelOpenInit) (*sdk.Result, capability.Capability, error) { + capKey, err := k.ChanOpenInit( ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, - msg.Channel.Counterparty, msg.Channel.Version, + portCap, msg.Channel.Counterparty, msg.Channel.Version, ) if err != nil { - return nil, err + return nil, nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -34,16 +35,16 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCha return &sdk.Result{ Events: ctx.EventManager().Events(), - }, nil + }, capKey, nil } // HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry -func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenTry) (*sdk.Result, error) { - err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, - msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, +func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap capability.Capability, msg types.MsgChannelOpenTry) (*sdk.Result, capability.Capability, error) { + capKey, err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, + portCap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, ) if err != nil { - return nil, err + return nil, nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -64,13 +65,13 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan return &sdk.Result{ Events: ctx.EventManager().Events(), - }, nil + }, capKey, nil } // HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck -func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenAck) (*sdk.Result, error) { +func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, channelCap capability.Capability, msg types.MsgChannelOpenAck) (*sdk.Result, error) { err := k.ChanOpenAck( - ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight, + ctx, msg.PortID, msg.ChannelID, channelCap, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight, ) if err != nil { return nil, err @@ -95,8 +96,8 @@ func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan } // HandleMsgChannelOpenConfirm defines the sdk.Handler for MsgChannelOpenConfirm -func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenConfirm) (*sdk.Result, error) { - err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofAck, msg.ProofHeight) +func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, channelCap capability.Capability, msg types.MsgChannelOpenConfirm) (*sdk.Result, error) { + err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, channelCap, msg.ProofAck, msg.ProofHeight) if err != nil { return nil, err } @@ -120,8 +121,8 @@ func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Msg } // HandleMsgChannelCloseInit defines the sdk.Handler for MsgChannelCloseInit -func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseInit) (*sdk.Result, error) { - err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID) +func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, channelCap capability.Capability, msg types.MsgChannelCloseInit) (*sdk.Result, error) { + err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID, channelCap) if err != nil { return nil, err } @@ -145,8 +146,8 @@ func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCh } // HandleMsgChannelCloseConfirm defines the sdk.Handler for MsgChannelCloseConfirm -func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseConfirm) (*sdk.Result, error) { - err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofInit, msg.ProofHeight) +func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, channelCap capability.Capability, msg types.MsgChannelCloseConfirm) (*sdk.Result, error) { + err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, channelCap, msg.ProofInit, msg.ProofHeight) if err != nil { return nil, err } diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index 0b434d2ea650..30f5394ca3bb 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -3,12 +3,15 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/capability" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // CounterpartyHops returns the connection hops of the counterparty channel. @@ -33,38 +36,44 @@ func (k Keeper) ChanOpenInit( connectionHops []string, portID, channelID string, + portCap capability.Capability, counterparty types.Counterparty, version string, -) error { +) (capability.Capability, error) { // channel identifier and connection hop length checked on msg.ValidateBasic() _, found := k.GetChannel(ctx, portID, channelID) if found { - return sdkerrors.Wrap(types.ErrChannelExists, channelID) + return nil, sdkerrors.Wrap(types.ErrChannelExists, channelID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.GetState() == connectionexported.UNINITIALIZED { - return sdkerrors.Wrap( + return nil, sdkerrors.Wrap( connection.ErrInvalidConnectionState, "connection state cannot be UNINITIALIZED", ) } + if !k.portKeeper.Authenticate(ctx, portCap, portID) { + return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "caller does not own port capability") + } + channel := types.NewChannel(exported.INIT, order, counterparty, connectionHops, version) k.SetChannel(ctx, portID, channelID, channel) - // TODO: blocked by #5542 - // key := "" - // k.SetChannelCapability(ctx, portID, channelID, key) + capKey, err := k.scopedKeeper.NewCapability(ctx, ibctypes.ChannelCapabilityPath(portID, channelID)) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrInvalidChannelCapability, err.Error()) + } k.SetNextSequenceSend(ctx, portID, channelID, 1) k.SetNextSequenceRecv(ctx, portID, channelID, 1) - return nil + return capKey, nil } // ChanOpenTry is called by a module to accept the first step of a channel opening @@ -75,12 +84,13 @@ func (k Keeper) ChanOpenTry( connectionHops []string, portID, channelID string, + portCap capability.Capability, counterparty types.Counterparty, version, counterpartyVersion string, proofInit commitmentexported.Proof, proofHeight uint64, -) error { +) (capability.Capability, error) { // channel identifier and connection hop length checked on msg.ValidateBasic() previousChannel, found := k.GetChannel(ctx, portID, channelID) @@ -93,19 +103,17 @@ func (k Keeper) ChanOpenTry( sdkerrors.Wrap(types.ErrInvalidChannel, "cannot relay connection attempt") } - // TODO: blocked by #5542 - // key := sdk.NewKVStoreKey(portID) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.portKeeper.Authenticate(ctx, portCap, portID) { + return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "caller does not own port capability") + } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.GetState() != connectionexported.OPEN { - return sdkerrors.Wrapf( + return nil, sdkerrors.Wrapf( connection.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectionEnd.GetState().String(), ) @@ -133,18 +141,19 @@ func (k Keeper) ChanOpenTry( ctx, connectionEnd, proofHeight, proofInit, counterparty.PortID, counterparty.ChannelID, expectedChannel, ); err != nil { - return err + return nil, err } k.SetChannel(ctx, portID, channelID, channel) - // TODO: blocked by #5542 - // key := "" - // k.SetChannelCapability(ctx, portID, channelID, key) + capKey, err := k.scopedKeeper.NewCapability(ctx, ibctypes.ChannelCapabilityPath(portID, channelID)) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrInvalidChannelCapability, err.Error()) + } k.SetNextSequenceSend(ctx, portID, channelID, 1) k.SetNextSequenceRecv(ctx, portID, channelID, 1) - return nil + return capKey, nil } // ChanOpenAck is called by the handshake-originating module to acknowledge the @@ -152,7 +161,8 @@ func (k Keeper) ChanOpenTry( func (k Keeper) ChanOpenAck( ctx sdk.Context, portID, - channelID, + channelID string, + chanCap capability.Capability, counterpartyVersion string, proofTry commitmentexported.Proof, proofHeight uint64, @@ -169,11 +179,9 @@ func (k Keeper) ChanOpenAck( ) } - // TODO: blocked by #5542 - // key := sdk.NewKVStoreKey(portID) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) { + return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel") + } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { @@ -221,6 +229,7 @@ func (k Keeper) ChanOpenConfirm( ctx sdk.Context, portID, channelID string, + chanCap capability.Capability, proofAck commitmentexported.Proof, proofHeight uint64, ) error { @@ -236,16 +245,9 @@ func (k Keeper) ChanOpenConfirm( ) } - // TODO: blocked by #5542 - // capkey, found := k.GetChannelCapability(ctx, portID, channelID) - // if !found { - // return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID) - // } - - // key := sdk.NewKVStoreKey(capkey) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) { + return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel") + } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { @@ -296,17 +298,11 @@ func (k Keeper) ChanCloseInit( ctx sdk.Context, portID, channelID string, + chanCap capability.Capability, ) error { - // TODO: blocked by #5542 - // capkey, found := k.GetChannelCapability(ctx, portID, channelID) - // if !found { - // return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID) - // } - - // key := sdk.NewKVStoreKey(capkey) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) { + return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel") + } channel, found := k.GetChannel(ctx, portID, channelID) if !found { @@ -341,19 +337,13 @@ func (k Keeper) ChanCloseConfirm( ctx sdk.Context, portID, channelID string, + chanCap capability.Capability, proofInit commitmentexported.Proof, proofHeight uint64, ) error { - // TODO: blocked by #5542 - // capkey, found := k.GetChannelCapability(ctx, portID, channelID) - // if !found { - // return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID) - // } - - // key := sdk.NewKVStoreKey(capkey) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) { + return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel") + } channel, found := k.GetChannel(ctx, portID, channelID) if !found { diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index ab756c044971..70d1ba1a47dd 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -19,13 +20,14 @@ type Keeper struct { clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper portKeeper types.PortKeeper + scopedKeeper capability.ScopedKeeper } // NewKeeper creates a new IBC channel Keeper instance func NewKeeper( cdc *codec.Codec, key sdk.StoreKey, clientKeeper types.ClientKeeper, connectionKeeper types.ConnectionKeeper, - portKeeper types.PortKeeper, + portKeeper types.PortKeeper, scopedKeeper capability.ScopedKeeper, ) Keeper { return Keeper{ storeKey: key, @@ -33,6 +35,7 @@ func NewKeeper( clientKeeper: clientKeeper, connectionKeeper: connectionKeeper, portKeeper: portKeeper, + scopedKeeper: scopedKeeper, } } @@ -61,23 +64,6 @@ func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel ty store.Set(ibctypes.KeyChannel(portID, channelID), bz) } -// GetChannelCapability gets a channel's capability key from the store -func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) (string, bool) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(ibctypes.KeyChannelCapabilityPath(portID, channelID)) - if bz == nil { - return "", false - } - - return string(bz), true -} - -// SetChannelCapability sets a channel's capability key to the store -func (k Keeper) SetChannelCapability(ctx sdk.Context, portID, channelID string, key string) { - store := ctx.KVStore(k.storeKey) - store.Set(ibctypes.KeyChannelCapabilityPath(portID, channelID), []byte(key)) -} - // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go index a184314bbd56..1def7a4d004e 100644 --- a/x/ibc/04-channel/types/errors.go +++ b/x/ibc/04-channel/types/errors.go @@ -12,11 +12,12 @@ var ( ErrInvalidChannelState = sdkerrors.Register(SubModuleName, 4, "invalid channel state") ErrInvalidChannelOrdering = sdkerrors.Register(SubModuleName, 5, "invalid channel ordering") ErrInvalidCounterparty = sdkerrors.Register(SubModuleName, 6, "invalid counterparty channel") - ErrChannelCapabilityNotFound = sdkerrors.Register(SubModuleName, 7, "channel capability not found") - ErrSequenceSendNotFound = sdkerrors.Register(SubModuleName, 8, "sequence send not found") - ErrSequenceReceiveNotFound = sdkerrors.Register(SubModuleName, 9, "sequence receive not found") - ErrInvalidPacket = sdkerrors.Register(SubModuleName, 10, "invalid packet") - ErrPacketTimeout = sdkerrors.Register(SubModuleName, 11, "packet timeout") - ErrTooManyConnectionHops = sdkerrors.Register(SubModuleName, 12, "too many connection hops") - ErrAcknowledgementTooLong = sdkerrors.Register(SubModuleName, 13, "acknowledgement too long") + ErrInvalidChannelCapability = sdkerrors.Register(SubModuleName, 7, "invalid channel capability") + ErrChannelCapabilityNotFound = sdkerrors.Register(SubModuleName, 8, "channel capability not found") + ErrSequenceSendNotFound = sdkerrors.Register(SubModuleName, 9, "sequence send not found") + ErrSequenceReceiveNotFound = sdkerrors.Register(SubModuleName, 10, "sequence receive not found") + ErrInvalidPacket = sdkerrors.Register(SubModuleName, 11, "invalid packet") + ErrPacketTimeout = sdkerrors.Register(SubModuleName, 12, "packet timeout") + ErrTooManyConnectionHops = sdkerrors.Register(SubModuleName, 13, "too many connection hops") + ErrAcknowledgementTooLong = sdkerrors.Register(SubModuleName, 14, "acknowledgement too long") ) diff --git a/x/ibc/04-channel/types/expected_keepers.go b/x/ibc/04-channel/types/expected_keepers.go index 26c6ad1547a4..13a86406ac14 100644 --- a/x/ibc/04-channel/types/expected_keepers.go +++ b/x/ibc/04-channel/types/expected_keepers.go @@ -2,6 +2,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" @@ -68,5 +69,5 @@ type ConnectionKeeper interface { // PortKeeper expected account IBC port keeper type PortKeeper interface { - Authenticate(key sdk.CapabilityKey, portID string) bool + Authenticate(ctx sdk.Context, key capability.Capability, portID string) bool } diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index 45f0817f7702..0ce2cdddfc73 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -3,47 +3,47 @@ package keeper import ( "fmt" - "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) // Keeper defines the IBC connection keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - ports map[string]bool + scopedKeeper capability.ScopedKeeper } // NewKeeper creates a new IBC connection Keeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey) Keeper { +func NewKeeper(sck capability.ScopedKeeper) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - ports: make(map[string]bool), // map of capability key names to port ids + scopedKeeper: sck, } } // isBounded checks a given port ID is already bounded. -func (k Keeper) isBounded(portID string) bool { - return k.ports[portID] +func (k Keeper) isBounded(ctx sdk.Context, portID string) bool { + _, ok := k.scopedKeeper.GetCapability(ctx, types.PortPath(portID)) + return ok } // BindPort binds to a port and returns the associated capability. // Ports must be bound statically when the chain starts in `app.go`. // The capability must then be passed to a module which will need to pass // it as an extra parameter when calling functions on the IBC module. -func (k *Keeper) BindPort(portID string) sdk.CapabilityKey { +func (k *Keeper) BindPort(ctx sdk.Context, portID string) capability.Capability { if err := host.DefaultPortIdentifierValidator(portID); err != nil { panic(err.Error()) } - if k.isBounded(portID) { + if k.isBounded(ctx, portID) { panic(fmt.Sprintf("port %s is already bound", portID)) } - key := sdk.NewKVStoreKey(portID) - k.ports[key.Name()] = true // NOTE: key name and value always match + key, err := k.scopedKeeper.NewCapability(ctx, types.PortPath(portID)) + if err != nil { + panic(err.Error()) + } return key } @@ -52,14 +52,10 @@ func (k *Keeper) BindPort(portID string) sdk.CapabilityKey { // by checking if the memory address of the capability was previously // generated and bound to the port (provided as a parameter) which the capability // is being authenticated against. -func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { +func (k Keeper) Authenticate(ctx sdk.Context, key capability.Capability, portID string) bool { if err := host.DefaultPortIdentifierValidator(portID); err != nil { panic(err.Error()) } - if key.Name() != portID { - return false - } - - return k.ports[key.Name()] + return k.scopedKeeper.AuthenticateCapability(ctx, key, types.PortPath(portID)) } diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 1a3f5843f01f..2494937d6489 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -37,7 +37,7 @@ func NewHandler(k Keeper) sdk.Handler { // IBC channel msgs case channel.MsgChannelOpenInit: - return channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, msg) + res, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, msg) case channel.MsgChannelOpenTry: return channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, msg) diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index aefe2863b4de..4add1bb214aa 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -3,6 +3,7 @@ package keeper import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -19,12 +20,12 @@ type Keeper struct { // NewKeeper creates a new ibc Keeper func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, stakingKeeper client.StakingKeeper, + cdc *codec.Codec, key sdk.StoreKey, stakingKeeper client.StakingKeeper, scopedKeeper capability.ScopedKeeper, ) Keeper { clientKeeper := client.NewKeeper(cdc, key, stakingKeeper) connectionKeeper := connection.NewKeeper(cdc, key, clientKeeper) - portKeeper := port.NewKeeper(cdc, key) - channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper) + portKeeper := port.NewKeeper(scopedKeeper) + channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper, scopedKeeper) return Keeper{ ClientKeeper: clientKeeper,