@agoric/cosmos 0.35.0-upgrade-14-dev-c8f9e7b.0 → 0.35.0-upgrade-16a-dev-fb592e4.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.
Files changed (133) hide show
  1. package/CHANGELOG.md +121 -77
  2. package/MAINTAINERS.md +3 -0
  3. package/Makefile +36 -26
  4. package/ante/ante.go +7 -9
  5. package/ante/inbound_test.go +3 -2
  6. package/ante/vm_admission.go +2 -1
  7. package/app/app.go +212 -140
  8. package/app/upgrade.go +76 -0
  9. package/cmd/agd/agvm.go +42 -0
  10. package/cmd/agd/main.go +130 -11
  11. package/cmd/libdaemon/main.go +64 -53
  12. package/cmd/libdaemon/main_test.go +2 -1
  13. package/daemon/cmd/root.go +171 -74
  14. package/daemon/cmd/root_test.go +189 -1
  15. package/daemon/main.go +4 -2
  16. package/e2e_test/Makefile +29 -0
  17. package/e2e_test/README.md +100 -0
  18. package/e2e_test/go.mod +217 -0
  19. package/e2e_test/go.sum +1323 -0
  20. package/e2e_test/ibc_conformance_test.go +56 -0
  21. package/e2e_test/pfm_test.go +613 -0
  22. package/e2e_test/util.go +271 -0
  23. package/git-revision.txt +1 -1
  24. package/go.mod +22 -11
  25. package/go.sum +17 -13
  26. package/package.json +9 -5
  27. package/proto/agoric/swingset/genesis.proto +4 -0
  28. package/proto/agoric/swingset/swingset.proto +1 -1
  29. package/proto/agoric/vlocalchain/.clang-format +7 -0
  30. package/proto/agoric/vlocalchain/vlocalchain.proto +31 -0
  31. package/proto/agoric/vtransfer/genesis.proto +18 -0
  32. package/scripts/protocgen.sh +7 -8
  33. package/types/kv_entry_helpers.go +42 -0
  34. package/upgradegaia.sh +8 -8
  35. package/vm/action.go +5 -4
  36. package/vm/action_test.go +31 -11
  37. package/vm/client.go +113 -0
  38. package/vm/client_test.go +182 -0
  39. package/vm/controller.go +17 -40
  40. package/vm/core_proposals.go +22 -2
  41. package/vm/jsonrpcconn/jsonrpcconn.go +160 -0
  42. package/vm/jsonrpcconn/jsonrpcconn_test.go +126 -0
  43. package/vm/proto_json.go +38 -0
  44. package/vm/proto_json_test.go +103 -0
  45. package/vm/server.go +124 -0
  46. package/x/swingset/abci.go +10 -10
  47. package/x/swingset/alias.go +2 -0
  48. package/x/swingset/client/cli/tx.go +4 -0
  49. package/x/swingset/genesis.go +84 -24
  50. package/x/swingset/handler.go +2 -1
  51. package/x/swingset/keeper/extension_snapshotter.go +2 -2
  52. package/x/swingset/keeper/keeper.go +13 -25
  53. package/x/swingset/keeper/msg_server.go +18 -18
  54. package/x/swingset/keeper/proposal.go +3 -3
  55. package/x/swingset/keeper/querier.go +12 -11
  56. package/x/swingset/keeper/swing_store_exports_handler.go +21 -6
  57. package/x/swingset/keeper/test_utils.go +16 -0
  58. package/x/swingset/module.go +7 -7
  59. package/x/swingset/proposal_handler.go +2 -1
  60. package/x/swingset/testing/queue.go +17 -0
  61. package/x/swingset/types/default-params.go +1 -1
  62. package/x/swingset/types/expected_keepers.go +3 -2
  63. package/x/swingset/types/genesis.pb.go +78 -25
  64. package/x/swingset/types/msgs.go +44 -24
  65. package/x/swingset/types/params.go +2 -1
  66. package/x/swingset/types/proposal.go +5 -4
  67. package/x/swingset/types/swingset.pb.go +1 -1
  68. package/x/vbank/genesis.go +0 -2
  69. package/x/vbank/handler.go +2 -1
  70. package/x/vbank/keeper/querier.go +4 -3
  71. package/x/vbank/module.go +0 -5
  72. package/x/vbank/types/msgs.go +0 -12
  73. package/x/vbank/vbank.go +9 -9
  74. package/x/vbank/vbank_test.go +2 -2
  75. package/x/vibc/alias.go +3 -0
  76. package/x/vibc/handler.go +16 -9
  77. package/x/vibc/keeper/keeper.go +102 -65
  78. package/x/vibc/keeper/triggers.go +101 -0
  79. package/x/vibc/module.go +5 -8
  80. package/x/vibc/types/expected_keepers.go +13 -0
  81. package/x/vibc/types/ibc_module.go +336 -0
  82. package/x/vibc/types/receiver.go +170 -0
  83. package/x/vlocalchain/alias.go +19 -0
  84. package/x/vlocalchain/handler.go +21 -0
  85. package/x/vlocalchain/keeper/keeper.go +279 -0
  86. package/x/vlocalchain/keeper/keeper_test.go +97 -0
  87. package/x/vlocalchain/types/codec.go +34 -0
  88. package/x/vlocalchain/types/key.go +27 -0
  89. package/x/vlocalchain/types/msgs.go +16 -0
  90. package/x/vlocalchain/types/vlocalchain.pb.go +1072 -0
  91. package/x/vlocalchain/vlocalchain.go +114 -0
  92. package/x/vlocalchain/vlocalchain_test.go +434 -0
  93. package/x/vstorage/handler.go +2 -1
  94. package/x/vstorage/keeper/grpc_query.go +0 -1
  95. package/x/vstorage/keeper/keeper.go +13 -20
  96. package/x/vstorage/keeper/querier.go +6 -5
  97. package/x/vstorage/keeper/querier_test.go +4 -3
  98. package/x/vstorage/module.go +0 -5
  99. package/x/vstorage/testing/queue.go +27 -0
  100. package/x/vtransfer/alias.go +13 -0
  101. package/x/vtransfer/genesis.go +39 -0
  102. package/x/vtransfer/genesis_test.go +12 -0
  103. package/x/vtransfer/handler.go +20 -0
  104. package/x/vtransfer/ibc_middleware.go +186 -0
  105. package/x/vtransfer/ibc_middleware_test.go +448 -0
  106. package/x/vtransfer/keeper/keeper.go +281 -0
  107. package/x/vtransfer/module.go +124 -0
  108. package/x/vtransfer/types/expected_keepers.go +38 -0
  109. package/x/vtransfer/types/genesis.pb.go +327 -0
  110. package/x/vtransfer/types/key.go +9 -0
  111. package/x/vtransfer/types/msgs.go +9 -0
  112. package/ante/fee.go +0 -96
  113. package/proto/agoric/lien/genesis.proto +0 -25
  114. package/proto/agoric/lien/lien.proto +0 -25
  115. package/x/lien/alias.go +0 -17
  116. package/x/lien/genesis.go +0 -58
  117. package/x/lien/genesis_test.go +0 -101
  118. package/x/lien/keeper/account.go +0 -290
  119. package/x/lien/keeper/keeper.go +0 -255
  120. package/x/lien/keeper/keeper_test.go +0 -623
  121. package/x/lien/lien.go +0 -205
  122. package/x/lien/lien_test.go +0 -533
  123. package/x/lien/module.go +0 -115
  124. package/x/lien/spec/01_concepts.md +0 -146
  125. package/x/lien/spec/02_messages.md +0 -96
  126. package/x/lien/types/accountkeeper.go +0 -81
  127. package/x/lien/types/accountstate.go +0 -27
  128. package/x/lien/types/expected_keepers.go +0 -18
  129. package/x/lien/types/genesis.pb.go +0 -567
  130. package/x/lien/types/key.go +0 -25
  131. package/x/lien/types/lien.pb.go +0 -403
  132. package/x/vibc/ibc.go +0 -394
  133. /package/{src/index.cjs → index.cjs} +0 -0
@@ -0,0 +1,448 @@
1
+ package vtransfer_test
2
+
3
+ import (
4
+ "context"
5
+ "encoding/json"
6
+ "fmt"
7
+ "strconv"
8
+ "strings"
9
+ "testing"
10
+ "text/template"
11
+
12
+ app "github.com/Agoric/agoric-sdk/golang/cosmos/app"
13
+ "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
14
+ "github.com/cosmos/cosmos-sdk/store"
15
+ "github.com/stretchr/testify/suite"
16
+ "github.com/tendermint/tendermint/libs/log"
17
+ dbm "github.com/tendermint/tm-db"
18
+
19
+ swingsettesting "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/testing"
20
+ swingsettypes "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/types"
21
+ vibckeeper "github.com/Agoric/agoric-sdk/golang/cosmos/x/vibc/keeper"
22
+
23
+ "github.com/cosmos/cosmos-sdk/baseapp"
24
+ sdk "github.com/cosmos/cosmos-sdk/types"
25
+ authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
26
+ banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
27
+ ibctransfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
28
+ channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
29
+ ibctesting "github.com/cosmos/ibc-go/v6/testing"
30
+ "github.com/cosmos/ibc-go/v6/testing/simapp"
31
+ tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
32
+ )
33
+
34
+ type IntegrationTestSuite struct {
35
+ suite.Suite
36
+
37
+ coordinator *ibctesting.Coordinator
38
+
39
+ // testing chains used for convenience and readability
40
+ chainA *ibctesting.TestChain
41
+ chainB *ibctesting.TestChain
42
+
43
+ queryClient ibctransfertypes.QueryClient
44
+ }
45
+
46
+ // interBlockCacheOpt returns a BaseApp option function that sets the persistent
47
+ // inter-block write-through cache.
48
+ func interBlockCacheOpt() func(*baseapp.BaseApp) {
49
+ return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager())
50
+ }
51
+
52
+ type TestingAppMaker func() (ibctesting.TestingApp, map[string]json.RawMessage)
53
+
54
+ // Each instance has unique IBC genesis state with deterministic
55
+ // client/connection/channel initial sequence numbers
56
+ // (respectively, X000/X010/X050 where X is the zero-based
57
+ // instance number plus one, such that instance 0 uses
58
+ // 1000/1010/1050, instance 1 uses 2000/2010/2050, etc.).
59
+ func computeSequences(instance int) (clientSeq, connectionSeq, channelSeq int) {
60
+ baseSequence := 1000 * (instance + 1)
61
+ return baseSequence, baseSequence + 10, baseSequence + 50
62
+ }
63
+
64
+ func SetupAgoricTestingApp(instance int) TestingAppMaker {
65
+ return func() (ibctesting.TestingApp, map[string]json.RawMessage) {
66
+ db := dbm.NewMemDB()
67
+ encCdc := app.MakeEncodingConfig()
68
+ mockController := func(ctx context.Context, needReply bool, jsonRequest string) (jsonReply string, err error) {
69
+ // fmt.Printf("controller %d got: %s\n", instance, jsonRequest)
70
+
71
+ // Check that the message is at least JSON.
72
+ var jsonAny interface{}
73
+ if err := json.Unmarshal([]byte(jsonRequest), &jsonAny); err != nil {
74
+ panic(err)
75
+ }
76
+
77
+ // Our reply must be truthy or else we don't make it past AG_COSMOS_INIT.
78
+ jsonReply = `true`
79
+ return jsonReply, nil
80
+ }
81
+ appd := app.NewAgoricApp(mockController, vm.NewAgdServer(), log.TestingLogger(), db, nil,
82
+ true, map[int64]bool{}, app.DefaultNodeHome, simapp.FlagPeriodValue, encCdc, simapp.EmptyAppOptions{}, interBlockCacheOpt())
83
+ genesisState := app.NewDefaultGenesisState()
84
+
85
+ t := template.Must(template.New("").Parse(`
86
+ {
87
+ "client_genesis": {
88
+ "clients": [],
89
+ "clients_consensus": [],
90
+ "clients_metadata": [],
91
+ "create_localhost": false,
92
+ "next_client_sequence": "{{.nextClientSequence}}",
93
+ "params": {
94
+ "allowed_clients": [
95
+ "06-solomachine",
96
+ "07-tendermint"
97
+ ]
98
+ }
99
+ },
100
+ "connection_genesis": {
101
+ "client_connection_paths": [],
102
+ "connections": [],
103
+ "next_connection_sequence": "{{.nextConnectionSequence}}",
104
+ "params": {
105
+ "max_expected_time_per_block": "30000000000"
106
+ }
107
+ },
108
+ "channel_genesis": {
109
+ "ack_sequences": [],
110
+ "acknowledgements": [],
111
+ "channels": [],
112
+ "commitments": [],
113
+ "next_channel_sequence": "{{.nextChannelSequence}}",
114
+ "receipts": [],
115
+ "recv_sequences": [],
116
+ "send_sequences": []
117
+ }
118
+ }`))
119
+ var result strings.Builder
120
+ clientSeq, connectionSeq, channelSeq := computeSequences(instance)
121
+ err := t.Execute(&result, map[string]any{
122
+ "nextClientSequence": clientSeq,
123
+ "nextConnectionSequence": connectionSeq,
124
+ "nextChannelSequence": channelSeq,
125
+ })
126
+ if err != nil {
127
+ panic(err)
128
+ }
129
+ genesisState["ibc"] = json.RawMessage(result.String())
130
+ return appd, genesisState
131
+ }
132
+ }
133
+
134
+ func TestKeeperTestSuite(t *testing.T) {
135
+ suite.Run(t, new(IntegrationTestSuite))
136
+ }
137
+
138
+ // SetupTest initializes an IntegrationTestSuite with two similar chains, a
139
+ // shared coordinator, and a query client that happens to point at chainA.
140
+ func (s *IntegrationTestSuite) SetupTest() {
141
+ s.coordinator = ibctesting.NewCoordinator(s.T(), 0)
142
+
143
+ chains := make(map[string]*ibctesting.TestChain)
144
+ for i := 0; i < 2; i++ {
145
+ ibctesting.DefaultTestingAppInit = SetupAgoricTestingApp(i)
146
+
147
+ chainID := ibctesting.GetChainID(i)
148
+ chain := ibctesting.NewTestChain(s.T(), s.coordinator, chainID)
149
+
150
+ balance := banktypes.Balance{
151
+ Address: chain.SenderAccount.GetAddress().String(),
152
+ Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
153
+ }
154
+
155
+ // create application and override files in the IBC test chain
156
+ app := ibctesting.SetupWithGenesisValSet(
157
+ s.T(),
158
+ chain.Vals,
159
+ []authtypes.GenesisAccount{
160
+ chain.SenderAccount.(authtypes.GenesisAccount),
161
+ },
162
+ chainID,
163
+ sdk.DefaultPowerReduction,
164
+ balance,
165
+ )
166
+
167
+ chain.App = app
168
+ chain.QueryServer = app.GetIBCKeeper()
169
+ chain.TxConfig = app.GetTxConfig()
170
+ chain.Codec = app.AppCodec()
171
+ chain.CurrentHeader = tmproto.Header{
172
+ ChainID: chainID,
173
+ Height: 1,
174
+ Time: s.coordinator.CurrentTime.UTC(),
175
+ }
176
+
177
+ s.coordinator.CommitBlock(chain)
178
+
179
+ chains[chainID] = chain
180
+ }
181
+
182
+ s.coordinator.Chains = chains
183
+ s.chainA = s.coordinator.GetChain(ibctesting.GetChainID(0))
184
+ s.chainB = s.coordinator.GetChain(ibctesting.GetChainID(1))
185
+
186
+ agoricApp := s.GetApp(s.chainA)
187
+
188
+ queryHelper := baseapp.NewQueryServerTestHelper(s.chainA.GetContext(), agoricApp.InterfaceRegistry())
189
+ ibctransfertypes.RegisterQueryServer(queryHelper, agoricApp.TransferKeeper)
190
+ s.queryClient = ibctransfertypes.NewQueryClient(queryHelper)
191
+ }
192
+
193
+ func (s *IntegrationTestSuite) GetApp(chain *ibctesting.TestChain) *app.GaiaApp {
194
+ app, ok := chain.App.(*app.GaiaApp)
195
+ if !ok {
196
+ panic("not agoric app")
197
+ }
198
+
199
+ return app
200
+ }
201
+
202
+ func (s *IntegrationTestSuite) NewTransferPath() *ibctesting.Path {
203
+ path := ibctesting.NewPath(s.chainA, s.chainB)
204
+ _, _, channelASeq := computeSequences(0)
205
+ _, _, channelBSeq := computeSequences(1)
206
+ path.EndpointA.ChannelID = fmt.Sprintf("channel-%d", channelASeq)
207
+ path.EndpointB.ChannelID = fmt.Sprintf("channel-%d", channelBSeq)
208
+ path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort
209
+ path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort
210
+ path.EndpointA.ChannelConfig.Version = "ics20-1"
211
+ path.EndpointB.ChannelConfig.Version = "ics20-1"
212
+
213
+ s.coordinator.Setup(path)
214
+
215
+ s.coordinator.CommitBlock(s.chainA, s.chainB)
216
+
217
+ return path
218
+ }
219
+
220
+ func (s *IntegrationTestSuite) assertActionQueue(chain *ibctesting.TestChain, expectedRecords []swingsettypes.InboundQueueRecord) {
221
+ actualRecords, err := swingsettesting.GetActionQueueRecords(
222
+ s.T(),
223
+ chain.GetContext(),
224
+ s.GetApp(chain).SwingSetKeeper,
225
+ )
226
+ s.Require().NoError(err)
227
+
228
+ exLen := len(expectedRecords)
229
+ recLen := len(actualRecords)
230
+ maxLen := exLen
231
+ if recLen > maxLen {
232
+ maxLen = recLen
233
+ }
234
+ for i := 0; i < maxLen; i++ {
235
+ if i >= recLen {
236
+ s.Fail("expected record", "%d: %q", i, expectedRecords[i])
237
+ continue
238
+ } else if i >= exLen {
239
+ s.Fail("unexpected record", "%d: %v", i, actualRecords[i])
240
+ continue
241
+ }
242
+ expi := expectedRecords[i]
243
+ var reci swingsettypes.InboundQueueRecord
244
+ err := json.Unmarshal([]byte(actualRecords[i]), &reci)
245
+ s.Require().NoError(err)
246
+
247
+ if expi.Context.TxHash == "" {
248
+ // Default the TxHash.
249
+ expi.Context.TxHash = reci.Context.TxHash
250
+ }
251
+
252
+ // Comparing unmarshaled values with an inlined object fails.
253
+ // So we marshal the expected object and compare the strings.
254
+ expbz, err := json.Marshal(expi)
255
+ s.Require().NoError(err)
256
+
257
+ s.Equal(string(expbz), actualRecords[i])
258
+ }
259
+ }
260
+
261
+ func (s *IntegrationTestSuite) RegisterBridgeTarget(chain *ibctesting.TestChain, target string) {
262
+ agdServer := s.GetApp(chain).AgdServer
263
+ defer agdServer.SetControllerContext(chain.GetContext())()
264
+ var reply string
265
+ err := agdServer.ReceiveMessage(
266
+ &vm.Message{
267
+ Port: agdServer.GetPort("vtransfer"),
268
+ Data: `{"type":"BRIDGE_TARGET_REGISTER","target":"` + target + `"}`,
269
+ },
270
+ &reply,
271
+ )
272
+ s.Require().NoError(err)
273
+ s.Require().Equal(reply, "true")
274
+ }
275
+
276
+ func (s *IntegrationTestSuite) TransferFromSourceChain(
277
+ srcChain *ibctesting.TestChain,
278
+ data ibctransfertypes.FungibleTokenPacketData,
279
+ src, dst *ibctesting.Endpoint,
280
+ ) (channeltypes.Packet, error) {
281
+ tokenAmt, ok := sdk.NewIntFromString(data.Amount)
282
+ s.Require().True(ok)
283
+
284
+ timeoutHeight := srcChain.GetTimeoutHeight()
285
+ packet := channeltypes.NewPacket(data.GetBytes(), 0, src.ChannelConfig.PortID, src.ChannelID, dst.ChannelConfig.PortID, dst.ChannelID, timeoutHeight, 0)
286
+
287
+ // send a transfer packet from src
288
+ imt := ibctransfertypes.MsgTransfer{
289
+ SourcePort: packet.SourcePort,
290
+ SourceChannel: packet.SourceChannel,
291
+ Memo: data.Memo,
292
+ Token: sdk.NewCoin(data.Denom, tokenAmt),
293
+ Sender: data.Sender,
294
+ Receiver: data.Receiver,
295
+ TimeoutHeight: packet.TimeoutHeight,
296
+ TimeoutTimestamp: packet.TimeoutTimestamp,
297
+ }
298
+ imr, err := s.GetApp(srcChain).TransferKeeper.Transfer(srcChain.GetContext(), &imt)
299
+ s.Require().NoError(err)
300
+ packet.Sequence = imr.Sequence
301
+
302
+ return packet, nil
303
+ }
304
+
305
+ func (s *IntegrationTestSuite) mintToAddress(chain *ibctesting.TestChain, addr sdk.AccAddress, denom, amount string) {
306
+ app := s.GetApp(chain)
307
+ tokenAmt, ok := sdk.NewIntFromString(amount)
308
+ s.Require().True(ok)
309
+ intAmt, err := strconv.ParseInt(amount, 10, 64)
310
+ s.Require().NoError(err)
311
+ coins := sdk.NewCoins(sdk.NewCoin(denom, tokenAmt.Mul(sdk.NewInt(intAmt))))
312
+ err = app.BankKeeper.MintCoins(chain.GetContext(), ibctransfertypes.ModuleName, coins)
313
+ s.Require().NoError(err)
314
+ err = app.BankKeeper.SendCoinsFromModuleToAccount(chain.GetContext(), ibctransfertypes.ModuleName, addr, coins)
315
+ s.Require().NoError(err)
316
+
317
+ // Verify success.
318
+ balances := app.BankKeeper.GetAllBalances(chain.GetContext(), addr)
319
+ s.Require().Equal(coins[0], balances[1])
320
+ }
321
+
322
+ // TestTransferFromAgdToAgd relays an IBC transfer initiated from a chain A to a
323
+ // chain B, and relays the chain B's resulting acknowledgement in return. It
324
+ // verifies that the source and destination accounts' bridge targets are called
325
+ // by inspecting their resulting actionQueue records. By committing blocks
326
+ // between actions, the test verifies that the VM results are permitted to be
327
+ // async across blocks.
328
+ func (s *IntegrationTestSuite) TestTransferFromAgdToAgd() {
329
+ path := s.NewTransferPath()
330
+ s.Require().Equal(path.EndpointA.ChannelID, "channel-1050")
331
+
332
+ s.Run("TransferFromAgdToAgd", func() {
333
+ // create a transfer packet's data contents
334
+ transferData := ibctransfertypes.NewFungibleTokenPacketData(
335
+ "uosmo",
336
+ "1000000",
337
+ s.chainA.SenderAccount.GetAddress().String(),
338
+ s.chainB.SenderAccounts[1].SenderAccount.GetAddress().String(),
339
+ `"This is a JSON memo"`,
340
+ )
341
+
342
+ // Register the sender and receiver as bridge targets on their specific
343
+ // chain.
344
+ s.RegisterBridgeTarget(s.chainA, transferData.Sender)
345
+ s.RegisterBridgeTarget(s.chainB, transferData.Receiver)
346
+
347
+ s.mintToAddress(s.chainA, s.chainA.SenderAccount.GetAddress(), transferData.Denom, transferData.Amount)
348
+
349
+ // Initiate the transfer
350
+ packet, err := s.TransferFromSourceChain(s.chainA, transferData, path.EndpointA, path.EndpointB)
351
+ s.Require().NoError(err)
352
+
353
+ // Relay the packet
354
+ s.coordinator.CommitBlock(s.chainA)
355
+ err = path.EndpointB.UpdateClient()
356
+ s.Require().NoError(err)
357
+ s.coordinator.CommitBlock(s.chainB)
358
+
359
+ writeAcknowledgementHeight := s.chainB.CurrentHeader.Height
360
+ writeAcknowledgementTime := s.chainB.CurrentHeader.Time.Unix()
361
+
362
+ err = path.EndpointB.RecvPacket(packet)
363
+ s.Require().NoError(err)
364
+
365
+ // Create a success ack as defined by ICS20.
366
+ ack := channeltypes.NewResultAcknowledgement([]byte{1})
367
+ // Create a different ack to show that a contract can change it.
368
+ contractAck := channeltypes.NewResultAcknowledgement([]byte{5})
369
+
370
+ s.coordinator.CommitBlock(s.chainA, s.chainB)
371
+
372
+ {
373
+ expectedRecords := []swingsettypes.InboundQueueRecord{}
374
+ s.assertActionQueue(s.chainA, expectedRecords)
375
+ }
376
+
377
+ {
378
+ expectedRecords := []swingsettypes.InboundQueueRecord{
379
+ {
380
+ Action: &vibckeeper.WriteAcknowledgementEvent{
381
+ ActionHeader: &vm.ActionHeader{
382
+ Type: "VTRANSFER_IBC_EVENT",
383
+ BlockHeight: writeAcknowledgementHeight,
384
+ BlockTime: writeAcknowledgementTime,
385
+ },
386
+ Event: "writeAcknowledgement",
387
+ Target: transferData.Receiver,
388
+ Packet: packet,
389
+ Acknowledgement: ack.Acknowledgement(),
390
+ },
391
+ Context: swingsettypes.ActionContext{
392
+ BlockHeight: writeAcknowledgementHeight,
393
+ // TxHash is filled in below
394
+ MsgIdx: 0,
395
+ },
396
+ },
397
+ }
398
+
399
+ s.assertActionQueue(s.chainB, expectedRecords)
400
+
401
+ // write out a different acknowledgement from the "contract", one block later.
402
+ s.coordinator.CommitBlock(s.chainB)
403
+ err = s.GetApp(s.chainB).VtransferKeeper.ReceiveWriteAcknowledgement(s.chainB.GetContext(), packet, contractAck)
404
+ s.Require().NoError(err)
405
+
406
+ s.coordinator.CommitBlock(s.chainB)
407
+ }
408
+
409
+ // Update Client
410
+ err = path.EndpointA.UpdateClient()
411
+ s.Require().NoError(err)
412
+
413
+ acknowledgementHeight := s.chainA.CurrentHeader.Height
414
+ acknowledgementTime := s.chainA.CurrentHeader.Time.Unix()
415
+
416
+ // Prove the packet's acknowledgement.
417
+ err = path.EndpointA.AcknowledgePacket(packet, contractAck.Acknowledgement())
418
+ s.Require().NoError(err)
419
+
420
+ s.coordinator.CommitBlock(s.chainA, s.chainB)
421
+
422
+ {
423
+ expectedRecords := []swingsettypes.InboundQueueRecord{
424
+ {
425
+ Action: &vibckeeper.WriteAcknowledgementEvent{
426
+ ActionHeader: &vm.ActionHeader{
427
+ Type: "VTRANSFER_IBC_EVENT",
428
+ BlockHeight: acknowledgementHeight,
429
+ BlockTime: acknowledgementTime,
430
+ },
431
+ Event: "acknowledgementPacket",
432
+ Target: transferData.Sender,
433
+ Packet: packet,
434
+ Acknowledgement: contractAck.Acknowledgement(),
435
+ Relayer: s.chainA.SenderAccount.GetAddress(),
436
+ },
437
+ Context: swingsettypes.ActionContext{
438
+ BlockHeight: acknowledgementHeight,
439
+ // TxHash is filled in below
440
+ MsgIdx: 0,
441
+ },
442
+ },
443
+ }
444
+
445
+ s.assertActionQueue(s.chainA, expectedRecords)
446
+ }
447
+ })
448
+ }