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

MsgTransfer For Eureka #7957

Merged
merged 13 commits into from
Feb 24, 2025
2 changes: 2 additions & 0 deletions modules/apps/callbacks/testing/simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ func NewSimApp(
appCodec, runtime.NewKVStoreService(keys[ibctransfertypes.StoreKey]), app.GetSubspace(ibctransfertypes.ModuleName),
app.IBCFeeKeeper, // ISC4 Wrapper: fee IBC middleware
app.IBCKeeper.ChannelKeeper,
app.IBCKeeper.ChannelKeeperV2,
app.IBCKeeper.ClientV2Keeper,
app.AccountKeeper, app.BankKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
Expand Down
30 changes: 18 additions & 12 deletions modules/apps/transfer/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ type Keeper struct {
cdc codec.BinaryCodec
legacySubspace types.ParamSubspace

ics4Wrapper porttypes.ICS4Wrapper
channelKeeper types.ChannelKeeper
AuthKeeper types.AccountKeeper
BankKeeper types.BankKeeper
ics4Wrapper porttypes.ICS4Wrapper
channelKeeper types.ChannelKeeper
channelKeeperV2 types.ChannelKeeperV2
clientKeeperV2 types.ClientKeeperV2
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could remove this if desired

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to have less stuff to put in here, but what would that mean for the code?

AuthKeeper types.AccountKeeper
BankKeeper types.BankKeeper

// the address capable of executing a MsgUpdateParams message. Typically, this
// should be the x/gov module account.
Expand All @@ -47,6 +49,8 @@ func NewKeeper(
legacySubspace types.ParamSubspace,
ics4Wrapper porttypes.ICS4Wrapper,
channelKeeper types.ChannelKeeper,
channelKeeperV2 types.ChannelKeeperV2,
clientKeeperV2 types.ClientKeeperV2,
authKeeper types.AccountKeeper,
bankKeeper types.BankKeeper,
authority string,
Expand All @@ -61,14 +65,16 @@ func NewKeeper(
}

return Keeper{
cdc: cdc,
storeService: storeService,
legacySubspace: legacySubspace,
ics4Wrapper: ics4Wrapper,
channelKeeper: channelKeeper,
AuthKeeper: authKeeper,
BankKeeper: bankKeeper,
authority: authority,
cdc: cdc,
storeService: storeService,
legacySubspace: legacySubspace,
ics4Wrapper: ics4Wrapper,
channelKeeper: channelKeeper,
channelKeeperV2: channelKeeperV2,
clientKeeperV2: clientKeeperV2,
AuthKeeper: authKeeper,
BankKeeper: bankKeeper,
authority: authority,
}
}

Expand Down
6 changes: 6 additions & 0 deletions modules/apps/transfer/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
suite.chainA.GetSimApp().GetSubspace(types.ModuleName),
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeperV2,
suite.chainA.App.GetIBCKeeper().ClientV2Keeper,
suite.chainA.GetSimApp().AccountKeeper,
suite.chainA.GetSimApp().BankKeeper,
suite.chainA.GetSimApp().ICAControllerKeeper.GetAuthority(),
Expand All @@ -72,6 +74,8 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
suite.chainA.GetSimApp().GetSubspace(types.ModuleName),
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeperV2,
suite.chainA.App.GetIBCKeeper().ClientV2Keeper,
authkeeper.AccountKeeper{}, // empty account keeper
suite.chainA.GetSimApp().BankKeeper,
suite.chainA.GetSimApp().ICAControllerKeeper.GetAuthority(),
Expand All @@ -84,6 +88,8 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
suite.chainA.GetSimApp().GetSubspace(types.ModuleName),
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeperV2,
suite.chainA.App.GetIBCKeeper().ClientV2Keeper,
suite.chainA.GetSimApp().AccountKeeper,
suite.chainA.GetSimApp().BankKeeper,
"", // authority
Expand Down
86 changes: 63 additions & 23 deletions modules/apps/transfer/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (
"github.com/cosmos/ibc-go/v9/modules/apps/transfer/internal/events"
"github.com/cosmos/ibc-go/v9/modules/apps/transfer/internal/telemetry"
"github.com/cosmos/ibc-go/v9/modules/apps/transfer/types"
clienttypesv2 "github.com/cosmos/ibc-go/v9/modules/core/02-client/v2/types"
channeltypes "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"
)

Expand All @@ -29,14 +31,22 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.
return nil, err
}

channel, found := k.channelKeeper.GetChannel(ctx, msg.SourcePort, msg.SourceChannel)
if !found {
return nil, errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "port ID (%s) channel ID (%s)", msg.SourcePort, msg.SourceChannel)
}

appVersion, found := k.ics4Wrapper.GetAppVersion(ctx, msg.SourcePort, msg.SourceChannel)
if !found {
return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidRequest, "application version not found for source port: %s and source channel: %s", msg.SourcePort, msg.SourceChannel)
// if a eurela counterparty exists with source channel, then use IBC V2 protocol
// otherwise use IBC V1 protocol
var (
channel channeltypes.Channel
counterparty clienttypesv2.CounterpartyInfo
isIBCV2 bool
destinationPort string
destinationChannel string
)
counterparty, isIBCV2 = k.clientKeeperV2.GetClientCounterparty(ctx, msg.SourceChannel)
if !isIBCV2 {
var found bool
channel, found = k.channelKeeper.GetChannel(ctx, msg.SourcePort, msg.SourceChannel)
if !found {
return nil, errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "port ID (%s) channel ID (%s)", msg.SourcePort, msg.SourceChannel)
}
}

coin := msg.Token
Expand All @@ -54,26 +64,56 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.
return nil, err
}

if err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, token, sender); err != nil {
return nil, err
}
packetData := types.NewFungibleTokenPacketData(token.Denom.Path(), token.Amount, sender.String(), msg.Receiver, msg.Memo)

packetDataBytes, err := createPacketDataBytesFromVersion(
appVersion, sender.String(), msg.Receiver, msg.Memo, token,
)
if err != nil {
return nil, err
if err := packetData.ValidateBasic(); err != nil {
return nil, errorsmod.Wrapf(err, "failed to validate %s packet data", types.V1)
}

sequence, err := k.ics4Wrapper.SendPacket(ctx, msg.SourcePort, msg.SourceChannel, msg.TimeoutHeight, msg.TimeoutTimestamp, packetDataBytes)
if err != nil {
return nil, err
}
var sequence uint64
if isIBCV2 {
data, err := types.MarshalPacketData(packetData, types.V1, msg.Encoding)
if err != nil {
return nil, err
}
payload := channeltypesv2.NewPayload(
types.PortID, types.PortID,
types.V1, msg.Encoding, data,
)
msg := channeltypesv2.NewMsgSendPacket(
msg.SourceChannel, msg.TimeoutTimestamp,
sender.String(), payload,
)
res, err := k.channelKeeperV2.SendPacket(ctx, msg)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SendPacket will call transfer module's OnSendPacket

if err != nil {
return nil, err
}
sequence = res.Sequence
destinationPort = types.PortID
destinationChannel = counterparty.ClientId
} else {

if err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, token, sender); err != nil {
return nil, err
}

events.EmitTransferEvent(ctx, sender.String(), msg.Receiver, token, msg.Memo)
packetDataBytes, err := createPacketDataBytesFromVersion(
types.V1, sender.String(), msg.Receiver, msg.Memo, token,
)
if err != nil {
return nil, err
}

sequence, err = k.ics4Wrapper.SendPacket(ctx, msg.SourcePort, msg.SourceChannel, msg.TimeoutHeight, msg.TimeoutTimestamp, packetDataBytes)
if err != nil {
return nil, err
}

events.EmitTransferEvent(ctx, sender.String(), msg.Receiver, token, msg.Memo)
destinationPort = channel.Counterparty.PortId
destinationChannel = channel.Counterparty.ChannelId
}

destinationPort := channel.Counterparty.PortId
destinationChannel := channel.Counterparty.ChannelId
telemetry.ReportTransfer(msg.SourcePort, msg.SourceChannel, destinationPort, destinationChannel, token)

k.Logger(ctx).Info("IBC fungible token transfer", "token", coin, "sender", msg.Sender, "receiver", msg.Receiver)
Expand Down
58 changes: 29 additions & 29 deletions modules/apps/transfer/types/authz.pb.go

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

12 changes: 9 additions & 3 deletions modules/apps/transfer/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"

clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/v2/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"
ibcexported "github.com/cosmos/ibc-go/v9/modules/core/exported"
channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
)

// AccountKeeper defines the contract required for account APIs.
Expand Down Expand Up @@ -41,9 +42,14 @@ type ChannelKeeper interface {
HasChannel(ctx context.Context, portID, channelID string) bool
}

// ChannelKeeperV2 defines the expected IBC channelV2 keeper
type ChannelKeeperV2 interface {
SendPacket(ctx context.Context, msg *channeltypesv2.MsgSendPacket) (*channeltypesv2.MsgSendPacketResponse, error)
}

// ClientKeeper defines the expected IBC client keeper
type ClientKeeper interface {
GetClientConsensusState(ctx sdk.Context, clientID string) (connection ibcexported.ConsensusState, found bool)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonsensical method not used

type ClientKeeperV2 interface {
GetClientCounterparty(ctx sdk.Context, clientID string) (counterparty clienttypes.CounterpartyInfo, found bool)
}

// ConnectionKeeper defines the expected IBC connection keeper
Expand Down
52 changes: 25 additions & 27 deletions modules/apps/transfer/types/genesis.pb.go

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

Loading
Loading