Skip to content

Commit

Permalink
refactor: update transfer to use runtime.Environment (#7615)
Browse files Browse the repository at this point in the history
Co-authored-by: Damian Nolan <damiannolan@gmail.com>
Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>
  • Loading branch information
3 people authored Dec 18, 2024
1 parent 39d8547 commit fd6a78a
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 60 deletions.
4 changes: 3 additions & 1 deletion modules/apps/callbacks/testing/simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,9 @@ func NewSimApp(
// since fee middleware will wrap the IBCKeeper for underlying application.
// NOTE: the Transfer Keeper's ICS4Wrapper can later be replaced.
app.TransferKeeper = ibctransferkeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[ibctransfertypes.StoreKey]), app.GetSubspace(ibctransfertypes.ModuleName),
appCodec,
runtime.NewEnvironment(runtime.NewKVStoreService(keys[ibctransfertypes.StoreKey]), logger.With(log.ModuleKey, fmt.Sprintf("x/%s-%s", ibcexported.ModuleName, ibctransfertypes.ModuleName))),
app.GetSubspace(ibctransfertypes.ModuleName),
app.IBCFeeKeeper, // ISC4 Wrapper: fee IBC middleware
app.IBCKeeper.ChannelKeeper,
app.AuthKeeper, app.BankKeeper,
Expand Down
10 changes: 5 additions & 5 deletions modules/apps/transfer/ibc_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (im IBCModule) OnChanOpenTry(
}

if !slices.Contains(types.SupportedVersions, counterpartyVersion) {
im.keeper.Logger(ctx).Debug("invalid counterparty version, proposing latest app version", "counterpartyVersion", counterpartyVersion, "version", types.V2)
im.keeper.Logger.Debug("invalid counterparty version, proposing latest app version", "counterpartyVersion", counterpartyVersion, "version", types.V2)
return types.V2, nil
}

Expand Down Expand Up @@ -187,17 +187,17 @@ func (im IBCModule) OnRecvPacket(
data, ackErr = types.UnmarshalPacketData(packet.GetData(), channelVersion)
if ackErr != nil {
ack = channeltypes.NewErrorAcknowledgement(ackErr)
im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), packet.Sequence))
im.keeper.Logger.Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), packet.Sequence))
return ack
}

if ackErr = im.keeper.OnRecvPacket(ctx, packet, data); ackErr != nil {
ack = channeltypes.NewErrorAcknowledgement(ackErr)
im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), packet.Sequence))
im.keeper.Logger.Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), packet.Sequence))
return ack
}

im.keeper.Logger(ctx).Info("successfully handled ICS-20 packet", "sequence", packet.Sequence)
im.keeper.Logger.Info("successfully handled ICS-20 packet", "sequence", packet.Sequence)

if data.HasForwarding() {
// NOTE: acknowledgement will be written asynchronously
Expand Down Expand Up @@ -276,7 +276,7 @@ func (im IBCModule) OnChanUpgradeTry(ctx context.Context, portID, channelID stri
}

if !slices.Contains(types.SupportedVersions, counterpartyVersion) {
im.keeper.Logger(ctx).Debug("invalid counterparty version, proposing latest app version", "counterpartyVersion", counterpartyVersion, "version", types.V2)
im.keeper.Logger.Debug("invalid counterparty version, proposing latest app version", "counterpartyVersion", counterpartyVersion, "version", types.V2)
return types.V2, nil
}

Expand Down
2 changes: 1 addition & 1 deletion modules/apps/transfer/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (k Keeper) Denoms(ctx context.Context, req *types.QueryDenomsRequest) (*typ
}

var denoms types.Denoms
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.DenomKey)
store := prefix.NewStore(runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx)), types.DenomKey)

pageRes, err := query.Paginate(store, req.Pagination, func(_, value []byte) error {
var denom types.Denom
Expand Down
53 changes: 23 additions & 30 deletions modules/apps/transfer/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import (
"fmt"
"strings"

corestore "cosmossdk.io/core/store"
"cosmossdk.io/log"
"cosmossdk.io/core/appmodule"
sdkmath "cosmossdk.io/math"
"cosmossdk.io/store/prefix"
storetypes "cosmossdk.io/store/types"
Expand All @@ -23,13 +22,13 @@ import (
channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v9/modules/core/05-port/types"
host "github.com/cosmos/ibc-go/v9/modules/core/24-host"
"github.com/cosmos/ibc-go/v9/modules/core/exported"
coretypes "github.com/cosmos/ibc-go/v9/modules/core/types"
)

// Keeper defines the IBC fungible transfer keeper
type Keeper struct {
storeService corestore.KVStoreService
appmodule.Environment

cdc codec.BinaryCodec
legacySubspace types.ParamSubspace

Expand All @@ -46,7 +45,7 @@ type Keeper struct {
// NewKeeper creates a new IBC transfer Keeper instance
func NewKeeper(
cdc codec.BinaryCodec,
storeService corestore.KVStoreService,
env appmodule.Environment,
legacySubspace types.ParamSubspace,
ics4Wrapper porttypes.ICS4Wrapper,
channelKeeper types.ChannelKeeper,
Expand All @@ -65,7 +64,7 @@ func NewKeeper(

return Keeper{
cdc: cdc,
storeService: storeService,
Environment: env,
legacySubspace: legacySubspace,
ics4Wrapper: ics4Wrapper,
channelKeeper: channelKeeper,
Expand All @@ -92,15 +91,9 @@ func (k Keeper) GetAuthority() string {
return k.authority
}

// Logger returns a module-specific logger.
func (Keeper) Logger(ctx context.Context) log.Logger {
sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917
return sdkCtx.Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName)
}

// GetPort returns the portID for the transfer module. Used in ExportGenesis
func (k Keeper) GetPort(ctx context.Context) string {
store := k.storeService.OpenKVStore(ctx)
store := k.KVStoreService.OpenKVStore(ctx)
bz, err := store.Get(types.PortKey)
if err != nil {
panic(err)
Expand All @@ -110,15 +103,15 @@ func (k Keeper) GetPort(ctx context.Context) string {

// SetPort sets the portID for the transfer module. Used in InitGenesis
func (k Keeper) SetPort(ctx context.Context, portID string) {
store := k.storeService.OpenKVStore(ctx)
store := k.KVStoreService.OpenKVStore(ctx)
if err := store.Set(types.PortKey, []byte(portID)); err != nil {
panic(err)
}
}

// GetParams returns the current transfer module parameters.
func (k Keeper) GetParams(ctx context.Context) types.Params {
store := k.storeService.OpenKVStore(ctx)
store := k.KVStoreService.OpenKVStore(ctx)
bz, err := store.Get([]byte(types.ParamsKey))
if err != nil {
panic(err)
Expand All @@ -134,7 +127,7 @@ func (k Keeper) GetParams(ctx context.Context) types.Params {

// SetParams sets the transfer module parameters.
func (k Keeper) SetParams(ctx context.Context, params types.Params) {
store := k.storeService.OpenKVStore(ctx)
store := k.KVStoreService.OpenKVStore(ctx)
bz := k.cdc.MustMarshal(&params)
if err := store.Set([]byte(types.ParamsKey), bz); err != nil {
panic(err)
Expand All @@ -143,7 +136,7 @@ func (k Keeper) SetParams(ctx context.Context, params types.Params) {

// GetDenom retrieves the denom from store given the hash of the denom.
func (k Keeper) GetDenom(ctx context.Context, denomHash cmtbytes.HexBytes) (types.Denom, bool) {
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.DenomKey)
store := prefix.NewStore(runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx)), types.DenomKey)
bz := store.Get(denomHash)
if len(bz) == 0 {
return types.Denom{}, false
Expand All @@ -157,14 +150,14 @@ func (k Keeper) GetDenom(ctx context.Context, denomHash cmtbytes.HexBytes) (type

// HasDenom checks if a the key with the given denomination hash exists on the store.
func (k Keeper) HasDenom(ctx context.Context, denomHash cmtbytes.HexBytes) bool {
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.DenomKey)
store := prefix.NewStore(runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx)), types.DenomKey)
return store.Has(denomHash)
}

// SetDenom sets a new {denom hash -> denom } pair to the store.
// This allows for reverse lookup of the denom given the hash.
func (k Keeper) SetDenom(ctx context.Context, denom types.Denom) {
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.DenomKey)
store := prefix.NewStore(runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx)), types.DenomKey)
bz := k.cdc.MustMarshal(&denom)
store.Set(denom.Hash(), bz)
}
Expand All @@ -182,10 +175,10 @@ func (k Keeper) GetAllDenoms(ctx context.Context) types.Denoms {

// IterateDenoms iterates over the denominations in the store and performs a callback function.
func (k Keeper) IterateDenoms(ctx context.Context, cb func(denom types.Denom) bool) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
store := runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx))
iterator := storetypes.KVStorePrefixIterator(store, types.DenomKey)

defer coretypes.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
defer coretypes.LogDeferred(k.Logger, func() error { return iterator.Close() })
for ; iterator.Valid(); iterator.Next() {
var denom types.Denom
k.cdc.MustUnmarshal(iterator.Value(), &denom)
Expand Down Expand Up @@ -224,7 +217,7 @@ func (k Keeper) setDenomMetadata(ctx context.Context, denom types.Denom) {
// NOTE: if there is no value stored in state for the provided denom then a new Coin is returned for the denom with an initial value of zero.
// This accommodates callers to simply call `Add()` on the returned Coin as an empty Coin literal (e.g. sdk.Coin{}) will trigger a panic due to the absence of a denom.
func (k Keeper) GetTotalEscrowForDenom(ctx context.Context, denom string) sdk.Coin {
store := k.storeService.OpenKVStore(ctx)
store := k.KVStoreService.OpenKVStore(ctx)
bz, err := store.Get(types.TotalEscrowForDenomKey(denom))
if err != nil {
panic(err)
Expand All @@ -249,7 +242,7 @@ func (k Keeper) SetTotalEscrowForDenom(ctx context.Context, coin sdk.Coin) {
panic(fmt.Errorf("amount cannot be negative: %s", coin.Amount))
}

store := k.storeService.OpenKVStore(ctx)
store := k.KVStoreService.OpenKVStore(ctx)
key := types.TotalEscrowForDenomKey(coin.Denom)

if coin.Amount.IsZero() {
Expand Down Expand Up @@ -283,10 +276,10 @@ func (k Keeper) GetAllTotalEscrowed(ctx context.Context) sdk.Coins {
// and performs a callback function. Denominations for which an invalid value
// (i.e. not integer) is stored, will be skipped.
func (k Keeper) IterateTokensInEscrow(ctx context.Context, storeprefix []byte, cb func(denomEscrow sdk.Coin) bool) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
store := runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx))
iterator := storetypes.KVStorePrefixIterator(store, storeprefix)

defer coretypes.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
defer coretypes.LogDeferred(k.Logger, func() error { return iterator.Close() })
for ; iterator.Valid(); iterator.Next() {
denom := strings.TrimPrefix(string(iterator.Key()), fmt.Sprintf("%s/", types.KeyTotalEscrowPrefix))
if strings.TrimSpace(denom) == "" {
Expand All @@ -307,7 +300,7 @@ func (k Keeper) IterateTokensInEscrow(ctx context.Context, storeprefix []byte, c

// setForwardedPacket sets the forwarded packet in the store.
func (k Keeper) setForwardedPacket(ctx context.Context, portID, channelID string, sequence uint64, packet channeltypes.Packet) {
store := k.storeService.OpenKVStore(ctx)
store := k.KVStoreService.OpenKVStore(ctx)
bz := k.cdc.MustMarshal(&packet)
if err := store.Set(types.PacketForwardKey(portID, channelID, sequence), bz); err != nil {
panic(err)
Expand All @@ -316,7 +309,7 @@ func (k Keeper) setForwardedPacket(ctx context.Context, portID, channelID string

// getForwardedPacket gets the forwarded packet from the store.
func (k Keeper) getForwardedPacket(ctx context.Context, portID, channelID string, sequence uint64) (channeltypes.Packet, bool) {
store := k.storeService.OpenKVStore(ctx)
store := k.KVStoreService.OpenKVStore(ctx)
bz, err := store.Get(types.PacketForwardKey(portID, channelID, sequence))
if err != nil {
panic(err)
Expand All @@ -333,7 +326,7 @@ func (k Keeper) getForwardedPacket(ctx context.Context, portID, channelID string

// deleteForwardedPacket deletes the forwarded packet from the store.
func (k Keeper) deleteForwardedPacket(ctx context.Context, portID, channelID string, sequence uint64) {
store := k.storeService.OpenKVStore(ctx)
store := k.KVStoreService.OpenKVStore(ctx)
packetKey := types.PacketForwardKey(portID, channelID, sequence)

if err := store.Delete(packetKey); err != nil {
Expand All @@ -354,10 +347,10 @@ func (k Keeper) getAllForwardedPackets(ctx context.Context) []types.ForwardedPac

// iterateForwardedPackets iterates over the forward packets in the store and performs a callback function.
func (k Keeper) iterateForwardedPackets(ctx context.Context, cb func(packet types.ForwardedPacket) bool) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
store := runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx))
iterator := storetypes.KVStorePrefixIterator(store, types.ForwardedPacketKey)

defer coretypes.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
defer coretypes.LogDeferred(k.Logger, func() error { return iterator.Close() })
for ; iterator.Valid(); iterator.Next() {
var forwardPacket types.ForwardedPacket
k.cdc.MustUnmarshal(iterator.Value(), &forwardPacket.Packet)
Expand Down
7 changes: 4 additions & 3 deletions modules/apps/transfer/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

testifysuite "github.com/stretchr/testify/suite"

"cosmossdk.io/log"
sdkmath "cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
minttypes "cosmossdk.io/x/mint/types"
Expand Down Expand Up @@ -57,7 +58,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
{"success", func() {
keeper.NewKeeper(
suite.chainA.GetSimApp().AppCodec(),
runtime.NewKVStoreService(suite.chainA.GetSimApp().GetKey(types.StoreKey)),
runtime.NewEnvironment(runtime.NewKVStoreService(suite.chainA.GetSimApp().GetKey(types.StoreKey)), log.NewNopLogger()),
suite.chainA.GetSimApp().GetSubspace(types.ModuleName),
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
Expand All @@ -69,7 +70,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
{"failure: transfer module account does not exist", func() {
keeper.NewKeeper(
suite.chainA.GetSimApp().AppCodec(),
runtime.NewKVStoreService(suite.chainA.GetSimApp().GetKey(types.StoreKey)),
runtime.NewEnvironment(runtime.NewKVStoreService(suite.chainA.GetSimApp().GetKey(types.StoreKey)), log.NewNopLogger()),
suite.chainA.GetSimApp().GetSubspace(types.ModuleName),
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
Expand All @@ -81,7 +82,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
{"failure: empty authority", func() {
keeper.NewKeeper(
suite.chainA.GetSimApp().AppCodec(),
runtime.NewKVStoreService(suite.chainA.GetSimApp().GetKey(types.StoreKey)),
runtime.NewEnvironment(runtime.NewKVStoreService(suite.chainA.GetSimApp().GetKey(types.StoreKey)), log.NewNopLogger()),
suite.chainA.GetSimApp().GetSubspace(types.ModuleName),
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
Expand Down
14 changes: 7 additions & 7 deletions modules/apps/transfer/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (m Migrator) MigrateParams(ctx sdk.Context) error {
m.keeper.legacySubspace.GetParamSet(ctx, &params)

m.keeper.SetParams(ctx, params)
m.keeper.Logger(ctx).Info("successfully migrated transfer app self-manage params")
m.keeper.Logger.Info("successfully migrated transfer app self-manage params")
return nil
}

Expand All @@ -50,7 +50,7 @@ func (m Migrator) MigrateDenomMetadata(ctx sdk.Context) error {
return false
})

m.keeper.Logger(ctx).Info("successfully added metadata to IBC voucher denominations")
m.keeper.Logger.Info("successfully added metadata to IBC voucher denominations")
return nil
}

Expand All @@ -71,7 +71,7 @@ func (m Migrator) MigrateTotalEscrowForDenom(ctx sdk.Context) error {
m.keeper.SetTotalEscrowForDenom(ctx, totalEscrow)
}

m.keeper.Logger(ctx).Info("successfully set total escrow", "number of denominations", totalEscrowed.Len())
m.keeper.Logger.Info("successfully set total escrow", "number of denominations", totalEscrowed.Len())
return nil
}

Expand Down Expand Up @@ -117,25 +117,25 @@ func (m Migrator) MigrateDenomTraceToDenom(ctx sdk.Context) error {

// setDenomTrace sets a new {trace hash -> denom trace} pair to the store.
func (k Keeper) setDenomTrace(ctx context.Context, denomTrace internaltypes.DenomTrace) {
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.DenomTraceKey)
store := prefix.NewStore(runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx)), types.DenomTraceKey)
bz := k.cdc.MustMarshal(&denomTrace)

store.Set(denomTrace.Hash(), bz)
}

// deleteDenomTrace deletes the denom trace
func (k Keeper) deleteDenomTrace(ctx context.Context, denomTrace internaltypes.DenomTrace) {
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.DenomTraceKey)
store := prefix.NewStore(runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx)), types.DenomTraceKey)
store.Delete(denomTrace.Hash())
}

// iterateDenomTraces iterates over the denomination traces in the store
// and performs a callback function.
func (k Keeper) iterateDenomTraces(ctx context.Context, cb func(denomTrace internaltypes.DenomTrace) bool) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
store := runtime.KVStoreAdapter(k.KVStoreService.OpenKVStore(ctx))
iterator := storetypes.KVStorePrefixIterator(store, types.DenomTraceKey)

defer coretypes.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
defer coretypes.LogDeferred(k.Logger, func() error { return iterator.Close() })
for ; iterator.Valid(); iterator.Next() {
var denomTrace internaltypes.DenomTrace
k.cdc.MustUnmarshal(iterator.Value(), &denomTrace)
Expand Down
13 changes: 5 additions & 8 deletions modules/apps/transfer/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ import (
var _ types.MsgServer = (*Keeper)(nil)

// Transfer defines an rpc handler method for MsgTransfer.
func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.MsgTransferResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

func (k Keeper) Transfer(ctx context.Context, msg *types.MsgTransfer) (*types.MsgTransferResponse, error) {
if !k.GetParams(ctx).SendEnabled {
return nil, types.ErrSendDisabled
}
Expand Down Expand Up @@ -51,18 +49,17 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.
return nil, err
}

k.Logger(ctx).Info("IBC fungible token transfer", "tokens", coins, "sender", msg.Sender, "receiver", msg.Receiver)
k.Logger.Info("IBC fungible token transfer", "tokens", coins, "sender", msg.Sender, "receiver", msg.Receiver)

return &types.MsgTransferResponse{Sequence: sequence}, nil
}

// UpdateParams defines an rpc handler method for MsgUpdateParams. Updates the ibc-transfer module's parameters.
func (k Keeper) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
func (k Keeper) UpdateParams(ctx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
if k.GetAuthority() != msg.Signer {
return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Signer)
}

ctx := sdk.UnwrapSDKContext(goCtx)
k.SetParams(ctx, msg.Params)

return &types.MsgUpdateParamsResponse{}, nil
Expand All @@ -71,7 +68,7 @@ func (k Keeper) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams)
// unwindHops unwinds the hops present in the tokens denomination and returns the message modified to reflect
// the unwound path to take. It assumes that only a single token is present (as this is verified in ValidateBasic)
// in the tokens list and ensures that the token is not native to the chain.
func (k Keeper) unwindHops(ctx sdk.Context, msg *types.MsgTransfer) (*types.MsgTransfer, error) {
func (k Keeper) unwindHops(ctx context.Context, msg *types.MsgTransfer) (*types.MsgTransfer, error) {
unwindHops, err := k.getUnwindHops(ctx, msg.GetCoins())
if err != nil {
return nil, err
Expand All @@ -92,7 +89,7 @@ func (k Keeper) unwindHops(ctx sdk.Context, msg *types.MsgTransfer) (*types.MsgT
// getUnwindHops returns the hops to be used during unwinding. If coins consists of more than
// one coin, all coins must have the exact same trace, else an error is returned. getUnwindHops
// also validates that the coins are not native to the chain.
func (k Keeper) getUnwindHops(ctx sdk.Context, coins sdk.Coins) ([]types.Hop, error) {
func (k Keeper) getUnwindHops(ctx context.Context, coins sdk.Coins) ([]types.Hop, error) {
// Sanity: validation for MsgTransfer ensures coins are not empty.
if len(coins) == 0 {
return nil, errorsmod.Wrap(types.ErrInvalidForwarding, "coins cannot be empty")
Expand Down
Loading

0 comments on commit fd6a78a

Please sign in to comment.