From c8b56b96851fe6caba1cedda7d4f6ce41289da0b Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Fri, 21 Jun 2024 11:40:15 -0600 Subject: [PATCH 1/4] module hash by height query --- cmd/osmosisd/cmd/module_hash_by_height.go | 111 ++++++++++++++++++++++ cmd/osmosisd/cmd/root.go | 1 + 2 files changed, 112 insertions(+) create mode 100644 cmd/osmosisd/cmd/module_hash_by_height.go diff --git a/cmd/osmosisd/cmd/module_hash_by_height.go b/cmd/osmosisd/cmd/module_hash_by_height.go new file mode 100644 index 00000000000..83a528e06f3 --- /dev/null +++ b/cmd/osmosisd/cmd/module_hash_by_height.go @@ -0,0 +1,111 @@ +package cmd + +// DONTCOVER + +import ( + "encoding/hex" + "fmt" + "sort" + "strconv" + "strings" + + "github.com/spf13/cobra" + + "path/filepath" + + dbm "github.com/cosmos/cosmos-db" + + "github.com/cosmos/cosmos-sdk/server" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + + "cosmossdk.io/store/rootmulti" + storetypes "cosmossdk.io/store/types" +) + +// forceprune gets cmd to convert any bech32 address to an osmo prefix. +func moduleHashByHeightQuery(appCreator servertypes.AppCreator) *cobra.Command { + cmd := &cobra.Command{ + Use: "module-hash-by-height [height]", + Short: "Get module hashes at a given height", + Long: `Get module hashes at a given height. This command is useful for debugging and verifying the state of the application at a given height. +Example: + osmosisd module-hash-by-height 16841115, +`, + Args: cobra.ExactArgs(1), // Ensure exactly one argument is provided + RunE: func(cmd *cobra.Command, args []string) error { + heightToRetrieveString := args[0] + + serverCtx := server.GetServerContextFromCmd(cmd) + + height, err := strconv.ParseInt(heightToRetrieveString, 10, 64) + if err != nil { + return err + } + + commitInfoForHeight, err := getModuleHashesAtHeight(serverCtx, appCreator, height) + if err != nil { + return err + } + + // Print the CommitInfo to the console. + fmt.Println(commitInfoForHeight.String()) + + return nil + }, + } + + return cmd +} + +func getModuleHashesAtHeight(svrCtx *server.Context, appCreator servertypes.AppCreator, height int64) (*storetypes.CommitInfo, error) { + home := svrCtx.Config.RootDir + db, err := openDB(home, server.GetAppDBBackend(svrCtx.Viper)) + if err != nil { + return nil, err + } + app := appCreator(svrCtx.Logger, db, nil, nil) + rms, ok := app.CommitMultiStore().(*rootmulti.Store) + if !ok { + return nil, fmt.Errorf("expected rootmulti.Store, got %T", app.CommitMultiStore()) + } + + commitInfoForHeight, err := rms.GetCommitInfo(height) + if err != nil { + return nil, err + } + + // Create a new slice of StoreInfos for storing the modified hashes. + storeInfos := make([]storetypes.StoreInfo, len(commitInfoForHeight.StoreInfos)) + + for i, storeInfo := range commitInfoForHeight.StoreInfos { + // Convert the hash to a hexadecimal string. + hash := strings.ToUpper(hex.EncodeToString(storeInfo.CommitId.Hash)) + + // Create a new StoreInfo with the modified hash. + storeInfos[i] = storetypes.StoreInfo{ + Name: storeInfo.Name, + CommitId: storetypes.CommitID{ + Version: storeInfo.CommitId.Version, + Hash: []byte(hash), + }, + } + } + + // Sort the storeInfos slice based on the module name. + sort.Slice(storeInfos, func(i, j int) bool { + return storeInfos[i].Name < storeInfos[j].Name + }) + + // Create a new CommitInfo with the modified StoreInfos. + commitInfoForHeight = &storetypes.CommitInfo{ + Version: commitInfoForHeight.Version, + StoreInfos: storeInfos, + } + + return commitInfoForHeight, nil +} + +func openDB(rootDir string, backendType dbm.BackendType) (dbm.DB, error) { + dataDir := filepath.Join(rootDir, "data") + return dbm.NewDB("application", backendType, dataDir) +} diff --git a/cmd/osmosisd/cmd/root.go b/cmd/osmosisd/cmd/root.go index 964e439106b..06342957fc7 100644 --- a/cmd/osmosisd/cmd/root.go +++ b/cmd/osmosisd/cmd/root.go @@ -717,6 +717,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig, t rootCmd.AddCommand( // genutilcli.InitCmd(tempApp.ModuleBasics, osmosis.DefaultNodeHome), forceprune(), + moduleHashByHeightQuery(newApp), InitCmd(tempApp.ModuleBasics, osmosis.DefaultNodeHome), genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, osmosis.DefaultNodeHome, genutiltypes.DefaultMessageValidator, valOperAddressCodec), ExportDeriveBalancesCmd(), From 1c5561fdb28a6fe6b64854de7c6f4f8262603e96 Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Fri, 21 Jun 2024 11:56:15 -0600 Subject: [PATCH 2/4] expand error --- cmd/osmosisd/cmd/module_hash_by_height.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/osmosisd/cmd/module_hash_by_height.go b/cmd/osmosisd/cmd/module_hash_by_height.go index 83a528e06f3..ce49d7910a2 100644 --- a/cmd/osmosisd/cmd/module_hash_by_height.go +++ b/cmd/osmosisd/cmd/module_hash_by_height.go @@ -61,7 +61,7 @@ func getModuleHashesAtHeight(svrCtx *server.Context, appCreator servertypes.AppC home := svrCtx.Config.RootDir db, err := openDB(home, server.GetAppDBBackend(svrCtx.Viper)) if err != nil { - return nil, err + return nil, fmt.Errorf("error opening DB, make sure osmosisd is not running when calling this query: %w", err) } app := appCreator(svrCtx.Logger, db, nil, nil) rms, ok := app.CommitMultiStore().(*rootmulti.Store) From fd5d68e223263e24549893407b42de6c099d4ae5 Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Fri, 21 Jun 2024 11:56:39 -0600 Subject: [PATCH 3/4] add viper ctx --- cmd/osmosisd/cmd/module_hash_by_height.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/osmosisd/cmd/module_hash_by_height.go b/cmd/osmosisd/cmd/module_hash_by_height.go index ce49d7910a2..4d52b4ef9cd 100644 --- a/cmd/osmosisd/cmd/module_hash_by_height.go +++ b/cmd/osmosisd/cmd/module_hash_by_height.go @@ -63,7 +63,7 @@ func getModuleHashesAtHeight(svrCtx *server.Context, appCreator servertypes.AppC if err != nil { return nil, fmt.Errorf("error opening DB, make sure osmosisd is not running when calling this query: %w", err) } - app := appCreator(svrCtx.Logger, db, nil, nil) + app := appCreator(svrCtx.Logger, db, nil, svrCtx.Viper) rms, ok := app.CommitMultiStore().(*rootmulti.Store) if !ok { return nil, fmt.Errorf("expected rootmulti.Store, got %T", app.CommitMultiStore()) From 40c208993248462602fe49d3a65783790267531e Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Tue, 25 Jun 2024 16:41:43 -0500 Subject: [PATCH 4/4] Update module_hash_by_height.go --- cmd/osmosisd/cmd/module_hash_by_height.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/osmosisd/cmd/module_hash_by_height.go b/cmd/osmosisd/cmd/module_hash_by_height.go index 4d52b4ef9cd..caa1bc28c0d 100644 --- a/cmd/osmosisd/cmd/module_hash_by_height.go +++ b/cmd/osmosisd/cmd/module_hash_by_height.go @@ -22,7 +22,7 @@ import ( storetypes "cosmossdk.io/store/types" ) -// forceprune gets cmd to convert any bech32 address to an osmo prefix. +// ModuleHashByHeightQuery retrieves the module hashes at a given height. func moduleHashByHeightQuery(appCreator servertypes.AppCreator) *cobra.Command { cmd := &cobra.Command{ Use: "module-hash-by-height [height]",