From 55ba7f6c3d6a958d3eb5c6c8b191b649da05809f Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Sat, 22 Jul 2023 00:16:08 +0000 Subject: [PATCH] feat(x/swingset): import swing store from genesis state --- golang/cosmos/daemon/cmd/root.go | 8 +++++ golang/cosmos/x/swingset/genesis.go | 47 ++++++++++++++++++++++++----- golang/cosmos/x/swingset/module.go | 3 +- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/golang/cosmos/daemon/cmd/root.go b/golang/cosmos/daemon/cmd/root.go index 95c6c1f2433..35a59ceb101 100644 --- a/golang/cosmos/daemon/cmd/root.go +++ b/golang/cosmos/daemon/cmd/root.go @@ -28,6 +28,7 @@ import ( genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" "github.com/spf13/cast" "github.com/spf13/cobra" + "github.com/spf13/viper" tmcli "github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" @@ -243,6 +244,13 @@ func (ac appCreator) newApp( homePath := cast.ToString(appOpts.Get(flags.FlagHome)) + // Set a default value for FlagSwingStoreExportDir based on the homePath + // in case we need to InitGenesis with swing-store data + viper, ok := appOpts.(*viper.Viper) + if ok && cast.ToString(appOpts.Get(gaia.FlagSwingStoreExportDir)) == "" { + viper.Set(gaia.FlagSwingStoreExportDir, filepath.Join(homePath, "config", ExportedSwingStoreDirectoryName)) + } + snapshotDir := filepath.Join(homePath, "data", "snapshots") snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir) if err != nil { diff --git a/golang/cosmos/x/swingset/genesis.go b/golang/cosmos/x/swingset/genesis.go index 1334da697bd..a738e1497c7 100644 --- a/golang/cosmos/x/swingset/genesis.go +++ b/golang/cosmos/x/swingset/genesis.go @@ -30,18 +30,49 @@ func DefaultGenesisState() *types.GenesisState { // InitGenesis initializes the (Cosmos-side) SwingSet state from the GenesisState. // Returns whether the app should send a bootstrap action to the controller. -func InitGenesis(ctx sdk.Context, keeper Keeper, data *types.GenesisState) bool { - keeper.SetParams(ctx, data.GetParams()) - keeper.SetState(ctx, data.GetState()) +func InitGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingStoreExportsHandler, swingStoreExportDir string, data *types.GenesisState) bool { + k.SetParams(ctx, data.GetParams()) + k.SetState(ctx, data.GetState()) swingStoreExportData := data.GetSwingStoreExportData() - if len(swingStoreExportData) > 0 { - // See https://github.com/Agoric/agoric-sdk/issues/6527 - panic("genesis with swing-store state not implemented") + if len(swingStoreExportData) == 0 { + return true } - // TODO: bootstrap only if not restoring swing-store from genesis state - return true + artifactProvider, err := keeper.OpenSwingStoreExportDirectory(swingStoreExportDir) + if err != nil { + panic(err) + } + + swingStore := k.GetSwingStore(ctx) + + for _, entry := range swingStoreExportData { + swingStore.Set([]byte(entry.Key), []byte(entry.Value)) + } + + snapshotHeight := uint64(ctx.BlockHeight()) + + getExportDataReader := func() (agoric.KVEntryReader, error) { + exportDataIterator := swingStore.Iterator(nil, nil) + return agoric.NewKVIteratorReader(exportDataIterator), nil + } + + err = swingStoreExportsHandler.RestoreExport( + keeper.SwingStoreExportProvider{ + BlockHeight: snapshotHeight, + GetExportDataReader: getExportDataReader, + ReadNextArtifact: artifactProvider.ReadNextArtifact, + }, + keeper.SwingStoreRestoreOptions{ + ArtifactMode: keeper.SwingStoreArtifactModeReplay, + ExportDataMode: keeper.SwingStoreExportDataModeAll, + }, + ) + if err != nil { + panic(err) + } + + return false } func ExportGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingStoreExportsHandler, swingStoreExportDir string) *types.GenesisState { diff --git a/golang/cosmos/x/swingset/module.go b/golang/cosmos/x/swingset/module.go index 42b207dab38..ec6f3b4fd45 100644 --- a/golang/cosmos/x/swingset/module.go +++ b/golang/cosmos/x/swingset/module.go @@ -163,7 +163,8 @@ func (am AppModule) checkSwingStoreExportSetup() { func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - bootstrapNeeded := InitGenesis(ctx, am.keeper, &genesisState) + am.checkSwingStoreExportSetup() + bootstrapNeeded := InitGenesis(ctx, am.keeper, am.swingStoreExportsHandler, am.swingStoreExportDir, &genesisState) if bootstrapNeeded { am.setBootstrapNeeded() }