@agoric/cosmos 0.34.2-upgrade-16-dev-91eb8f4.0 → 0.34.2-upgrade-17-dev-e67cd91.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/Makefile CHANGED
@@ -61,10 +61,10 @@ node-compile-gyp:
61
61
  npm run build:gyp; \
62
62
  fi
63
63
 
64
- compile-agd: go-mod-cache
64
+ compile-agd: go.sum
65
65
  go build -v $(MOD_READONLY) $(BUILD_FLAGS) -buildmode=exe -o build/agd ./cmd/agd
66
66
 
67
- install-agd: go-mod-cache
67
+ install-agd: go.sum
68
68
  go install -v $(MOD_READONLY) $(BUILD_FLAGS) -buildmode=exe ./cmd/agd
69
69
 
70
70
  # Only run from the package.json build:gyp script.
@@ -73,17 +73,18 @@ compile-gyp:
73
73
  node-gyp configure build $(GYP_DEBUG) || { status=$$?; rm -f binding.gyp; exit $$status; }
74
74
  rm -f binding.gyp
75
75
 
76
- compile-libdaemon: go-mod-cache
76
+ compile-libdaemon: go.sum
77
77
  go build -v $(MOD_READONLY) $(SHARED_BUILD_FLAGS) -buildmode=c-shared \
78
78
  -o build/libagcosmosdaemon.so ./cmd/libdaemon/main.go
79
79
 
80
- go-mod-cache: go.sum
81
- @echo "--> Download go modules to local cache"
82
- @go mod download
83
-
84
80
  go.sum: go.mod
85
- @echo "--> Ensure dependencies have not been modified"
81
+ @echo "--> Ensure dependencies have not been modified unless suppressed by SKIP_MOD_VERIFY ..."
82
+ ifndef SKIP_MOD_VERIFY
86
83
  GO111MODULE=on go mod verify
84
+ endif
85
+ GO111MODULE=on go mod tidy
86
+ @echo "--> Download go modules to local cache"
87
+ go mod download
87
88
 
88
89
  ###############################################################################
89
90
  ### Protobuf ###
package/app/app.go CHANGED
@@ -214,6 +214,7 @@ var (
214
214
  // capabilities aren't needed for testing.
215
215
  type GaiaApp struct { // nolint: golint
216
216
  *baseapp.BaseApp
217
+ resolvedConfig servertypes.AppOptions
217
218
  legacyAmino *codec.LegacyAmino
218
219
  appCodec codec.Codec
219
220
  interfaceRegistry types.InterfaceRegistry
@@ -314,9 +315,18 @@ func NewGaiaApp(
314
315
  }
315
316
 
316
317
  func NewAgoricApp(
317
- sendToController vm.Sender, agdServer *vm.AgdServer,
318
- logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool,
319
- homePath string, invCheckPeriod uint, encodingConfig gaiaappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp),
318
+ sendToController vm.Sender,
319
+ agdServer *vm.AgdServer,
320
+ logger log.Logger,
321
+ db dbm.DB,
322
+ traceStore io.Writer,
323
+ loadLatest bool,
324
+ skipUpgradeHeights map[int64]bool,
325
+ homePath string,
326
+ invCheckPeriod uint,
327
+ encodingConfig gaiaappparams.EncodingConfig,
328
+ appOpts servertypes.AppOptions,
329
+ baseAppOptions ...func(*baseapp.BaseApp),
320
330
  ) *GaiaApp {
321
331
  appCodec := encodingConfig.Marshaler
322
332
  legacyAmino := encodingConfig.Amino
@@ -342,6 +352,7 @@ func NewAgoricApp(
342
352
  app := &GaiaApp{
343
353
  BaseApp: bApp,
344
354
  AgdServer: agdServer,
355
+ resolvedConfig: appOpts,
345
356
  legacyAmino: legacyAmino,
346
357
  appCodec: appCodec,
347
358
  interfaceRegistry: interfaceRegistry,
@@ -862,27 +873,26 @@ func NewAgoricApp(
862
873
  app.SetBeginBlocker(app.BeginBlocker)
863
874
  app.SetEndBlocker(app.EndBlocker)
864
875
 
865
- for name := range upgradeNamesOfThisVersion {
876
+ for _, name := range upgradeNamesOfThisVersion {
866
877
  app.UpgradeKeeper.SetUpgradeHandler(
867
878
  name,
868
- upgrade16Handler(app, name),
879
+ unreleasedUpgradeHandler(app, name),
869
880
  )
870
881
  }
871
882
 
883
+ // At this point we don't have a way to read from the store, so we have to
884
+ // rely on data saved by the x/upgrade module in the previous software.
872
885
  upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
873
886
  if err != nil {
874
887
  panic(err)
875
888
  }
876
- if upgradeNamesOfThisVersion[upgradeInfo.Name] && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
889
+ // Store migrations can only run once, so we use a notion of "primary upgrade
890
+ // name" to trigger them. Testnets may end up upgrading from one rc to
891
+ // another, which shouldn't re-run store upgrades.
892
+ if isPrimaryUpgradeName(upgradeInfo.Name) && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
877
893
  storeUpgrades := storetypes.StoreUpgrades{
878
- Added: []string{
879
- packetforwardtypes.ModuleName, // Added PFM
880
- vlocalchain.ModuleName, // Agoric added vlocalchain
881
- vtransfer.ModuleName, // Agoric added vtransfer
882
- },
883
- Deleted: []string{
884
- "lien", // Agoric removed the lien module
885
- },
894
+ Added: []string{},
895
+ Deleted: []string{},
886
896
  }
887
897
 
888
898
  // configure store loader that checks if version == upgradeHeight and applies store upgrades
@@ -933,11 +943,12 @@ type upgradeDetails struct {
933
943
 
934
944
  type cosmosInitAction struct {
935
945
  vm.ActionHeader `actionType:"AG_COSMOS_INIT"`
936
- ChainID string `json:"chainID"`
937
- IsBootstrap bool `json:"isBootstrap"`
938
- UpgradeDetails *upgradeDetails `json:"upgradeDetails,omitempty"`
939
- Params swingset.Params `json:"params"`
940
- SupplyCoins sdk.Coins `json:"supplyCoins"`
946
+ ChainID string `json:"chainID"`
947
+ IsBootstrap bool `json:"isBootstrap"`
948
+ Params swingset.Params `json:"params"`
949
+ ResolvedConfig *swingset.SwingsetConfig `json:"resolvedConfig"`
950
+ SupplyCoins sdk.Coins `json:"supplyCoins"`
951
+ UpgradeDetails *upgradeDetails `json:"upgradeDetails,omitempty"`
941
952
  // CAVEAT: Every property ending in "Port" is saved in chain-main.js/portNums
942
953
  // with a key consisting of this name with the "Port" stripped.
943
954
  StoragePort int `json:"storagePort"`
@@ -969,10 +980,15 @@ func (app *GaiaApp) initController(ctx sdk.Context, bootstrap bool) {
969
980
  app.controllerInited = true
970
981
 
971
982
  // Begin initializing the controller here.
983
+ swingsetConfig, err := swingset.SwingsetConfigFromViper(app.resolvedConfig)
984
+ if err != nil {
985
+ panic(err)
986
+ }
972
987
  action := &cosmosInitAction{
973
988
  ChainID: ctx.ChainID(),
974
989
  IsBootstrap: bootstrap,
975
990
  Params: app.SwingSetKeeper.GetParams(ctx),
991
+ ResolvedConfig: swingsetConfig,
976
992
  SupplyCoins: sdk.NewCoins(app.BankKeeper.GetSupply(ctx, "uist")),
977
993
  UpgradeDetails: app.upgradeDetails,
978
994
  // See CAVEAT in cosmosInitAction.
package/app/upgrade.go CHANGED
@@ -1,6 +1,8 @@
1
1
  package gaia
2
2
 
3
3
  import (
4
+ "fmt"
5
+
4
6
  "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
5
7
  swingsetkeeper "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
6
8
  sdk "github.com/cosmos/cosmos-sdk/types"
@@ -8,12 +10,61 @@ import (
8
10
  upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
9
11
  )
10
12
 
11
- var upgradeNamesOfThisVersion = map[string]bool{
12
- "agoric-upgrade-16": true,
13
+ var upgradeNamesOfThisVersion = []string{
14
+ "UNRELEASED_BASIC", // no-frills
15
+ "UNRELEASED_A3P_INTEGRATION",
16
+ "UNRELEASED_main",
17
+ "UNRELEASED_devnet",
18
+ "UNRELEASED_REAPPLY",
19
+ }
20
+
21
+ // isUpgradeNameOfThisVersion returns whether the provided plan name is a
22
+ // known upgrade name of this software version
23
+ func isUpgradeNameOfThisVersion(name string) bool {
24
+ for _, upgradeName := range upgradeNamesOfThisVersion {
25
+ if upgradeName == name {
26
+ return true
27
+ }
28
+ }
29
+ return false
30
+ }
31
+
32
+ // validUpgradeName is an identity function that asserts the provided name
33
+ // is an upgrade name of this software version. It can be used as a sort of
34
+ // dynamic enum check.
35
+ func validUpgradeName(name string) string {
36
+ if !isUpgradeNameOfThisVersion(name) {
37
+ panic(fmt.Errorf("invalid upgrade name: %s", name))
38
+ }
39
+ return name
13
40
  }
14
41
 
42
+ // isPrimaryUpgradeName returns wether the provided plan name is considered a
43
+ // primary for the purpose of applying store migrations for the first upgrade
44
+ // of this version.
45
+ // It is expected that only primary plan names are used for non testing chains.
46
+ func isPrimaryUpgradeName(name string) bool {
47
+ if name == "" {
48
+ // An empty upgrade name can happen if there are no upgrade in progress
49
+ return false
50
+ }
51
+ switch name {
52
+ case validUpgradeName("UNRELEASED_BASIC"),
53
+ validUpgradeName("UNRELEASED_A3P_INTEGRATION"),
54
+ validUpgradeName("UNRELEASED_main"),
55
+ validUpgradeName("UNRELEASED_devnet"):
56
+ return true
57
+ case validUpgradeName("UNRELEASED_REAPPLY"):
58
+ return false
59
+ default:
60
+ panic(fmt.Errorf("unexpected upgrade name %s", validUpgradeName(name)))
61
+ }
62
+ }
63
+
64
+ // isFirstTimeUpgradeOfThisVersion looks up in the upgrade store whether no
65
+ // upgrade plan name of this version have previously been applied.
15
66
  func isFirstTimeUpgradeOfThisVersion(app *GaiaApp, ctx sdk.Context) bool {
16
- for name := range upgradeNamesOfThisVersion {
67
+ for _, name := range upgradeNamesOfThisVersion {
17
68
  if app.UpgradeKeeper.GetDoneHeight(ctx, name) != 0 {
18
69
  return false
19
70
  }
@@ -21,8 +72,8 @@ func isFirstTimeUpgradeOfThisVersion(app *GaiaApp, ctx sdk.Context) bool {
21
72
  return true
22
73
  }
23
74
 
24
- // upgrade16Handler performs standard upgrade actions plus custom actions for upgrade-16.
25
- func upgrade16Handler(app *GaiaApp, targetUpgrade string) func(sdk.Context, upgradetypes.Plan, module.VersionMap) (module.VersionMap, error) {
75
+ // unreleasedUpgradeHandler performs standard upgrade actions plus custom actions for the unreleased upgrade.
76
+ func unreleasedUpgradeHandler(app *GaiaApp, targetUpgrade string) func(sdk.Context, upgradetypes.Plan, module.VersionMap) (module.VersionMap, error) {
26
77
  return func(ctx sdk.Context, plan upgradetypes.Plan, fromVm module.VersionMap) (module.VersionMap, error) {
27
78
  app.CheckControllerInited(false)
28
79
 
@@ -31,21 +82,27 @@ func upgrade16Handler(app *GaiaApp, targetUpgrade string) func(sdk.Context, upgr
31
82
  // These CoreProposalSteps are not idempotent and should only be executed
32
83
  // as part of the first upgrade using this handler on any given chain.
33
84
  if isFirstTimeUpgradeOfThisVersion(app, ctx) {
85
+ // The storeUpgrades defined in app.go only execute for the primary upgrade name
86
+ // If we got here and this first upgrade of this version does not use the
87
+ // primary upgrade name, stores have not been initialized correctly.
88
+ if !isPrimaryUpgradeName(plan.Name) {
89
+ return module.VersionMap{}, fmt.Errorf("cannot run %s as first upgrade", plan.Name)
90
+ }
91
+
34
92
  // Each CoreProposalStep runs sequentially, and can be constructed from
35
93
  // one or more modules executing in parallel within the step.
36
94
  CoreProposalSteps = []vm.CoreProposalStep{
37
- // Upgrade Zoe + ZCF
38
- vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/replace-zoe.js"),
39
- // Revive KREAd characters
40
- vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/revive-kread.js"),
41
-
42
- // upgrade the provisioning vat
43
- vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/replace-provisioning.js"),
44
- // Enable low-level Orchestration.
45
95
  vm.CoreProposalStepForModules(
46
- "@agoric/builders/scripts/vats/init-network.js",
47
- "@agoric/builders/scripts/vats/init-localchain.js",
48
- "@agoric/builders/scripts/vats/init-transfer.js",
96
+ // Upgrade to new liveslots for repaired vow usage.
97
+ "@agoric/builders/scripts/vats/upgrade-orch-core.js",
98
+ ),
99
+ vm.CoreProposalStepForModules(
100
+ // Upgrade to new liveslots and support vows.
101
+ "@agoric/builders/scripts/smart-wallet/build-wallet-factory2-upgrade.js",
102
+ ),
103
+ vm.CoreProposalStepForModules(
104
+ // Create vat-orchestration.
105
+ "@agoric/builders/scripts/vats/init-orchestration.js",
49
106
  ),
50
107
  }
51
108
  }
@@ -6,6 +6,7 @@ import (
6
6
  "io"
7
7
  "os"
8
8
  "path/filepath"
9
+ "strings"
9
10
 
10
11
  serverconfig "github.com/cosmos/cosmos-sdk/server/config"
11
12
 
@@ -36,6 +37,7 @@ import (
36
37
  gaia "github.com/Agoric/agoric-sdk/golang/cosmos/app"
37
38
  "github.com/Agoric/agoric-sdk/golang/cosmos/app/params"
38
39
  "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
40
+ swingset "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset"
39
41
  swingsetkeeper "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
40
42
  )
41
43
 
@@ -43,6 +45,31 @@ var AppName = "agd"
43
45
  var OnStartHook func(*vm.AgdServer, log.Logger, servertypes.AppOptions) error
44
46
  var OnExportHook func(*vm.AgdServer, log.Logger, servertypes.AppOptions) error
45
47
 
48
+ // CustomAppConfig extends the base config struct.
49
+ type CustomAppConfig struct {
50
+ serverconfig.Config `mapstructure:",squash"`
51
+ // Swingset must be named as expected by swingset.DefaultConfigTemplate
52
+ // and must use a mapstructure key matching swingset.ConfigPrefix.
53
+ Swingset swingset.SwingsetConfig `mapstructure:"swingset"`
54
+ }
55
+
56
+ type cobraRunE func(cmd *cobra.Command, args []string) error
57
+
58
+ func appendToPreRunE(cmd *cobra.Command, fn cobraRunE) {
59
+ preRunE := cmd.PreRunE
60
+ if preRunE == nil {
61
+ cmd.PreRunE = fn
62
+ return
63
+ }
64
+ composite := func(cmd *cobra.Command, args []string) error {
65
+ if err := preRunE(cmd, args); err != nil {
66
+ return err
67
+ }
68
+ return fn(cmd, args)
69
+ }
70
+ cmd.PreRunE = composite
71
+ }
72
+
46
73
  // NewRootCmd creates a new root command for simd. It is called once in the
47
74
  // main function.
48
75
  func NewRootCmd(sender vm.Sender) (*cobra.Command, params.EncodingConfig) {
@@ -99,24 +126,25 @@ func initTendermintConfig() *tmcfg.Config {
99
126
  // initAppConfig helps to override default appConfig template and configs.
100
127
  // return "", nil if no custom configuration is required for the application.
101
128
  func initAppConfig() (string, interface{}) {
102
- // Allow us to overwrite the SDK's default server config.
103
129
  srvCfg := serverconfig.DefaultConfig()
104
- // The SDK's default minimum gas price is set to "" (empty value) inside
105
- // app.toml. If left empty by validators, the node will halt on startup.
106
- // However, the chain developer can set a default app.toml value for their
107
- // validators here.
108
- //
109
- // In summary:
110
- // - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their
111
- // own app.toml config,
112
- // - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their
113
- // own app.toml to override, or use this default value.
114
- //
115
- // FIXME: We may want to have Agoric set a min gas price in uist.
116
- // For now, we set it to zero so that validators don't have to worry about it.
130
+
131
+ // FIXME: We may want a non-zero min gas price.
132
+ // For now, we set it to zero to reduce friction (the default "" fails
133
+ // startup, forcing each validator to set their own value).
117
134
  srvCfg.MinGasPrices = "0uist"
118
135
 
119
- return serverconfig.DefaultConfigTemplate, *srvCfg
136
+ customAppConfig := CustomAppConfig{
137
+ Config: *srvCfg,
138
+ Swingset: swingset.DefaultSwingsetConfig,
139
+ }
140
+
141
+ // Config TOML.
142
+ customAppTemplate := strings.Join([]string{
143
+ serverconfig.DefaultConfigTemplate,
144
+ swingset.DefaultConfigTemplate,
145
+ }, "")
146
+
147
+ return customAppTemplate, customAppConfig
120
148
  }
121
149
 
122
150
  func initRootCmd(sender vm.Sender, rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
@@ -144,10 +172,27 @@ func initRootCmd(sender vm.Sender, rootCmd *cobra.Command, encodingConfig params
144
172
  snapshot.Cmd(ac.newSnapshotsApp),
145
173
  )
146
174
 
147
- server.AddCommands(rootCmd, gaia.DefaultNodeHome, ac.newApp, ac.appExport, addModuleInitFlags)
175
+ server.AddCommands(rootCmd, gaia.DefaultNodeHome, ac.newApp, ac.appExport, addStartFlags)
148
176
 
149
177
  for _, command := range rootCmd.Commands() {
150
178
  switch command.Name() {
179
+ case "start":
180
+ var preRunE cobraRunE = func(cmd *cobra.Command, _ []string) error {
181
+ // Consume and validate config.
182
+ viper := server.GetServerContextFromCmd(cmd).Viper
183
+ baseConfig, err := serverconfig.GetConfig(viper)
184
+ if err != nil {
185
+ return err
186
+ }
187
+ if err = baseConfig.ValidateBasic(); err != nil {
188
+ return err
189
+ }
190
+ if _, err = swingset.SwingsetConfigFromViper(viper); err != nil {
191
+ return err
192
+ }
193
+ return nil
194
+ }
195
+ appendToPreRunE(command, preRunE)
151
196
  case "export":
152
197
  addAgoricVMFlags(command)
153
198
  extendCosmosExportCommand(command)
@@ -197,7 +242,7 @@ func addAgoricVMFlags(cmd *cobra.Command) {
197
242
  )
198
243
  }
199
244
 
200
- func addModuleInitFlags(startCmd *cobra.Command) {
245
+ func addStartFlags(startCmd *cobra.Command) {
201
246
  addAgoricVMFlags(startCmd)
202
247
  }
203
248
 
@@ -282,11 +327,12 @@ func (ac appCreator) newApp(
282
327
 
283
328
  homePath := cast.ToString(appOpts.Get(flags.FlagHome))
284
329
 
285
- // Set a default value for FlagSwingStoreExportDir based on the homePath
330
+ // Set a default value for FlagSwingStoreExportDir based on homePath
286
331
  // in case we need to InitGenesis with swing-store data
287
332
  viper, ok := appOpts.(*viper.Viper)
288
- if ok && cast.ToString(appOpts.Get(gaia.FlagSwingStoreExportDir)) == "" {
289
- viper.Set(gaia.FlagSwingStoreExportDir, filepath.Join(homePath, "config", ExportedSwingStoreDirectoryName))
333
+ if ok && viper.GetString(gaia.FlagSwingStoreExportDir) == "" {
334
+ exportDir := filepath.Join(homePath, "config", ExportedSwingStoreDirectoryName)
335
+ viper.Set(gaia.FlagSwingStoreExportDir, exportDir)
290
336
  }
291
337
 
292
338
  return gaia.NewAgoricApp(
package/git-revision.txt CHANGED
@@ -1 +1 @@
1
- 91eb8f4
1
+ e67cd91
package/go.mod CHANGED
@@ -17,6 +17,7 @@ require (
17
17
  github.com/rakyll/statik v0.1.7
18
18
  github.com/spf13/cast v1.5.0
19
19
  github.com/spf13/cobra v1.7.0
20
+ github.com/spf13/pflag v1.0.5
20
21
  github.com/spf13/viper v1.14.0
21
22
  github.com/stretchr/testify v1.8.4
22
23
  github.com/tendermint/tendermint v0.34.29
@@ -133,7 +134,6 @@ require (
133
134
  github.com/sasha-s/go-deadlock v0.3.1 // indirect
134
135
  github.com/spf13/afero v1.9.2 // indirect
135
136
  github.com/spf13/jwalterweatherman v1.1.0 // indirect
136
- github.com/spf13/pflag v1.0.5 // indirect
137
137
  github.com/subosito/gotenv v1.4.1 // indirect
138
138
  github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
139
139
  github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/cosmos",
3
- "version": "0.34.2-upgrade-16-dev-91eb8f4.0+91eb8f4",
3
+ "version": "0.34.2-upgrade-17-dev-e67cd91.0+e67cd91",
4
4
  "description": "Connect JS to the Cosmos blockchain SDK",
5
5
  "parsers": {
6
6
  "js": "mjs"
@@ -9,7 +9,7 @@
9
9
  "engines": {
10
10
  "node": "^18.12 || ^20.9"
11
11
  },
12
- "packageManager": "yarn@1.22.19",
12
+ "packageManager": "yarn@1.22.22",
13
13
  "scripts": {
14
14
  "test": "exit 0",
15
15
  "build:all": "make",
@@ -39,5 +39,5 @@
39
39
  "typeCoverage": {
40
40
  "atLeast": 0
41
41
  },
42
- "gitHead": "91eb8f468c6ac5e9c4892633855eac3db365001d"
42
+ "gitHead": "e67cd918f33dafb1708bd4341f2a737b79fa574f"
43
43
  }
package/util/util.go ADDED
@@ -0,0 +1,21 @@
1
+ package util
2
+
3
+ import (
4
+ "github.com/spf13/viper"
5
+ )
6
+
7
+ func IndexOf[T comparable](a []T, x T) int {
8
+ for i, s := range a {
9
+ if s == x {
10
+ return i
11
+ }
12
+ }
13
+ return -1
14
+ }
15
+
16
+ func NewFileOnlyViper(v1 *viper.Viper) (*viper.Viper, error) {
17
+ v2 := viper.New()
18
+ v2.SetConfigFile(v1.ConfigFileUsed())
19
+ err := v2.ReadInConfig()
20
+ return v2, err
21
+ }
@@ -0,0 +1,234 @@
1
+ package swingset
2
+
3
+ import (
4
+ "fmt"
5
+ "path/filepath"
6
+
7
+ "github.com/spf13/viper"
8
+
9
+ "github.com/cosmos/cosmos-sdk/client/flags"
10
+ pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types"
11
+ serverconfig "github.com/cosmos/cosmos-sdk/server/config"
12
+ servertypes "github.com/cosmos/cosmos-sdk/server/types"
13
+
14
+ "github.com/Agoric/agoric-sdk/golang/cosmos/util"
15
+ )
16
+
17
+ const (
18
+ ConfigPrefix = "swingset"
19
+ FlagSlogfile = ConfigPrefix + ".slogfile"
20
+ FlagVatSnapshotArchiveDir = ConfigPrefix + ".vat-snapshot-archive-dir"
21
+ FlagVatTranscriptArchiveDir = ConfigPrefix + ".vat-transcript-archive-dir"
22
+
23
+ SnapshotRetentionOptionDebug = "debug"
24
+ SnapshotRetentionOptionOperational = "operational"
25
+
26
+ TranscriptRetentionOptionArchival = "archival"
27
+ TranscriptRetentionOptionOperational = "operational"
28
+ )
29
+
30
+ var snapshotRetentionValues []string = []string{
31
+ SnapshotRetentionOptionDebug,
32
+ SnapshotRetentionOptionOperational,
33
+ }
34
+
35
+ var transcriptRetentionValues []string = []string{
36
+ TranscriptRetentionOptionArchival,
37
+ TranscriptRetentionOptionOperational,
38
+ }
39
+
40
+ // DefaultConfigTemplate defines a default TOML configuration section for the SwingSet VM.
41
+ // Values are pulled from a "Swingset" property, in accord with CustomAppConfig from
42
+ // ../../daemon/cmd/root.go.
43
+ // See https://github.com/cosmos/cosmos-sdk/issues/20097 for auto-synchronization ideas.
44
+ const DefaultConfigTemplate = `
45
+ ###############################################################################
46
+ ### SwingSet Configuration ###
47
+ ###############################################################################
48
+
49
+ [swingset]
50
+ # The path at which a SwingSet log "slog" file should be written.
51
+ # If relative, it is interpreted against the application home directory
52
+ # (e.g., ~/.agoric).
53
+ # May be overridden by a SLOGFILE environment variable, which if relative is
54
+ # interpreted against the working directory.
55
+ slogfile = "{{ .Swingset.SlogFile }}"
56
+
57
+ # The maximum number of vats that the SwingSet kernel will bring online. A lower number
58
+ # requires less memory but may have a negative performance impact if vats need to
59
+ # be frequently paged out to remain under this limit.
60
+ max-vats-online = {{ .Swingset.MaxVatsOnline }}
61
+
62
+ # Retention of vat snapshots, with values analogous to those of export
63
+ # 'artifactMode' (cf.
64
+ # https://github.com/Agoric/agoric-sdk/blob/master/packages/swing-store/docs/data-export.md#optional--historical-data ).
65
+ # * "debug": keep all snapshots
66
+ # * "operational": keep only the last snapshot
67
+ vat-snapshot-retention = "{{ .Swingset.VatSnapshotRetention }}"
68
+
69
+ # Retention of vat transcript spans, with values analogous to those of export
70
+ # 'artifactMode' (cf.
71
+ # https://github.com/Agoric/agoric-sdk/blob/master/packages/swing-store/docs/data-export.md#optional--historical-data ).
72
+ # * "archival": keep all transcript spans
73
+ # * "operational": keep only necessary transcript spans (i.e., since the
74
+ # last snapshot of their vat)
75
+ # * "default": determined by 'pruning' ("archival" if 'pruning' is "nothing",
76
+ # otherwise "operational")
77
+ vat-transcript-retention = "{{ .Swingset.VatTranscriptRetention }}"
78
+
79
+ # Archival of gzipped vat snapshots.
80
+ vat-snapshot-archive-dir = "{{ .Swingset.VatSnapshotArchiveDir }}"
81
+
82
+ # Archival of historical (i.e., closed) vat transcript spans to gzipped files.
83
+ vat-transcript-archive-dir = "{{ .Swingset.VatTranscriptArchiveDir }}"
84
+ `
85
+
86
+ // SwingsetConfig defines configuration for the SwingSet VM.
87
+ // "mapstructure" tag data is used to direct reads from app.toml;
88
+ // "json" tag data is used to populate init messages for the VM.
89
+ // This should be kept in sync with SwingsetConfigShape in
90
+ // ../../../../packages/cosmic-swingset/src/chain-main.js.
91
+ // TODO: Consider extensions from docs/env.md.
92
+ type SwingsetConfig struct {
93
+ // SlogFile is the path at which a SwingSet log "slog" file should be written.
94
+ // If relative, it is interpreted against the application home directory
95
+ SlogFile string `mapstructure:"slogfile" json:"slogfile,omitempty"`
96
+
97
+ // MaxVatsOnline is the maximum number of vats that the SwingSet kernel will have online
98
+ // at any given time.
99
+ MaxVatsOnline int `mapstructure:"max-vats-online" json:"maxVatsOnline,omitempty"`
100
+
101
+ // VatSnapshotRetention controls retention of vat snapshots,
102
+ // and has values analogous to those of export `artifactMode` (cf.
103
+ // ../../../../packages/swing-store/docs/data-export.md#optional--historical-data ).
104
+ // * "debug": keep all snapshots
105
+ // * "operational": keep only the last snapshot
106
+ VatSnapshotRetention string `mapstructure:"vat-snapshot-retention" json:"vatSnapshotRetention,omitempty"`
107
+
108
+ // VatTranscriptRetention controls retention of vat transcript spans,
109
+ // and has values analogous to those of export `artifactMode` (cf.
110
+ // ../../../../packages/swing-store/docs/data-export.md#optional--historical-data ).
111
+ // * "archival": keep all transcript spans
112
+ // * "operational": keep only necessary transcript spans (i.e., since the
113
+ // last snapshot of their vat)
114
+ // * "default": determined by `pruning` ("archival" if `pruning` is
115
+ // "nothing", otherwise "operational")
116
+ VatTranscriptRetention string `mapstructure:"vat-transcript-retention" json:"vatTranscriptRetention,omitempty"`
117
+
118
+ // VatSnapshotArchiveDir controls archival of gzipped vat snapshots.
119
+ VatSnapshotArchiveDir string `mapstructure:"vat-snapshot-archive-dir" json:"vatSnapshotArchiveDir,omitempty"`
120
+
121
+ // VatTranscriptArchiveDir controls archival of historical (i.e., closed) vat
122
+ // transcript spans to gzipped files.
123
+ VatTranscriptArchiveDir string `mapstructure:"vat-transcript-archive-dir" json:"vatTranscriptArchiveDir,omitempty"`
124
+ }
125
+
126
+ var DefaultSwingsetConfig = SwingsetConfig{
127
+ SlogFile: "",
128
+ MaxVatsOnline: 50,
129
+ VatSnapshotRetention: "operational",
130
+ VatTranscriptRetention: "default",
131
+ }
132
+
133
+ func SwingsetConfigFromViper(resolvedConfig servertypes.AppOptions) (*SwingsetConfig, error) {
134
+ v, ok := resolvedConfig.(*viper.Viper)
135
+ if !ok {
136
+ // Tolerate an apparently empty configuration such as
137
+ // cosmos/cosmos-sdk/simapp EmptyAppOptions, but otherwise require viper.
138
+ if resolvedConfig.Get(flags.FlagHome) != nil {
139
+ return nil, fmt.Errorf("expected an instance of viper!")
140
+ }
141
+ }
142
+ if v == nil {
143
+ return nil, nil
144
+ }
145
+ v.MustBindEnv(FlagSlogfile, "SLOGFILE")
146
+ // See CustomAppConfig in ../../daemon/cmd/root.go.
147
+ type ExtendedConfig struct {
148
+ serverconfig.Config `mapstructure:",squash"`
149
+ Swingset SwingsetConfig `mapstructure:"swingset"`
150
+ }
151
+ extendedConfig := ExtendedConfig{}
152
+ if err := v.Unmarshal(&extendedConfig); err != nil {
153
+ return nil, err
154
+ }
155
+ ssConfig := &extendedConfig.Swingset
156
+
157
+ // Validate vat snapshot retention only if non-empty (because otherwise it
158
+ // it will be omitted, leaving the VM to apply its own defaults).
159
+ if ssConfig.VatSnapshotRetention != "" {
160
+ if util.IndexOf(snapshotRetentionValues, ssConfig.VatSnapshotRetention) == -1 {
161
+ err := fmt.Errorf(
162
+ "value for vat-snapshot-retention must be in %q",
163
+ snapshotRetentionValues,
164
+ )
165
+ return nil, err
166
+ }
167
+ }
168
+
169
+ // Default/validate vat transcript retention.
170
+ if ssConfig.VatTranscriptRetention == "" || ssConfig.VatTranscriptRetention == "default" {
171
+ if extendedConfig.Pruning == pruningtypes.PruningOptionNothing {
172
+ ssConfig.VatTranscriptRetention = TranscriptRetentionOptionArchival
173
+ } else {
174
+ ssConfig.VatTranscriptRetention = TranscriptRetentionOptionOperational
175
+ }
176
+ }
177
+ if util.IndexOf(transcriptRetentionValues, ssConfig.VatTranscriptRetention) == -1 {
178
+ valuesCopy := append([]string{}, transcriptRetentionValues...)
179
+ err := fmt.Errorf(
180
+ "value for vat-transcript-retention must be in %q",
181
+ append(valuesCopy, "default"),
182
+ )
183
+ return nil, err
184
+ }
185
+
186
+ // Interpret relative paths from config files against the application home
187
+ // directory and from other sources (e.g. env vars) against the current
188
+ // working directory.
189
+ var fileOnlyViper *viper.Viper
190
+ resolvePath := func(path, configKey string) (string, error) {
191
+ if path == "" || filepath.IsAbs(path) {
192
+ return path, nil
193
+ }
194
+ if v.InConfig(configKey) {
195
+ if fileOnlyViper == nil {
196
+ var err error
197
+ fileOnlyViper, err = util.NewFileOnlyViper(v)
198
+ if err != nil {
199
+ return "", err
200
+ }
201
+ }
202
+ pathFromFile := fileOnlyViper.GetString(configKey)
203
+ if path == pathFromFile {
204
+ homePath := viper.GetString(flags.FlagHome)
205
+ if homePath == "" {
206
+ return "", fmt.Errorf("cannot resolve path against empty application home")
207
+ }
208
+ absHomePath, err := filepath.Abs(homePath)
209
+ return filepath.Join(absHomePath, path), err
210
+ }
211
+ }
212
+ return filepath.Abs(path)
213
+ }
214
+
215
+ resolvedSlogFile, err := resolvePath(ssConfig.SlogFile, FlagSlogfile)
216
+ if err != nil {
217
+ return nil, err
218
+ }
219
+ ssConfig.SlogFile = resolvedSlogFile
220
+
221
+ resolvedSnapshotDir, err := resolvePath(ssConfig.VatSnapshotArchiveDir, FlagVatSnapshotArchiveDir)
222
+ if err != nil {
223
+ return nil, err
224
+ }
225
+ ssConfig.VatSnapshotArchiveDir = resolvedSnapshotDir
226
+
227
+ resolvedTranscriptDir, err := resolvePath(ssConfig.VatTranscriptArchiveDir, FlagVatTranscriptArchiveDir)
228
+ if err != nil {
229
+ return nil, err
230
+ }
231
+ ssConfig.VatTranscriptArchiveDir = resolvedTranscriptDir
232
+
233
+ return ssConfig, nil
234
+ }
@@ -1,6 +1,8 @@
1
1
  package types
2
2
 
3
3
  import (
4
+ fmt "fmt"
5
+
4
6
  sdkioerrors "cosmossdk.io/errors"
5
7
  "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
6
8
  capability "github.com/cosmos/cosmos-sdk/x/capability/types"
@@ -221,7 +223,10 @@ func (im IBCModule) OnChanCloseInit(
221
223
  }
222
224
 
223
225
  err := im.impl.PushAction(ctx, event)
224
- return err
226
+ if err != nil {
227
+ return err
228
+ }
229
+ return fmt.Errorf("OnChanCloseInit can only be sent by the VM")
225
230
  }
226
231
 
227
232
  type ChannelCloseConfirmEvent struct {
@@ -50,7 +50,7 @@ func NewIBCMiddleware(ibcModule porttypes.IBCModule, vtransferKeeper keeper.Keep
50
50
  // wrapped IBCModule. They are not performed in the context of a packet, and so
51
51
  // do not need to be intercepted.
52
52
 
53
- // OnChanCloseInit implements the IBCModule interface.
53
+ // OnChanOpenInit implements the IBCModule interface.
54
54
  func (im IBCMiddleware) OnChanOpenInit(
55
55
  ctx sdk.Context,
56
56
  order channeltypes.Order,