Skip to content

Commit

Permalink
feat(server/v2/store): Add ModuleHashByHeightQuery command (#23479)
Browse files Browse the repository at this point in the history
  • Loading branch information
julienrbrt authored Jan 22, 2025
1 parent 39b0244 commit 3860b2b
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 1 deletion.
90 changes: 90 additions & 0 deletions server/v2/store/commands.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package store

import (
"encoding/hex"
"encoding/json"
"fmt"
"sort"
"strconv"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"cosmossdk.io/log"
serverv2 "cosmossdk.io/server/v2"
storev2 "cosmossdk.io/store/v2"
"cosmossdk.io/store/v2/proof"
"cosmossdk.io/store/v2/root"
)

Expand Down Expand Up @@ -74,6 +80,90 @@ Supported app-db-backend types include 'goleveldb', 'pebbledb'.`,
return cmd
}

// ModuleHashByHeightQuery retrieves the module hashes at a given height.
func (s *Server[T]) ModuleHashByHeightQuery() *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. Daemon should not be running when calling this command.",
Example: "<appd module-hash-by-height 16841115",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
vp := serverv2.GetViperFromCmd(cmd)
if err := vp.BindPFlags(cmd.Flags()); err != nil {
return err
}
if err := vp.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
}

heightToRetrieveString := args[0]
height, err := strconv.ParseInt(heightToRetrieveString, 10, 64)
if err != nil {
return fmt.Errorf("invalid height: %w", err)
}

commitInfoForHeight, err := getModuleHashesAtHeight(vp, serverv2.GetLoggerFromCmd(cmd), uint64(height))
if err != nil {
return err
}

bytes, err := json.Marshal(commitInfoForHeight)
if err != nil {
return fmt.Errorf("failed to marshal commit info: %w", err)
}

cmd.Println(string(bytes))
return nil
},
}

return cmd
}

func getModuleHashesAtHeight(vp *viper.Viper, logger log.Logger, height uint64) (*proof.CommitInfo, error) {
rootStore, _, err := createRootStore(vp, logger)
if err != nil {
return nil, fmt.Errorf("can not create root store %w", err)
}

commitInfoForHeight, err := rootStore.GetStateCommitment().GetCommitInfo(height)
if err != nil {
return nil, err
}

// Create a new slice of StoreInfos for storing the modified hashes.
storeInfos := make([]*proof.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] = &proof.StoreInfo{
Name: storeInfo.Name,
CommitId: &proof.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 = &proof.CommitInfo{
Version: commitInfoForHeight.Version,
StoreInfos: storeInfos,
Timestamp: commitInfoForHeight.Timestamp,
}

return commitInfoForHeight, nil
}

func createRootStore(v *viper.Viper, logger log.Logger) (storev2.RootStore, root.Options, error) {
storeConfig, err := UnmarshalConfig(v.AllSettings())
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions server/v2/store/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func (s *Server[T]) CLICommands() serverv2.CLIConfig {
s.DumpArchiveCmd(),
s.LoadArchiveCmd(),
s.RestoreSnapshotCmd(),
s.ModuleHashByHeightQuery(),
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion server/v2/store/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (s *Server[T]) ExportSnapshotCmd() *cobra.Command {
if err != nil {
return err
}
height = int64(lastCommitId.Version)
height = lastCommitId.Version
}

cmd.Printf("Exporting snapshot for height %d\n", height)
Expand Down

0 comments on commit 3860b2b

Please sign in to comment.