Skip to content

Commit c4987a7

Browse files
duonghb53crodriguezvegaDimitrisJim
authored
Add func convert token to coin ibc (#6584)
* add func convert token to coin ibc * fix command: change func to ToCoin and add godoc * add unit test * Revert using ToCoin on Recv where trace manipulation occurs. Use ToCoin while forwarding. Update tests as per Carlos's review. * rename variable --------- Co-authored-by: Carlos Rodriguez <carlos@interchain.io> Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>
1 parent fbb9cd8 commit c4987a7

File tree

4 files changed

+76
-10
lines changed

4 files changed

+76
-10
lines changed

modules/apps/transfer/keeper/forwarding.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"errors"
55

66
errorsmod "cosmossdk.io/errors"
7-
sdkmath "cosmossdk.io/math"
87

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

@@ -72,11 +71,10 @@ func (k Keeper) revertForwardedPacket(ctx sdk.Context, prevPacket channeltypes.P
7271
// we can iterate over the received tokens of prevPacket by iterating over the sent tokens of failedPacketData
7372
for _, token := range failedPacketData.Tokens {
7473
// parse the transfer amount
75-
transferAmount, ok := sdkmath.NewIntFromString(token.Amount)
76-
if !ok {
77-
return errorsmod.Wrapf(types.ErrInvalidAmount, "unable to parse transfer amount (%s) into math.Int", transferAmount)
74+
coin, err := token.ToCoin()
75+
if err != nil {
76+
return err
7877
}
79-
coin := sdk.NewCoin(token.Denom.IBCDenom(), transferAmount)
8078

8179
// check if the token we received originated on the sender
8280
// given that the packet is being reversed, we check the DestinationChannel and DestinationPort

modules/apps/transfer/keeper/relay.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,13 +331,11 @@ func (k Keeper) refundPacketTokens(ctx sdk.Context, packet channeltypes.Packet,
331331
// NOTE: packet data type already checked in handler.go
332332

333333
for _, token := range data.Tokens {
334-
transferAmount, ok := sdkmath.NewIntFromString(token.Amount)
335-
if !ok {
336-
return errorsmod.Wrapf(types.ErrInvalidAmount, "unable to parse transfer amount (%s) into math.Int", transferAmount)
334+
coin, err := token.ToCoin()
335+
if err != nil {
336+
return err
337337
}
338338

339-
coin := sdk.NewCoin(token.Denom.IBCDenom(), transferAmount)
340-
341339
sender, err := sdk.AccAddressFromBech32(data.Sender)
342340
if err != nil {
343341
return err

modules/apps/transfer/types/token.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package types
33
import (
44
errorsmod "cosmossdk.io/errors"
55
sdkmath "cosmossdk.io/math"
6+
7+
sdk "github.com/cosmos/cosmos-sdk/types"
68
)
79

810
// Tokens is a slice of Tokens
@@ -25,3 +27,18 @@ func (t Token) Validate() error {
2527

2628
return nil
2729
}
30+
31+
// ToCoin converts a Token to an sdk.Coin.
32+
//
33+
// The function parses the Amount field of the Token into an sdkmath.Int and returns a new sdk.Coin with
34+
// the IBCDenom of the Token's Denom field and the parsed Amount.
35+
// If the Amount cannot be parsed, an error is returned with a wrapped error message.
36+
func (t Token) ToCoin() (sdk.Coin, error) {
37+
transferAmount, ok := sdkmath.NewIntFromString(t.Amount)
38+
if !ok {
39+
return sdk.Coin{}, errorsmod.Wrapf(ErrInvalidAmount, "unable to parse transfer amount (%s) into math.Int", transferAmount)
40+
}
41+
42+
coin := sdk.NewCoin(t.Denom.IBCDenom(), transferAmount)
43+
return coin, nil
44+
}

modules/apps/transfer/types/token_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import (
55
"testing"
66

77
"github.com/stretchr/testify/require"
8+
9+
sdkmath "cosmossdk.io/math"
10+
11+
sdk "github.com/cosmos/cosmos-sdk/types"
812
)
913

1014
const (
@@ -149,3 +153,52 @@ func TestValidate(t *testing.T) {
149153
})
150154
}
151155
}
156+
157+
func TestToCoin(t *testing.T) {
158+
testCases := []struct {
159+
name string
160+
token Token
161+
expCoin sdk.Coin
162+
expError error
163+
}{
164+
{
165+
"success: convert token to coin",
166+
Token{
167+
Denom: Denom{
168+
Base: denom,
169+
Trace: []Trace{},
170+
},
171+
Amount: amount,
172+
},
173+
sdk.NewCoin(denom, sdkmath.NewInt(100)),
174+
nil,
175+
},
176+
{
177+
"failure: invalid amount string",
178+
Token{
179+
Denom: Denom{
180+
Base: denom,
181+
Trace: []Trace{},
182+
},
183+
Amount: "value",
184+
},
185+
sdk.Coin{},
186+
ErrInvalidAmount,
187+
},
188+
}
189+
190+
for _, tc := range testCases {
191+
t.Run(tc.name, func(t *testing.T) {
192+
coin, err := tc.token.ToCoin()
193+
194+
require.Equal(t, tc.expCoin, coin, tc.name)
195+
196+
expPass := tc.expError == nil
197+
if expPass {
198+
require.NoError(t, err, tc.name)
199+
} else {
200+
require.ErrorContains(t, err, tc.expError.Error(), tc.name)
201+
}
202+
})
203+
}
204+
}

0 commit comments

Comments
 (0)