Skip to content

Commit

Permalink
feat: sync inspect mpt tool from bsc (bnb-chain#52)
Browse files Browse the repository at this point in the history
Co-authored-by: Fynn <zcheng1004@gmail.com>
Co-authored-by: will@2012 <xibaow2020@qq.com>
  • Loading branch information
3 people authored and andyzhang2023 committed Feb 22, 2024
1 parent 7b6b468 commit 92aa515
Show file tree
Hide file tree
Showing 3 changed files with 396 additions and 0 deletions.
89 changes: 89 additions & 0 deletions cmd/geth/dbcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/console/prompt"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state/snapshot"
Expand Down Expand Up @@ -62,6 +63,7 @@ Remove blockchain and state databases`,
dbCompactCmd,
dbGetCmd,
dbDeleteCmd,
dbInspectTrieCmd,
dbPutCmd,
dbGetSlotsCmd,
dbDumpFreezerIndex,
Expand All @@ -81,6 +83,17 @@ Remove blockchain and state databases`,
Usage: "Inspect the storage size for each type of data in the database",
Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`,
}
dbInspectTrieCmd = &cli.Command{
Action: inspectTrie,
Name: "inspect-trie",
ArgsUsage: "<blocknum> <jobnum>",
Flags: []cli.Flag{
utils.DataDirFlag,
utils.SyncModeFlag,
},
Usage: "Inspect the MPT tree of the account and contract.",
Description: `This commands iterates the entrie WorldState.`,
}
dbCheckStateContentCmd = &cli.Command{
Action: checkStateContent,
Name: "check-state-content",
Expand Down Expand Up @@ -255,6 +268,82 @@ func confirmAndRemoveDB(database string, kind string) {
}
}

func inspectTrie(ctx *cli.Context) error {
if ctx.NArg() < 1 {
return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage)
}

if ctx.NArg() > 3 {
return fmt.Errorf("Max 3 arguments: %v", ctx.Command.ArgsUsage)
}

var (
blockNumber uint64
trieRootHash common.Hash
jobnum uint64
)

stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, true)
defer db.Close()

var headerBlockHash common.Hash
if ctx.NArg() >= 1 {
if ctx.Args().Get(0) == "latest" {
headerHash := rawdb.ReadHeadHeaderHash(db)
blockNumber = *(rawdb.ReadHeaderNumber(db, headerHash))
} else if ctx.Args().Get(0) == "snapshot" {
trieRootHash = rawdb.ReadSnapshotRoot(db)
blockNumber = math.MaxUint64
} else {
var err error
blockNumber, err = strconv.ParseUint(ctx.Args().Get(0), 10, 64)
if err != nil {
return fmt.Errorf("failed to Parse blocknum, Args[0]: %v, err: %v", ctx.Args().Get(0), err)
}
}

if ctx.NArg() == 1 {
jobnum = 1000
} else {
var err error
jobnum, err = strconv.ParseUint(ctx.Args().Get(1), 10, 64)
if err != nil {
return fmt.Errorf("failed to Parse jobnum, Args[1]: %v, err: %v", ctx.Args().Get(1), err)
}
}

if blockNumber != math.MaxUint64 {
headerBlockHash = rawdb.ReadCanonicalHash(db, blockNumber)
if headerBlockHash == (common.Hash{}) {
return fmt.Errorf("ReadHeadBlockHash empty hash")
}
blockHeader := rawdb.ReadHeader(db, headerBlockHash, blockNumber)
trieRootHash = blockHeader.Root
}
if (trieRootHash == common.Hash{}) {
log.Error("Empty root hash")
}
fmt.Printf("ReadBlockHeader, root: %v, blocknum: %v\n", trieRootHash, blockNumber)

triedb := trie.NewDatabase(db)
theTrie, err := trie.New(trie.TrieID(trieRootHash), triedb)
if err != nil {
fmt.Printf("fail to new trie tree, err: %v, rootHash: %v\n", err, trieRootHash.String())
return err
}
theInspect, err := trie.NewInspector(theTrie, triedb, trieRootHash, blockNumber, jobnum)
if err != nil {
return err
}
theInspect.Run()
theInspect.DisplayResult()
}
return nil
}

func inspect(ctx *cli.Context) error {
var (
prefix []byte
Expand Down
Loading

0 comments on commit 92aa515

Please sign in to comment.