diff --git a/cli/state.go b/cli/state.go index b68f60fb5..a761b8f58 100644 --- a/cli/state.go +++ b/cli/state.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "reflect" + "sort" "strconv" "strings" "time" @@ -493,6 +494,12 @@ var stateGetDealSetCmd = &cli.Command{ var stateListMinersCmd = &cli.Command{ Name: "list-miners", Usage: "list all miners in the network", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "sort-by", + Usage: "criteria to sort miners by (none, num-deals)", + }, + }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) if err != nil { @@ -512,6 +519,26 @@ var stateListMinersCmd = &cli.Command{ return err } + switch cctx.String("sort-by") { + case "num-deals": + ndm, err := getDealsCounts(ctx, api) + if err != nil { + return err + } + + sort.Slice(miners, func(i, j int) bool { + return ndm[miners[i]] > ndm[miners[j]] + }) + + for i := 0; i < 50 && i < len(miners); i++ { + fmt.Printf("%s %d\n", miners[i], ndm[miners[i]]) + } + return nil + default: + return fmt.Errorf("unrecognized sorting order") + case "", "none": + } + for _, m := range miners { fmt.Println(m.String()) } @@ -520,6 +547,22 @@ var stateListMinersCmd = &cli.Command{ }, } +func getDealsCounts(ctx context.Context, lapi api.FullNode) (map[address.Address]int, error) { + allDeals, err := lapi.StateMarketDeals(ctx, types.EmptyTSK) + if err != nil { + return nil, err + } + + out := make(map[address.Address]int) + for _, d := range allDeals { + if d.State.SectorStartEpoch != -1 { + out[d.Proposal.Provider]++ + } + } + + return out, nil +} + var stateListActorsCmd = &cli.Command{ Name: "list-actors", Usage: "list all actors in the network", diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 819ecc572..58633b27a 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -445,7 +445,13 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (m var s market.DealState if err := sa.Get(ctx, i, &s); err != nil { - return err + if err != nil { + if _, ok := err.(*amt.ErrNotFound); !ok { + return xerrors.Errorf("failed to get state for deal in proposals array: %w", err) + } + + s.SectorStartEpoch = -1 + } } out[strconv.FormatInt(int64(i), 10)] = api.MarketDeal{ Proposal: d,