diff --git a/a3p-integration/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch b/a3p-integration/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch new file mode 100644 index 00000000000..3d01386399d --- /dev/null +++ b/a3p-integration/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch @@ -0,0 +1,13 @@ +diff --git a/dist/upgrade-test-scripts/env_setup.sh b/dist/upgrade-test-scripts/env_setup.sh +index 617a0fbe7efdfa457e28fc52806dba1b323930d8..25f52a6cf133dca830bd0dcd47c91700e6a8effe 100755 +--- a/dist/upgrade-test-scripts/env_setup.sh ++++ b/dist/upgrade-test-scripts/env_setup.sh +@@ -100,7 +100,7 @@ killAgd() { + AGD_PID=$(cat $HOME/.agoric/agd.pid) + kill $AGD_PID + rm $HOME/.agoric/agd.pid +- wait $AGD_PID || true ++ tail --pid=$AGD_PID -f /dev/null || true + } + + provisionSmartWallet() { diff --git a/a3p-integration/package.json b/a3p-integration/package.json index ad8954bd0da..71207d38918 100644 --- a/a3p-integration/package.json +++ b/a3p-integration/package.json @@ -12,7 +12,7 @@ "doctor": "yarn synthetic-chain doctor" }, "dependencies": { - "@agoric/synthetic-chain": "^0.1.0", + "@agoric/synthetic-chain": "patch:@agoric/synthetic-chain@npm%3A0.1.0#~/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch", "@types/better-sqlite3": "^7.6.9" }, "packageManager": "yarn@4.2.2", diff --git a/a3p-integration/proposals/z:acceptance/state-sync-snapshots-test.sh b/a3p-integration/proposals/z:acceptance/state-sync-snapshots-test.sh new file mode 100755 index 00000000000..f4dcf018e97 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/state-sync-snapshots-test.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +source /usr/src/upgrade-test-scripts/env_setup.sh + +set -e + +killAgd +agd snapshots export +SNAPSHOT_DETAILS=$(agd snapshots list | head -n1 | sed -E 's/height: ([0-9]+) format: ([0-9]+) chunks: [0-9]+/\1 \2/') +echo found snapshot $SNAPSHOT_DETAILS +rm -rf /root/.agoric/data/application.db /root/.agoric/data/agoric +agd snapshots restore $SNAPSHOT_DETAILS + +startAgd diff --git a/a3p-integration/proposals/z:acceptance/test.sh b/a3p-integration/proposals/z:acceptance/test.sh index 38ffa27a4ae..0447826a85d 100755 --- a/a3p-integration/proposals/z:acceptance/test.sh +++ b/a3p-integration/proposals/z:acceptance/test.sh @@ -11,3 +11,5 @@ GLOBIGNORE=initial.test.js yarn ava ./*.test.js ./create-kread-item-test.sh + +./state-sync-snapshots-test.sh diff --git a/a3p-integration/yarn.lock b/a3p-integration/yarn.lock index ea0f0da0407..c5c8e80616e 100644 --- a/a3p-integration/yarn.lock +++ b/a3p-integration/yarn.lock @@ -5,7 +5,7 @@ __metadata: version: 8 cacheKey: 10c0 -"@agoric/synthetic-chain@npm:^0.1.0": +"@agoric/synthetic-chain@npm:0.1.0": version: 0.1.0 resolution: "@agoric/synthetic-chain@npm:0.1.0" dependencies: @@ -19,6 +19,20 @@ __metadata: languageName: node linkType: hard +"@agoric/synthetic-chain@patch:@agoric/synthetic-chain@npm%3A0.1.0#~/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch": + version: 0.1.0 + resolution: "@agoric/synthetic-chain@patch:@agoric/synthetic-chain@npm%3A0.1.0#~/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch::version=0.1.0&hash=4a65eb" + dependencies: + "@endo/zip": "npm:^1.0.1" + better-sqlite3: "npm:^9.4.0" + chalk: "npm:^5.3.0" + execa: "npm:^8.0.1" + bin: + synthetic-chain: dist/cli/cli.js + checksum: 10c0/e974038161b1a9570912a02d9366c6680bc13ee3dfd0e49d06e5ce5e93dbcddf04d1d4cd453af0969bf29ccfe96ce3e141a214539722449add90b13f0785f1f7 + languageName: node + linkType: hard + "@endo/zip@npm:^1.0.1": version: 1.0.1 resolution: "@endo/zip@npm:1.0.1" @@ -990,7 +1004,7 @@ __metadata: version: 0.0.0-use.local resolution: "root-workspace-0b6124@workspace:." dependencies: - "@agoric/synthetic-chain": "npm:^0.1.0" + "@agoric/synthetic-chain": "patch:@agoric/synthetic-chain@npm%3A0.1.0#~/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch" "@types/better-sqlite3": "npm:^7.6.9" languageName: unknown linkType: soft diff --git a/golang/cosmos/daemon/cmd/root.go b/golang/cosmos/daemon/cmd/root.go index 55550755207..11af8c8c22e 100644 --- a/golang/cosmos/daemon/cmd/root.go +++ b/golang/cosmos/daemon/cmd/root.go @@ -8,7 +8,6 @@ import ( serverconfig "github.com/cosmos/cosmos-sdk/server/config" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/client/debug" @@ -19,9 +18,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/snapshot" "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/snapshots" - snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" - "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -39,6 +35,7 @@ import ( gaia "github.com/Agoric/agoric-sdk/golang/cosmos/app" "github.com/Agoric/agoric-sdk/golang/cosmos/app/params" "github.com/Agoric/agoric-sdk/golang/cosmos/vm" + swingsetkeeper "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper" ) var AppName = "agd" @@ -142,16 +139,27 @@ func initRootCmd(sender vm.Sender, rootCmd *cobra.Command, encodingConfig params testnetCmd(gaia.ModuleBasics, banktypes.GenesisBalancesIterator{}), debug.Cmd(), config.Cmd(), - pruning.Cmd(ac.newApp, gaia.DefaultNodeHome), - snapshot.Cmd(ac.newApp), + pruning.Cmd(ac.newSnapshotsApp, gaia.DefaultNodeHome), + snapshot.Cmd(ac.newSnapshotsApp), ) server.AddCommands(rootCmd, gaia.DefaultNodeHome, ac.newApp, ac.appExport, addModuleInitFlags) for _, command := range rootCmd.Commands() { - if command.Name() == "export" { + switch command.Name() { + case "export": + addAgoricVMFlags(command) extendCosmosExportCommand(command) - break + case "snapshots": + for _, subCommand := range command.Commands() { + switch subCommand.Name() { + case "restore": + addAgoricVMFlags(subCommand) + case "export": + addAgoricVMFlags(subCommand) + replaceCosmosSnapshotExportCommand(subCommand, ac) + } + } } } @@ -264,22 +272,13 @@ func (ac appCreator) newApp( } } - var cache sdk.MultiStorePersistentCache - - if cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) { - cache = store.NewCommitKVStoreCacheManager() - } + baseappOptions := server.DefaultBaseappOptions(appOpts) skipUpgradeHeights := make(map[int64]bool) for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) { skipUpgradeHeights[int64(h)] = true } - pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts) - if err != nil { - panic(err) - } - homePath := cast.ToString(appOpts.Get(flags.FlagHome)) // Set a default value for FlagSwingStoreExportDir based on the homePath @@ -289,39 +288,41 @@ func (ac appCreator) newApp( viper.Set(gaia.FlagSwingStoreExportDir, filepath.Join(homePath, "config", ExportedSwingStoreDirectoryName)) } - snapshotDir := filepath.Join(homePath, "data", "snapshots") - snapshotDB, err := dbm.NewDB("metadata", dbm.GoLevelDBBackend, snapshotDir) - if err != nil { - panic(err) - } - snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) - if err != nil { - panic(err) - } - snapshotOptions := snapshottypes.NewSnapshotOptions( - cast.ToUint64(appOpts.Get(server.FlagStateSyncSnapshotInterval)), - cast.ToUint32(appOpts.Get(server.FlagStateSyncSnapshotKeepRecent)), + return gaia.NewAgoricApp( + ac.sender, ac.agdServer, + logger, db, traceStore, true, skipUpgradeHeights, + homePath, + cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), + ac.encCfg, + appOpts, + baseappOptions..., ) +} + +func (ac appCreator) newSnapshotsApp( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + appOpts servertypes.AppOptions, +) servertypes.Application { + if OnExportHook != nil { + if err := OnExportHook(ac.agdServer, logger, appOpts); err != nil { + panic(err) + } + } + + baseappOptions := server.DefaultBaseappOptions(appOpts) + + homePath := cast.ToString(appOpts.Get(flags.FlagHome)) return gaia.NewAgoricApp( ac.sender, ac.agdServer, - logger, db, traceStore, true, skipUpgradeHeights, + logger, db, traceStore, true, map[int64]bool{}, homePath, cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), ac.encCfg, appOpts, - baseapp.SetPruning(pruningOpts), - baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))), - baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))), - baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(server.FlagHaltTime))), - baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))), - baseapp.SetInterBlockCache(cache), - baseapp.SetTrace(cast.ToBool(appOpts.Get(server.FlagTrace))), - baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))), - baseapp.SetSnapshot(snapshotStore, snapshotOptions), - baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(server.FlagIAVLCacheSize))), - baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagDisableIAVLFastNode))), - baseapp.SetIAVLLazyLoading(cast.ToBool(appOpts.Get(server.FlagIAVLLazyLoading))), + baseappOptions..., ) } @@ -342,7 +343,6 @@ const ( // cosmos-sdk to add a required "export-dir" command-line flag, and create the // genesis export in the specified directory if the VM is running. func extendCosmosExportCommand(cmd *cobra.Command) { - addAgoricVMFlags(cmd) cmd.Flags().String(FlagExportDir, "", "The directory where to create the genesis export") err := cmd.MarkFlagRequired(FlagExportDir) if err != nil { @@ -443,3 +443,62 @@ func (ac appCreator) appExport( return gaiaApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) } + +// replaceCosmosSnapshotExportCommand monkey-patches the "snapshots export" command +// added by cosmos-sdk and replaces its implementation with one suitable for +// our modifications to the cosmos snapshots process +func replaceCosmosSnapshotExportCommand(cmd *cobra.Command, ac appCreator) { + // Copy of RunE is cosmos-sdk/client/snapshot/export.go + replacedRunE := func(cmd *cobra.Command, args []string) error { + ctx := server.GetServerContextFromCmd(cmd) + + height, err := cmd.Flags().GetInt64("height") + if err != nil { + return err + } + + home := ctx.Config.RootDir + dataDir := filepath.Join(home, "data") + db, err := dbm.NewDB("application", server.GetAppDBBackend(ctx.Viper), dataDir) + if err != nil { + return err + } + + app := ac.newSnapshotsApp(ctx.Logger, db, nil, ctx.Viper) + gaiaApp := app.(*gaia.GaiaApp) + + if height == 0 { + height = app.CommitMultiStore().LastCommitID().Version + } + + cmd.Printf("Exporting snapshot for height %d\n", height) + + err = gaiaApp.SwingSetSnapshotter.InitiateSnapshot(height) + if err != nil { + return err + } + + err = swingsetkeeper.WaitUntilSwingStoreExportDone() + if err != nil { + return err + } + + snapshotList, err := app.SnapshotManager().List() + if err != nil { + return err + } + + snapshotHeight := uint64(height) + + for _, snapshot := range snapshotList { + if snapshot.Height == snapshotHeight { + cmd.Printf("Snapshot created at height %d, format %d, chunks %d\n", snapshot.Height, snapshot.Format, snapshot.Chunks) + break + } + } + + return nil + } + + cmd.RunE = replacedRunE +}