cmd/radiance: add blockstore yaml command
This commit is contained in:
parent
3c69cf0eea
commit
b902a03a05
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue