Skip to content

Commit

Permalink
Support for snapshots export command (#9563)
Browse files Browse the repository at this point in the history
closes: #9100
closes: #9425

Until we have better layering of the snapshots extensions in cosmos-sdk, this replaces the implementation of the `snapshots export` command to initiate the snapshot creation through our front-running mechanism used for state-sync.

Drive-by cleanup of the root command as well to address #9425

None,

None

Communicate to validators that we fixed the command and that it's usable as expected with any cosmos chain.

Added an integration test since this only modifies the command line handling

Manually tested with the following
```
cd packages/cosmic-swingset
make scenario2-setup
make scenario2-run-chain
agd --home t1/n0 snapshots export
rm -rf t1/n0/data/application.db t1/n0/data/agoric
agd --home t1/n0 snapshot restore $snapshot_height 2
make scenario2-run-chain
```

Since we replace the upstream sdk command handling, any future changes upstream would have to be reflected in the override.
  • Loading branch information
mergify[bot] authored and mhofman committed Jun 23, 2024
1 parent 6f7ea64 commit a54db22
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -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() {
2 changes: 1 addition & 1 deletion a3p-integration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"doctor": "yarn synthetic-chain doctor"
},
"dependencies": {
"@agoric/synthetic-chain": "^0.0.10"
"@agoric/synthetic-chain": "patch:@agoric/synthetic-chain@npm%3A0.1.0#~/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch"
},
"packageManager": "yarn@4.1.0",
"license": "Apache-2.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions a3p-integration/proposals/a:upgrade-15/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
# The effects of this step are not persisted in further proposal layers.

yarn ava

./state-sync-snapshots-test.sh
23 changes: 19 additions & 4 deletions a3p-integration/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ __metadata:
version: 8
cacheKey: 10c0

"@agoric/synthetic-chain@npm:^0.0.10":
version: 0.0.10
resolution: "@agoric/synthetic-chain@npm:0.0.10"
"@agoric/synthetic-chain@npm:0.1.0":
version: 0.1.0
resolution: "@agoric/synthetic-chain@npm:0.1.0"
dependencies:
"@endo/zip": "npm:^1.0.1"
better-sqlite3: "npm:^9.4.0"
Expand All @@ -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.4
resolution: "@endo/zip@npm:1.0.4"
Expand Down Expand Up @@ -982,7 +996,8 @@ __metadata:
version: 0.0.0-use.local
resolution: "root-workspace-0b6124@workspace:."
dependencies:
"@agoric/synthetic-chain": "npm:^0.0.10"
"@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

Expand Down
143 changes: 100 additions & 43 deletions golang/cosmos/daemon/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,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"
Expand All @@ -20,9 +19,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"
Expand All @@ -39,6 +35,7 @@ import (

gaia "github.com/Agoric/agoric-sdk/golang/cosmos/app"
"github.com/Agoric/agoric-sdk/golang/cosmos/app/params"
swingsetkeeper "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
)

// Sender is a function that sends a request to the controller.
Expand Down Expand Up @@ -144,17 +141,25 @@ func initRootCmd(sender Sender, rootCmd *cobra.Command, encodingConfig params.En
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)

hasVMController := sender != nil
for _, command := range rootCmd.Commands() {
if command.Name() == "export" {
switch command.Name() {
case "export":
extendCosmosExportCommand(command, hasVMController)
break
case "snapshots":
for _, subCommand := range command.Commands() {
switch subCommand.Name() {
case "restore":
case "export":
replaceCosmosSnapshotExportCommand(subCommand, ac)
}
}
}
}

Expand Down Expand Up @@ -243,22 +248,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
Expand All @@ -268,39 +264,41 @@ func (ac appCreator) newApp(
viper.Set(gaia.FlagSwingStoreExportDir, filepath.Join(homePath, "config", ExportedSwingStoreDirectoryName))
}

snapshotDir := filepath.Join(homePath, "data", "snapshots")
snapshotDB, err := sdk.NewLevelDB("metadata", 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,
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(logger, appOpts); err != nil {
panic(err)
}
}

baseappOptions := server.DefaultBaseappOptions(appOpts)

homePath := cast.ToString(appOpts.Get(flags.FlagHome))

return gaia.NewAgoricApp(
ac.sender,
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...,
)
}

Expand Down Expand Up @@ -418,3 +416,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
}

0 comments on commit a54db22

Please sign in to comment.