add a command to view block space utilization

This commit is contained in:
whyrusleeping 2020-10-05 14:06:03 -07:00
parent d0c52535a6
commit bd0633ff90
2 changed files with 116 additions and 1 deletions

View File

@ -117,7 +117,7 @@ func (c *client) doRequest(
res, err := c.sendRequestToPeer(ctx, peer, req) res, err := c.sendRequestToPeer(ctx, peer, req)
if err != nil { if err != nil {
if !xerrors.Is(err, network.ErrNoConn) { if !xerrors.Is(err, network.ErrNoConn) {
log.Warnf("could not connect to peer %s: %s", log.Warnf("could not send request to peer %s: %s",
peer.String(), err) peer.String(), err)
} }
continue continue

View File

@ -8,6 +8,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path" "path"
"sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -30,6 +31,7 @@ import (
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/stmgr"
types "github.com/filecoin-project/lotus/chain/types" types "github.com/filecoin-project/lotus/chain/types"
) )
@ -50,6 +52,7 @@ var chainCmd = &cli.Command{
chainExportCmd, chainExportCmd,
slashConsensusFault, slashConsensusFault,
chainGasPriceCmd, chainGasPriceCmd,
chainInspectUsage,
}, },
} }
@ -375,6 +378,118 @@ var chainSetHeadCmd = &cli.Command{
}, },
} }
var chainInspectUsage = &cli.Command{
Name: "inspect-usage",
Usage: "Inspect block space usage of a given tipset",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "tipset",
Usage: "specify tipset to view block space usage of",
Value: "@head",
},
},
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
ts, err := LoadTipSet(ctx, cctx, api)
if err != nil {
return err
}
pmsgs, err := api.ChainGetParentMessages(ctx, ts.Blocks()[0].Cid())
if err != nil {
return err
}
codeCache := make(map[address.Address]cid.Cid)
lookupActorCode := func(a address.Address) (cid.Cid, error) {
c, ok := codeCache[a]
if ok {
return c, nil
}
act, err := api.StateGetActor(ctx, a, ts.Key())
if err != nil {
return cid.Undef, err
}
codeCache[a] = act.Code
return act.Code, nil
}
bySender := make(map[string]int64)
byDest := make(map[string]int64)
byMethod := make(map[string]int64)
var sum int64
for _, m := range pmsgs {
bySender[m.Message.From.String()] += m.Message.GasLimit
byDest[m.Message.To.String()] += m.Message.GasLimit
sum += m.Message.GasLimit
code, err := lookupActorCode(m.Message.To)
if err != nil {
return err
}
mm := stmgr.MethodsMap[code][m.Message.Method]
byMethod[mm.Name] += m.Message.GasLimit
}
type keyGasPair struct {
Key string
Gas int64
}
mapToSortedKvs := func(m map[string]int64) []keyGasPair {
var vals []keyGasPair
for k, v := range m {
vals = append(vals, keyGasPair{
Key: k,
Gas: v,
})
}
sort.Slice(vals, func(i, j int) bool {
return vals[i].Gas > vals[j].Gas
})
return vals
}
senderVals := mapToSortedKvs(bySender)
destVals := mapToSortedKvs(byDest)
methodVals := mapToSortedKvs(byMethod)
fmt.Printf("Total Gas Limit: %d\n", sum)
fmt.Printf("By Sender:\n")
for i := 0; i < 10 && i < len(senderVals); i++ {
sv := senderVals[i]
fmt.Printf("%s\t%0.2f\t(%d)\n", sv.Key, (100*float64(sv.Gas))/float64(sum), sv.Gas)
}
fmt.Println()
fmt.Printf("By Receiver:\n")
for i := 0; i < 10 && i < len(destVals); i++ {
sv := destVals[i]
fmt.Printf("%s\t%0.2f\t(%d)\n", sv.Key, (100*float64(sv.Gas))/float64(sum), sv.Gas)
}
fmt.Println()
fmt.Printf("By Method:\n")
for i := 0; i < 10 && i < len(methodVals); i++ {
sv := methodVals[i]
fmt.Printf("%s\t%0.2f\t(%d)\n", sv.Key, (100*float64(sv.Gas))/float64(sum), sv.Gas)
}
return nil
},
}
var chainListCmd = &cli.Command{ var chainListCmd = &cli.Command{
Name: "list", Name: "list",
Usage: "View a segment of the chain", Usage: "View a segment of the chain",