diff --git a/cli/state.go b/cli/state.go
index acc648c23..47a1624c4 100644
--- a/cli/state.go
+++ b/cli/state.go
@@ -5,10 +5,12 @@ import (
"context"
"encoding/json"
"fmt"
+ "os"
"reflect"
"sort"
"strconv"
"strings"
+ "text/template"
"time"
"github.com/ipfs/go-cid"
@@ -31,6 +33,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
+ "github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api"
@@ -40,7 +43,7 @@ import (
)
type methodMeta struct {
- name string
+ Name string
params reflect.Type
ret reflect.Type
@@ -68,7 +71,7 @@ func init() {
nf := rt.NumField()
methods[c] = append(methods[c], methodMeta{
- name: "Send",
+ Name: "Send",
params: reflect.TypeOf(new(adt.EmptyValue)),
ret: reflect.TypeOf(new(adt.EmptyValue)),
})
@@ -78,7 +81,7 @@ func init() {
export := reflect.TypeOf(exports[i+1])
methods[c] = append(methods[c], methodMeta{
- name: rt.Field(i).Name,
+ Name: rt.Field(i).Name,
params: export.In(1),
ret: export.Out(0),
})
@@ -923,7 +926,7 @@ var stateComputeStateCmd = &cli.Command{
return c.Code, nil
}
- return computeStateHtml(ts, stout, getCode)
+ return computeStateHtmlT(ts, stout, getCode)
}
fmt.Println("computed state cid: ", stout.Root)
@@ -944,16 +947,8 @@ func printInternalExecutions(prefix string, trace []types.ExecutionTrace) {
}
}
-func codeStr(c cid.Cid) string {
- cmh, err := multihash.Decode(c.Hash())
- if err != nil {
- panic(err)
- }
- return string(cmh.Digest)
-}
-
-func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func(addr address.Address) (cid.Cid, error)) error {
- fmt.Printf(`
+var compStateTemplate = `
+
- Tipset: %s
- Height: %d
- State CID: %s
- Calls
`, ts.Key(), ts.Height(), o.Root)
+ Tipset: {{.TipSet.Key}}
+ Epoch: {{.TipSet.Height}}
+ State CID: {{.Comp.Root}}
+ Calls
+ {{range .Comp.Trace}}
+ {{template "message" (Call .ExecutionTrace false .Msg.Cid.String)}}
+ {{end}}
+
+
+`
- for _, ir := range o.Trace {
- toCode, err := getCode(ir.Msg.To)
- if err != nil {
- return xerrors.Errorf("getting code for %s: %w", toCode, err)
- }
+var compStateMsg = `
+
+ {{$code := GetCode .Msg.To}}
+ {{$h := "h2"}}{{if .Subcall}}{{$h = "h4"}}{{end}}
- params, err := jsonParams(toCode, ir.Msg.Method, ir.Msg.Params)
- if err != nil {
- return xerrors.Errorf("decoding params: %w", err)
- }
+
+
{{.Msg.From}} -> {{.Msg.To}} ({{ToFil .Msg.Value}} FIL), M{{.Msg.Method}}
+ {{if not .Subcall}}
Msg CID: {{.Msg.Cid}}
{{end}}
+ {{if gt (len .Msg.Params) 0}}
+
{{JsonParams ($code) (.Msg.Method) (.Msg.Params) | html}}
+ {{end}}
+
Took {{.Duration}}, Exit: {{.MsgRct.ExitCode}}{{if gt (len .MsgRct.Return) 0}}, Return{{end}}
+
+ {{if gt (len .MsgRct.Return) 0}}
+
{{JsonReturn ($code) (.Msg.Method) (.MsgRct.Return) | html}}
+ {{end}}
- if len(ir.Msg.Params) != 0 {
- params = `
`
- } else {
- params = ""
- }
+ {{if ne .MsgRct.ExitCode 0}}
+
+ {{end}}
- ret, err := jsonReturn(toCode, ir.Msg.Method, ir.MsgRct.Return)
- if err != nil {
- return xerrors.Errorf("decoding return value: %w", err)
- }
+
+ Gas Trace
+
+ Name | Total/Compute/Storage | Time Taken | Location |
+ {{range .GasCharges}}
+ {{.Name}} | {{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}} | {{.TimeTaken}} | {{.Location}} |
+ {{end}}
+ {{with SumGas .GasCharges}}
+ Sum | {{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}} | {{.TimeTaken}} | |
+ {{end}}
+
+
+ {{if gt (len .Subcalls) 0}}
+
Subcalls:
+ {{$hash := .Hash}}
+ {{range .Subcalls}}
+ {{template "message" (Call . true (printf "%s-%s" $hash .Msg.Cid.String))}}
+ {{end}}
+ {{end}}
+
`
- if len(ir.MsgRct.Return) == 0 {
- ret = ""
- } else {
- ret = `, Return`
- }
-
- slow := ir.Duration > 10*time.Millisecond
- veryslow := ir.Duration > 50*time.Millisecond
-
- cid := ir.Msg.Cid()
-
- fmt.Printf(`
-
-
%s -> %s (%s FIL), M%d
-
Msg CID: %s
-%s
-
Took %s,
Exit: %d%s
-`, cid, cid, codeStr(toCode), methods[toCode][ir.Msg.Method].name, ir.Msg.From, ir.Msg.To, types.FIL(ir.Msg.Value), ir.Msg.Method, cid, params, slow, veryslow, ir.Duration, ir.MsgRct.ExitCode, ir.MsgRct.ExitCode, ret)
- if ir.MsgRct.ExitCode != 0 {
- fmt.Printf(`
`, ir.Error)
- }
- fmt.Printf("\n
Gas Trace
" +
- "Name | Total/Compute/Storage | Time Taken | Location |
")
-
- var sumTotal, sumCompute, sumStorage int64
- var sumTime time.Duration
- for _, gc := range ir.ExecutionTrace.GasCharges {
- fmt.Printf("%s | %d/%d/%d | %s | %s |
",
- gc.Name, gc.TotalGas, gc.ComputeGas, gc.StorageGas, gc.TimeTaken, gc.Location)
- sumTotal += gc.TotalGas
- sumCompute += gc.ComputeGas
- sumStorage += gc.StorageGas
- sumTime += gc.TimeTaken
- }
- fmt.Printf("%s | %d/%d/%d | %s | %s |
",
- "Sum", sumTotal, sumCompute, sumStorage, sumTime, "")
-
- fmt.Printf("
\n")
-
- fmt.Println("
Execution trace:
")
- if err := printInternalExecutionsHtml(cid.String(), ir.ExecutionTrace.Subcalls, getCode); err != nil {
- return err
- }
- fmt.Println("
")
- }
-
- fmt.Printf(`
-