mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-11-10 10:05:18 +00:00
* port iavlviewer to kava v0.26.x to debug app hash * add hash subcommand to iavlviewer additionally, use better error handling * update changelog * separate iavlviewer command into subcommands --------- Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com>
This commit is contained in:
parent
0dc30538b7
commit
1f31621b11
@ -36,6 +36,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- (cli) [#1922] Add `iavlviewer` CLI command for low-level iavl db debugging.
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
- (pricefeed) [#1851] optimize EndBlocker to iterate all markets only once
|
- (pricefeed) [#1851] optimize EndBlocker to iterate all markets only once
|
||||||
- (cdp) [#1822] optimize BeginBlocker by removing unnecessary/redundant checks & calculations
|
- (cdp) [#1822] optimize BeginBlocker by removing unnecessary/redundant checks & calculations
|
||||||
@ -334,6 +337,7 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md).
|
|||||||
- [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run
|
- [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run
|
||||||
large-scale simulations remotely using aws-batch
|
large-scale simulations remotely using aws-batch
|
||||||
|
|
||||||
|
[#1922]: https://github.com/Kava-Labs/kava/pull/1922
|
||||||
[#1851]: https://github.com/Kava-Labs/kava/pull/1851
|
[#1851]: https://github.com/Kava-Labs/kava/pull/1851
|
||||||
[#1846]: https://github.com/Kava-Labs/kava/pull/1846
|
[#1846]: https://github.com/Kava-Labs/kava/pull/1846
|
||||||
[#1848]: https://github.com/Kava-Labs/kava/pull/1848
|
[#1848]: https://github.com/Kava-Labs/kava/pull/1848
|
||||||
|
56
cmd/kava/cmd/iavlviewer/data.go
Normal file
56
cmd/kava/cmd/iavlviewer/data.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package iavlviewer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/cosmos/iavl"
|
||||||
|
ethermintserver "github.com/evmos/ethermint/server"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newDataCmd(opts ethermintserver.StartOptions) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "data <prefix> [version number]",
|
||||||
|
Short: "View all keys, hash, & size of tree.",
|
||||||
|
Args: cobra.RangeArgs(1, 2),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
prefix := args[0]
|
||||||
|
version := 0
|
||||||
|
if len(args) == 2 {
|
||||||
|
var err error
|
||||||
|
version, err = parseVersion(args[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tree, err := openPrefixTree(opts, cmd, prefix, version)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
printKeys(tree)
|
||||||
|
hash, err := tree.Hash()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Hash: %X\n", hash)
|
||||||
|
fmt.Printf("Size: %X\n", tree.Size())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func printKeys(tree *iavl.MutableTree) {
|
||||||
|
fmt.Println("Printing all keys with hashed values (to detect diff)")
|
||||||
|
tree.Iterate(func(key []byte, value []byte) bool { //nolint:errcheck
|
||||||
|
printKey := parseWeaveKey(key)
|
||||||
|
digest := sha256.Sum256(value)
|
||||||
|
fmt.Printf(" %s\n %X\n", printKey, digest)
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
42
cmd/kava/cmd/iavlviewer/hash.go
Normal file
42
cmd/kava/cmd/iavlviewer/hash.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package iavlviewer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
ethermintserver "github.com/evmos/ethermint/server"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newHashCmd(opts ethermintserver.StartOptions) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "hash <prefix> [version number]",
|
||||||
|
Short: "Print the root hash of the iavl tree.",
|
||||||
|
Args: cobra.RangeArgs(1, 2),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
prefix := args[0]
|
||||||
|
version := 0
|
||||||
|
if len(args) == 2 {
|
||||||
|
var err error
|
||||||
|
version, err = parseVersion(args[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tree, err := openPrefixTree(opts, cmd, prefix, version)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := tree.Hash()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Hash: %X\n", hash)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
83
cmd/kava/cmd/iavlviewer/root.go
Normal file
83
cmd/kava/cmd/iavlviewer/root.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package iavlviewer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
dbm "github.com/cometbft/cometbft-db"
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
|
ethermintserver "github.com/evmos/ethermint/server"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/cosmos/iavl"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultCacheSize int = 10000
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCmd(opts ethermintserver.StartOptions) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "iavlviewer <data|hash|shape|versions> <prefix> [version number]",
|
||||||
|
Short: "Output various data, hashes, and calculations for an iavl tree",
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(newDataCmd(opts))
|
||||||
|
cmd.AddCommand(newHashCmd(opts))
|
||||||
|
cmd.AddCommand(newShapeCmd(opts))
|
||||||
|
cmd.AddCommand(newVersionsCmd(opts))
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseVersion(arg string) (int, error) {
|
||||||
|
version, err := strconv.Atoi(arg)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("invalid version number: '%s'", arg)
|
||||||
|
}
|
||||||
|
return version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func openPrefixTree(opts ethermintserver.StartOptions, cmd *cobra.Command, prefix string, version int) (*iavl.MutableTree, error) {
|
||||||
|
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||||
|
ctx := server.GetServerContextFromCmd(cmd)
|
||||||
|
ctx.Config.SetRoot(clientCtx.HomeDir)
|
||||||
|
|
||||||
|
db, err := opts.DBOpener(ctx.Viper, clientCtx.HomeDir, server.GetAppDBBackend(ctx.Viper))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to open database at %s: %s", clientCtx.HomeDir, err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := db.Close(); err != nil {
|
||||||
|
ctx.Logger.Error("error closing db", "error", err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
tree, err := readTree(db, version, []byte(prefix))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to read tree with prefix %s: %s", prefix, err)
|
||||||
|
}
|
||||||
|
return tree, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadTree loads an iavl tree from the directory
|
||||||
|
// If version is 0, load latest, otherwise, load named version
|
||||||
|
// The prefix represents which iavl tree you want to read. The iaviwer will always set a prefix.
|
||||||
|
func readTree(db dbm.DB, version int, prefix []byte) (*iavl.MutableTree, error) {
|
||||||
|
if len(prefix) != 0 {
|
||||||
|
db = dbm.NewPrefixDB(db, prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
tree, err := iavl.NewMutableTree(db, DefaultCacheSize, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ver, err := tree.LoadVersion(int64(version))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fmt.Printf("Latest version: %d\n", ver)
|
||||||
|
fmt.Printf("Got version: %d\n", version)
|
||||||
|
return tree, err
|
||||||
|
}
|
47
cmd/kava/cmd/iavlviewer/shape.go
Normal file
47
cmd/kava/cmd/iavlviewer/shape.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package iavlviewer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cosmos/iavl"
|
||||||
|
ethermintserver "github.com/evmos/ethermint/server"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newShapeCmd(opts ethermintserver.StartOptions) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "shape <prefix> [version number]",
|
||||||
|
Short: "View shape of iavl tree.",
|
||||||
|
Args: cobra.RangeArgs(1, 2),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
prefix := args[0]
|
||||||
|
version := 0
|
||||||
|
if len(args) == 2 {
|
||||||
|
var err error
|
||||||
|
version, err = parseVersion(args[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tree, err := openPrefixTree(opts, cmd, prefix, version)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
printShape(tree)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func printShape(tree *iavl.MutableTree) {
|
||||||
|
// shape := tree.RenderShape(" ", nil)
|
||||||
|
// TODO: handle this error
|
||||||
|
shape, _ := tree.RenderShape(" ", nodeEncoder)
|
||||||
|
fmt.Println(strings.Join(shape, "\n"))
|
||||||
|
}
|
74
cmd/kava/cmd/iavlviewer/versions.go
Normal file
74
cmd/kava/cmd/iavlviewer/versions.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package iavlviewer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cosmos/iavl"
|
||||||
|
ethermintserver "github.com/evmos/ethermint/server"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newVersionsCmd(opts ethermintserver.StartOptions) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "versions <prefix>",
|
||||||
|
Short: "Print all versions of iavl tree",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
prefix := args[0]
|
||||||
|
tree, err := openPrefixTree(opts, cmd, prefix, 15)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
printVersions(tree)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func printVersions(tree *iavl.MutableTree) {
|
||||||
|
versions := tree.AvailableVersions()
|
||||||
|
fmt.Println("Available versions:")
|
||||||
|
for _, v := range versions {
|
||||||
|
fmt.Printf(" %d\n", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseWeaveKey assumes a separating : where all in front should be ascii,
|
||||||
|
// and all afterwards may be ascii or binary
|
||||||
|
func parseWeaveKey(key []byte) string {
|
||||||
|
cut := bytes.IndexRune(key, ':')
|
||||||
|
if cut == -1 {
|
||||||
|
return encodeID(key)
|
||||||
|
}
|
||||||
|
prefix := key[:cut]
|
||||||
|
id := key[cut+1:]
|
||||||
|
return fmt.Sprintf("%s:%s", encodeID(prefix), encodeID(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// casts to a string if it is printable ascii, hex-encodes otherwise
|
||||||
|
func encodeID(id []byte) string {
|
||||||
|
for _, b := range id {
|
||||||
|
if b < 0x20 || b >= 0x80 {
|
||||||
|
return strings.ToUpper(hex.EncodeToString(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func nodeEncoder(id []byte, depth int, isLeaf bool) string {
|
||||||
|
prefix := fmt.Sprintf("-%d ", depth)
|
||||||
|
if isLeaf {
|
||||||
|
prefix = fmt.Sprintf("*%d ", depth)
|
||||||
|
}
|
||||||
|
if len(id) == 0 {
|
||||||
|
return fmt.Sprintf("%s<nil>", prefix)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s%s", prefix, parseWeaveKey(id))
|
||||||
|
}
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
"github.com/kava-labs/kava/app"
|
||||||
"github.com/kava-labs/kava/app/params"
|
"github.com/kava-labs/kava/app/params"
|
||||||
|
"github.com/kava-labs/kava/cmd/kava/cmd/iavlviewer"
|
||||||
"github.com/kava-labs/kava/cmd/kava/cmd/rocksdb"
|
"github.com/kava-labs/kava/cmd/kava/cmd/rocksdb"
|
||||||
"github.com/kava-labs/kava/cmd/kava/opendb"
|
"github.com/kava-labs/kava/cmd/kava/opendb"
|
||||||
)
|
)
|
||||||
@ -134,5 +135,6 @@ func addSubCmds(rootCmd *cobra.Command, encodingConfig params.EncodingConfig, de
|
|||||||
keyCommands(app.DefaultNodeHome),
|
keyCommands(app.DefaultNodeHome),
|
||||||
rocksdb.RocksDBCmd,
|
rocksdb.RocksDBCmd,
|
||||||
newShardCmd(opts),
|
newShardCmd(opts),
|
||||||
|
iavlviewer.NewCmd(opts),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -13,6 +13,7 @@ require (
|
|||||||
github.com/cosmos/cosmos-sdk v0.47.10
|
github.com/cosmos/cosmos-sdk v0.47.10
|
||||||
github.com/cosmos/go-bip39 v1.0.0
|
github.com/cosmos/go-bip39 v1.0.0
|
||||||
github.com/cosmos/gogoproto v1.4.10
|
github.com/cosmos/gogoproto v1.4.10
|
||||||
|
github.com/cosmos/iavl v0.20.1
|
||||||
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 v7.1.3
|
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 v7.1.3
|
||||||
github.com/cosmos/ibc-go/v7 v7.4.0
|
github.com/cosmos/ibc-go/v7 v7.4.0
|
||||||
github.com/ethereum/go-ethereum v1.10.26
|
github.com/ethereum/go-ethereum v1.10.26
|
||||||
@ -76,7 +77,6 @@ require (
|
|||||||
github.com/confio/ics23/go v0.9.0 // indirect
|
github.com/confio/ics23/go v0.9.0 // indirect
|
||||||
github.com/cosmos/btcutil v1.0.5 // indirect
|
github.com/cosmos/btcutil v1.0.5 // indirect
|
||||||
github.com/cosmos/gogogateway v1.2.0 // indirect
|
github.com/cosmos/gogogateway v1.2.0 // indirect
|
||||||
github.com/cosmos/iavl v0.20.1 // indirect
|
|
||||||
github.com/cosmos/ics23/go v0.10.0 // indirect
|
github.com/cosmos/ics23/go v0.10.0 // indirect
|
||||||
github.com/cosmos/ledger-cosmos-go v0.13.1 // indirect
|
github.com/cosmos/ledger-cosmos-go v0.13.1 // indirect
|
||||||
github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect
|
github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect
|
||||||
|
Loading…
Reference in New Issue
Block a user