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:
Łukasz Magiera 2022-03-25 15:29:27 -04:00 committed by GitHub
commit d437f19aae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 3 deletions

View File

@ -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{})

View File

@ -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 ""

View File

@ -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)
``` ```