lotus/cmd/lotus-storage-miner/proving.go

314 lines
7.6 KiB
Go
Raw Normal View History

2020-04-17 22:02:04 +00:00
package main
import (
"bytes"
2020-04-17 22:02:04 +00:00
"fmt"
"os"
"text/tabwriter"
"time"
"github.com/fatih/color"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
2020-09-07 03:49:10 +00:00
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api/apibstore"
2020-04-17 22:02:04 +00:00
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/store"
2020-04-17 22:02:04 +00:00
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
)
var provingCmd = &cli.Command{
2020-06-15 09:43:42 +00:00
Name: "proving",
Usage: "View proving information",
2020-04-17 22:02:04 +00:00
Subcommands: []*cli.Command{
provingInfoCmd,
provingDeadlinesCmd,
provingFaultsCmd,
},
}
var provingFaultsCmd = &cli.Command{
Name: "faults",
Usage: "View the currently known proving faulty sectors information",
Action: func(cctx *cli.Context) error {
color.NoColor = !cctx.Bool("color")
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer acloser()
ctx := lcli.ReqContext(cctx)
stor := store.ActorStore(ctx, apibstore.NewAPIBlockstore(api))
2020-07-03 17:45:21 +00:00
maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor"))
if err != nil {
return err
}
mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
mas, err := miner.Load(stor, mact)
if err != nil {
return err
}
fmt.Printf("Miner: %s\n", color.BlueString("%s", maddr))
tw := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
2020-07-14 20:14:37 +00:00
_, _ = fmt.Fprintln(tw, "deadline\tpartition\tsectors")
err = mas.ForEachDeadline(func(dlIdx uint64, dl miner.Deadline) error {
dl.ForEachPartition(func(partIdx uint64, part miner.Partition) error {
faults, err := part.Faults()
2020-07-14 20:14:37 +00:00
if err != nil {
return err
}
faults.ForEach(func(num uint64) error {
2020-07-14 20:14:37 +00:00
_, _ = fmt.Fprintf(tw, "%d\t%d\t%d\n", dlIdx, partIdx, num)
return nil
})
})
})
if err != nil {
return err
}
return tw.Flush()
2020-04-17 22:02:04 +00:00
},
}
var provingInfoCmd = &cli.Command{
2020-06-15 09:43:42 +00:00
Name: "info",
Usage: "View current state information",
2020-04-17 22:02:04 +00:00
Action: func(cctx *cli.Context) error {
color.NoColor = !cctx.Bool("color")
2020-04-17 22:02:04 +00:00
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer acloser()
ctx := lcli.ReqContext(cctx)
2020-07-03 17:45:21 +00:00
maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor"))
2020-04-17 22:02:04 +00:00
if err != nil {
return err
2020-04-17 22:02:04 +00:00
}
head, err := api.ChainHead(ctx)
if err != nil {
return xerrors.Errorf("getting chain head: %w", err)
}
mact, err := api.StateGetActor(ctx, maddr, head.Key())
2020-04-17 22:02:04 +00:00
if err != nil {
return err
2020-04-17 22:02:04 +00:00
}
stor := store.ActorStore(ctx, apibstore.NewAPIBlockstore(api))
mas, err := miner.Load(stor, mact)
2020-04-17 22:02:04 +00:00
if err != nil {
return err
2020-04-17 22:02:04 +00:00
}
cd, err := api.StateMinerProvingDeadline(ctx, maddr, head.Key())
if err != nil {
return xerrors.Errorf("getting miner info: %w", err)
}
fmt.Printf("Miner: %s\n", color.BlueString("%s", maddr))
2020-07-14 20:14:37 +00:00
proving := uint64(0)
faults := uint64(0)
recovering := uint64(0)
curDeadlineSectors := uint64(0)
if err := mas.ForEachDeadline(func(dlIdx uint64, dl miner.Deadline) error {
return dl.ForEachPartition(func(partIdx uint64, part miner.Partition) error {
if bf, err := part.LiveSectors(); err != nil {
return err
} else if count, err := bf.Count(); err != nil {
return err
} else {
proving += count
if dlIdx == cd.Index {
curDeadlineSectors += count
}
2020-07-14 20:14:37 +00:00
}
if bf, err := part.Faults(); err != nil {
return err
} else if count, err := bf.Count(); err != nil {
return err
} else {
faults += count
2020-07-14 20:14:37 +00:00
}
if bf, err := part.Recovering(); err != nil {
return err
} else if count, err := bf.Count(); err != nil {
return err
} else {
recovering += count
2020-07-14 20:14:37 +00:00
}
})
}); err != nil {
return xerrors.Errorf("walking miner deadlines and partitions: %w", err)
}
2020-05-13 16:53:07 +00:00
var faultPerc float64
2020-07-14 20:14:37 +00:00
if proving > 0 {
faultPerc = float64(faults*10000/proving) / 100
2020-05-13 16:53:07 +00:00
}
2020-04-20 17:34:08 +00:00
fmt.Printf("Current Epoch: %d\n", cd.CurrentEpoch)
fmt.Printf("Proving Period Boundary: %d\n", cd.PeriodStart%cd.WPoStProvingPeriod)
2020-04-20 17:34:08 +00:00
fmt.Printf("Proving Period Start: %s\n", epochTime(cd.CurrentEpoch, cd.PeriodStart))
fmt.Printf("Next Period Start: %s\n\n", epochTime(cd.CurrentEpoch, cd.PeriodStart+cd.WPoStProvingPeriod))
2020-04-20 17:34:08 +00:00
2020-05-13 16:53:07 +00:00
fmt.Printf("Faults: %d (%.2f%%)\n", faults, faultPerc)
2020-07-14 20:14:37 +00:00
fmt.Printf("Recovering: %d\n", recovering)
2020-04-20 17:34:08 +00:00
fmt.Printf("Deadline Index: %d\n", cd.Index)
fmt.Printf("Deadline Sectors: %d\n", curDeadlineSectors)
2020-04-20 17:34:08 +00:00
fmt.Printf("Deadline Open: %s\n", epochTime(cd.CurrentEpoch, cd.Open))
fmt.Printf("Deadline Close: %s\n", epochTime(cd.CurrentEpoch, cd.Close))
fmt.Printf("Deadline Challenge: %s\n", epochTime(cd.CurrentEpoch, cd.Challenge))
fmt.Printf("Deadline FaultCutoff: %s\n", epochTime(cd.CurrentEpoch, cd.FaultCutoff))
2020-04-17 22:02:04 +00:00
return nil
},
}
2020-04-20 17:34:08 +00:00
func epochTime(curr, e abi.ChainEpoch) string {
switch {
case curr > e:
return fmt.Sprintf("%d (%s ago)", e, time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(curr-e)))
2020-04-20 17:34:08 +00:00
case curr == e:
return fmt.Sprintf("%d (now)", e)
case curr < e:
return fmt.Sprintf("%d (in %s)", e, time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(e-curr)))
2020-04-20 17:34:08 +00:00
}
panic("math broke")
}
2020-04-17 22:02:04 +00:00
var provingDeadlinesCmd = &cli.Command{
2020-06-15 09:43:42 +00:00
Name: "deadlines",
Usage: "View the current proving period deadlines information",
2020-04-17 22:02:04 +00:00
Action: func(cctx *cli.Context) error {
color.NoColor = !cctx.Bool("color")
2020-04-17 22:02:04 +00:00
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer acloser()
ctx := lcli.ReqContext(cctx)
2020-07-03 17:45:21 +00:00
maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor"))
2020-04-17 22:02:04 +00:00
if err != nil {
return err
2020-04-17 22:02:04 +00:00
}
deadlines, err := api.StateMinerDeadlines(ctx, maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting deadlines: %w", err)
}
di, err := api.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting deadlines: %w", err)
}
var mas miner.State
{
mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
miner.Load
rmas, err := api.ChainReadObj(ctx, mact.Head)
if err != nil {
return err
}
if err := mas.UnmarshalCBOR(bytes.NewReader(rmas)); err != nil {
return err
}
}
fmt.Printf("Miner: %s\n", color.BlueString("%s", maddr))
tw := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
2020-07-27 16:15:47 +00:00
_, _ = fmt.Fprintln(tw, "deadline\tpartitions\tsectors (faults)\tproven partitions")
2020-07-14 20:14:37 +00:00
for dlIdx, deadline := range deadlines {
partitions, err := api.StateMinerPartitions(ctx, maddr, uint64(dlIdx), types.EmptyTSK)
2020-04-17 22:02:04 +00:00
if err != nil {
2020-07-14 20:14:37 +00:00
return xerrors.Errorf("getting partitions for deadline %d: %w", dlIdx, err)
2020-04-17 22:02:04 +00:00
}
2020-07-14 20:14:37 +00:00
provenPartitions, err := deadline.PostSubmissions.Count()
if err != nil {
return err
}
2020-07-27 16:15:47 +00:00
sectors := uint64(0)
faults := uint64(0)
for _, partition := range partitions {
sc, err := partition.Sectors.Count()
if err != nil {
return err
}
sectors += sc
fc, err := partition.Faults.Count()
if err != nil {
return err
}
faults += fc
}
var cur string
2020-07-14 20:14:37 +00:00
if di.Index == uint64(dlIdx) {
cur += "\t(current)"
}
2020-07-27 16:15:47 +00:00
_, _ = fmt.Fprintf(tw, "%d\t%d\t%d (%d)\t%d%s\n", dlIdx, len(partitions), sectors, faults, provenPartitions, cur)
2020-04-17 22:02:04 +00:00
}
return tw.Flush()
2020-04-17 22:02:04 +00:00
},
2020-04-17 22:02:43 +00:00
}