@agoric/cosmos 0.35.0-u19.2 → 0.35.0-u20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,56 +0,0 @@
1
- package e2etest
2
-
3
- import (
4
- "context"
5
- "fmt"
6
- "testing"
7
-
8
- "github.com/agoric-labs/interchaintest/v6"
9
- "github.com/agoric-labs/interchaintest/v6/conformance"
10
- "github.com/agoric-labs/interchaintest/v6/testreporter"
11
- "go.uber.org/zap/zaptest"
12
- )
13
-
14
- // TestConformance builds chainspec & relayers from env vars then runs conformance tests
15
- func TestConformance(t *testing.T) {
16
- cs := getChainSpec(t)
17
- rf := getRelayerFactory(t)
18
- testConformance(t, cs[0:2], rf)
19
- }
20
-
21
- // TestChainPair builds chainspec & relayers from env vars then runs chain pair tests
22
- func TestChainPair(t *testing.T) {
23
- cs := getChainSpec(t)
24
- rf := getRelayerFactory(t)
25
- testChainPair(t, cs[0:2], rf)
26
- }
27
-
28
- func testConformance(t *testing.T, cs []*interchaintest.ChainSpec, rf interchaintest.RelayerFactory) {
29
- cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), cs)
30
-
31
- ctx := context.Background()
32
-
33
- // For our example we will use a No-op reporter that does not actually collect any test reports.
34
- rep := testreporter.NewNopReporter()
35
-
36
- // Test will now run the conformance test suite against both of our chains, ensuring that they both have basic
37
- // IBC capabilities properly implemented and work with both the Go relayer and Hermes.
38
- conformance.Test(t, ctx, []interchaintest.ChainFactory{cf}, []interchaintest.RelayerFactory{rf}, rep)
39
- }
40
-
41
- func testChainPair(t *testing.T, cs []*interchaintest.ChainSpec, rf interchaintest.RelayerFactory) {
42
- cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), cs)
43
-
44
- ctx := context.Background()
45
-
46
- // For our example we will use a No-op reporter that does not actually collect any test reports.
47
- rep := testreporter.NewNopReporter()
48
-
49
- chains, err := cf.Chains(t.Name())
50
- if err != nil {
51
- panic(fmt.Errorf("failed to get chains: %v", err))
52
- }
53
-
54
- client, network := interchaintest.DockerSetup(t)
55
- conformance.TestChainPair(t, ctx, client, network, chains[0], chains[1], rf, rep, nil)
56
- }
@@ -1,613 +0,0 @@
1
- package e2etest
2
-
3
- import (
4
- "context"
5
- "encoding/json"
6
- "fmt"
7
- "testing"
8
- "time"
9
-
10
- "github.com/agoric-labs/interchaintest/v6"
11
- "github.com/agoric-labs/interchaintest/v6/chain/cosmos"
12
- "github.com/agoric-labs/interchaintest/v6/ibc"
13
- "github.com/agoric-labs/interchaintest/v6/testreporter"
14
- sdk "github.com/cosmos/cosmos-sdk/types"
15
- transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
16
- "github.com/stretchr/testify/require"
17
- "go.uber.org/zap/zaptest"
18
- )
19
-
20
- func TestPFM(t *testing.T) {
21
- cs := getChainSpec(t)
22
- rf := getRelayerFactory(t)
23
-
24
- testPFM(t, cs, rf)
25
- }
26
-
27
- // ForwardMetadata is the shape of the JSON in a single PFM hop in the IBC memo
28
- type ForwardMetadata struct {
29
- Receiver string `json:"receiver"`
30
- Port string `json:"port"`
31
- Channel string `json:"channel"`
32
- Timeout time.Duration `json:"timeout"`
33
- Retries *uint8 `json:"retries,omitempty"`
34
- Next *string `json:"next,omitempty"`
35
- RefundSequence *uint64 `json:"refund_sequence,omitempty"`
36
- }
37
-
38
- // PacketMetadata is a chain of ForwardMetadata collectively describing the full IBC memo
39
- type PacketMetadata struct {
40
- Forward *ForwardMetadata `json:"forward"`
41
- }
42
-
43
- // testPFM verified multiple PFM scenarios serially
44
- func testPFM(t *testing.T, cs []*interchaintest.ChainSpec, rf interchaintest.RelayerFactory) {
45
- var (
46
- ctx = context.Background()
47
- client, network = interchaintest.DockerSetup(t)
48
- rep = testreporter.NewNopReporter()
49
- eRep = rep.RelayerExecReporter(t)
50
- )
51
-
52
- cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), cs)
53
-
54
- chains, err := cf.Chains(t.Name())
55
- require.NoError(t, err)
56
-
57
- chainA, chainB, chainC, chainD := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain), chains[2].(*cosmos.CosmosChain), chains[3].(*cosmos.CosmosChain)
58
- chainID_A, chainID_B, chainID_C, chainID_D := chainA.Config().ChainID, chainB.Config().ChainID, chainC.Config().ChainID, chainD.Config().ChainID
59
- chainName_A, chainName_B, chainName_C, chainName_D := chainA.Config().Name, chainB.Config().Name, chainC.Config().Name, chainD.Config().Name
60
-
61
- r := rf.Build(t, client, network)
62
-
63
- pathAB := fmt.Sprintf("%s-%s", chainName_A, chainName_B)
64
- pathBC := fmt.Sprintf("%s-%s", chainName_B, chainName_C)
65
- pathCD := fmt.Sprintf("%s-%s", chainName_C, chainName_D)
66
-
67
- ic := interchaintest.NewInterchain().
68
- AddChain(chainA).
69
- AddChain(chainB).
70
- AddChain(chainC).
71
- AddChain(chainD).
72
- AddRelayer(r, "relayer").
73
- AddLink(interchaintest.InterchainLink{
74
- Chain1: chainA,
75
- Chain2: chainB,
76
- Relayer: r,
77
- Path: pathAB,
78
- }).
79
- AddLink(interchaintest.InterchainLink{
80
- Chain1: chainB,
81
- Chain2: chainC,
82
- Relayer: r,
83
- Path: pathBC,
84
- }).
85
- AddLink(interchaintest.InterchainLink{
86
- Chain1: chainC,
87
- Chain2: chainD,
88
- Relayer: r,
89
- Path: pathCD,
90
- })
91
-
92
- require.NoError(t, ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{
93
- TestName: t.Name(),
94
- Client: client,
95
- NetworkID: network,
96
- BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(),
97
-
98
- SkipPathCreation: false,
99
- }))
100
- t.Cleanup(func() {
101
- _ = ic.Close()
102
- })
103
-
104
- users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), sdk.NewInt(10_000_000_000), chainA, chainB, chainC, chainD)
105
-
106
- abChan, err := ibc.GetTransferChannel(ctx, r, eRep, chainID_A, chainID_B)
107
- require.NoError(t, err)
108
-
109
- baChan := abChan.Counterparty
110
-
111
- cbChan, err := ibc.GetTransferChannel(ctx, r, eRep, chainID_C, chainID_B)
112
- require.NoError(t, err)
113
-
114
- bcChan := cbChan.Counterparty
115
-
116
- dcChan, err := ibc.GetTransferChannel(ctx, r, eRep, chainID_D, chainID_C)
117
- require.NoError(t, err)
118
-
119
- cdChan := dcChan.Counterparty
120
-
121
- // Start the relayer on both paths
122
- err = r.StartRelayer(ctx, eRep, pathAB, pathBC, pathCD)
123
- require.NoError(t, err)
124
-
125
- t.Cleanup(
126
- func() {
127
- err := r.StopRelayer(ctx, eRep)
128
- if err != nil {
129
- t.Logf("an error occured while stopping the relayer: %s", err)
130
- }
131
- },
132
- )
133
-
134
- // Get original account balances
135
- userA, userB, userC, userD := users[0], users[1], users[2], users[3]
136
-
137
- transferAmount := sdk.NewInt(100_000)
138
-
139
- // Compose the prefixed denoms and ibc denom for asserting balances
140
- firstHopDenom := transfertypes.GetPrefixedDenom(baChan.PortID, baChan.ChannelID, chainA.Config().Denom)
141
- secondHopDenom := transfertypes.GetPrefixedDenom(cbChan.PortID, cbChan.ChannelID, firstHopDenom)
142
- thirdHopDenom := transfertypes.GetPrefixedDenom(dcChan.PortID, dcChan.ChannelID, secondHopDenom)
143
-
144
- firstHopDenomTrace := transfertypes.ParseDenomTrace(firstHopDenom)
145
- secondHopDenomTrace := transfertypes.ParseDenomTrace(secondHopDenom)
146
- thirdHopDenomTrace := transfertypes.ParseDenomTrace(thirdHopDenom)
147
-
148
- firstHopIBCDenom := firstHopDenomTrace.IBCDenom()
149
- secondHopIBCDenom := secondHopDenomTrace.IBCDenom()
150
- thirdHopIBCDenom := thirdHopDenomTrace.IBCDenom()
151
-
152
- firstHopEscrowAccount := sdk.MustBech32ifyAddressBytes(chainA.Config().Bech32Prefix, transfertypes.GetEscrowAddress(abChan.PortID, abChan.ChannelID))
153
- secondHopEscrowAccount := sdk.MustBech32ifyAddressBytes(chainB.Config().Bech32Prefix, transfertypes.GetEscrowAddress(bcChan.PortID, bcChan.ChannelID))
154
- thirdHopEscrowAccount := sdk.MustBech32ifyAddressBytes(chainC.Config().Bech32Prefix, transfertypes.GetEscrowAddress(cdChan.PortID, abChan.ChannelID))
155
-
156
- t.Run("multi-hop a->b->c->d", func(t *testing.T) {
157
- // Send packet from Chain A->Chain B->Chain C->Chain D
158
-
159
- transfer := ibc.WalletAmount{
160
- Address: userB.FormattedAddress(),
161
- Denom: chainA.Config().Denom,
162
- Amount: transferAmount,
163
- }
164
-
165
- secondHopMetadata := &PacketMetadata{
166
- Forward: &ForwardMetadata{
167
- Receiver: userD.FormattedAddress(),
168
- Channel: cdChan.ChannelID,
169
- Port: cdChan.PortID,
170
- },
171
- }
172
- nextBz, err := json.Marshal(secondHopMetadata)
173
- require.NoError(t, err)
174
- next := string(nextBz)
175
-
176
- firstHopMetadata := &PacketMetadata{
177
- Forward: &ForwardMetadata{
178
- Receiver: userC.FormattedAddress(),
179
- Channel: bcChan.ChannelID,
180
- Port: bcChan.PortID,
181
- Next: &next,
182
- },
183
- }
184
-
185
- memo, err := json.Marshal(firstHopMetadata)
186
- require.NoError(t, err)
187
-
188
- initialChainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
189
- require.NoError(t, err)
190
-
191
- transferTx, err := sendIBCTransferWithWait(chainA, ctx, abChan.ChannelID, userA.KeyName(), transfer, ibc.TransferOptions{Memo: string(memo)})
192
- require.NoError(t, err)
193
-
194
- chainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
195
- require.NoError(t, err)
196
-
197
- chainBBalance, err := chainB.GetBalance(ctx, userB.FormattedAddress(), firstHopIBCDenom)
198
- require.NoError(t, err)
199
-
200
- chainCBalance, err := chainC.GetBalance(ctx, userC.FormattedAddress(), secondHopIBCDenom)
201
- require.NoError(t, err)
202
-
203
- chainDBalance, err := chainD.GetBalance(ctx, userD.FormattedAddress(), thirdHopIBCDenom)
204
- require.NoError(t, err)
205
-
206
- t.Logf("Balances: userA[%v] userB[%v] userC[%v] userD[%v]", chainABalance, chainBBalance, chainCBalance, chainDBalance)
207
- gasFees := chainA.GetGasFeesInNativeDenom(transferTx.GasSpent)
208
- expectedChainABalance := initialChainABalance.Sub(transferAmount).Sub(sdk.NewInt(gasFees))
209
- require.Equalf(t, expectedChainABalance, chainABalance, "Wrong user balance on chainA expected[%v] actual[%v]", expectedChainABalance, chainABalance)
210
- require.Equalf(t, sdk.NewInt(0), chainBBalance, "Wrong user balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), chainBBalance)
211
- require.Equalf(t, sdk.NewInt(0), chainCBalance, "Wrong user balance on chainC expected[%v] actual[%v]", sdk.NewInt(0), chainCBalance)
212
- require.Equalf(t, transferAmount, chainDBalance, "Wrong user balance on chainD expected[%v] actual[%v]", transferAmount, chainDBalance)
213
-
214
- firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom)
215
- require.NoError(t, err)
216
-
217
- secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom)
218
- require.NoError(t, err)
219
-
220
- thirdHopEscrowBalance, err := chainC.GetBalance(ctx, thirdHopEscrowAccount, secondHopIBCDenom)
221
- require.NoError(t, err)
222
-
223
- require.Equalf(t, transferAmount, firstHopEscrowBalance, "Wrong escrow balance on chainA expected[%v] actual[%v]", transferAmount, firstHopEscrowBalance)
224
- require.Equalf(t, transferAmount, secondHopEscrowBalance, "Wrong escrow balance on chainB expected[%v] actual[%v]", transferAmount, secondHopEscrowBalance)
225
- require.Equalf(t, transferAmount, thirdHopEscrowBalance, "Wrong escrow balance on chainC expected[%v] actual[%v]", transferAmount, thirdHopEscrowBalance)
226
- })
227
-
228
- t.Run("multi-hop denom unwind d->c->b->a", func(t *testing.T) {
229
- // Send packet back from Chain D->Chain C->Chain B->Chain A
230
- transfer := ibc.WalletAmount{
231
- Address: userC.FormattedAddress(),
232
- Denom: thirdHopIBCDenom,
233
- Amount: transferAmount,
234
- }
235
-
236
- secondHopMetadata := &PacketMetadata{
237
- Forward: &ForwardMetadata{
238
- Receiver: userA.FormattedAddress(),
239
- Channel: baChan.ChannelID,
240
- Port: baChan.PortID,
241
- },
242
- }
243
-
244
- nextBz, err := json.Marshal(secondHopMetadata)
245
- require.NoError(t, err)
246
-
247
- next := string(nextBz)
248
-
249
- firstHopMetadata := &PacketMetadata{
250
- Forward: &ForwardMetadata{
251
- Receiver: userB.FormattedAddress(),
252
- Channel: cbChan.ChannelID,
253
- Port: cbChan.PortID,
254
- Next: &next,
255
- },
256
- }
257
-
258
- memo, err := json.Marshal(firstHopMetadata)
259
- require.NoError(t, err)
260
-
261
- initialChainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
262
- require.NoError(t, err)
263
-
264
- _, err = sendIBCTransferWithWait(chainD, ctx, dcChan.ChannelID, userD.KeyName(), transfer, ibc.TransferOptions{Memo: string(memo)})
265
- require.NoError(t, err)
266
-
267
- // assert balances for user controlled wallets
268
- chainDBalance, err := chainD.GetBalance(ctx, userD.FormattedAddress(), thirdHopIBCDenom)
269
- require.NoError(t, err)
270
-
271
- chainCBalance, err := chainC.GetBalance(ctx, userC.FormattedAddress(), secondHopIBCDenom)
272
- require.NoError(t, err)
273
-
274
- chainBBalance, err := chainB.GetBalance(ctx, userB.FormattedAddress(), firstHopIBCDenom)
275
- require.NoError(t, err)
276
-
277
- chainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
278
- require.NoError(t, err)
279
-
280
- t.Logf("Balances: userA[%v] userB[%v] userC[%v] userD[%v]", chainABalance, chainBBalance, chainCBalance, chainDBalance)
281
- require.Equalf(t, sdk.NewInt(0), chainDBalance, "Wrong user balance on chainD expected[%v] actual[%v]", sdk.NewInt(0), chainDBalance)
282
- require.Equalf(t, sdk.NewInt(0), chainCBalance, "Wrong user balance on chainC expected[%v] actual[%v]", sdk.NewInt(0), chainCBalance)
283
- require.Equalf(t, sdk.NewInt(0), chainBBalance, "Wrong user balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), chainBBalance)
284
- expectedChainABalance := initialChainABalance.Add(transferAmount)
285
- require.Equalf(t, expectedChainABalance, chainABalance, "Wrong user balance on chainA expected[%v] actual[%v]", expectedChainABalance, chainABalance)
286
-
287
- // assert balances for IBC escrow accounts
288
- firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom)
289
- require.NoError(t, err)
290
-
291
- secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom)
292
- require.NoError(t, err)
293
-
294
- thirdHopEscrowBalance, err := chainC.GetBalance(ctx, thirdHopEscrowAccount, secondHopIBCDenom)
295
- require.NoError(t, err)
296
-
297
- require.Equalf(t, sdk.NewInt(0), firstHopEscrowBalance, "Wrong escrow balance on chainA expected[%v] actual[%v]", sdk.NewInt(0), firstHopEscrowBalance)
298
- require.Equalf(t, sdk.NewInt(0), secondHopEscrowBalance, "Wrong escrow balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), secondHopEscrowBalance)
299
- require.Equalf(t, sdk.NewInt(0), thirdHopEscrowBalance, "Wrong escrow balance on chainC expected[%v] actual[%v]", sdk.NewInt(0), thirdHopEscrowBalance)
300
- })
301
-
302
- t.Run("forward ack error refund", func(t *testing.T) {
303
- // Send a malformed packet with invalid receiver address from Chain A->Chain B->Chain C
304
- // This should succeed in the first hop and fail to make the second hop; funds should then be refunded to Chain A.
305
- transfer := ibc.WalletAmount{
306
- Address: userB.FormattedAddress(),
307
- Denom: chainA.Config().Denom,
308
- Amount: transferAmount,
309
- }
310
-
311
- metadata := &PacketMetadata{
312
- Forward: &ForwardMetadata{
313
- Receiver: "xyz1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq", // malformed receiver address on Chain C
314
- Channel: bcChan.ChannelID,
315
- Port: bcChan.PortID,
316
- },
317
- }
318
-
319
- memo, err := json.Marshal(metadata)
320
- require.NoError(t, err)
321
-
322
- initialChainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
323
- require.NoError(t, err)
324
-
325
- transferTx, err := sendIBCTransferWithWait(chainA, ctx, abChan.ChannelID, userA.KeyName(), transfer, ibc.TransferOptions{Memo: string(memo)})
326
- require.NoError(t, err)
327
-
328
- // assert balances for user controlled wallets
329
- chainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
330
- require.NoError(t, err)
331
-
332
- chainBBalance, err := chainB.GetBalance(ctx, userB.FormattedAddress(), firstHopIBCDenom)
333
- require.NoError(t, err)
334
-
335
- chainCBalance, err := chainC.GetBalance(ctx, userC.FormattedAddress(), secondHopIBCDenom)
336
- require.NoError(t, err)
337
-
338
- t.Logf("Balances: userA[%v] userB[%v] userC[%v]", chainABalance, chainBBalance, chainCBalance)
339
- gasFees := chainA.GetGasFeesInNativeDenom(transferTx.GasSpent)
340
- expectedChainABalance := initialChainABalance.Sub(sdk.NewInt(gasFees))
341
- require.Equal(t, expectedChainABalance, chainABalance, "Wrong user balance on chainA expected[%v] actual[%v]", expectedChainABalance, chainABalance)
342
- require.Equal(t, sdk.NewInt(0), chainBBalance, "Wrong user balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), chainBBalance)
343
- require.Equal(t, sdk.NewInt(0), chainCBalance, "Wrong user balance on chainC expected[%v] actual[%v]", sdk.NewInt(0), chainCBalance)
344
-
345
- // assert balances for IBC escrow accounts
346
- firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom)
347
- require.NoError(t, err)
348
-
349
- secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom)
350
- require.NoError(t, err)
351
-
352
- require.Equalf(t, sdk.NewInt(0), firstHopEscrowBalance, "Wrong escrow balance on chainA expected[%v] actual[%v]", sdk.NewInt(0), firstHopEscrowBalance)
353
- require.Equalf(t, sdk.NewInt(0), secondHopEscrowBalance, "Wrong escrow balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), secondHopEscrowBalance)
354
- })
355
-
356
- t.Run("forward timeout refund", func(t *testing.T) {
357
- // Send packet from Chain A->Chain B->Chain C with the timeout so low for B->C transfer that it can not make it from B to C, which should result in a refund from B to A after two retries.
358
- transfer := ibc.WalletAmount{
359
- Address: userB.FormattedAddress(),
360
- Denom: chainA.Config().Denom,
361
- Amount: transferAmount,
362
- }
363
-
364
- retries := uint8(2)
365
- metadata := &PacketMetadata{
366
- Forward: &ForwardMetadata{
367
- Receiver: userC.FormattedAddress(),
368
- Channel: bcChan.ChannelID,
369
- Port: bcChan.PortID,
370
- Retries: &retries,
371
- Timeout: 1 * time.Second,
372
- },
373
- }
374
-
375
- memo, err := json.Marshal(metadata)
376
- require.NoError(t, err)
377
-
378
- initialChainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
379
- require.NoError(t, err)
380
-
381
- transferTx, err := sendIBCTransferWithWait(chainA, ctx, abChan.ChannelID, userA.KeyName(), transfer, ibc.TransferOptions{Memo: string(memo)})
382
- require.NoError(t, err)
383
-
384
- // assert balances for user controlled wallets
385
- chainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
386
- require.NoError(t, err)
387
-
388
- chainBBalance, err := chainB.GetBalance(ctx, userB.FormattedAddress(), firstHopIBCDenom)
389
- require.NoError(t, err)
390
-
391
- chainCBalance, err := chainC.GetBalance(ctx, userC.FormattedAddress(), secondHopIBCDenom)
392
- require.NoError(t, err)
393
-
394
- t.Logf("Balances: userA[%v] userB[%v] userC[%v]", chainABalance, chainBBalance, chainCBalance)
395
- gasFees := chainA.GetGasFeesInNativeDenom(transferTx.GasSpent)
396
- expectedChainABalance := initialChainABalance.Sub(sdk.NewInt(gasFees))
397
- require.Equalf(t, expectedChainABalance, chainABalance, "Wrong user balance on chainA expected[%v] actual[%v]", expectedChainABalance, chainABalance)
398
- require.Equalf(t, sdk.NewInt(0), chainBBalance, "Wrong user balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), chainBBalance)
399
- require.Equalf(t, sdk.NewInt(0), chainCBalance, "Wrong user balance on chainC expected[%v] actual[%v]", sdk.NewInt(0), chainCBalance)
400
-
401
- firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom)
402
- require.NoError(t, err)
403
-
404
- secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom)
405
- require.NoError(t, err)
406
-
407
- require.Equalf(t, sdk.NewInt(0), firstHopEscrowBalance, "Wrong escrow balance on chainA expected[%v] actual[%v]", sdk.NewInt(0), firstHopEscrowBalance)
408
- require.Equalf(t, sdk.NewInt(0), secondHopEscrowBalance, "Wrong escrow balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), secondHopEscrowBalance)
409
- })
410
-
411
- t.Run("multi-hop ack error refund", func(t *testing.T) {
412
- // Send a malformed packet with invalid receiver address from Chain A->Chain B->Chain C->Chain D
413
- // This should succeed in the first hop and second hop, then fail to make the third hop.
414
- // Funds should be refunded to Chain B and then to Chain A via acknowledgements with errors.
415
- transfer := ibc.WalletAmount{
416
- Address: userB.FormattedAddress(),
417
- Denom: chainA.Config().Denom,
418
- Amount: transferAmount,
419
- }
420
-
421
- secondHopMetadata := &PacketMetadata{
422
- Forward: &ForwardMetadata{
423
- Receiver: "xyz1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq", // malformed receiver address on chain D
424
- Channel: cdChan.ChannelID,
425
- Port: cdChan.PortID,
426
- },
427
- }
428
-
429
- nextBz, err := json.Marshal(secondHopMetadata)
430
- require.NoError(t, err)
431
-
432
- next := string(nextBz)
433
-
434
- firstHopMetadata := &PacketMetadata{
435
- Forward: &ForwardMetadata{
436
- Receiver: userC.FormattedAddress(),
437
- Channel: bcChan.ChannelID,
438
- Port: bcChan.PortID,
439
- Next: &next,
440
- },
441
- }
442
-
443
- memo, err := json.Marshal(firstHopMetadata)
444
- require.NoError(t, err)
445
-
446
- initialChainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
447
- require.NoError(t, err)
448
-
449
- transferTx, err := sendIBCTransferWithWait(chainA, ctx, abChan.ChannelID, userA.KeyName(), transfer, ibc.TransferOptions{Memo: string(memo)})
450
- require.NoError(t, err)
451
-
452
- // assert balances for user controlled wallets
453
- chainDBalance, err := chainD.GetBalance(ctx, userD.FormattedAddress(), thirdHopIBCDenom)
454
- require.NoError(t, err)
455
-
456
- chainCBalance, err := chainC.GetBalance(ctx, userC.FormattedAddress(), secondHopIBCDenom)
457
- require.NoError(t, err)
458
-
459
- chainBBalance, err := chainB.GetBalance(ctx, userB.FormattedAddress(), firstHopIBCDenom)
460
- require.NoError(t, err)
461
-
462
- chainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), chainA.Config().Denom)
463
- require.NoError(t, err)
464
-
465
- gasFees := chainA.GetGasFeesInNativeDenom(transferTx.GasSpent)
466
- expectedChainABalance := initialChainABalance.Sub(sdk.NewInt(gasFees))
467
- require.Equalf(t, expectedChainABalance, chainABalance, "Wrong user balance on chainA expected[%v] actual[%v]", expectedChainABalance, chainABalance)
468
- require.Equalf(t, sdk.NewInt(0), chainBBalance, "Wrong user balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), chainBBalance)
469
- require.Equalf(t, sdk.NewInt(0), chainCBalance, "Wrong user balance on chainC expected[%v] actual[%v]", sdk.NewInt(0), chainCBalance)
470
- require.Equalf(t, sdk.NewInt(0), chainDBalance, "Wrong user balance on chainD expected[%v] actual[%v]", sdk.NewInt(0), chainDBalance)
471
-
472
- // assert balances for IBC escrow accounts
473
- firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom)
474
- require.NoError(t, err)
475
-
476
- secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom)
477
- require.NoError(t, err)
478
-
479
- thirdHopEscrowBalance, err := chainC.GetBalance(ctx, thirdHopEscrowAccount, secondHopIBCDenom)
480
- require.NoError(t, err)
481
-
482
- require.Equal(t, sdk.NewInt(0), firstHopEscrowBalance, "Wrong escrow balance on chainA expected[%v] actual[%v]", sdk.NewInt(0), firstHopEscrowBalance)
483
- require.Equal(t, sdk.NewInt(0), secondHopEscrowBalance, "Wrong escrow balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), secondHopEscrowBalance)
484
- require.Equal(t, sdk.NewInt(0), thirdHopEscrowBalance, "Wrong escrow balance on chainC expected[%v] actual[%v]", sdk.NewInt(0), thirdHopEscrowBalance)
485
- })
486
-
487
- t.Run("multi-hop through native chain ack error refund", func(t *testing.T) {
488
- // send normal IBC transfer from B->A to get funds in IBC denom, then do multihop A->B(native)->C->D
489
- // this lets us test the burn from escrow account on chain C and the escrow to escrow transfer on chain B.
490
-
491
- // Compose the prefixed denoms and ibc denom for asserting balances
492
- baDenom := transfertypes.GetPrefixedDenom(abChan.PortID, abChan.ChannelID, chainB.Config().Denom)
493
- bcDenom := transfertypes.GetPrefixedDenom(cbChan.PortID, cbChan.ChannelID, chainB.Config().Denom)
494
- cdDenom := transfertypes.GetPrefixedDenom(dcChan.PortID, dcChan.ChannelID, bcDenom)
495
-
496
- baDenomTrace := transfertypes.ParseDenomTrace(baDenom)
497
- bcDenomTrace := transfertypes.ParseDenomTrace(bcDenom)
498
- cdDenomTrace := transfertypes.ParseDenomTrace(cdDenom)
499
-
500
- baIBCDenom := baDenomTrace.IBCDenom()
501
- bcIBCDenom := bcDenomTrace.IBCDenom()
502
- cdIBCDenom := cdDenomTrace.IBCDenom()
503
-
504
- transfer := ibc.WalletAmount{
505
- Address: userA.FormattedAddress(),
506
- Denom: chainB.Config().Denom,
507
- Amount: transferAmount,
508
- }
509
-
510
- _, err := sendIBCTransferWithWait(chainB, ctx, baChan.ChannelID, userB.KeyName(), transfer, ibc.TransferOptions{})
511
- require.NoError(t, err)
512
-
513
- // assert balance for user controlled wallet
514
- chainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), baIBCDenom)
515
- require.NoError(t, err)
516
-
517
- baEscrowBalance, err := chainB.GetBalance(
518
- ctx,
519
- sdk.MustBech32ifyAddressBytes(chainB.Config().Bech32Prefix, transfertypes.GetEscrowAddress(baChan.PortID, baChan.ChannelID)),
520
- chainB.Config().Denom,
521
- )
522
- require.NoError(t, err)
523
-
524
- require.Equalf(t, transferAmount, chainABalance, "Wrong user balance on chainA expected[%v] actual[%v]", transferAmount, chainABalance)
525
- require.Equalf(t, transferAmount, baEscrowBalance, "Wrong escrow balance on chainB expected[%v] actual[%v]", transferAmount, baEscrowBalance)
526
-
527
- // Send a malformed packet with invalid receiver address from Chain A->Chain B->Chain C->Chain D
528
- // This should succeed in the first hop and second hop, then fail to make the third hop.
529
- // Funds should be refunded to Chain B and then to Chain A via acknowledgements with errors.
530
- transfer = ibc.WalletAmount{
531
- Address: userB.FormattedAddress(),
532
- Denom: baIBCDenom,
533
- Amount: transferAmount,
534
- }
535
-
536
- secondHopMetadata := &PacketMetadata{
537
- Forward: &ForwardMetadata{
538
- Receiver: "xyz1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq", // malformed receiver address on chain D
539
- Channel: cdChan.ChannelID,
540
- Port: cdChan.PortID,
541
- },
542
- }
543
-
544
- nextBz, err := json.Marshal(secondHopMetadata)
545
- require.NoError(t, err)
546
-
547
- next := string(nextBz)
548
-
549
- firstHopMetadata := &PacketMetadata{
550
- Forward: &ForwardMetadata{
551
- Receiver: userC.FormattedAddress(),
552
- Channel: bcChan.ChannelID,
553
- Port: bcChan.PortID,
554
- Next: &next,
555
- },
556
- }
557
-
558
- memo, err := json.Marshal(firstHopMetadata)
559
- require.NoError(t, err)
560
-
561
- initialChainBBalance, err := chainB.GetBalance(ctx, userB.FormattedAddress(), chainB.Config().Denom)
562
- require.NoError(t, err)
563
-
564
- _, err = sendIBCTransferWithWait(chainA, ctx, abChan.ChannelID, userA.KeyName(), transfer, ibc.TransferOptions{Memo: string(memo)})
565
- require.NoError(t, err)
566
-
567
- // assert balances for user controlled wallets
568
- chainDBalance, err := chainD.GetBalance(ctx, userD.FormattedAddress(), cdIBCDenom)
569
- require.NoError(t, err)
570
-
571
- chainCBalance, err := chainC.GetBalance(ctx, userC.FormattedAddress(), bcIBCDenom)
572
- require.NoError(t, err)
573
-
574
- chainBBalance, err := chainB.GetBalance(ctx, userB.FormattedAddress(), chainB.Config().Denom)
575
- require.NoError(t, err)
576
-
577
- chainABalance, err = chainA.GetBalance(ctx, userA.FormattedAddress(), baIBCDenom)
578
- require.NoError(t, err)
579
-
580
- t.Logf("Balances: userA[%v] userB[%v] userC[%v] userD[%v]", chainABalance, chainBBalance, chainCBalance, chainDBalance)
581
- require.Equal(t, transferAmount, chainABalance, "Wrong user balance on chainA expected[%v] actual[%v]", transferAmount, chainABalance)
582
- expectedChainBBalance := initialChainBBalance
583
- require.Equal(t, expectedChainBBalance, chainBBalance, "Wrong user balance on chainB expected[%v] actual[%v]", expectedChainBBalance, chainBBalance)
584
- require.Equal(t, sdk.NewInt(0), chainCBalance, "Wrong user balance on chainC expected[%v] actual[%v]", sdk.NewInt(0), chainCBalance)
585
- require.Equal(t, sdk.NewInt(0), chainDBalance, "Wrong user balance on chainD expected[%v] actual[%v]", sdk.NewInt(0), chainDBalance)
586
-
587
- // assert balances for IBC escrow accounts
588
- cdEscrowBalance, err := chainC.GetBalance(
589
- ctx,
590
- sdk.MustBech32ifyAddressBytes(chainC.Config().Bech32Prefix, transfertypes.GetEscrowAddress(cdChan.PortID, cdChan.ChannelID)),
591
- bcIBCDenom,
592
- )
593
- require.NoError(t, err)
594
-
595
- bcEscrowBalance, err := chainB.GetBalance(
596
- ctx,
597
- sdk.MustBech32ifyAddressBytes(chainB.Config().Bech32Prefix, transfertypes.GetEscrowAddress(bcChan.PortID, bcChan.ChannelID)),
598
- chainB.Config().Denom,
599
- )
600
- require.NoError(t, err)
601
-
602
- baEscrowBalance, err = chainB.GetBalance(
603
- ctx,
604
- sdk.MustBech32ifyAddressBytes(chainB.Config().Bech32Prefix, transfertypes.GetEscrowAddress(baChan.PortID, baChan.ChannelID)),
605
- chainB.Config().Denom,
606
- )
607
- require.NoError(t, err)
608
-
609
- require.Equal(t, transferAmount, baEscrowBalance, "Wrong escrow balance on chainB expected[%v] actual[%v]", transferAmount, baEscrowBalance)
610
- require.Equal(t, sdk.NewInt(0), bcEscrowBalance, "Wrong escrow balance on chainB expected[%v] actual[%v]", sdk.NewInt(0), bcEscrowBalance)
611
- require.Equal(t, sdk.NewInt(0), cdEscrowBalance, "Wrong escrow balance on chainC expected[%v] actual[%v]", sdk.NewInt(0), cdEscrowBalance)
612
- })
613
- }