cmd/radiance: add blockstore yaml command

This commit is contained in:
Richard Patel 2022-09-10 19:57:10 +02:00
parent 3c69cf0eea
commit b902a03a05
2 changed files with 154 additions and 0 deletions

View File

@ -2,6 +2,7 @@ package blockstore
import (
"github.com/certusone/radiance/cmd/radiance/blockstore/dumpshreds"
"github.com/certusone/radiance/cmd/radiance/blockstore/yaml"
"github.com/spf13/cobra"
)
@ -13,5 +14,6 @@ var Cmd = cobra.Command{
func init() {
Cmd.AddCommand(
&dumpshreds.Cmd,
&yaml.Cmd,
)
}

View File

@ -0,0 +1,152 @@
package yaml
import (
"fmt"
"os"
"strings"
"github.com/certusone/radiance/cmd/radiance/blockstore/util"
"github.com/certusone/radiance/pkg/blockstore"
"github.com/linxGnu/grocksdb"
"github.com/segmentio/textio"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"k8s.io/klog/v2"
)
var Cmd = cobra.Command{
Use: "yaml <rocksdb>",
Short: "Dump blockstore content to YAML",
Args: cobra.ExactArgs(1),
}
var flags = Cmd.Flags()
var (
flagSlots = flags.String("slots", "", "Slots to dump")
flagEntries = flags.Bool("entries", false, "Also dump slot entries")
flagShreds = flags.Bool("shreds", false, "Also dump shreds")
)
func init() {
Cmd.Run = run
}
func run(_ *cobra.Command, args []string) {
rocksDB := args[0]
printColumnFamilies(rocksDB)
db, err := blockstore.OpenReadOnly(rocksDB)
if err != nil {
klog.Exitf("Failed to open blockstore: %s", err)
}
defer db.Close()
printRoot(db)
slots, ok := util.ParseInts(*flagSlots)
if !ok {
klog.Exitf("Invalid slots specifier: %s", *flagSlots)
}
if len(slots) > 0 {
dumpSlots(db, slots)
}
if klog.Stats.Error.Lines() > 0 {
os.Exit(1)
}
}
func printColumnFamilies(dbPath string) {
dbOpts := grocksdb.NewDefaultOptions()
names, err := grocksdb.ListColumnFamilies(dbOpts, dbPath)
if err != nil {
klog.Error("Failed to list column families: %s", err)
return
}
fmt.Println("column_families:")
for _, name := range names {
fmt.Println(" - " + name)
}
}
func printRoot(db *blockstore.DB) {
root, err := db.MaxRoot()
if err != nil {
klog.Error("Failed to get root: ", err)
return
}
fmt.Println("root:", root)
}
func dumpSlots(db *blockstore.DB, slots util.Ints) {
fmt.Println("slots:")
slots.Iter(func(slot uint64) bool {
dumpSlot(db, slot)
return true
})
}
func dumpSlot(db *blockstore.DB, slot uint64) {
slotMeta, err := db.GetSlotMeta(slot)
if err != nil {
klog.Errorf("Failed to get slot %d: %s", slot, err)
return
}
fmt.Printf(" %d:\n", slot)
printSlotMeta(slotMeta)
if *flagShreds {
dumpDataShreds(db, slot)
}
if *flagEntries {
dumpDataEntries(db, slotMeta)
}
}
func printSlotMeta(slotMeta *blockstore.SlotMeta) {
enc := newYAMLPrinter(2)
defer enc.Close()
if err := enc.Encode(slotMeta); err != nil {
panic(err.Error())
}
}
func dumpDataShreds(db *blockstore.DB, slot uint64) {
shreds, err := db.GetAllDataShreds(slot)
if err != nil {
klog.Errorf("Failed to get data shreds of slot %d: %s", slot, err)
return
}
fmt.Println(" data_shreds:")
enc := newYAMLPrinter(3)
defer enc.Close()
if err := enc.Encode(shreds); err != nil {
panic(err.Error())
}
}
func dumpDataEntries(db *blockstore.DB, meta *blockstore.SlotMeta) {
entries, err := db.GetEntries(meta)
if err != nil {
klog.Errorf("Failed to recover entries of slot %d: %s", meta.Slot, err)
return
}
fmt.Println(" entries:")
enc := newYAMLPrinter(3)
defer enc.Close()
if err := enc.Encode(entries); err != nil {
panic(err.Error())
}
}
func newYAMLPrinter(level int) *yaml.Encoder {
enc := yaml.NewEncoder(textio.NewPrefixWriter(os.Stdout, strings.Repeat(" ", level)))
enc.SetIndent(2)
return enc
}