Skip to content

Commit f1b6652

Browse files
committed
add: added TC for token transfer to-and-from ibc-centauri
1 parent 84ae017 commit f1b6652

File tree

9 files changed

+186
-27
lines changed

9 files changed

+186
-27
lines changed

test/chains/chain.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ type Chain interface {
6666
//integration test specific
6767
SendPacketMockDApp(ctx context.Context, targetChain Chain, keyName string, params map[string]interface{}) (PacketTransferResponse, error)
6868
SetupIBCICS20(ctx context.Context, keyName string) (context.Context, error)
69-
SendIBCTokenTransfer(ctx context.Context, address, port, receiver string, amount uint64) (string, error)
69+
SendIBCTokenTransfer(ctx context.Context, sourceChannel, destinationChannel, port, receiver, chainID string, amount uint64) (string, error)
7070
GetWalletBalance(ctx context.Context, address string, denom string) (*big.Int, error)
7171
}
7272

test/chains/cosmos/localnet.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ func (c *CosmosLocalnet) SetupIBCICS20(ctx context.Context, keyName string) (con
783783
panic("not implemented")
784784
}
785785

786-
func (c *CosmosLocalnet) SendIBCTokenTransfer(ctx context.Context, channel, port, receiver string, amount uint64) (string, error) {
786+
func (c *CosmosLocalnet) SendIBCTokenTransfer(ctx context.Context, sourceChannel, destinationChannel, port, receiver, chainID string, amount uint64) (string, error) {
787787
panic("not implemented")
788788
}
789789

test/chains/cosmos/remotenet.go

+30-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cosmos
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67
"time"
78

@@ -219,8 +220,35 @@ func (c *CosmosRemotenet) SetupIBCICS20(ctx context.Context, keyName string) (co
219220
return ctx, nil
220221
}
221222

222-
func (c *CosmosRemotenet) SendIBCTokenTransfer(ctx context.Context, channel, port, receiver string, amount uint64) (string, error) {
223-
panic("not implemented")
223+
func (c *CosmosRemotenet) SendIBCTokenTransfer(ctx context.Context, sourceChannel, destinationChannel, port, receiver, chainID string, amount uint64) (string, error) {
224+
ibcamount := fmt.Sprint(amount) + "000000000000000000" + "transfer/" + destinationChannel + "/icx"
225+
commands := []string{"tx", "ibc-transfer", port, port, sourceChannel, receiver, ibcamount}
226+
commands = append(commands,
227+
"--node", c.GetHostRPCAddress(),
228+
"--packet-timeout-height", "1-500000",
229+
"--packet-timeout-timestamp", "0",
230+
"--gas-prices", "0.1stake",
231+
"--gas-adjustment", "1.5",
232+
"--gas", "auto",
233+
"--from", c.testConfig.KeystoreFile,
234+
"--keyring-backend", c.testConfig.KeystorePassword,
235+
"--output", "json",
236+
"--chain-id", chainID,
237+
"-y",
238+
)
239+
stdout, _, err := c.Exec(ctx, commands, nil)
240+
if err != nil {
241+
return "", err
242+
}
243+
var output TxResul
244+
if err != nil {
245+
return "", err
246+
}
247+
err = json.Unmarshal(stdout, &output)
248+
if err != nil {
249+
return "", err
250+
}
251+
return output.Txhash, nil
224252
}
225253

226254
// GetBalance fetches the current balance for a specific account address and denom.

test/chains/icon/localnet.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,6 @@ func (c *IconLocalnet) SetupIBCICS20(ctx context.Context, keyName string) (conte
10441044
panic("not implemented")
10451045
}
10461046

1047-
func (c *IconLocalnet) SendIBCTokenTransfer(ctx context.Context, channel, port, receiver string, amount uint64) (string, error) {
1047+
func (c *IconLocalnet) SendIBCTokenTransfer(ctx context.Context, sourceChannel, destinationChannel, port, receiver, chainID string, amount uint64) (string, error) {
10481048
panic("not implemented")
10491049
}

test/chains/icon/remotenet.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ func (c *IconRemotenet) SendFundsFromGodwallet(ctx context.Context, amount ibc.W
194194
func (c *IconRemotenet) SendIBCTransfer(ctx context.Context, channelID string, keyName string, amount ibc.WalletAmount, options ibc.TransferOptions) (ibc.Tx, error) {
195195
panic("not implemented")
196196
}
197-
func (c *IconRemotenet) SendIBCTokenTransfer(ctx context.Context, channel, port, receiver string, amount uint64) (string, error) {
197+
func (c *IconRemotenet) SendIBCTokenTransfer(ctx context.Context, sourceChannel, destinationChannel, port, receiver, chainID string, amount uint64) (string, error) {
198198
bankAppClient := c.IBCAddresses["bankAppClient"]
199199
commands := []string{"rpc", "sendtx", "call"}
200200
commands = append(commands,
@@ -207,7 +207,7 @@ func (c *IconRemotenet) SendIBCTokenTransfer(ctx context.Context, channel, port,
207207
"--step_limit", "10000000000000",
208208
"--nid", "0x3",
209209
)
210-
params := `{"denom":"icx","receiver":"centauri1g5r2vmnp6lta9cpst4lzc4syy3kcj2ljte3tlh","amount":"` + fmt.Sprint(amount) + "000000000000000000" + `","sourcePort":"transfer","sourceChannel":"` + channel + `","timeoutHeight":"5000000","timeoutRevisionNumber":"1"}`
210+
params := `{"denom":"icx","receiver":"` + receiver + `","amount":"` + fmt.Sprint(amount) + "000000000000000000" + `","sourcePort":"` + port + `","sourceChannel":"` + sourceChannel + `","timeoutHeight":"5000000","timeoutRevisionNumber":"1"}`
211211
commands = append(commands, "--params", params)
212212
var output string
213213
stdout, _, err := c.Exec(ctx, commands, nil)

test/e2e-hopchain/e2e_hopchain_test.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
package e2e_hopchain_test
1+
package e2e_hopchain
22

33
import (
44
"context"
55
"testing"
66

7-
e2e_hopchain "github.com/icon-project/ibc-integration/test/e2e-hopchain"
87
"github.com/icon-project/ibc-integration/test/testsuite"
98
"github.com/stretchr/testify/suite"
109
)
@@ -24,7 +23,7 @@ func (s *E2EHopchainTest) TestE2E_hopchain() {
2423
ctx := context.TODO()
2524
s.Require().NoError(s.SetCfg())
2625
relayer := s.SetupICS20ChainsAndRelayer(ctx)
27-
hopchain := e2e_hopchain.HopchainTestSuite{
26+
hopchain := HopchainTestSuite{
2827
E2ETestSuite: &s.E2ETestSuite,
2928
T: t,
3029
}

test/e2e-hopchain/hopchain.go

+139-10
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ import (
44
"context"
55
"fmt"
66
"math/big"
7+
"regexp"
8+
"strings"
79
"testing"
810
"time"
911

12+
"github.com/icon-project/ibc-integration/test/chains"
1013
"github.com/icon-project/ibc-integration/test/testsuite"
1114
"github.com/strangelove-ventures/interchaintest/v7/ibc"
15+
"github.com/strangelove-ventures/interchaintest/v7/testreporter"
1216
"github.com/stretchr/testify/assert"
1317
)
1418

@@ -17,21 +21,146 @@ type HopchainTestSuite struct {
1721
T *testing.T
1822
}
1923

24+
type AddressBalance struct {
25+
Address string
26+
Balances []Balance `mapstructure:"balance"`
27+
}
28+
29+
type Balance struct {
30+
Denom string
31+
Amount *big.Int
32+
}
33+
34+
const IconChainName = "icon"
35+
const CentauriChainName = "centauri"
36+
37+
func getBalance(balanceStdout string) AddressBalance {
38+
balanceSplit := strings.Split(balanceStdout, "\n")
39+
address := ""
40+
var balances []Balance
41+
for _, balanceInfo := range balanceSplit {
42+
if strings.HasPrefix(balanceInfo, "address") {
43+
// Define regular expressions to extract address, ICX balance, and stake balance
44+
addressRegex := regexp.MustCompile(`address\s*{([^}]*)}`)
45+
balanceRegex := regexp.MustCompile(`balance\s(.*)`)
46+
47+
// Extract address
48+
addressMatches := addressRegex.FindStringSubmatch(balanceInfo)
49+
address = addressMatches[1]
50+
51+
// Extract ICX balance and stake balance
52+
balanceMatches := balanceRegex.FindStringSubmatch(balanceInfo)
53+
re := regexp.MustCompile(`(\d+)([a-zA-Z\/\-\d+]+)`)
54+
55+
// Find all matches in the input string
56+
matches := re.FindAllStringSubmatch(balanceMatches[0], -1)
57+
58+
// Iterate over matches and populate the map
59+
for _, match := range matches {
60+
amount := new(big.Int)
61+
amount.SetString(match[1], 10)
62+
// currencyBalance[match[2]] = amount
63+
balances = append(balances, Balance{
64+
Denom: match[2],
65+
Amount: amount,
66+
})
67+
}
68+
69+
}
70+
}
71+
return AddressBalance{
72+
Address: address,
73+
Balances: balances,
74+
}
75+
}
76+
77+
func getLatestChannels(ctx context.Context, eRep *testreporter.RelayerExecReporter, chainID string, relayer ibc.Relayer) (string, string, error) {
78+
channels, err := relayer.GetChannels(ctx, eRep, chainID)
79+
if err != nil {
80+
return "", "", err
81+
}
82+
latestChannel := channels[len(channels)-1]
83+
return latestChannel.Counterparty.ChannelID, latestChannel.ChannelID, nil
84+
}
85+
86+
func getIconChain(chains ...chains.Chain) chains.Chain {
87+
for _, chain := range chains {
88+
if chain.(ibc.Chain).Config().Name == IconChainName {
89+
return chain
90+
}
91+
}
92+
return nil
93+
}
94+
95+
func getCentauriChain(chains ...chains.Chain) chains.Chain {
96+
for _, chain := range chains {
97+
if chain.(ibc.Chain).Config().Name == CentauriChainName {
98+
return chain
99+
}
100+
}
101+
return nil
102+
}
103+
104+
func getChainAddressBalance(ctx context.Context, eRep *testreporter.RelayerExecReporter, relayer ibc.Relayer, chain chains.Chain) AddressBalance {
105+
balanceCommands := []string{"rly", "query", "balance", chain.(ibc.Chain).Config().ChainID}
106+
balanceResult := relayer.Exec(ctx, eRep, balanceCommands, nil)
107+
balanceInfo := getBalance(string(balanceResult.Stdout[:]))
108+
return balanceInfo
109+
}
110+
111+
func getChainBalance(balances []Balance, denom string) Balance {
112+
for _, bal := range balances {
113+
if bal.Denom == denom {
114+
return bal
115+
}
116+
}
117+
return Balance{}
118+
}
119+
20120
func (h *HopchainTestSuite) TestICS20(relayer ibc.Relayer) {
21121
testcase := "ics20"
22122
// portId := "transfer"
23123
ctx := context.WithValue(context.TODO(), "testcase", testcase)
24124
chainA, chainB := h.GetChains()
25-
h.T.Run("send IBC Ftokens", func(t *testing.T) {
26-
receiver := "centauri1g5r2vmnp6lta9cpst4lzc4syy3kcj2ljte3tlh"
27-
txnhash, err := chainA.SendIBCTokenTransfer(ctx, "channel-0", "transfer", receiver, 100)
28-
h.Require().NoError(err, "error should be nil")
29-
fmt.Println(txnhash)
30-
time.Sleep(5 * time.Second)
31-
// find balance in chainB
32-
balance, err := chainB.GetWalletBalance(ctx, receiver, "ibc/27029D876FCF5510CB000161B8CEEEB25B25C35309B3512ECD36D921385E8C52")
125+
eRep := h.GetRelayerExecReporter()
126+
portId := "transfer"
127+
h.T.Run("send IBC Ftokens for relay centauri-ibc", func(t *testing.T) {
128+
iconChain := getIconChain(chainA, chainB)
129+
centauriChain := getCentauriChain(chainA, chainB)
130+
iconAccountBalance := getChainAddressBalance(ctx, eRep, relayer, iconChain)
131+
cenauriAccountBalance := getChainAddressBalance(ctx, eRep, relayer, centauriChain)
132+
centauriReceiver := cenauriAccountBalance.Address
133+
iconReceiver := iconAccountBalance.Address
134+
relaySourceChannel, relayDestinationChannel, err := getLatestChannels(ctx, eRep, centauriChain.(ibc.Chain).Config().ChainID, relayer)
135+
denom := "transfer/" + relayDestinationChannel + "/icx"
33136
h.Require().NoError(err, "error should be nil")
34-
fmt.Println("The retrieved balance is", balance)
35-
assert.True(t, balance.Cmp(big.NewInt(0)) > 0, "balance should be greater than 0")
137+
h.T.Run("send IBC Ftokens from ibc to centauri ", func(t *testing.T) {
138+
_, err := iconChain.SendIBCTokenTransfer(ctx, relaySourceChannel, relayDestinationChannel, portId, centauriReceiver, centauriChain.(ibc.Chain).Config().ChainID, 100)
139+
h.Require().NoError(err, "error should be nil")
140+
// give some time for txn to settle
141+
time.Sleep(10 * time.Second)
142+
iconAccountBalance = getChainAddressBalance(ctx, eRep, relayer, iconChain)
143+
cenauriAccountBalance = getChainAddressBalance(ctx, eRep, relayer, centauriChain)
144+
145+
valueTocheck := new(big.Int)
146+
valueTocheck, _ = valueTocheck.SetString("100000000000000000000", 10)
147+
148+
centauriChanBalance := getChainBalance(cenauriAccountBalance.Balances, denom)
149+
assert.True(t, centauriChanBalance.Amount.Cmp(valueTocheck) == 0, "balance should be equal to 100000000000000000000")
150+
})
151+
152+
h.T.Run("send IBC Ftokens from centauri to ibc ", func(t *testing.T) {
153+
// send back to icon
154+
txnhash, err := centauriChain.SendIBCTokenTransfer(ctx, relayDestinationChannel, relayDestinationChannel, "transfer", iconReceiver, centauriChain.(ibc.Chain).Config().ChainID, 50)
155+
h.Require().NoError(err, "error should be nil")
156+
fmt.Println("Txn hash is ", txnhash)
157+
time.Sleep(10 * time.Second)
158+
valueTocheck := new(big.Int)
159+
valueTocheck, _ = valueTocheck.SetString("50000000000000000000", 10)
160+
iconAccountBalance = getChainAddressBalance(ctx, eRep, relayer, iconChain)
161+
cenauriAccountBalance = getChainAddressBalance(ctx, eRep, relayer, centauriChain)
162+
centauriChanBalance := getChainBalance(cenauriAccountBalance.Balances, denom)
163+
assert.True(t, centauriChanBalance.Amount.Cmp(valueTocheck) == 0, "balance should be equal to 50000000000000000000")
164+
})
36165
})
37166
}

test/relayer/icon/icon_relayer_remote.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func ChainConfigToICONRemoteRelayerRemoteChainConfig(chainConfig ibc.ChainConfig
7676
Value: ICONRemoteRelayerChainConfigValue{
7777
Key: "icx",
7878
ChainID: chainConfig.ChainID,
79-
RPCAddr: "http://" + rpcAddr + "/api/v3/",
79+
RPCAddr: rpcAddr,
8080
Timeout: "10s",
8181
Keystore: keystore,
8282
KeyDirectory: "/home/relayer/.relayer/keys",
@@ -326,13 +326,15 @@ func (c RemoteCommander) ParseGetChannelsOutput(stdout, stderr string) ([]ibc.Ch
326326
if strings.TrimSpace(channel) == "" {
327327
continue
328328
}
329-
var channelOutput ibc.ChannelOutput
330-
err := json.Unmarshal([]byte(channel), &channelOutput)
331-
if err != nil {
332-
c.log.Error("Failed to parse channels json", zap.Error(err))
333-
continue
329+
if strings.HasPrefix(channel, "{") {
330+
var channelOutput ibc.ChannelOutput
331+
err := json.Unmarshal([]byte(channel), &channelOutput)
332+
if err != nil {
333+
c.log.Error("Failed to parse channels json", zap.Error(err))
334+
continue
335+
}
336+
channels = append(channels, channelOutput)
334337
}
335-
channels = append(channels, channelOutput)
336338
}
337339

338340
return channels, nil

test/testsuite/sample-config-ics20.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ chains:
3737
contracts_path: "$BASE_PATH/artifacts/centauri"
3838
config_path: "$BASE_PATH/test/chains/cosmos/data"
3939
keystore_file: default
40+
keystore_password: test
4041
rpc_uri: http://docker.for.mac.host.internal:50001
4142
chain_config:
4243
type: cosmos

0 commit comments

Comments
 (0)