Merge pull request #2560 from filecoin-project/feat/state-root-stat
add command to print state size statistics of actors
This commit is contained in:
commit
c3ff29cd7f
@ -68,7 +68,11 @@ type FullNode interface {
|
|||||||
|
|
||||||
// ChainHasObj checks if a given CID exists in the chain blockstore.
|
// ChainHasObj checks if a given CID exists in the chain blockstore.
|
||||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||||
ChainStatObj(context.Context, cid.Cid, cid.Cid) (ObjStat, error)
|
|
||||||
|
// ChainStatObj returns statistics about the graph referenced by 'obj'.
|
||||||
|
// If 'base' is also specified, then the returned stat will be a diff
|
||||||
|
// between the two objects.
|
||||||
|
ChainStatObj(ctx context.Context, obj cid.Cid, base cid.Cid) (ObjStat, error)
|
||||||
|
|
||||||
// ChainSetHead forcefully sets current chain head. Use with caution.
|
// ChainSetHead forcefully sets current chain head. Use with caution.
|
||||||
ChainSetHead(context.Context, types.TipSetKey) error
|
ChainSetHead(context.Context, types.TipSetKey) error
|
||||||
|
@ -131,7 +131,15 @@ func LoadTipSet(ctx context.Context, cctx *cli.Context, api api.FullNode) (*type
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ParseTipSetRef(ctx, api, tss)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseTipSetRef(ctx context.Context, api api.FullNode, tss string) (*types.TipSet, error) {
|
||||||
if tss[0] == '@' {
|
if tss[0] == '@' {
|
||||||
|
if tss == "@head" {
|
||||||
|
return api.ChainHead(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
var h uint64
|
var h uint64
|
||||||
if _, err := fmt.Sscanf(tss, "@%d", &h); err != nil {
|
if _, err := fmt.Sscanf(tss, "@%d", &h); err != nil {
|
||||||
return nil, xerrors.Errorf("parsing height tipset ref: %w", err)
|
return nil, xerrors.Errorf("parsing height tipset ref: %w", err)
|
||||||
|
@ -21,7 +21,7 @@ func main() {
|
|||||||
keyinfoCmd,
|
keyinfoCmd,
|
||||||
noncefix,
|
noncefix,
|
||||||
bigIntParseCmd,
|
bigIntParseCmd,
|
||||||
staterootStatsCmd,
|
staterootCmd,
|
||||||
importCarCmd,
|
importCarCmd,
|
||||||
commpToCidCmd,
|
commpToCidCmd,
|
||||||
fetchParamCmd,
|
fetchParamCmd,
|
||||||
|
@ -2,17 +2,29 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/multiformats/go-multihash"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var staterootStatsCmd = &cli.Command{
|
var staterootCmd = &cli.Command{
|
||||||
Name: "stateroot-stats",
|
Name: "stateroot",
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
staterootDiffsCmd,
|
||||||
|
staterootStatCmd,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var staterootDiffsCmd = &cli.Command{
|
||||||
|
Name: "diffs",
|
||||||
Description: "Walk down the chain and collect stats-obj changes between tipsets",
|
Description: "Walk down the chain and collect stats-obj changes between tipsets",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -92,3 +104,101 @@ var staterootStatsCmd = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type statItem struct {
|
||||||
|
Addr address.Address
|
||||||
|
Actor *types.Actor
|
||||||
|
Stat api.ObjStat
|
||||||
|
}
|
||||||
|
|
||||||
|
var staterootStatCmd = &cli.Command{
|
||||||
|
Name: "stat",
|
||||||
|
Usage: "print statistics for the stateroot of a given block",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "tipset",
|
||||||
|
Usage: "specify tipset to start from",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer closer()
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
ts, err := lcli.LoadTipSet(ctx, cctx, api)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if ts == nil {
|
||||||
|
ts, err = api.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var addrs []address.Address
|
||||||
|
|
||||||
|
for _, inp := range cctx.Args().Slice() {
|
||||||
|
a, err := address.NewFromString(inp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
addrs = append(addrs, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(addrs) == 0 {
|
||||||
|
allActors, err := api.StateListActors(ctx, ts.Key())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
addrs = allActors
|
||||||
|
}
|
||||||
|
|
||||||
|
var infos []statItem
|
||||||
|
for _, a := range addrs {
|
||||||
|
act, err := api.StateGetActor(ctx, a, ts.Key())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
stat, err := api.ChainStatObj(ctx, act.Head, cid.Undef)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
infos = append(infos, statItem{
|
||||||
|
Addr: a,
|
||||||
|
Actor: act,
|
||||||
|
Stat: stat,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(infos, func(i, j int) bool {
|
||||||
|
return infos[i].Stat.Size > infos[j].Stat.Size
|
||||||
|
})
|
||||||
|
|
||||||
|
outcap := 10
|
||||||
|
if cctx.Args().Len() > outcap {
|
||||||
|
outcap = cctx.Args().Len()
|
||||||
|
}
|
||||||
|
if len(infos) < outcap {
|
||||||
|
outcap = len(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print("Addr\tType\tSize\n")
|
||||||
|
for _, inf := range infos[:outcap] {
|
||||||
|
cmh, err := multihash.Decode(inf.Actor.Code.Hash())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\t%s\t%d\n", inf.Addr, string(cmh.Digest), inf.Stat.Size)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user