Merge pull request #8349 from filecoin-project/feat/faulty-cli-utils
feat: miner cli: proving check --faulty, faults in storage list sectors
This commit is contained in:
commit
d437f19aae
@ -365,6 +365,10 @@ var provingCheckProvableCmd = &cli.Command{
|
|||||||
Name: "storage-id",
|
Name: "storage-id",
|
||||||
Usage: "filter sectors by storage path (path id)",
|
Usage: "filter sectors by storage path (path id)",
|
||||||
},
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "faulty",
|
||||||
|
Usage: "only check faulty sectors",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
if cctx.Args().Len() != 1 {
|
if cctx.Args().Len() != 1 {
|
||||||
@ -376,7 +380,7 @@ var provingCheckProvableCmd = &cli.Command{
|
|||||||
return xerrors.Errorf("could not parse deadline index: %w", err)
|
return xerrors.Errorf("could not parse deadline index: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
api, closer, err := lcli.GetFullNodeAPIV1(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -428,6 +432,38 @@ var provingCheckProvableCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cctx.Bool("faulty") {
|
||||||
|
parts, err := getAllPartitions(ctx, addr, api)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting partitions: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if filter != nil {
|
||||||
|
for k := range filter {
|
||||||
|
set, err := parts.FaultySectors.IsSet(uint64(k.Number))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !set {
|
||||||
|
delete(filter, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filter = map[abi.SectorID]struct{}{}
|
||||||
|
|
||||||
|
err = parts.FaultySectors.ForEach(func(s uint64) error {
|
||||||
|
filter[abi.SectorID{
|
||||||
|
Miner: abi.ActorID(mid),
|
||||||
|
Number: abi.SectorNumber(s),
|
||||||
|
}] = struct{}{}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for parIdx, par := range partitions {
|
for parIdx, par := range partitions {
|
||||||
sectors := make(map[abi.SectorNumber]struct{})
|
sectors := make(map[abi.SectorNumber]struct{})
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-bitfield"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
@ -557,7 +558,7 @@ var storageListSectorsCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
defer closer()
|
defer closer()
|
||||||
|
|
||||||
napi, closer2, err := lcli.GetFullNodeAPI(cctx)
|
napi, closer2, err := lcli.GetFullNodeAPIV1(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -592,6 +593,11 @@ var storageListSectorsCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allParts, err := getAllPartitions(ctx, maddr, napi)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting partition states: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
type entry struct {
|
type entry struct {
|
||||||
id abi.SectorNumber
|
id abi.SectorNumber
|
||||||
storage stores.ID
|
storage stores.ID
|
||||||
@ -601,6 +607,8 @@ var storageListSectorsCmd = &cli.Command{
|
|||||||
primary, copy, main, seal, store bool
|
primary, copy, main, seal, store bool
|
||||||
|
|
||||||
state api.SectorState
|
state api.SectorState
|
||||||
|
|
||||||
|
faulty bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var list []entry
|
var list []entry
|
||||||
@ -610,6 +618,10 @@ var storageListSectorsCmd = &cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("getting sector status for sector %d: %w", sector, err)
|
return xerrors.Errorf("getting sector status for sector %d: %w", sector, err)
|
||||||
}
|
}
|
||||||
|
fault, err := allParts.FaultySectors.IsSet(uint64(sector))
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("checking if sector is faulty: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, ft := range storiface.PathTypes {
|
for _, ft := range storiface.PathTypes {
|
||||||
si, err := nodeApi.StorageFindSector(ctx, sid(sector), ft, mi.SectorSize, false)
|
si, err := nodeApi.StorageFindSector(ctx, sid(sector), ft, mi.SectorSize, false)
|
||||||
@ -632,7 +644,8 @@ var storageListSectorsCmd = &cli.Command{
|
|||||||
seal: info.CanSeal,
|
seal: info.CanSeal,
|
||||||
store: info.CanStore,
|
store: info.CanStore,
|
||||||
|
|
||||||
state: st.State,
|
state: st.State,
|
||||||
|
faulty: fault,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -660,6 +673,7 @@ var storageListSectorsCmd = &cli.Command{
|
|||||||
tablewriter.Col("Sector"),
|
tablewriter.Col("Sector"),
|
||||||
tablewriter.Col("Type"),
|
tablewriter.Col("Type"),
|
||||||
tablewriter.Col("State"),
|
tablewriter.Col("State"),
|
||||||
|
tablewriter.Col("Faulty"),
|
||||||
tablewriter.Col("Primary"),
|
tablewriter.Col("Primary"),
|
||||||
tablewriter.Col("Path use"),
|
tablewriter.Col("Path use"),
|
||||||
tablewriter.Col("URLs"),
|
tablewriter.Col("URLs"),
|
||||||
@ -687,6 +701,10 @@ var storageListSectorsCmd = &cli.Command{
|
|||||||
"Path use": maybeStr(e.seal, color.FgMagenta, "seal ") + maybeStr(e.store, color.FgCyan, "store"),
|
"Path use": maybeStr(e.seal, color.FgMagenta, "seal ") + maybeStr(e.store, color.FgCyan, "store"),
|
||||||
"URLs": e.urls,
|
"URLs": e.urls,
|
||||||
}
|
}
|
||||||
|
if e.faulty {
|
||||||
|
// only set when there is a fault, so the column is hidden with no faults
|
||||||
|
m["Faulty"] = color.RedString("faulty")
|
||||||
|
}
|
||||||
tw.Write(m)
|
tw.Write(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -694,6 +712,52 @@ var storageListSectorsCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAllPartitions(ctx context.Context, maddr address.Address, napi api.FullNode) (api.Partition, error) {
|
||||||
|
deadlines, err := napi.StateMinerDeadlines(ctx, maddr, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return api.Partition{}, xerrors.Errorf("getting deadlines: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out := api.Partition{
|
||||||
|
AllSectors: bitfield.New(),
|
||||||
|
FaultySectors: bitfield.New(),
|
||||||
|
RecoveringSectors: bitfield.New(),
|
||||||
|
LiveSectors: bitfield.New(),
|
||||||
|
ActiveSectors: bitfield.New(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for dlIdx := range deadlines {
|
||||||
|
partitions, err := napi.StateMinerPartitions(ctx, maddr, uint64(dlIdx), types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return api.Partition{}, xerrors.Errorf("getting partitions for deadline %d: %w", dlIdx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, partition := range partitions {
|
||||||
|
out.AllSectors, err = bitfield.MergeBitFields(out.AllSectors, partition.AllSectors)
|
||||||
|
if err != nil {
|
||||||
|
return api.Partition{}, err
|
||||||
|
}
|
||||||
|
out.FaultySectors, err = bitfield.MergeBitFields(out.FaultySectors, partition.FaultySectors)
|
||||||
|
if err != nil {
|
||||||
|
return api.Partition{}, err
|
||||||
|
}
|
||||||
|
out.RecoveringSectors, err = bitfield.MergeBitFields(out.RecoveringSectors, partition.RecoveringSectors)
|
||||||
|
if err != nil {
|
||||||
|
return api.Partition{}, err
|
||||||
|
}
|
||||||
|
out.LiveSectors, err = bitfield.MergeBitFields(out.LiveSectors, partition.LiveSectors)
|
||||||
|
if err != nil {
|
||||||
|
return api.Partition{}, err
|
||||||
|
}
|
||||||
|
out.ActiveSectors, err = bitfield.MergeBitFields(out.ActiveSectors, partition.ActiveSectors)
|
||||||
|
if err != nil {
|
||||||
|
return api.Partition{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
func maybeStr(c bool, col color.Attribute, s string) string {
|
func maybeStr(c bool, col color.Attribute, s string) string {
|
||||||
if !c {
|
if !c {
|
||||||
return ""
|
return ""
|
||||||
|
@ -2111,6 +2111,7 @@ OPTIONS:
|
|||||||
--only-bad print only bad sectors (default: false)
|
--only-bad print only bad sectors (default: false)
|
||||||
--slow run slower checks (default: false)
|
--slow run slower checks (default: false)
|
||||||
--storage-id value filter sectors by storage path (path id)
|
--storage-id value filter sectors by storage path (path id)
|
||||||
|
--faulty only check faulty sectors (default: false)
|
||||||
--help, -h show help (default: false)
|
--help, -h show help (default: false)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user