Skip to content

Commit

Permalink
Merge branch 'feat/ibc-eureka' into bznein/7410/timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
bznein authored Oct 14, 2024
2 parents 8c7eb30 + a539936 commit 6a0d99d
Show file tree
Hide file tree
Showing 42 changed files with 1,462 additions and 1,705 deletions.
4 changes: 2 additions & 2 deletions e2e/testsuite/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types"
connectiontypes "github.com/cosmos/ibc-go/v9/modules/core/03-connection/types"
channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types"
packetservertypes "github.com/cosmos/ibc-go/v9/modules/core/packet-server/types"
channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
solomachine "github.com/cosmos/ibc-go/v9/modules/light-clients/06-solomachine"
ibctmtypes "github.com/cosmos/ibc-go/v9/modules/light-clients/07-tendermint"
ibctesting "github.com/cosmos/ibc-go/v9/testing"
Expand Down Expand Up @@ -70,7 +70,7 @@ func codecAndEncodingConfig() (*codec.ProtoCodec, testutil.TestEncodingConfig) {
connectiontypes.RegisterInterfaces(cfg.InterfaceRegistry)
ibctmtypes.RegisterInterfaces(cfg.InterfaceRegistry)
wasmtypes.RegisterInterfaces(cfg.InterfaceRegistry)
packetservertypes.RegisterInterfaces(cfg.InterfaceRegistry)
channeltypesv2.RegisterInterfaces(cfg.InterfaceRegistry)

// all other types
upgradetypes.RegisterInterfaces(cfg.InterfaceRegistry)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/version"

"github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
"github.com/cosmos/ibc-go/v9/modules/core/exported"
"github.com/cosmos/ibc-go/v9/modules/core/packet-server/types"
)

// getCmdQueryChannel defines the command to query the client information (creator and channel) for the given client ID.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/version"

"github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
"github.com/cosmos/ibc-go/v9/modules/core/exported"
"github.com/cosmos/ibc-go/v9/modules/core/packet-server/types"
)

// newProvideCounterpartyCmd defines the command to provide the counterparty to an IBC channel.
Expand Down
18 changes: 18 additions & 0 deletions modules/core/04-channel/v2/keeper/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package keeper
import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"

channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
)

Expand All @@ -25,3 +27,19 @@ func EmitAcknowledgePacketEvents(ctx context.Context, packet channeltypesv2.Pack
func EmitTimeoutPacketEvents(ctx context.Context, packet channeltypesv2.Packet) {
// TODO: https://github.com/cosmos/ibc-go/issues/7386
}

// EmitCreateChannelEvent emits a channel create event.
func (*Keeper) EmitCreateChannelEvent(ctx context.Context, channelID string) {
sdkCtx := sdk.UnwrapSDKContext(ctx)

sdkCtx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
channeltypesv2.EventTypeCreateChannel,
sdk.NewAttribute(channeltypesv2.AttributeKeyChannelID, channelID),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, channeltypesv2.AttributeValueCategory),
),
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
host "github.com/cosmos/ibc-go/v9/modules/core/24-host"
"github.com/cosmos/ibc-go/v9/modules/core/packet-server/types"
)

var _ types.QueryServer = (*queryServer)(nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/keeper"
"github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types"
"github.com/cosmos/ibc-go/v9/modules/core/packet-server/keeper"
"github.com/cosmos/ibc-go/v9/modules/core/packet-server/types"
ibctesting "github.com/cosmos/ibc-go/v9/testing"
)

Expand All @@ -28,8 +28,8 @@ func (suite *KeeperTestSuite) TestQueryChannel() {
"success",
func() {
ctx := suite.chainA.GetContext()
suite.chainA.App.GetIBCKeeper().PacketServerKeeper.SetCreator(ctx, ibctesting.FirstChannelID, expCreator)
suite.chainA.App.GetIBCKeeper().PacketServerKeeper.SetChannel(ctx, ibctesting.FirstChannelID, expChannel)
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetCreator(ctx, ibctesting.FirstChannelID, expCreator)
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetChannel(ctx, ibctesting.FirstChannelID, expChannel)

req = &types.QueryChannelRequest{
ChannelId: ibctesting.FirstChannelID,
Expand All @@ -42,7 +42,7 @@ func (suite *KeeperTestSuite) TestQueryChannel() {
func() {
expCreator = ""

suite.chainA.App.GetIBCKeeper().PacketServerKeeper.SetChannel(suite.chainA.GetContext(), ibctesting.FirstChannelID, expChannel)
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetChannel(suite.chainA.GetContext(), ibctesting.FirstChannelID, expChannel)

req = &types.QueryChannelRequest{
ChannelId: ibctesting.FirstChannelID,
Expand All @@ -55,7 +55,7 @@ func (suite *KeeperTestSuite) TestQueryChannel() {
func() {
expChannel = types.Channel{}

suite.chainA.App.GetIBCKeeper().PacketServerKeeper.SetCreator(suite.chainA.GetContext(), ibctesting.FirstChannelID, expCreator)
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetCreator(suite.chainA.GetContext(), ibctesting.FirstChannelID, expCreator)

req = &types.QueryChannelRequest{
ChannelId: ibctesting.FirstChannelID,
Expand Down Expand Up @@ -100,7 +100,7 @@ func (suite *KeeperTestSuite) TestQueryChannel() {

tc.malleate()

queryServer := keeper.NewQueryServer(suite.chainA.GetSimApp().IBCKeeper.PacketServerKeeper)
queryServer := keeper.NewQueryServer(suite.chainA.GetSimApp().IBCKeeper.ChannelKeeperV2)
res, err := queryServer.Channel(suite.chainA.GetContext(), req)

expPass := tc.expError == nil
Expand Down
23 changes: 23 additions & 0 deletions modules/core/04-channel/v2/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,29 @@ func (k *Keeper) GetChannel(ctx context.Context, channelID string) (types.Channe
return channel, true
}

// GetCreator returns the creator of the client.
func (k *Keeper) GetCreator(ctx context.Context, clientID string) (string, bool) {
sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917
bz := k.ChannelStore(sdkCtx, clientID).Get([]byte(types.CreatorKey))
if len(bz) == 0 {
return "", false
}

return string(bz), true
}

// SetCreator sets the creator of the client.
func (k *Keeper) SetCreator(ctx context.Context, clientID, creator string) {
sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917
k.ChannelStore(sdkCtx, clientID).Set([]byte(types.CreatorKey), []byte(creator))
}

// DeleteCreator deletes the creator associated with the client.
func (k *Keeper) DeleteCreator(ctx context.Context, clientID string) {
sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917
k.ChannelStore(sdkCtx, clientID).Delete([]byte(types.CreatorKey))
}

// GetPacketReceipt returns the packet receipt from the packet receipt path based on the channelID and sequence.
func (k *Keeper) GetPacketReceipt(ctx context.Context, channelID string, sequence uint64) ([]byte, bool) {
store := k.storeService.OpenKVStore(ctx)
Expand Down
45 changes: 45 additions & 0 deletions modules/core/04-channel/v2/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/cosmos/ibc-go/v9/modules/core/04-channel/types"
channeltypes2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types"
commitmentv2types "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2"
ibctesting "github.com/cosmos/ibc-go/v9/testing"
)
Expand Down Expand Up @@ -107,3 +108,47 @@ func (suite *KeeperTestSuite) TestAliasV1Channel() {
})
}
}

func (suite *KeeperTestSuite) TestSetChannel() {
merklePathPrefix := commitmenttypes.NewMerklePath([]byte("ibc"), []byte(""))
channel := channeltypes2.Channel{
ClientId: ibctesting.FirstClientID,
MerklePathPrefix: merklePathPrefix,
}
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetChannel(suite.chainA.GetContext(), ibctesting.FirstChannelID, channel)

retrievedChannel, found := suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.GetChannel(suite.chainA.GetContext(), ibctesting.FirstChannelID)
suite.Require().True(found, "GetChannel does not return channel")
suite.Require().Equal(channel, retrievedChannel, "Channel retrieved not equal")

// Channel not yet stored for another client.
retrievedChannel, found = suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.GetChannel(suite.chainA.GetContext(), ibctesting.SecondClientID)
suite.Require().False(found, "GetChannel unexpectedly returned a channel")
suite.Require().Equal(channeltypes2.Channel{}, retrievedChannel, "Channel retrieved not empty")
}

func (suite *KeeperTestSuite) TestSetCreator() {
clientID := ibctesting.FirstClientID
expectedCreator := "test-creator"

// Set the creator for the client
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetCreator(suite.chainA.GetContext(), clientID, expectedCreator)

// Retrieve the creator from the store
retrievedCreator, found := suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.GetCreator(suite.chainA.GetContext(), clientID)

// Verify that the retrieved creator matches the expected creator
suite.Require().True(found, "GetCreator did not return stored creator")
suite.Require().Equal(expectedCreator, retrievedCreator, "Creator is not retrieved correctly")

// Verify non stored creator is not found
retrievedCreator, found = suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.GetCreator(suite.chainA.GetContext(), ibctesting.SecondClientID)
suite.Require().False(found, "GetCreator unexpectedly returned a creator")
suite.Require().Empty(retrievedCreator, "Creator is not empty")

// Verify that the creator is deleted from the store
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.DeleteCreator(suite.chainA.GetContext(), clientID)
retrievedCreator, found = suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.GetCreator(suite.chainA.GetContext(), clientID)
suite.Require().False(found, "GetCreator unexpectedly returned a creator")
suite.Require().Empty(retrievedCreator, "Creator is not empty")
}
44 changes: 44 additions & 0 deletions modules/core/04-channel/v2/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

channeltypesv1 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types"
channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
ibcerrors "github.com/cosmos/ibc-go/v9/modules/core/errors"
)

var _ channeltypesv2.MsgServer = &Keeper{}
Expand Down Expand Up @@ -135,3 +136,46 @@ func (k *Keeper) Timeout(ctx context.Context, timeout *channeltypesv2.MsgTimeout

return &channeltypesv2.MsgTimeoutResponse{Result: channeltypesv1.SUCCESS}, nil
}

// CreateChannel defines a rpc handler method for MsgCreateChannel
func (k *Keeper) CreateChannel(goCtx context.Context, msg *channeltypesv2.MsgCreateChannel) (*channeltypesv2.MsgCreateChannelResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

channelID := k.channelKeeperV1.GenerateChannelIdentifier(ctx)

// Initialize channel with empty counterparty channel identifier.
channel := channeltypesv2.NewChannel(msg.ClientId, "", msg.MerklePathPrefix)
k.SetChannel(ctx, channelID, channel)

k.SetCreator(ctx, channelID, msg.Signer)

k.EmitCreateChannelEvent(goCtx, channelID)

return &channeltypesv2.MsgCreateChannelResponse{ChannelId: channelID}, nil
}

// ProvideCounterparty defines a rpc handler method for MsgProvideCounterparty.
func (k *Keeper) ProvideCounterparty(goCtx context.Context, msg *channeltypesv2.MsgProvideCounterparty) (*channeltypesv2.MsgProvideCounterpartyResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

creator, found := k.GetCreator(ctx, msg.ChannelId)
if !found {
return nil, errorsmod.Wrap(ibcerrors.ErrUnauthorized, "channel creator must be set")
}

if creator != msg.Signer {
return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "channel creator (%s) must match signer (%s)", creator, msg.Signer)
}

channel, ok := k.GetChannel(ctx, msg.ChannelId)
if !ok {
return nil, errorsmod.Wrapf(channeltypesv2.ErrInvalidChannel, "channel must exist for channel id %s", msg.ChannelId)
}

channel.CounterpartyChannelId = msg.CounterpartyChannelId
k.SetChannel(ctx, msg.ChannelId, channel)
// Delete client creator from state as it is not needed after this point.
k.DeleteCreator(ctx, msg.ChannelId)

return &channeltypesv2.MsgProvideCounterpartyResponse{}, nil
}
71 changes: 71 additions & 0 deletions modules/core/04-channel/v2/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types"
channeltypesv1 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types"
channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
ibcerrors "github.com/cosmos/ibc-go/v9/modules/core/errors"
ibctesting "github.com/cosmos/ibc-go/v9/testing"
"github.com/cosmos/ibc-go/v9/testing/mock"
mockv2 "github.com/cosmos/ibc-go/v9/testing/mock/v2"
Expand Down Expand Up @@ -111,3 +112,73 @@ func (suite *KeeperTestSuite) TestMsgSendPacket() {
})
}
}

func (suite *KeeperTestSuite) TestProvideCounterparty() {
var (
path *ibctesting.Path
msg *channeltypesv2.MsgProvideCounterparty
)
cases := []struct {
name string
malleate func()
expError error
}{
{
"success",
func() {
// set it before handler
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetChannel(suite.chainA.GetContext(), msg.ChannelId, channeltypesv2.NewChannel(path.EndpointA.ClientID, "", ibctesting.MerklePath))
},
nil,
},

{
"failure: signer does not match creator",
func() {
msg.Signer = path.EndpointB.Chain.SenderAccount.GetAddress().String()
},
ibcerrors.ErrUnauthorized,
},
/* // Account sequence mismatch, expected 5, got 6. :thinking:
{
"failure: counterparty does not already exists",
func() {
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.ChannelStore(suite.chainA.GetContext(), path.EndpointA.ChannelID).Delete([]byte(channeltypesv2.ChannelKey))
},
channeltypesv2.ErrInvalidChannel,
},
*/
}

for _, tc := range cases {
tc := tc
path = ibctesting.NewPath(suite.chainA, suite.chainB)
path.SetupClients()

suite.Require().NoError(path.EndpointA.CreateChannel())
suite.Require().NoError(path.EndpointB.CreateChannel())

signer := path.EndpointA.Chain.SenderAccount.GetAddress().String()
msg = channeltypesv2.NewMsgProvideCounterparty(path.EndpointA.ChannelID, path.EndpointB.ChannelID, signer)

tc.malleate()

res, err := path.EndpointA.Chain.SendMsgs(msg)

expPass := tc.expError == nil
if expPass {
suite.Require().NotNil(res)
suite.Require().Nil(err)

// Assert counterparty channel id filled in and creator deleted
channel, found := suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.GetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelID)
suite.Require().True(found)
suite.Require().Equal(channel.CounterpartyChannelId, path.EndpointB.ChannelID)

_, found = suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.GetCreator(suite.chainA.GetContext(), path.EndpointA.ClientID)
suite.Require().False(found)
} else {
suite.Require().Error(err)
}
}
}
Loading

0 comments on commit 6a0d99d

Please sign in to comment.