diff --git a/cli/state.go b/cli/state.go
index 2ac2cd37c..e4d28d1af 100644
--- a/cli/state.go
+++ b/cli/state.go
@@ -769,6 +769,10 @@ var stateComputeStateCmd = &cli.Command{
Name: "show-trace",
Usage: "print out full execution trace for given tipset",
},
+ &cli.BoolFlag{
+ Name: "html",
+ Usage: "generate html report",
+ },
},
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
@@ -818,6 +822,10 @@ var stateComputeStateCmd = &cli.Command{
return err
}
+ if cctx.Bool("html") {
+ return computeStateHtml(stout)
+ }
+
fmt.Println("computed state cid: ", stout.Root)
if cctx.Bool("show-trace") {
for _, ir := range stout.Trace {
@@ -836,6 +844,65 @@ func printInternalExecutions(prefix string, trace []*types.ExecutionResult) {
}
}
+func computeStateHtml(o *api.ComputeStateOutput) error {
+ fmt.Printf(`
+
+
+
+
+ State CID: %s
+ Calls
`, o.Root)
+
+ for _, ir := range o.Trace {
+ fmt.Printf(`
+
%s -> %s (%s FIL), Method %d
+
Params: %x
+
Exit: %d, Return: %x
+`, ir.Msg.From, ir.Msg.To, types.FIL(ir.Msg.Value), ir.Msg.Method, ir.Msg.Params, ir.MsgRct.ExitCode, ir.MsgRct.ExitCode, ir.MsgRct.Return)
+ if ir.MsgRct.ExitCode != 0 {
+ fmt.Printf(`
`, ir.Error)
+ }
+
+ if len(ir.InternalExecutions) > 0 {
+ fmt.Println("
Internal executions:
")
+ printInternalExecutionsHtml(ir.InternalExecutions)
+ }
+ fmt.Println("
")
+ }
+
+ fmt.Printf(`
+`)
+ return nil
+}
+
+func printInternalExecutionsHtml(trace []*types.ExecutionResult) {
+ for _, im := range trace {
+ fmt.Printf(`
+
%s -> %s (%s FIL), Method %d
+
Params: %x
+
Exit: %d, Return: %x
+`, im.Msg.From, im.Msg.To, types.FIL(im.Msg.Value), im.Msg.Method, im.Msg.Params, im.MsgRct.ExitCode, im.MsgRct.ExitCode, im.MsgRct.Return)
+ if im.MsgRct.ExitCode != 0 {
+ fmt.Printf(`
`, im.Error)
+ }
+ if len(im.Subcalls) > 0 {
+ fmt.Println("
Subcalls:
")
+ printInternalExecutionsHtml(im.Subcalls)
+ }
+ fmt.Println("
")
+ }
+}
+
var stateWaitMsgCmd = &cli.Command{
Name: "wait-msg",
Usage: "Wait for a message to appear on chain",