@agoric/cosmos 0.35.0-u18.4 → 0.35.0-u18a.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 (39) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/ante/inbound_test.go +2 -2
  3. package/app/app.go +26 -9
  4. package/app/upgrade.go +47 -134
  5. package/daemon/cmd/root.go +48 -15
  6. package/git-revision.txt +1 -1
  7. package/go.mod +82 -71
  8. package/go.sum +200 -167
  9. package/package.json +2 -2
  10. package/proto/agoric/swingset/swingset.proto +25 -0
  11. package/proto/agoric/vbank/vbank.proto +7 -0
  12. package/types/address_hooks.go +242 -0
  13. package/types/address_hooks_test.go +221 -0
  14. package/x/swingset/genesis.go +99 -21
  15. package/x/swingset/keeper/keeper.go +16 -7
  16. package/x/swingset/module.go +17 -2
  17. package/x/swingset/testing/queue.go +8 -0
  18. package/x/swingset/types/default-params.go +31 -5
  19. package/x/swingset/types/expected_keepers.go +2 -2
  20. package/x/swingset/types/msgs.go +34 -12
  21. package/x/swingset/types/params.go +53 -43
  22. package/x/swingset/types/params_test.go +75 -9
  23. package/x/swingset/types/swingset.pb.go +386 -56
  24. package/x/vbank/README.md +6 -1
  25. package/x/vbank/keeper/keeper.go +4 -9
  26. package/x/vbank/keeper/migrations.go +30 -0
  27. package/x/vbank/module.go +8 -2
  28. package/x/vbank/types/params.go +43 -2
  29. package/x/vbank/types/vbank.pb.go +105 -36
  30. package/x/vbank/vbank_test.go +12 -7
  31. package/x/vibc/keeper/keeper.go +2 -5
  32. package/x/vibc/keeper/triggers.go +3 -6
  33. package/x/vibc/types/receiver.go +11 -5
  34. package/x/vstorage/testing/queue.go +10 -3
  35. package/x/vtransfer/ibc_middleware.go +5 -1
  36. package/x/vtransfer/ibc_middleware_test.go +511 -145
  37. package/x/vtransfer/keeper/keeper.go +215 -50
  38. package/x/vtransfer/types/genesis.pb.go +1 -0
  39. package/x/vtransfer/utils_test.go +111 -0
@@ -1,8 +1,10 @@
1
1
  package keeper
2
2
 
3
3
  import (
4
+ "bytes"
4
5
  "context"
5
6
  "encoding/json"
7
+ "fmt"
6
8
 
7
9
  "github.com/cosmos/cosmos-sdk/codec"
8
10
  "github.com/cosmos/cosmos-sdk/store/prefix"
@@ -13,10 +15,12 @@ import (
13
15
  capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
14
16
  capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
15
17
 
18
+ "github.com/Agoric/agoric-sdk/golang/cosmos/types"
16
19
  "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
17
20
  "github.com/Agoric/agoric-sdk/golang/cosmos/x/vibc"
18
21
  vibctypes "github.com/Agoric/agoric-sdk/golang/cosmos/x/vibc/types"
19
- transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
22
+
23
+ clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
20
24
  channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
21
25
  porttypes "github.com/cosmos/ibc-go/v6/modules/core/05-port/types"
22
26
  host "github.com/cosmos/ibc-go/v6/modules/core/24-host"
@@ -24,6 +28,7 @@ import (
24
28
  )
25
29
 
26
30
  var _ porttypes.ICS4Wrapper = (*Keeper)(nil)
31
+ var _ porttypes.ICS4Wrapper = (*ics4Wrapper)(nil)
27
32
  var _ vibctypes.ReceiverImpl = (*Keeper)(nil)
28
33
  var _ vm.PortHandler = (*Keeper)(nil)
29
34
 
@@ -32,6 +37,7 @@ var _ vm.PortHandler = (*Keeper)(nil)
32
37
  // the address, and its corresponding value is a non-empty but otherwise irrelevant
33
38
  // sentinel.
34
39
  const (
40
+ packetDataStoreKeyPrefix = "originalData/"
35
41
  watchedAddressStoreKeyPrefix = "watchedAddress/"
36
42
  watchedAddressSentinel = "y"
37
43
  )
@@ -52,6 +58,84 @@ type Keeper struct {
52
58
  cdc codec.Codec
53
59
 
54
60
  vibcModule porttypes.IBCModule
61
+
62
+ // This is a pointer so that copies of the Keeper struct share the same mutable debug options.
63
+ debug *KeeperDebugOptions
64
+ }
65
+
66
+ type PacketDataOverrider func(ctx sdk.Context, cdc codec.Codec, data []byte) ([]byte, error)
67
+ type KeeperDebugOptions struct {
68
+ OverridePacket PacketDataOverrider
69
+ DoNotStore bool
70
+ }
71
+
72
+ type ics4Wrapper struct {
73
+ porttypes.ICS4Wrapper
74
+ k Keeper
75
+ }
76
+
77
+ func (i4 *ics4Wrapper) SendPacket(
78
+ ctx sdk.Context,
79
+ chanCap *capabilitytypes.Capability,
80
+ sourcePort string,
81
+ sourceChannel string,
82
+ timeoutHeight clienttypes.Height,
83
+ timeoutTimestamp uint64,
84
+ data []byte,
85
+ ) (sequence uint64, err error) {
86
+ // Permute the packet data when testing.
87
+ overridePacket := i4.k.debug.OverridePacket
88
+ if overridePacket != nil {
89
+ if data, err = overridePacket(ctx, i4.k.cdc, data); err != nil {
90
+ return sequence, err
91
+ }
92
+ }
93
+
94
+ var strippedData []byte
95
+ _, err = types.ExtractBaseAddressFromData(i4.k.cdc, data, types.RoleSender, &strippedData)
96
+ if err != nil {
97
+ return sequence, err
98
+ }
99
+
100
+ // Send the stripped data to the next wrapper.
101
+ sequence, err = i4.ICS4Wrapper.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, strippedData)
102
+ if err != nil {
103
+ return sequence, err
104
+ }
105
+
106
+ // Store the original data if it is hooked for later retrieval by middleware.
107
+ if !i4.k.debug.DoNotStore && !bytes.Equal(strippedData, data) {
108
+ packetStore, packetKey := i4.k.PacketStore(ctx, types.PacketSrc, sourcePort, sourceChannel, sequence)
109
+ packetStore.Set(packetKey, data)
110
+ }
111
+
112
+ return sequence, nil
113
+ }
114
+
115
+ func (i4 *ics4Wrapper) WriteAcknowledgement(
116
+ ctx sdk.Context,
117
+ chanCap *capabilitytypes.Capability,
118
+ packet ibcexported.PacketI,
119
+ ack ibcexported.Acknowledgement,
120
+ ) error {
121
+ origPacket := channeltypes.NewPacket(
122
+ packet.GetData(), packet.GetSequence(),
123
+ packet.GetSourcePort(), packet.GetSourceChannel(),
124
+ packet.GetDestPort(), packet.GetDestChannel(),
125
+ clienttypes.MustParseHeight(packet.GetTimeoutHeight().String()),
126
+ packet.GetTimeoutTimestamp(),
127
+ )
128
+ packetStore, packetKey := i4.k.PacketStoreFromOrigin(ctx, types.PacketDst, packet)
129
+ if packetStore.Has(packetKey) {
130
+ origPacket.Data = packetStore.Get(packetKey)
131
+ packetStore.Delete(packetKey)
132
+ }
133
+ return i4.ICS4Wrapper.WriteAcknowledgement(ctx, chanCap, origPacket, ack)
134
+ }
135
+
136
+ // NewICS4Wrapper creates a new ICS4Wrapper instance
137
+ func NewICS4Wrapper(k Keeper, down porttypes.ICS4Wrapper) *ics4Wrapper {
138
+ return &ics4Wrapper{k: k, ICS4Wrapper: down}
55
139
  }
56
140
 
57
141
  // NewKeeper creates a new vtransfer Keeper instance
@@ -67,15 +151,26 @@ func NewKeeper(
67
151
  // This vibcKeeper is used to send notifications from the vtransfer middleware
68
152
  // to the VM.
69
153
  vibcKeeper := prototypeVibcKeeper.WithScope(nil, scopedTransferKeeper, wrappedPushAction)
70
- return Keeper{
71
- ICS4Wrapper: vibcKeeper,
154
+ k := Keeper{
72
155
  ReceiverImpl: vibcKeeper,
73
156
 
74
157
  vibcKeeper: vibcKeeper,
75
158
  key: key,
76
159
  vibcModule: vibc.NewIBCModule(vibcKeeper),
77
160
  cdc: cdc,
161
+
162
+ debug: &KeeperDebugOptions{
163
+ OverridePacket: nil,
164
+ DoNotStore: false,
165
+ },
78
166
  }
167
+ k.ICS4Wrapper = NewICS4Wrapper(k, vibcKeeper)
168
+ return k
169
+ }
170
+
171
+ func (k Keeper) SetDebugging(doStore bool, overridePacket PacketDataOverrider) {
172
+ k.debug.DoNotStore = !doStore
173
+ k.debug.OverridePacket = overridePacket
79
174
  }
80
175
 
81
176
  // wrapActionPusher wraps an ActionPusher to prefix the action type with
@@ -101,17 +196,54 @@ func (k Keeper) GetReceiverImpl() vibctypes.ReceiverImpl {
101
196
  return k
102
197
  }
103
198
 
199
+ // Replicated from the 24-host ibc-go package, since it wasn't exported from there.
200
+ func channelPath(portID, channelID string) string {
201
+ return fmt.Sprintf("%s/%s/%s/%s", host.KeyPortPrefix, portID, host.KeyChannelPrefix, channelID)
202
+ }
203
+
204
+ // Replicated from the 24-host ibc-go package, since it wasn't exported from there.
205
+ func sequencePath(sequence uint64) string {
206
+ return fmt.Sprintf("%s/%d", host.KeySequencePrefix, sequence)
207
+ }
208
+
209
+ // PacketStore returns a new KVStore for storing packet data, and a key for
210
+ // that store. The KVStore is divided into src or dst PacketOrigins because we
211
+ // need to record separate data for packets travelling in each direction.
212
+ func (k Keeper) PacketStore(ctx sdk.Context, ourOrigin types.PacketOrigin, ourPort string, ourChannel string, sequence uint64) (storetypes.KVStore, []byte) {
213
+ key := fmt.Sprintf("%s/%s/%s", ourOrigin, channelPath(ourPort, ourChannel), sequencePath(sequence))
214
+ packetKey := []byte(key)
215
+ return prefix.NewStore(ctx.KVStore(k.key), []byte(packetDataStoreKeyPrefix)), packetKey
216
+ }
217
+
218
+ func (k Keeper) PacketStoreFromOrigin(ctx sdk.Context, ourOrigin types.PacketOrigin, packet ibcexported.PacketI) (storetypes.KVStore, []byte) {
219
+ var ourPort, ourChannel string
220
+
221
+ switch ourOrigin {
222
+ case types.PacketSrc:
223
+ ourPort = packet.GetSourcePort()
224
+ ourChannel = packet.GetSourceChannel()
225
+ case types.PacketDst:
226
+ ourPort = packet.GetDestPort()
227
+ ourChannel = packet.GetDestChannel()
228
+ default:
229
+ panic("unknown packet origin " + ourOrigin)
230
+ }
231
+
232
+ return k.PacketStore(ctx, ourOrigin, ourPort, ourChannel, packet.GetSequence())
233
+ }
234
+
104
235
  // InterceptOnRecvPacket runs the ibcModule and eventually acknowledges a packet.
105
236
  // Many error acknowledgments are sent synchronously, but most cases instead return nil
106
237
  // to tell the IBC system that acknowledgment is async (i.e., that WriteAcknowledgement
107
238
  // will be called later, after the VM has dealt with the packet).
108
239
  func (k Keeper) InterceptOnRecvPacket(ctx sdk.Context, ibcModule porttypes.IBCModule, packet channeltypes.Packet, relayer sdk.AccAddress) ibcexported.Acknowledgement {
109
- ack := ibcModule.OnRecvPacket(ctx, packet, relayer)
110
-
111
- if ack == nil {
112
- // Already declared to be an async ack.
113
- return nil
240
+ // Pass every (stripped-receiver) inbound packet to the wrapped IBC module.
241
+ var strippedPacket channeltypes.Packet
242
+ _, err := types.ExtractBaseAddressFromPacket(k.cdc, packet, types.RoleReceiver, &strippedPacket)
243
+ if err != nil {
244
+ return channeltypes.NewErrorAcknowledgement(err)
114
245
  }
246
+
115
247
  portID := packet.GetDestPort()
116
248
  channelID := packet.GetDestChannel()
117
249
  capName := host.ChannelCapabilityPath(portID, channelID)
@@ -120,11 +252,21 @@ func (k Keeper) InterceptOnRecvPacket(ctx sdk.Context, ibcModule porttypes.IBCMo
120
252
  err := sdkerrors.Wrapf(channeltypes.ErrChannelCapabilityNotFound, "could not retrieve channel capability at: %s", capName)
121
253
  return channeltypes.NewErrorAcknowledgement(err)
122
254
  }
123
- // Give the VM a chance to write (or override) the ack.
124
- if err := k.InterceptWriteAcknowledgement(ctx, chanCap, packet, ack); err != nil {
125
- return channeltypes.NewErrorAcknowledgement(err)
255
+
256
+ if !k.debug.DoNotStore && !bytes.Equal(strippedPacket.GetData(), packet.GetData()) {
257
+ packetStore, packetKey := k.PacketStore(ctx, types.PacketDst, portID, channelID, packet.GetSequence())
258
+ packetStore.Set(packetKey, packet.GetData())
126
259
  }
127
- return nil
260
+
261
+ ack := ibcModule.OnRecvPacket(ctx, strippedPacket, relayer)
262
+ if ack == nil {
263
+ // Already declared to be an async ack. Will be cleaned up by ics4Wrapper.WriteAcknowledgement.
264
+ return nil
265
+ }
266
+
267
+ // Give the VM a chance to write (or override) the ack.
268
+ syncAck, _ := k.InterceptWriteAcknowledgement(ctx, chanCap, packet, ack)
269
+ return syncAck
128
270
  }
129
271
 
130
272
  // InterceptOnAcknowledgementPacket checks to see if the packet sender is a
@@ -136,17 +278,27 @@ func (k Keeper) InterceptOnAcknowledgementPacket(
136
278
  acknowledgement []byte,
137
279
  relayer sdk.AccAddress,
138
280
  ) error {
139
- // Pass every acknowledgement to the wrapped IBC module.
281
+ baseSender, err := types.ExtractBaseAddressFromData(k.cdc, packet.GetData(), types.RoleSender, nil)
282
+ if err != nil {
283
+ return err
284
+ }
285
+
286
+ origPacket := packet
287
+ packetStore, packetKey := k.PacketStoreFromOrigin(ctx, types.PacketSrc, packet)
288
+ if packetStore.Has(packetKey) {
289
+ origPacket.Data = packetStore.Get(packetKey)
290
+ packetStore.Delete(packetKey)
291
+ }
292
+
140
293
  modErr := ibcModule.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer)
141
294
 
142
- // If the sender is not a targeted account, we're done.
143
- sender, _, err := k.parseTransfer(ctx, packet)
144
- if err != nil || sender == "" {
295
+ // If the sender is not a watched account, we're done.
296
+ if !k.targetIsWatched(ctx, baseSender) {
145
297
  return modErr
146
298
  }
147
299
 
148
- // Trigger VM, regardless of errors in the ibcModule.
149
- vmErr := k.vibcKeeper.TriggerOnAcknowledgementPacket(ctx, sender, packet, acknowledgement, relayer)
300
+ // Trigger VM with the original packet, regardless of errors in the ibcModule.
301
+ vmErr := k.vibcKeeper.TriggerOnAcknowledgementPacket(ctx, baseSender, origPacket, acknowledgement, relayer)
150
302
 
151
303
  // Any error from the VM is trumped by one from the wrapped IBC module.
152
304
  if modErr != nil {
@@ -163,17 +315,28 @@ func (k Keeper) InterceptOnTimeoutPacket(
163
315
  packet channeltypes.Packet,
164
316
  relayer sdk.AccAddress,
165
317
  ) error {
166
- // Pass every timeout to the wrapped IBC module.
318
+ baseSender, err := types.ExtractBaseAddressFromData(k.cdc, packet.GetData(), types.RoleSender, nil)
319
+ if err != nil {
320
+ return err
321
+ }
322
+
323
+ origPacket := packet
324
+ packetStore, packetKey := k.PacketStoreFromOrigin(ctx, types.PacketSrc, packet)
325
+ if packetStore.Has(packetKey) {
326
+ origPacket.Data = packetStore.Get(packetKey)
327
+ packetStore.Delete(packetKey)
328
+ }
329
+
330
+ // Pass every stripped-sender timeout to the wrapped IBC module.
167
331
  modErr := ibcModule.OnTimeoutPacket(ctx, packet, relayer)
168
332
 
169
- // If the sender is not a targeted account, we're done.
170
- sender, _, err := k.parseTransfer(ctx, packet)
171
- if err != nil || sender == "" {
333
+ // If the sender is not a watched account, we're done.
334
+ if !k.targetIsWatched(ctx, baseSender) {
172
335
  return modErr
173
336
  }
174
337
 
175
- // Trigger VM, regardless of errors in the app.
176
- vmErr := k.vibcKeeper.TriggerOnTimeoutPacket(ctx, sender, packet, relayer)
338
+ // Trigger VM with the original packet, regardless of errors in the app.
339
+ vmErr := k.vibcKeeper.TriggerOnTimeoutPacket(ctx, baseSender, origPacket, relayer)
177
340
 
178
341
  // Any error from the VM is trumped by one from the wrapped IBC module.
179
342
  if modErr != nil {
@@ -184,43 +347,45 @@ func (k Keeper) InterceptOnTimeoutPacket(
184
347
 
185
348
  // InterceptWriteAcknowledgement checks to see if the packet's receiver is a
186
349
  // targeted account, and if so, delegates to the VM.
187
- func (k Keeper) InterceptWriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) error {
188
- _, receiver, err := k.parseTransfer(ctx, packet)
189
- if err != nil || receiver == "" {
190
- // We can't parse, but that means just to ack directly.
191
- return k.WriteAcknowledgement(ctx, chanCap, packet, ack)
350
+ func (k Keeper) InterceptWriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) (ibcexported.Acknowledgement, ibcexported.PacketI) {
351
+ // Get the base receiver from the packet, without computing a stripped packet.
352
+ baseReceiver, err := types.ExtractBaseAddressFromPacket(k.cdc, packet, types.RoleReceiver, nil)
353
+
354
+ origPacket := channeltypes.NewPacket(
355
+ packet.GetData(), packet.GetSequence(),
356
+ packet.GetSourcePort(), packet.GetSourceChannel(),
357
+ packet.GetDestPort(), packet.GetDestChannel(),
358
+ clienttypes.MustParseHeight(packet.GetTimeoutHeight().String()),
359
+ packet.GetTimeoutTimestamp(),
360
+ )
361
+ packetStore, packetKey := k.PacketStoreFromOrigin(ctx, types.PacketDst, packet)
362
+ if packetStore.Has(packetKey) {
363
+ origPacket.Data = packetStore.Get(packetKey)
364
+ packetStore.Delete(packetKey)
192
365
  }
193
366
 
194
- // Trigger VM
195
- if err = k.vibcKeeper.TriggerWriteAcknowledgement(ctx, receiver, packet, ack); err != nil {
367
+ if err != nil || !k.targetIsWatched(ctx, baseReceiver) {
368
+ // We can't parse, or not watching, but that means just to ack directly.
369
+ return ack, origPacket
370
+ }
371
+
372
+ // Trigger VM with the original packet.
373
+ if err = k.vibcKeeper.TriggerWriteAcknowledgement(ctx, baseReceiver, origPacket, ack); err != nil {
196
374
  errAck := channeltypes.NewErrorAcknowledgement(err)
197
- return k.WriteAcknowledgement(ctx, chanCap, packet, errAck)
375
+ return errAck, origPacket
198
376
  }
199
377
 
200
- return nil
378
+ // The VM has taken over the ack, so we return nil to indicate that the ack is async.
379
+ return nil, origPacket
201
380
  }
202
381
 
203
- // parseTransfer checks if a packet's sender and/or receiver are targeted accounts.
204
- func (k Keeper) parseTransfer(ctx sdk.Context, packet ibcexported.PacketI) (string, string, error) {
205
- var transferData transfertypes.FungibleTokenPacketData
206
- err := k.cdc.UnmarshalJSON(packet.GetData(), &transferData)
207
- if err != nil {
208
- return "", "", err
209
- }
210
-
211
- var sender string
212
- var receiver string
382
+ // targetIsWatched checks if a target address has been watched by the VM.
383
+ func (k Keeper) targetIsWatched(ctx sdk.Context, target string) bool {
213
384
  prefixStore := prefix.NewStore(
214
385
  ctx.KVStore(k.key),
215
386
  []byte(watchedAddressStoreKeyPrefix),
216
387
  )
217
- if prefixStore.Has([]byte(transferData.Sender)) {
218
- sender = transferData.Sender
219
- }
220
- if prefixStore.Has([]byte(transferData.Receiver)) {
221
- receiver = transferData.Receiver
222
- }
223
- return sender, receiver, nil
388
+ return prefixStore.Has([]byte(target))
224
389
  }
225
390
 
226
391
  // GetWatchedAdresses returns the watched addresses from the keeper as a slice
@@ -26,6 +26,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
26
26
 
27
27
  // The initial and exported module state.
28
28
  type GenesisState struct {
29
+ // The list of account addresses that are being watched by the VM.
29
30
  WatchedAddresses []github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,rep,name=watched_addresses,json=watchedAddresses,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"watched_addresses" yaml:"watched_addresses"`
30
31
  }
31
32
 
@@ -0,0 +1,111 @@
1
+ package vtransfer_test
2
+
3
+ import (
4
+ "fmt"
5
+ "strconv"
6
+
7
+ sdk "github.com/cosmos/cosmos-sdk/types"
8
+ clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
9
+ channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
10
+ host "github.com/cosmos/ibc-go/v6/modules/core/24-host"
11
+ ibctesting "github.com/cosmos/ibc-go/v6/testing"
12
+ )
13
+
14
+ // acknowledgePacketWithResult sends a MsgAcknowledgement to the channel associated with the endpoint.
15
+ // [AGORIC] Would be nice to create a new ibctesting.AcknowledgePacketWithResult
16
+ func acknowledgePacketWithResult(endpoint *ibctesting.Endpoint, packet channeltypes.Packet, ack []byte) (*sdk.Result, error) {
17
+ // get proof of acknowledgement on counterparty
18
+ packetKey := host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
19
+ proof, proofHeight := endpoint.Counterparty.QueryProof(packetKey)
20
+
21
+ ackMsg := channeltypes.NewMsgAcknowledgement(packet, ack, proof, proofHeight, endpoint.Chain.SenderAccount.GetAddress().String())
22
+
23
+ return endpoint.Chain.SendMsgs(ackMsg)
24
+ }
25
+
26
+ // ParseAckFromEvents parses events emitted from a MsgRecvPacket and returns the
27
+ // acknowledgement.
28
+ // [AGORIC] Signature taken from ibctesting.ParseAckFromEvents
29
+ func ParseAckFromEvents(events sdk.Events) ([]byte, error) {
30
+ return ParseAckFromFilteredEvents(events, channeltypes.EventTypeWriteAck)
31
+ }
32
+
33
+ // ParseAckFromFilteredEvents parses events emitted matching filteredType and returns the acknowledgement.
34
+ // [AGORIC] Would be nice to improve the implementation and upstream it
35
+ func ParseAckFromFilteredEvents(events sdk.Events, filteredType string) ([]byte, error) {
36
+ for _, ev := range events {
37
+ if ev.Type == filteredType {
38
+ for _, attr := range ev.Attributes {
39
+ if string(attr.Key) == channeltypes.AttributeKeyAck { //nolint:staticcheck // DEPRECATED
40
+ return attr.Value, nil
41
+ }
42
+ }
43
+ }
44
+ }
45
+ return nil, fmt.Errorf("acknowledgement event attribute not found")
46
+ }
47
+
48
+ // ParsePacketFromEvents parses the send_packet type events emitted by the IBC
49
+ // module and returns the packet.
50
+ // [AGORIC] Signature taken from ibctesting.ParsePacketFromEvents
51
+ func ParsePacketFromEvents(events sdk.Events) (channeltypes.Packet, error) {
52
+ return ParsePacketFromFilteredEvents(events, channeltypes.EventTypeSendPacket)
53
+ }
54
+
55
+ // ParsePacketFromFilteredEvents parses events emitted matching filteredType and returns the packet.
56
+ // [AGORIC] Would be nice to improve the implementation and upstream it
57
+ func ParsePacketFromFilteredEvents(events sdk.Events, filteredType string) (channeltypes.Packet, error) {
58
+ for _, ev := range events {
59
+ if ev.Type == filteredType {
60
+ packet := channeltypes.Packet{}
61
+ for _, attr := range ev.Attributes {
62
+ switch string(attr.Key) {
63
+ case channeltypes.AttributeKeyData: //nolint:staticcheck // DEPRECATED
64
+ packet.Data = attr.Value
65
+
66
+ case channeltypes.AttributeKeySequence:
67
+ seq, err := strconv.ParseUint(string(attr.Value), 10, 64)
68
+ if err != nil {
69
+ return channeltypes.Packet{}, err
70
+ }
71
+
72
+ packet.Sequence = seq
73
+
74
+ case channeltypes.AttributeKeySrcPort:
75
+ packet.SourcePort = string(attr.Value)
76
+
77
+ case channeltypes.AttributeKeySrcChannel:
78
+ packet.SourceChannel = string(attr.Value)
79
+
80
+ case channeltypes.AttributeKeyDstPort:
81
+ packet.DestinationPort = string(attr.Value)
82
+
83
+ case channeltypes.AttributeKeyDstChannel:
84
+ packet.DestinationChannel = string(attr.Value)
85
+
86
+ case channeltypes.AttributeKeyTimeoutHeight:
87
+ height, err := clienttypes.ParseHeight(string(attr.Value))
88
+ if err != nil {
89
+ return channeltypes.Packet{}, err
90
+ }
91
+
92
+ packet.TimeoutHeight = height
93
+
94
+ case channeltypes.AttributeKeyTimeoutTimestamp:
95
+ timestamp, err := strconv.ParseUint(string(attr.Value), 10, 64)
96
+ if err != nil {
97
+ return channeltypes.Packet{}, err
98
+ }
99
+
100
+ packet.TimeoutTimestamp = timestamp
101
+
102
+ default:
103
+ continue
104
+ }
105
+ }
106
+
107
+ return packet, nil
108
+ }
109
+ }
110
+ return channeltypes.Packet{}, fmt.Errorf("filtered event type %s not found", filteredType)
111
+ }