mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Pretty pcli (#6099)
* new spanner db structure * pretty print ssz structures in pcli * nishant feedback * remove from workspace * dependency * update names * add to go.mod Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
1
go.mod
1
go.mod
@@ -50,6 +50,7 @@ require (
|
||||
github.com/json-iterator/go v1.1.9
|
||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
|
||||
github.com/kevinms/leakybucket-go v0.0.0-20200115003610-082473db97ca
|
||||
github.com/kr/pretty v0.2.0
|
||||
github.com/libp2p/go-libp2p v0.9.2
|
||||
github.com/libp2p/go-libp2p-blankhost v0.1.6
|
||||
github.com/libp2p/go-libp2p-circuit v0.2.3
|
||||
|
||||
@@ -15,6 +15,7 @@ go_library(
|
||||
"//beacon-chain/state/stateutil:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//shared/version:go_default_library",
|
||||
"@com_github_kr_pretty//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
@@ -44,6 +45,7 @@ go_image(
|
||||
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
"@com_github_kr_pretty//:go_default_library",
|
||||
"@com_github_x_cray_logrus_prefixed_formatter//:go_default_library",
|
||||
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
|
||||
],
|
||||
|
||||
@@ -6,8 +6,10 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/kr/pretty"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/go-ssz"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
@@ -25,113 +27,173 @@ func main() {
|
||||
var blockPath string
|
||||
var preStatePath string
|
||||
var expectedPostStatePath string
|
||||
var sszPath string
|
||||
var sszType string
|
||||
|
||||
customFormatter := new(prefixed.TextFormatter)
|
||||
customFormatter.TimestampFormat = "2006-01-02 15:04:05"
|
||||
customFormatter.FullTimestamp = true
|
||||
log.SetFormatter(customFormatter)
|
||||
|
||||
app := cli.App{}
|
||||
app.Name = "pcli"
|
||||
app.Usage = "A command line utility to run eth2 specific commands"
|
||||
app.Version = version.GetVersion()
|
||||
app.Commands = []*cli.Command{{
|
||||
Name: "state-transition",
|
||||
Category: "state-transition",
|
||||
Usage: "Subcommand to run manual state transitions",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "block-path",
|
||||
Usage: "Path to block file(ssz)",
|
||||
Destination: &blockPath,
|
||||
app.Commands = []*cli.Command{
|
||||
{
|
||||
Name: "pretty",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "pretty-print SSZ data",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "ssz-path",
|
||||
Usage: "Path to file(ssz)",
|
||||
Required: true,
|
||||
Destination: &sszPath,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "data-type",
|
||||
Usage: "ssz file data type: " +
|
||||
"block|" +
|
||||
"signed_block|" +
|
||||
"attestation|" +
|
||||
"block_header|" +
|
||||
"deposit|" +
|
||||
"proposer_slashing|" +
|
||||
"signed_block_header|" +
|
||||
"signed_voluntary_exit|" +
|
||||
"voluntary_exit|" +
|
||||
"state",
|
||||
Required: true,
|
||||
Destination: &sszType,
|
||||
},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "pre-state-path",
|
||||
Usage: "Path to pre state file(ssz)",
|
||||
Destination: &preStatePath,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "expected-post-state-path",
|
||||
Usage: "Path to expected post state file(ssz)",
|
||||
Destination: &expectedPostStatePath,
|
||||
Action: func(c *cli.Context) error {
|
||||
var data interface{}
|
||||
switch sszType {
|
||||
case "block":
|
||||
data = ðpb.BeaconBlock{}
|
||||
case "signed_block":
|
||||
data = ðpb.SignedBeaconBlock{}
|
||||
case "attestation":
|
||||
data = ðpb.Attestation{}
|
||||
case "block_header":
|
||||
data = ðpb.BeaconBlockHeader{}
|
||||
case "deposit":
|
||||
data = ðpb.Deposit{}
|
||||
case "proposer_slashing":
|
||||
data = ðpb.ProposerSlashing{}
|
||||
case "signed_block_header":
|
||||
data = ðpb.SignedBeaconBlockHeader{}
|
||||
case "signed_voluntary_exit":
|
||||
data = ðpb.SignedVoluntaryExit{}
|
||||
case "voluntary_exit":
|
||||
data = ðpb.VoluntaryExit{}
|
||||
case "state":
|
||||
data = &pb.BeaconState{}
|
||||
default:
|
||||
log.Fatal("Invalid type")
|
||||
}
|
||||
prettyPrint(sszPath, data)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if blockPath == "" {
|
||||
log.Info("Block path not provided for state transition. " +
|
||||
"Please provide path")
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
text, err := reader.ReadString('\n')
|
||||
{
|
||||
Name: "state-transition",
|
||||
Category: "state-transition",
|
||||
Usage: "Subcommand to run manual state transitions",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "block-path",
|
||||
Usage: "Path to block file(ssz)",
|
||||
Destination: &blockPath,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "pre-state-path",
|
||||
Usage: "Path to pre state file(ssz)",
|
||||
Destination: &preStatePath,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "expected-post-state-path",
|
||||
Usage: "Path to expected post state file(ssz)",
|
||||
Destination: &expectedPostStatePath,
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if blockPath == "" {
|
||||
log.Info("Block path not provided for state transition. " +
|
||||
"Please provide path")
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
text, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if text = strings.Replace(text, "\n", "", -1); text == "" {
|
||||
log.Fatal("Empty block path given")
|
||||
}
|
||||
blockPath = text
|
||||
}
|
||||
block := ðpb.SignedBeaconBlock{}
|
||||
if err := dataFetcher(blockPath, block); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
blkRoot, err := stateutil.BlockRoot(block.Block)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if text = strings.Replace(text, "\n", "", -1); text == "" {
|
||||
log.Fatal("Empty block path given")
|
||||
if preStatePath == "" {
|
||||
log.Info("Pre State path not provided for state transition. " +
|
||||
"Please provide path")
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
text, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if text = strings.Replace(text, "\n", "", -1); text == "" {
|
||||
log.Fatal("Empty state path given")
|
||||
}
|
||||
preStatePath = text
|
||||
}
|
||||
blockPath = text
|
||||
}
|
||||
block := ðpb.SignedBeaconBlock{}
|
||||
if err := dataFetcher(blockPath, block); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
blkRoot, err := stateutil.BlockRoot(block.Block)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if preStatePath == "" {
|
||||
log.Info("Pre State path not provided for state transition. " +
|
||||
"Please provide path")
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
text, err := reader.ReadString('\n')
|
||||
preState := &pb.BeaconState{}
|
||||
if err := dataFetcher(preStatePath, preState); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
stateObj, err := stateTrie.InitializeFromProto(preState)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if text = strings.Replace(text, "\n", "", -1); text == "" {
|
||||
log.Fatal("Empty state path given")
|
||||
preStateRoot, err := stateObj.HashTreeRoot(context.Background())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
preStatePath = text
|
||||
}
|
||||
preState := &pb.BeaconState{}
|
||||
if err := dataFetcher(preStatePath, preState); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
stateObj, err := stateTrie.InitializeFromProto(preState)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
preStateRoot, err := stateObj.HashTreeRoot(context.Background())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.WithFields(log.Fields{
|
||||
"blockSlot": fmt.Sprintf("%d", block.Block.Slot),
|
||||
"preStateSlot": fmt.Sprintf("%d", stateObj.Slot()),
|
||||
}).Infof(
|
||||
"Performing state transition with a block root of %#x and pre state root of %#x",
|
||||
blkRoot,
|
||||
preStateRoot,
|
||||
)
|
||||
postState, err := state.ExecuteStateTransition(context.Background(), stateObj, block)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
postRoot, err := postState.HashTreeRoot(context.Background())
|
||||
log.Infof("Finished state transition with post state root of %#x", postRoot)
|
||||
log.WithFields(log.Fields{
|
||||
"blockSlot": fmt.Sprintf("%d", block.Block.Slot),
|
||||
"preStateSlot": fmt.Sprintf("%d", stateObj.Slot()),
|
||||
}).Infof(
|
||||
"Performing state transition with a block root of %#x and pre state root of %#x",
|
||||
blkRoot,
|
||||
preStateRoot,
|
||||
)
|
||||
postState, err := state.ExecuteStateTransition(context.Background(), stateObj, block)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
postRoot, err := postState.HashTreeRoot(context.Background())
|
||||
log.Infof("Finished state transition with post state root of %#x", postRoot)
|
||||
|
||||
// Diff the state if a post state is provided.
|
||||
if expectedPostStatePath != "" {
|
||||
expectedState := &pb.BeaconState{}
|
||||
if err := dataFetcher(expectedPostStatePath, expectedState); err != nil {
|
||||
log.Fatal(err)
|
||||
// Diff the state if a post state is provided.
|
||||
if expectedPostStatePath != "" {
|
||||
expectedState := &pb.BeaconState{}
|
||||
if err := dataFetcher(expectedPostStatePath, expectedState); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if !ssz.DeepEqual(expectedState, postState.InnerStateUnsafe()) {
|
||||
diff, _ := messagediff.PrettyDiff(expectedState, postState.InnerStateUnsafe())
|
||||
log.Errorf("Derived state differs from provided post state: %s", diff)
|
||||
}
|
||||
}
|
||||
if !ssz.DeepEqual(expectedState, postState.InnerStateUnsafe()) {
|
||||
diff, _ := messagediff.PrettyDiff(expectedState, postState.InnerStateUnsafe())
|
||||
log.Errorf("Derived state differs from provided post state: %s", diff)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
log.Error(err.Error())
|
||||
@@ -147,3 +209,13 @@ func dataFetcher(fPath string, data interface{}) error {
|
||||
}
|
||||
return ssz.Unmarshal(rawFile, data)
|
||||
}
|
||||
|
||||
func prettyPrint(sszPath string, data interface{}) {
|
||||
if err := dataFetcher(sszPath, data); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
str := pretty.Sprint(data)
|
||||
re := regexp.MustCompile("(?m)[\r\n]+^.*XXX_.*$")
|
||||
str = re.ReplaceAllString(str, "")
|
||||
fmt.Print(str)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user