Skip to content

Commit

Permalink
find trie root
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangchiqing committed Jun 8, 2024
1 parent 5acf995 commit 7d0c94d
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 0 deletions.
145 changes: 145 additions & 0 deletions cmd/util/cmd/find-trie-root/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package find_trie_root

import (
"encoding/hex"
"fmt"
"math"

prometheusWAL "github.com/onflow/wal/wal"
"github.com/prometheus/client_golang/prometheus"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"

"github.com/onflow/flow-go/ledger"
"github.com/onflow/flow-go/ledger/common/hash"
"github.com/onflow/flow-go/ledger/complete/wal"
)

var (
flagExecutionStateDir string
flagRootHash string
flagFrom int
flagTo int
)

var Cmd = &cobra.Command{
Use: "find-trie-root",
Short: "find trie root",
Run: run,
}

func init() {
Cmd.Flags().StringVarP(&flagExecutionStateDir, "execution-state-dir", "e", "/var/flow/data/execution", "directory to the execution state")
_ = Cmd.MarkFlagRequired("execution-state-dir")

Cmd.Flags().StringVar(&flagRootHash, "root-hash", "",
"ledger root hash (hex-encoded, 64 characters)")
_ = Cmd.MarkFlagRequired("root-hash")

Cmd.Flags().IntVar(&flagFrom, "from", 0, "from segment")
Cmd.Flags().IntVar(&flagTo, "to", math.MaxInt32, "to segment")
}

func run(*cobra.Command, []string) {
rootHash, err := parseInput(flagRootHash)
if err != nil {
log.Fatal().Err(err).Msg("cannot parse input")
}

segment, offset, err := searchRootHashInSegments(rootHash, flagExecutionStateDir, flagFrom, flagTo)
if err != nil {
log.Fatal().Err(err).Msg("cannot find root hash in segments")
}
log.Info().Msgf("found root hash in segment %d at offset %d", segment, offset)
}

func parseInput(rootHashStr string) (ledger.RootHash, error) {
rootHashBytes, err := hex.DecodeString(rootHashStr)
if err != nil {
return ledger.RootHash(hash.DummyHash), fmt.Errorf("cannot decode root hash: %w", err)
}
rootHash, err := ledger.ToRootHash(rootHashBytes)
if err != nil {
return ledger.RootHash(hash.DummyHash), fmt.Errorf("invalid root hash: %w", err)
}
return rootHash, nil
}

func searchRootHashInSegments(
expectedHash ledger.RootHash,
dir string,
wantFrom, wantTo int,
) (int, int64, error) {
log := zerolog.Logger{}
w, err := prometheusWAL.NewSize(log, prometheus.DefaultRegisterer, dir, wal.SegmentSize, false)
if err != nil {
return 0, 0, fmt.Errorf("cannot create WAL: %w", err)
}

from, to, err := prometheusWAL.Segments(dir)
if err != nil {
return 0, 0, fmt.Errorf("cannot get segments: %w", err)
}

if wantFrom > to {
return 0, 0, fmt.Errorf("from segment %d is greater than the last segment %d", wantFrom, to)
}

if wantTo < from {
return 0, 0, fmt.Errorf("to segment %d is less than the first segment %d", wantTo, from)
}

if wantFrom > from {
from = wantFrom
}

if wantTo < to {
to = wantTo
}

log.Info().
Str("dir", dir).
Int("from", from).
Int("to", to).
Int("want-from", wantFrom).
Int("want-to", wantTo).
Msgf("searching for trie root hash %x in segments [%d,%d]", expectedHash, wantFrom, wantTo)

sr, err := prometheusWAL.NewSegmentsRangeReader(log, prometheusWAL.SegmentRange{
Dir: w.Dir(),
First: from,
Last: to,
})

if err != nil {
return 0, 0, fmt.Errorf("cannot create WAL segments reader: %w", err)
}

defer sr.Close()

reader := prometheusWAL.NewReader(sr)

for reader.Next() {
record := reader.Record()
operation, rootHash, _, err := wal.Decode(record)
if err != nil {
return 0, 0, fmt.Errorf("cannot decode LedgerWAL record: %w", err)
}
switch operation {
case wal.WALUpdate:
if rootHash == expectedHash {
log.Info().Msgf("found expected trie root hash %x", rootHash)
return reader.Segment(), reader.Offset(), nil
}
default:
}

err = reader.Err()
if err != nil {
return 0, 0, fmt.Errorf("cannot read LedgerWAL: %w", err)
}
}

return 0, 0, fmt.Errorf("finish reading all segment files from %d to %d, but not found", from, to)
}
2 changes: 2 additions & 0 deletions cmd/util/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
ledger_json_exporter "github.com/onflow/flow-go/cmd/util/cmd/export-json-execution-state"
export_json_transactions "github.com/onflow/flow-go/cmd/util/cmd/export-json-transactions"
find_inconsistent_result "github.com/onflow/flow-go/cmd/util/cmd/find-inconsistent-result"
find_trie_root "github.com/onflow/flow-go/cmd/util/cmd/find-trie-root"
read_badger "github.com/onflow/flow-go/cmd/util/cmd/read-badger/cmd"
read_execution_state "github.com/onflow/flow-go/cmd/util/cmd/read-execution-state"
read_hotstuff "github.com/onflow/flow-go/cmd/util/cmd/read-hotstuff/cmd"
Expand Down Expand Up @@ -81,6 +82,7 @@ func addCommands() {
rootCmd.AddCommand(export_json_transactions.Cmd)
rootCmd.AddCommand(read_hotstuff.RootCmd)
rootCmd.AddCommand(find_inconsistent_result.Cmd)
rootCmd.AddCommand(find_trie_root.Cmd)
rootCmd.AddCommand(update_commitment.Cmd)
}

Expand Down

0 comments on commit 7d0c94d

Please sign in to comment.