From f8f51c52e3f8c3ec407436e6c2508205c95cc546 Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 11 Jul 2024 19:04:10 +0400 Subject: [PATCH 1/2] fix: add fixed export with abci --- cmd/neutrond/export.go | 153 +++++++++++++++++++++++++++++++++++++++++ cmd/neutrond/root.go | 1 + cmd/neutrond/util.go | 17 +++++ 3 files changed, 171 insertions(+) create mode 100644 cmd/neutrond/export.go diff --git a/cmd/neutrond/export.go b/cmd/neutrond/export.go new file mode 100644 index 000000000..81c989ef5 --- /dev/null +++ b/cmd/neutrond/export.go @@ -0,0 +1,153 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + cmttypes "github.com/cometbft/cometbft/types" + "github.com/cosmos/cosmos-sdk/server" + "io" + "os" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/version" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" +) + +const ( + FlagHeight = "height" + FlagForZeroHeight = "for-zero-height" + FlagJailAllowedAddrs = "jail-allowed-addrs" + FlagModulesToExport = "modules-to-export" + flagTraceStore = "trace-store" +) + +// ExportCmd dumps app state to JSON. +func ExportFixCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Command { + cmd := &cobra.Command{ + Use: "export-fix", + Short: "(Fixed: ABCI) Export state to JSON", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + serverCtx := server.GetServerContextFromCmd(cmd) + config := serverCtx.Config + + homeDir, _ := cmd.Flags().GetString(flags.FlagHome) + config.SetRoot(homeDir) + + if _, err := os.Stat(config.GenesisFile()); os.IsNotExist(err) { + return err + } + + db, err := openDB(config.RootDir, server.GetAppDBBackend(serverCtx.Viper)) + if err != nil { + return err + } + + if appExporter == nil { + if _, err := fmt.Fprintln(cmd.ErrOrStderr(), "WARNING: App exporter not defined. Returning genesis file."); err != nil { + return err + } + + // Open file in read-only mode so we can copy it to stdout. + // It is possible that the genesis file is large, + // so we don't need to read it all into memory + // before we stream it out. + f, err := os.OpenFile(config.GenesisFile(), os.O_RDONLY, 0) + if err != nil { + return err + } + defer f.Close() + + if _, err := io.Copy(cmd.OutOrStdout(), f); err != nil { + return err + } + + return nil + } + + traceWriterFile, _ := cmd.Flags().GetString(flagTraceStore) + traceWriter, err := openTraceWriter(traceWriterFile) + if err != nil { + return err + } + + height, _ := cmd.Flags().GetInt64(FlagHeight) + forZeroHeight, _ := cmd.Flags().GetBool(FlagForZeroHeight) + jailAllowedAddrs, _ := cmd.Flags().GetStringSlice(FlagJailAllowedAddrs) + modulesToExport, _ := cmd.Flags().GetStringSlice(FlagModulesToExport) + outputDocument, _ := cmd.Flags().GetString(flags.FlagOutputDocument) + + exported, err := appExporter(serverCtx.Logger, db, traceWriter, height, forZeroHeight, jailAllowedAddrs, serverCtx.Viper, modulesToExport) + if err != nil { + return fmt.Errorf("error exporting state: %w", err) + } + + appGenesis, err := genutiltypes.AppGenesisFromFile(serverCtx.Config.GenesisFile()) + if err != nil { + return err + } + + // set current binary version + appGenesis.AppName = version.AppName + appGenesis.AppVersion = version.Version + + appGenesis.AppState = exported.AppState + appGenesis.InitialHeight = exported.Height + appGenesis.Consensus = NewConsensusGenesis(exported.ConsensusParams, exported.Validators) + + out, err := json.Marshal(appGenesis) + if err != nil { + return err + } + + if outputDocument == "" { + // Copy the entire genesis file to stdout. + _, err := io.Copy(cmd.OutOrStdout(), bytes.NewReader(out)) + return err + } + + if err = appGenesis.SaveAs(outputDocument); err != nil { + return err + } + + return nil + }, + } + + cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") + cmd.Flags().Int64(FlagHeight, -1, "Export state from a particular height (-1 means latest height)") + cmd.Flags().Bool(FlagForZeroHeight, false, "Export state to start at height zero (perform preproccessing)") + cmd.Flags().StringSlice(FlagJailAllowedAddrs, []string{}, "Comma-separated list of operator addresses of jailed validators to unjail") + cmd.Flags().StringSlice(FlagModulesToExport, []string{}, "Comma-separated list of modules to export. If empty, will export all modules") + cmd.Flags().String(flags.FlagOutputDocument, "", "Exported state is written to the given file instead of STDOUT") + + return cmd +} + +func NewConsensusGenesis(params cmtproto.ConsensusParams, validators []cmttypes.GenesisValidator) *genutiltypes.ConsensusGenesis { + return &genutiltypes.ConsensusGenesis{ + Params: &cmttypes.ConsensusParams{ + Block: cmttypes.BlockParams{ + MaxBytes: params.Block.MaxBytes, + MaxGas: params.Block.MaxGas, + }, + Evidence: cmttypes.EvidenceParams{ + MaxAgeNumBlocks: params.Evidence.MaxAgeNumBlocks, + MaxAgeDuration: params.Evidence.MaxAgeDuration, + MaxBytes: params.Evidence.MaxBytes, + }, + Validator: cmttypes.ValidatorParams{ + PubKeyTypes: params.Validator.PubKeyTypes, + }, + ABCI: cmttypes.ABCIParams{ + VoteExtensionsEnableHeight: params.Abci.VoteExtensionsEnableHeight, + }, + }, + Validators: validators, + } +} diff --git a/cmd/neutrond/root.go b/cmd/neutrond/root.go index 112182eba..ff5d2b79b 100644 --- a/cmd/neutrond/root.go +++ b/cmd/neutrond/root.go @@ -174,6 +174,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { server.ShowAddressCmd(), queryCommand(), txCommand(), + ExportFixCmd(ac.appExport, app.DefaultNodeHome), keys.Commands(), ) } diff --git a/cmd/neutrond/util.go b/cmd/neutrond/util.go index 00dece1ea..f5d17ee8d 100644 --- a/cmd/neutrond/util.go +++ b/cmd/neutrond/util.go @@ -2,6 +2,7 @@ package main import ( "fmt" + dbm "github.com/cosmos/cosmos-db" "io" "os" "path" @@ -256,3 +257,19 @@ func bindFlags(basename string, cmd *cobra.Command, v *viper.Viper) (err error) return err } + +func openDB(rootDir string, backendType dbm.BackendType) (dbm.DB, error) { + dataDir := filepath.Join(rootDir, "data") + return dbm.NewDB("application", backendType, dataDir) +} + +func openTraceWriter(traceWriterFile string) (w io.WriteCloser, err error) { + if traceWriterFile == "" { + return + } + return os.OpenFile( + traceWriterFile, + os.O_WRONLY|os.O_APPEND|os.O_CREATE, + 0o666, + ) +} From 2edeb4d8d4e544f869f9aa340e60293956b60baa Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 11 Jul 2024 19:25:21 +0400 Subject: [PATCH 2/2] lint --- cmd/neutrond/export.go | 5 +++-- cmd/neutrond/util.go | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cmd/neutrond/export.go b/cmd/neutrond/export.go index 81c989ef5..1ef15c658 100644 --- a/cmd/neutrond/export.go +++ b/cmd/neutrond/export.go @@ -4,11 +4,12 @@ import ( "bytes" "encoding/json" "fmt" + "io" + "os" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" cmttypes "github.com/cometbft/cometbft/types" "github.com/cosmos/cosmos-sdk/server" - "io" - "os" "github.com/spf13/cobra" diff --git a/cmd/neutrond/util.go b/cmd/neutrond/util.go index f5d17ee8d..23608e824 100644 --- a/cmd/neutrond/util.go +++ b/cmd/neutrond/util.go @@ -2,13 +2,14 @@ package main import ( "fmt" - dbm "github.com/cosmos/cosmos-db" "io" "os" "path" "path/filepath" "strings" + dbm "github.com/cosmos/cosmos-db" + "cosmossdk.io/log" cmtcfg "github.com/cometbft/cometbft/config"