@agoric/cosmos 0.34.2-upgrade-19-dev-2a71f04.0 → 0.34.2-upgrade-20-dev-31be299.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.
package/app/upgrade.go CHANGED
@@ -3,9 +3,6 @@ package gaia
3
3
  import (
4
4
  "encoding/json"
5
5
  "fmt"
6
- "reflect"
7
- "strings"
8
- "text/template"
9
6
 
10
7
  "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
11
8
  swingsetkeeper "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
@@ -78,45 +75,30 @@ func isFirstTimeUpgradeOfThisVersion(app *GaiaApp, ctx sdk.Context) bool {
78
75
  return true
79
76
  }
80
77
 
81
- func buildProposalStepWithArgs(moduleName string, entrypoint string, extra any) (vm.CoreProposalStep, error) {
82
- t := template.Must(template.New("").Parse(`{
83
- "module": "{{.moduleName}}",
84
- "entrypoint": "{{.entrypoint}}",
85
- "args": {{.args}}
86
- }`))
87
-
88
- var args []byte
89
- var err error
90
- if extra == nil {
91
- // The specified entrypoint will be called with no extra arguments after powers.
92
- args = []byte(`[]`)
93
- } else if reflect.TypeOf(extra).Kind() == reflect.Map && reflect.TypeOf(extra).Key().Kind() == reflect.String {
94
- // The specified entrypoint will be called with this options argument after powers.
95
- args, err = json.Marshal([]any{extra})
96
- } else if reflect.TypeOf(extra).Kind() == reflect.Slice {
97
- // The specified entrypoint will be called with each of these arguments after powers.
98
- args, err = json.Marshal(extra)
99
- } else {
100
- return nil, fmt.Errorf("proposal extra must be nil, array, or string map, not %v", extra)
101
- }
78
+ // buildProposalStepWithArgs returns a CoreProposal representing invocation of
79
+ // the specified module-specific entry point with arbitrary Jsonable arguments
80
+ // provided after core-eval powers.
81
+ func buildProposalStepWithArgs(moduleName string, entrypoint string, args ...vm.Jsonable) (vm.CoreProposalStep, error) {
82
+ argsBz, err := json.Marshal(args)
102
83
  if err != nil {
103
84
  return nil, err
104
85
  }
105
86
 
106
- var result strings.Builder
107
- err = t.Execute(&result, map[string]any{
108
- "moduleName": moduleName,
109
- "entrypoint": entrypoint,
110
- "args": string(args),
111
- })
87
+ mea := struct {
88
+ Module string `json:"module"`
89
+ Entrypoint string `json:"entrypoint"`
90
+ Args json.RawMessage `json:"args"`
91
+ }{
92
+ Module: moduleName,
93
+ Entrypoint: entrypoint,
94
+ Args: argsBz,
95
+ }
96
+
97
+ jsonBz, err := json.Marshal(mea)
112
98
  if err != nil {
113
99
  return nil, err
114
100
  }
115
- jsonStr := result.String()
116
- jsonBz := []byte(jsonStr)
117
- if !json.Valid(jsonBz) {
118
- return nil, fmt.Errorf("invalid JSON: %s", jsonStr)
119
- }
101
+
120
102
  proposal := vm.ArbitraryCoreProposal{Json: jsonBz}
121
103
  return vm.CoreProposalStepForModules(proposal), nil
122
104
  }
@@ -139,14 +121,6 @@ func getVariantFromUpgradeName(upgradeName string) string {
139
121
  }
140
122
  }
141
123
 
142
- func upgradeMintHolderCoreProposal(targetUpgrade string) (vm.CoreProposalStep, error) {
143
- return buildProposalStepFromScript(targetUpgrade, "@agoric/builders/scripts/vats/upgrade-mintHolder.js")
144
- }
145
-
146
- func restartFeeDistributorCoreProposal(targetUpgrade string) (vm.CoreProposalStep, error) {
147
- return buildProposalStepFromScript(targetUpgrade, "@agoric/builders/scripts/inter-protocol/replace-feeDistributor-combo.js")
148
- }
149
-
150
124
  func buildProposalStepFromScript(targetUpgrade string, builderScript string) (vm.CoreProposalStep, error) {
151
125
  variant := getVariantFromUpgradeName(targetUpgrade)
152
126
 
@@ -157,8 +131,11 @@ func buildProposalStepFromScript(targetUpgrade string, builderScript string) (vm
157
131
  return buildProposalStepWithArgs(
158
132
  builderScript,
159
133
  "defaultProposalBuilder",
160
- map[string]any{
161
- "variant": variant,
134
+ // Map iteration is randomised; use an anonymous struct instead.
135
+ struct {
136
+ Variant string `json:"variant"`
137
+ }{
138
+ Variant: variant,
162
139
  },
163
140
  )
164
141
  }
@@ -183,6 +160,11 @@ func unreleasedUpgradeHandler(app *GaiaApp, targetUpgrade string) func(sdk.Conte
183
160
  // Each CoreProposalStep runs sequentially, and can be constructed from
184
161
  // one or more modules executing in parallel within the step.
185
162
  CoreProposalSteps = append(CoreProposalSteps,
163
+ // Orchestration vats: Fix memory leak in vow tools
164
+ // vat-ibc (included in orchestration): Accommodate string sequence numbers.
165
+ vm.CoreProposalStepForModules(
166
+ "@agoric/builders/scripts/vats/upgrade-orchestration.js",
167
+ ),
186
168
  // Register a new ZCF to be used for all future contract instances and upgrades
187
169
  vm.CoreProposalStepForModules(
188
170
  "@agoric/builders/scripts/vats/upgrade-zcf.js",
@@ -192,40 +174,11 @@ func unreleasedUpgradeHandler(app *GaiaApp, targetUpgrade string) func(sdk.Conte
192
174
  vm.CoreProposalStepForModules(
193
175
  "@agoric/builders/scripts/smart-wallet/build-wallet-factory2-upgrade.js",
194
176
  ),
195
- )
196
-
197
- upgradeMintHolderStep, err := upgradeMintHolderCoreProposal(targetUpgrade)
198
- if err != nil {
199
- return nil, err
200
- } else if upgradeMintHolderStep != nil {
201
- CoreProposalSteps = append(CoreProposalSteps, upgradeMintHolderStep)
202
- }
203
- restartFeeDistributorStep, err := restartFeeDistributorCoreProposal(targetUpgrade)
204
- if err != nil {
205
- return nil, err
206
- } else if restartFeeDistributorStep != nil {
207
- CoreProposalSteps = append(CoreProposalSteps, restartFeeDistributorStep)
208
- }
209
-
210
- CoreProposalSteps = append(CoreProposalSteps,
211
- vm.CoreProposalStepForModules(
212
- "@agoric/builders/scripts/vats/upgrade-paRegistry.js",
213
- ),
214
- vm.CoreProposalStepForModules(
215
- "@agoric/builders/scripts/vats/upgrade-provisionPool.js",
216
- ),
177
+ // vat-bank is slowly leaking, possibly because of the liveslots resolved promise leak
178
+ // (https://github.com/Agoric/agoric-sdk/issues/11118). Restart to pick up the fix.
217
179
  vm.CoreProposalStepForModules(
218
180
  "@agoric/builders/scripts/vats/upgrade-bank.js",
219
181
  ),
220
- vm.CoreProposalStepForModules(
221
- "@agoric/builders/scripts/vats/upgrade-agoricNames.js",
222
- ),
223
- vm.CoreProposalStepForModules(
224
- "@agoric/builders/scripts/vats/upgrade-asset-reserve.js",
225
- ),
226
- vm.CoreProposalStepForModules(
227
- "@agoric/builders/scripts/vats/upgrade-psm.js",
228
- ),
229
182
  )
230
183
  }
231
184
 
@@ -0,0 +1,63 @@
1
+ package gaia
2
+
3
+ import (
4
+ "testing"
5
+
6
+ "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
7
+ "github.com/stretchr/testify/assert"
8
+ )
9
+
10
+ func TestBuildProposalSteps(t *testing.T) {
11
+ testCases := []struct {
12
+ name string
13
+ makeStep func() (vm.CoreProposalStep, error)
14
+ expectedJson string
15
+ }{
16
+ {
17
+ "buildProposalStepFromScript",
18
+ func() (vm.CoreProposalStep, error) {
19
+ return buildProposalStepFromScript(
20
+ "UNRELEASED_A3P_INTEGRATION",
21
+ "@agoric/builders/scripts/vats/upgrade-orchestration.js",
22
+ )
23
+ },
24
+ `{"module":"@agoric/builders/scripts/vats/upgrade-orchestration.js",` +
25
+ `"entrypoint":"defaultProposalBuilder",` +
26
+ `"args":[{"variant":"A3P_INTEGRATION"}]}`,
27
+ },
28
+ {
29
+ "buildProposalStepWithArgs",
30
+ func() (vm.CoreProposalStep, error) {
31
+ return buildProposalStepWithArgs(
32
+ "@agoric/builders/scripts/vats/upgrade-vats.js",
33
+ "upgradeVatsProposalBuilder",
34
+ // Map iteration is randomised; use an anonymous struct instead.
35
+ struct {
36
+ Ibc string `json:"ibc"`
37
+ }{
38
+ Ibc: "@agoric/vats/src/vat-ibc.js",
39
+ },
40
+ )
41
+ },
42
+ `{"module":"@agoric/builders/scripts/vats/upgrade-vats.js",` +
43
+ `"entrypoint":"upgradeVatsProposalBuilder",` +
44
+ `"args":[{"ibc":"@agoric/vats/src/vat-ibc.js"}]}`,
45
+ },
46
+ }
47
+
48
+ for _, tc := range testCases {
49
+ t.Run(tc.name, func(t *testing.T) {
50
+ ps, err := tc.makeStep()
51
+
52
+ assert.NoError(t, err)
53
+ expected := vm.CoreProposalStepForModules(*vm.NewArbitraryCoreProposal(
54
+ tc.expectedJson,
55
+ ))
56
+
57
+ assert.EqualValues(t, len(expected), len(ps), "Expected length %d to be %d", len(expected), len(ps))
58
+ for i, prop := range ps {
59
+ assert.EqualValues(t, expected[i], prop, "Expected %d to be %v, got %v", i, expected[i], prop)
60
+ }
61
+ })
62
+ }
63
+ }
package/git-revision.txt CHANGED
@@ -1 +1 @@
1
- 2a71f04
1
+ 31be299
package/go.mod CHANGED
@@ -204,7 +204,7 @@ replace (
204
204
  github.com/cosmos/iavl => github.com/cosmos/iavl v0.19.7
205
205
 
206
206
  // Use a version of ibc-go that is compatible with the above forks.
207
- github.com/cosmos/ibc-go/v6 => github.com/agoric-labs/ibc-go/v6 v6.3.1-alpha.agoric.2
207
+ github.com/cosmos/ibc-go/v6 => github.com/agoric-labs/ibc-go/v6 v6.3.1-alpha.agoric.4
208
208
 
209
209
  // use cometbft
210
210
  // Use our fork at least until post-v0.34.14 is released with
package/go.sum CHANGED
@@ -235,8 +235,8 @@ github.com/agoric-labs/cosmos-sdk v0.46.16-alpha.agoric.2.5 h1:cwbONQaVbGEPzfVqv
235
235
  github.com/agoric-labs/cosmos-sdk v0.46.16-alpha.agoric.2.5/go.mod h1:Yny/YE+GJ+y/++UgvraITGzfLhXCnwETSWw3dAY5NDg=
236
236
  github.com/agoric-labs/cosmos-sdk/ics23/go v0.8.0-alpha.agoric.1 h1:2jvHI/2d+psWAZy6FQ0vXJCHUtfU3ZbbW+pQFL04arQ=
237
237
  github.com/agoric-labs/cosmos-sdk/ics23/go v0.8.0-alpha.agoric.1/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg=
238
- github.com/agoric-labs/ibc-go/v6 v6.3.1-alpha.agoric.2 h1:vEzy4JaExzlWNHV3ZSVXEVZcRE9loEFUjieE2TXwDdI=
239
- github.com/agoric-labs/ibc-go/v6 v6.3.1-alpha.agoric.2/go.mod h1:L1xcBjCLIHN7Wd9j6cAQvZertn56pq+eRGFZjRO5bsY=
238
+ github.com/agoric-labs/ibc-go/v6 v6.3.1-alpha.agoric.4 h1:dlzsn/JzNsMWFh14lRn+pjog4L4C72SH3PNNO93xN+4=
239
+ github.com/agoric-labs/ibc-go/v6 v6.3.1-alpha.agoric.4/go.mod h1:pNhYr/yk5M0b4tWX6Nh+SopaE/YaY0oigx1qwepLlLg=
240
240
  github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
241
241
  github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
242
242
  github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/cosmos",
3
- "version": "0.34.2-upgrade-19-dev-2a71f04.0+2a71f04",
3
+ "version": "0.34.2-upgrade-20-dev-31be299.0+31be299",
4
4
  "description": "Connect JS to the Cosmos blockchain SDK",
5
5
  "parsers": {
6
6
  "js": "mjs"
@@ -38,5 +38,5 @@
38
38
  "typeCoverage": {
39
39
  "atLeast": 0
40
40
  },
41
- "gitHead": "2a71f04176f1a27be8e0356595d3dcd62f6d9186"
41
+ "gitHead": "31be2992aec21c06633699b7d8095423845b0530"
42
42
  }
@@ -8,8 +8,6 @@ import (
8
8
  "github.com/cosmos/cosmos-sdk/types/bech32"
9
9
 
10
10
  transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
11
- clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
12
- channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
13
11
  ibcexported "github.com/cosmos/ibc-go/v6/modules/core/exported"
14
12
  )
15
13
 
@@ -176,7 +174,7 @@ func extractBaseTransferData(transferData transfertypes.FungibleTokenPacketData,
176
174
  // address is exactly the original address.
177
175
  // If newPacket is not nil, it is populated with a new transfer packet whose
178
176
  // corresponding Sender or Receiver is replaced with the extracted base address.
179
- func ExtractBaseAddressFromPacket(cdc codec.Codec, packet ibcexported.PacketI, role AddressRole, newPacket *channeltypes.Packet) (string, error) {
177
+ func ExtractBaseAddressFromPacket(cdc codec.Codec, packet ibcexported.PacketI, role AddressRole, newPacket *IBCPacket) (string, error) {
180
178
  var newDataP *[]byte
181
179
  if newPacket != nil {
182
180
  // Capture the data for the new packet.
@@ -192,13 +190,8 @@ func ExtractBaseAddressFromPacket(cdc codec.Codec, packet ibcexported.PacketI, r
192
190
  }
193
191
 
194
192
  // Create a new packet with the new transfer packet data.
195
- *newPacket = channeltypes.NewPacket(
196
- *newDataP, packet.GetSequence(),
197
- packet.GetSourcePort(), packet.GetSourceChannel(),
198
- packet.GetDestPort(), packet.GetDestChannel(),
199
- clienttypes.MustParseHeight(packet.GetTimeoutHeight().String()),
200
- packet.GetTimeoutTimestamp(),
201
- )
193
+ *newPacket = CopyToIBCPacket(packet)
194
+ newPacket.Data = *newDataP
202
195
 
203
196
  return target, nil
204
197
  }
@@ -12,7 +12,7 @@ import (
12
12
  clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
13
13
  channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
14
14
 
15
- "github.com/Agoric/agoric-sdk/golang/cosmos/types"
15
+ agtypes "github.com/Agoric/agoric-sdk/golang/cosmos/types"
16
16
  )
17
17
 
18
18
  func TestSplitHookedAddress(t *testing.T) {
@@ -49,7 +49,7 @@ func TestSplitHookedAddress(t *testing.T) {
49
49
  for _, tc := range cases {
50
50
  tc := tc
51
51
  t.Run(tc.name, func(t *testing.T) {
52
- baseAddr, hookData, err := types.SplitHookedAddress(tc.hook)
52
+ baseAddr, hookData, err := agtypes.SplitHookedAddress(tc.hook)
53
53
  if len(tc.err) > 0 {
54
54
  require.Error(t, err)
55
55
  require.Equal(t, tc.err, err.Error())
@@ -90,9 +90,9 @@ func TestExtractBaseAddress(t *testing.T) {
90
90
  for _, s := range suffixes {
91
91
  s := s
92
92
  t.Run(b.name+" "+s.hookStr, func(t *testing.T) {
93
- addrHook, err := types.JoinHookedAddress(b.addr, []byte(s.hookStr))
93
+ addrHook, err := agtypes.JoinHookedAddress(b.addr, []byte(s.hookStr))
94
94
  require.NoError(t, err)
95
- addr, err := types.ExtractBaseAddress(addrHook)
95
+ addr, err := agtypes.ExtractBaseAddress(addrHook)
96
96
  if s.isErr {
97
97
  require.Error(t, err)
98
98
  } else {
@@ -101,7 +101,7 @@ func TestExtractBaseAddress(t *testing.T) {
101
101
  require.NotEqual(t, b.addr, addr)
102
102
  } else {
103
103
  require.Equal(t, b.addr, addr)
104
- addr, hookData, err := types.SplitHookedAddress(addrHook)
104
+ addr, hookData, err := agtypes.SplitHookedAddress(addrHook)
105
105
  require.NoError(t, err)
106
106
  require.Equal(t, b.addr, addr)
107
107
  require.Equal(t, s.hookStr, string(hookData))
@@ -121,48 +121,48 @@ func TestExtractBaseAddressFromPacket(t *testing.T) {
121
121
 
122
122
  cosmosAddr := "cosmos1qqxuevtt"
123
123
  cosmosHookStr := "?foo=bar&baz=bot#fragment"
124
- cosmosHook, err := types.JoinHookedAddress(cosmosAddr, []byte(cosmosHookStr))
124
+ cosmosHook, err := agtypes.JoinHookedAddress(cosmosAddr, []byte(cosmosHookStr))
125
125
  require.NoError(t, err)
126
- addr, hookData, err := types.SplitHookedAddress(cosmosHook)
126
+ addr, hookData, err := agtypes.SplitHookedAddress(cosmosHook)
127
127
  require.NoError(t, err)
128
128
  require.Equal(t, cosmosAddr, addr)
129
129
  require.Equal(t, cosmosHookStr, string(hookData))
130
130
 
131
131
  agoricAddr := "agoric1qqp0e5ys"
132
132
  agoricHookStr := "?bingo=again"
133
- agoricHook, err := types.JoinHookedAddress(agoricAddr, []byte(agoricHookStr))
133
+ agoricHook, err := agtypes.JoinHookedAddress(agoricAddr, []byte(agoricHookStr))
134
134
  require.NoError(t, err)
135
- addr, hookData, err = types.SplitHookedAddress(agoricHook)
135
+ addr, hookData, err = agtypes.SplitHookedAddress(agoricHook)
136
136
  require.NoError(t, err)
137
137
  require.Equal(t, agoricAddr, addr)
138
138
  require.Equal(t, agoricHookStr, string(hookData))
139
139
 
140
140
  cases := []struct {
141
141
  name string
142
- addrs map[types.AddressRole]struct{ addr, baseAddr string }
142
+ addrs map[agtypes.AddressRole]struct{ addr, baseAddr string }
143
143
  }{
144
144
  {"sender has params",
145
- map[types.AddressRole]struct{ addr, baseAddr string }{
146
- types.RoleSender: {cosmosHook, "cosmos1qqxuevtt"},
147
- types.RoleReceiver: {"agoric1qqp0e5ys", "agoric1qqp0e5ys"},
145
+ map[agtypes.AddressRole]struct{ addr, baseAddr string }{
146
+ agtypes.RoleSender: {cosmosHook, "cosmos1qqxuevtt"},
147
+ agtypes.RoleReceiver: {"agoric1qqp0e5ys", "agoric1qqp0e5ys"},
148
148
  },
149
149
  },
150
150
  {"receiver has params",
151
- map[types.AddressRole]struct{ addr, baseAddr string }{
152
- types.RoleSender: {"cosmos1qqxuevtt", "cosmos1qqxuevtt"},
153
- types.RoleReceiver: {agoricHook, "agoric1qqp0e5ys"},
151
+ map[agtypes.AddressRole]struct{ addr, baseAddr string }{
152
+ agtypes.RoleSender: {"cosmos1qqxuevtt", "cosmos1qqxuevtt"},
153
+ agtypes.RoleReceiver: {agoricHook, "agoric1qqp0e5ys"},
154
154
  },
155
155
  },
156
156
  {"both are base",
157
- map[types.AddressRole]struct{ addr, baseAddr string }{
158
- types.RoleSender: {"cosmos1qqxuevtt", "cosmos1qqxuevtt"},
159
- types.RoleReceiver: {"agoric1qqp0e5ys", "agoric1qqp0e5ys"},
157
+ map[agtypes.AddressRole]struct{ addr, baseAddr string }{
158
+ agtypes.RoleSender: {"cosmos1qqxuevtt", "cosmos1qqxuevtt"},
159
+ agtypes.RoleReceiver: {"agoric1qqp0e5ys", "agoric1qqp0e5ys"},
160
160
  },
161
161
  },
162
162
  {"both have params",
163
- map[types.AddressRole]struct{ addr, baseAddr string }{
164
- types.RoleSender: {agoricHook, "agoric1qqp0e5ys"},
165
- types.RoleReceiver: {cosmosHook, "cosmos1qqxuevtt"},
163
+ map[agtypes.AddressRole]struct{ addr, baseAddr string }{
164
+ agtypes.RoleSender: {agoricHook, "agoric1qqp0e5ys"},
165
+ agtypes.RoleReceiver: {cosmosHook, "cosmos1qqxuevtt"},
166
166
  },
167
167
  },
168
168
  }
@@ -170,29 +170,29 @@ func TestExtractBaseAddressFromPacket(t *testing.T) {
170
170
  for _, tc := range cases {
171
171
  tc := tc
172
172
  t.Run(tc.name, func(t *testing.T) {
173
- ftPacketData := transfertypes.NewFungibleTokenPacketData("denom", "100", tc.addrs[types.RoleSender].addr, tc.addrs[types.RoleReceiver].addr, "my-favourite-memo")
173
+ ftPacketData := transfertypes.NewFungibleTokenPacketData("denom", "100", tc.addrs[agtypes.RoleSender].addr, tc.addrs[agtypes.RoleReceiver].addr, "my-favourite-memo")
174
174
  packetBz := ftPacketData.GetBytes()
175
- packet := channeltypes.NewPacket(packetBz, 1234, "my-port", "my-channel", "their-port", "their-channel", clienttypes.NewHeight(133, 445), 10999)
175
+ packet := agtypes.MakeIBCPacket(packetBz, 1234, "my-port", "my-channel", "their-port", "their-channel", clienttypes.NewHeight(133, 445), 10999)
176
176
 
177
177
  for role, addrs := range tc.addrs {
178
178
  addrs := addrs
179
179
  role := role
180
180
 
181
181
  t.Run(string(role), func(t *testing.T) {
182
- baseAddr, err := types.ExtractBaseAddress(addrs.addr)
182
+ baseAddr, err := agtypes.ExtractBaseAddress(addrs.addr)
183
183
  require.NoError(t, err)
184
184
  require.Equal(t, addrs.baseAddr, baseAddr)
185
185
 
186
- packetBaseAddr0, err := types.ExtractBaseAddressFromData(cdc, packet.GetData(), role, nil)
186
+ packetBaseAddr0, err := agtypes.ExtractBaseAddressFromData(cdc, packet.GetData(), role, nil)
187
187
  require.NoError(t, err)
188
188
  require.Equal(t, addrs.baseAddr, packetBaseAddr0)
189
189
 
190
- packetBaseAddr1, err := types.ExtractBaseAddressFromPacket(cdc, packet, role, nil)
190
+ packetBaseAddr1, err := agtypes.ExtractBaseAddressFromPacket(cdc, packet, role, nil)
191
191
  require.NoError(t, err)
192
192
  require.Equal(t, addrs.baseAddr, packetBaseAddr1)
193
193
 
194
- var newPacket channeltypes.Packet
195
- packetBaseAddr2, err := types.ExtractBaseAddressFromPacket(cdc, packet, role, &newPacket)
194
+ var newPacket agtypes.IBCPacket
195
+ packetBaseAddr2, err := agtypes.ExtractBaseAddressFromPacket(cdc, packet, role, &newPacket)
196
196
  require.NoError(t, err)
197
197
  require.Equal(t, addrs.baseAddr, packetBaseAddr2)
198
198
 
@@ -203,10 +203,10 @@ func TestExtractBaseAddressFromPacket(t *testing.T) {
203
203
  // Check that the only difference between the packet data is the baseAddr.
204
204
  packetData := basePacketData
205
205
  switch role {
206
- case types.RoleSender:
206
+ case agtypes.RoleSender:
207
207
  require.Equal(t, addrs.baseAddr, basePacketData.Sender)
208
208
  packetData.Sender = addrs.addr
209
- case types.RoleReceiver:
209
+ case agtypes.RoleReceiver:
210
210
  require.Equal(t, addrs.baseAddr, basePacketData.Receiver)
211
211
  packetData.Receiver = addrs.addr
212
212
  default:
package/types/codec.go ADDED
@@ -0,0 +1,23 @@
1
+ package types
2
+
3
+ import (
4
+ "github.com/cosmos/cosmos-sdk/codec"
5
+ cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
6
+ )
7
+
8
+ var (
9
+ // packageCdc is the codec used for proto3 JSON serialization of proto.Message
10
+ // data structures that wouldn't otherwise survive round-tripping via a
11
+ // regular "encoding/json" Marshal->JSON.parse.
12
+ //
13
+ // The naïve json.Marshal output for an int64 (64-bit precision) is a JSON
14
+ // number, which is subject to rounding errors when parsed by JavaScript
15
+ // (whose numbers are IEEE 754 binary64 values with only 53-bit precision).
16
+ // The codec.ProtoCodec uses a custom JSON marshaller that converts each int64
17
+ // to and from a string with no loss of precision.
18
+ //
19
+ // The current package's IBCPacket was one such affected data structure, which
20
+ // now implements Marshaler and Unmarshaler interfaces for "encoding/json" to
21
+ // take advantage of the packageCdc.
22
+ packageCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry())
23
+ )
@@ -0,0 +1,64 @@
1
+ package types
2
+
3
+ import (
4
+ "encoding/json"
5
+
6
+ clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
7
+ channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
8
+ "github.com/cosmos/ibc-go/v6/modules/core/exported"
9
+ )
10
+
11
+ var _ json.Marshaler = IBCPacket{}
12
+ var _ json.Unmarshaler = (*IBCPacket)(nil)
13
+ var _ exported.PacketI = IBCPacket{}
14
+
15
+ type IBCPacket struct {
16
+ channeltypes.Packet
17
+ }
18
+
19
+ func (p IBCPacket) MarshalJSON() ([]byte, error) {
20
+ return packageCdc.MarshalJSON(&p.Packet)
21
+ }
22
+
23
+ func (p *IBCPacket) UnmarshalJSON(bz []byte) error {
24
+ return packageCdc.UnmarshalJSON(bz, &p.Packet)
25
+ }
26
+
27
+ func MakeIBCPacket(
28
+ data []byte,
29
+ sequence uint64,
30
+ sourcePort string,
31
+ sourceChannel string,
32
+ destPort string,
33
+ destChannel string,
34
+ timeoutHeight clienttypes.Height,
35
+ timeoutTimestamp uint64,
36
+ ) IBCPacket {
37
+ cp := channeltypes.NewPacket(
38
+ data, sequence,
39
+ sourcePort, sourceChannel,
40
+ destPort, destChannel,
41
+ timeoutHeight, timeoutTimestamp,
42
+ )
43
+ return IBCPacket{Packet: cp}
44
+ }
45
+
46
+ func CopyToChannelPacket(packet exported.PacketI) channeltypes.Packet {
47
+ timeoutHeight := clienttypes.MustParseHeight(packet.GetTimeoutHeight().String())
48
+ return channeltypes.NewPacket(
49
+ packet.GetData(), packet.GetSequence(),
50
+ packet.GetSourcePort(), packet.GetSourceChannel(),
51
+ packet.GetDestPort(), packet.GetDestChannel(),
52
+ timeoutHeight, packet.GetTimeoutTimestamp(),
53
+ )
54
+ }
55
+
56
+ func CopyToIBCPacket(packet exported.PacketI) IBCPacket {
57
+ timeoutHeight := clienttypes.MustParseHeight(packet.GetTimeoutHeight().String())
58
+ return MakeIBCPacket(
59
+ packet.GetData(), packet.GetSequence(),
60
+ packet.GetSourcePort(), packet.GetSourceChannel(),
61
+ packet.GetDestPort(), packet.GetDestChannel(),
62
+ timeoutHeight, packet.GetTimeoutTimestamp(),
63
+ )
64
+ }
@@ -0,0 +1,117 @@
1
+ package types_test
2
+
3
+ import (
4
+ "bytes"
5
+ "encoding/json"
6
+ fmt "fmt"
7
+ "reflect"
8
+ "testing"
9
+
10
+ agtypes "github.com/Agoric/agoric-sdk/golang/cosmos/types"
11
+ "github.com/stretchr/testify/assert"
12
+ "github.com/stretchr/testify/require"
13
+
14
+ clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
15
+ channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
16
+ ibcexported "github.com/cosmos/ibc-go/v6/modules/core/exported"
17
+ )
18
+
19
+ func CreateTestChannelPacket() channeltypes.Packet {
20
+ return channeltypes.NewPacket(
21
+ []byte("data"),
22
+ 987654321098765432,
23
+ "port-src", "channel-13",
24
+ "port-dst", "channel-42",
25
+ clienttypes.Height{},
26
+ 123456789012345678,
27
+ )
28
+ }
29
+
30
+ func TestPacket(t *testing.T) {
31
+ testCases := []struct {
32
+ name string
33
+ packet ibcexported.PacketI
34
+ }{
35
+ {
36
+ name: "ibc-go channel Packet",
37
+ packet: CreateTestChannelPacket(),
38
+ },
39
+ {
40
+ name: "agoric-sdk IBCPacket",
41
+ packet: agtypes.CopyToIBCPacket(CreateTestChannelPacket()),
42
+ },
43
+ }
44
+
45
+ // Check that the packets have the expected values
46
+ for _, tc := range testCases {
47
+ t.Run(tc.name, func(t *testing.T) {
48
+ pi := tc.packet
49
+ assert.Equal(t, "port-src", pi.GetSourcePort())
50
+ assert.Equal(t, "channel-13", pi.GetSourceChannel())
51
+ assert.Equal(t, "port-dst", pi.GetDestPort())
52
+ assert.Equal(t, "channel-42", pi.GetDestChannel())
53
+ assert.Equal(t, uint64(987654321098765432), pi.GetSequence())
54
+ assert.Equal(t, uint64(123456789012345678), pi.GetTimeoutTimestamp())
55
+ assert.Equal(t, []byte("data"), pi.GetData())
56
+ assert.Equal(t, clienttypes.Height{}, pi.GetTimeoutHeight())
57
+ })
58
+ }
59
+ }
60
+
61
+ func TestPacketJSON(t *testing.T) {
62
+ testCases := []struct {
63
+ name string
64
+ packet ibcexported.PacketI
65
+ quoted bool
66
+ }{
67
+ {
68
+ name: "ibc-go channel Packet",
69
+ packet: CreateTestChannelPacket(),
70
+ quoted: false,
71
+ },
72
+ {
73
+ name: "agoric-sdk IBCPacket",
74
+ packet: agtypes.CopyToIBCPacket(CreateTestChannelPacket()),
75
+ quoted: true,
76
+ },
77
+ }
78
+
79
+ for _, tc := range testCases {
80
+ t.Run(tc.name, func(t *testing.T) {
81
+ bz, err := json.Marshal(tc.packet)
82
+ require.NoError(t, err)
83
+
84
+ seqStr := fmt.Sprintf("%d", tc.packet.GetSequence())
85
+ if !bytes.Contains(bz, []byte(seqStr)) {
86
+ assert.Failf(t, "packet sequence should be present in JSON", "sequence %s, json %s", seqStr, string(bz))
87
+ }
88
+
89
+ if bytes.Contains(bz, []byte(`"`+seqStr+`"`)) != tc.quoted {
90
+ if tc.quoted {
91
+ assert.Failf(t, "packet sequence should be quoted in JSON", "sequence %s, json %s", seqStr, string(bz))
92
+ } else {
93
+ assert.Failf(t, "packet sequence should not be quoted in JSON", "sequence %s, json %s", seqStr, string(bz))
94
+ }
95
+ }
96
+
97
+ var packet2 ibcexported.PacketI
98
+ switch p := tc.packet.(type) {
99
+ case channeltypes.Packet:
100
+ var p2 channeltypes.Packet
101
+ err = json.Unmarshal(bz, &p2)
102
+ packet2 = p2
103
+ case agtypes.IBCPacket:
104
+ var p2 agtypes.IBCPacket
105
+ err = json.Unmarshal(bz, &p2)
106
+ packet2 = p2
107
+ default:
108
+ t.Fatalf("unexpected packet type %T", p)
109
+ }
110
+
111
+ require.NoError(t, err)
112
+ if !reflect.DeepEqual(tc.packet, packet2) {
113
+ assert.Failf(t, "nested packet not equal after JSON round trip", "src %q, dst %q", tc.packet, packet2)
114
+ }
115
+ })
116
+ }
117
+ }