feat: SPTool (#11788)
* sptool: Initial structure * sptool: Port lotus-miner actor withdraw * sptool: Make cli docsgen happy * actors are done * info * proving * sptool the rest * fixed gitignore * lints * oops * 2 * terminate * fixes * sptool: improve sectors list --------- Co-authored-by: Łukasz Magiera <magik6k@gmail.com>
This commit is contained in:
co-authored by
Łukasz Magiera
parent
8062f200bd
commit
b95e95f4d6
+1240
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,121 @@
|
||||
package spcli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
cliutil "github.com/filecoin-project/lotus/cli/util"
|
||||
)
|
||||
|
||||
func InfoCmd(getActorAddress ActorAddressGetter) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "Print miner actor info",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := cliutil.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := cliutil.ReqContext(cctx)
|
||||
|
||||
ts, err := lcli.LoadTipSet(ctx, cctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr, err := getActorAddress(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mi, err := api.StateMinerInfo(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
availableBalance, err := api.StateMinerAvailableBalance(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner available balance: %w", err)
|
||||
}
|
||||
fmt.Printf("Available Balance: %s\n", types.FIL(availableBalance))
|
||||
fmt.Printf("Owner:\t%s\n", mi.Owner)
|
||||
fmt.Printf("Worker:\t%s\n", mi.Worker)
|
||||
for i, controlAddress := range mi.ControlAddresses {
|
||||
fmt.Printf("Control %d: \t%s\n", i, controlAddress)
|
||||
}
|
||||
if mi.Beneficiary != address.Undef {
|
||||
fmt.Printf("Beneficiary:\t%s\n", mi.Beneficiary)
|
||||
if mi.Beneficiary != mi.Owner {
|
||||
fmt.Printf("Beneficiary Quota:\t%s\n", mi.BeneficiaryTerm.Quota)
|
||||
fmt.Printf("Beneficiary Used Quota:\t%s\n", mi.BeneficiaryTerm.UsedQuota)
|
||||
fmt.Printf("Beneficiary Expiration:\t%s\n", mi.BeneficiaryTerm.Expiration)
|
||||
}
|
||||
}
|
||||
if mi.PendingBeneficiaryTerm != nil {
|
||||
fmt.Printf("Pending Beneficiary Term:\n")
|
||||
fmt.Printf("New Beneficiary:\t%s\n", mi.PendingBeneficiaryTerm.NewBeneficiary)
|
||||
fmt.Printf("New Quota:\t%s\n", mi.PendingBeneficiaryTerm.NewQuota)
|
||||
fmt.Printf("New Expiration:\t%s\n", mi.PendingBeneficiaryTerm.NewExpiration)
|
||||
fmt.Printf("Approved By Beneficiary:\t%t\n", mi.PendingBeneficiaryTerm.ApprovedByBeneficiary)
|
||||
fmt.Printf("Approved By Nominee:\t%t\n", mi.PendingBeneficiaryTerm.ApprovedByNominee)
|
||||
}
|
||||
|
||||
fmt.Printf("PeerID:\t%s\n", mi.PeerId)
|
||||
fmt.Printf("Multiaddrs:\t")
|
||||
for _, addr := range mi.Multiaddrs {
|
||||
a, err := multiaddr.NewMultiaddrBytes(addr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("undecodable listen address: %w", err)
|
||||
}
|
||||
fmt.Printf("%s ", a)
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Printf("Consensus Fault End:\t%d\n", mi.ConsensusFaultElapsed)
|
||||
|
||||
fmt.Printf("SectorSize:\t%s (%d)\n", types.SizeStr(types.NewInt(uint64(mi.SectorSize))), mi.SectorSize)
|
||||
pow, err := api.StateMinerPower(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Byte Power: %s / %s (%0.4f%%)\n",
|
||||
color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)),
|
||||
types.SizeStr(pow.TotalPower.RawBytePower),
|
||||
types.BigDivFloat(
|
||||
types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)),
|
||||
pow.TotalPower.RawBytePower,
|
||||
),
|
||||
)
|
||||
|
||||
fmt.Printf("Actual Power: %s / %s (%0.4f%%)\n",
|
||||
color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)),
|
||||
types.DeciStr(pow.TotalPower.QualityAdjPower),
|
||||
types.BigDivFloat(
|
||||
types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)),
|
||||
pow.TotalPower.QualityAdjPower,
|
||||
),
|
||||
)
|
||||
|
||||
fmt.Println()
|
||||
|
||||
cd, err := api.StateMinerProvingDeadline(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner info: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Proving Period Start:\t%s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.PeriodStart))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
package spcli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
"github.com/filecoin-project/lotus/blockstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
cliutil "github.com/filecoin-project/lotus/cli/util"
|
||||
)
|
||||
|
||||
func ProvingInfoCmd(getActorAddress ActorAddressGetter) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "View current state information",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, acloser, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer acloser()
|
||||
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
maddr, err := getActorAddress(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
head, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting chain head: %w", err)
|
||||
}
|
||||
|
||||
mact, err := api.StateGetActor(ctx, maddr, head.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stor := store.ActorStore(ctx, blockstore.NewAPIBlockstore(api))
|
||||
|
||||
mas, err := miner.Load(stor, mact)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
if bf, err := part.FaultySectors(); err != nil {
|
||||
return err
|
||||
} else if count, err := bf.Count(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
faults += count
|
||||
}
|
||||
|
||||
if bf, err := part.RecoveringSectors(); err != nil {
|
||||
return err
|
||||
} else if count, err := bf.Count(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
recovering += count
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}); err != nil {
|
||||
return xerrors.Errorf("walking miner deadlines and partitions: %w", err)
|
||||
}
|
||||
|
||||
var faultPerc float64
|
||||
if proving > 0 {
|
||||
faultPerc = float64(faults * 100 / proving)
|
||||
}
|
||||
|
||||
fmt.Printf("Current Epoch: %d\n", cd.CurrentEpoch)
|
||||
|
||||
fmt.Printf("Proving Period Boundary: %d\n", cd.PeriodStart%cd.WPoStProvingPeriod)
|
||||
fmt.Printf("Proving Period Start: %s\n", cliutil.EpochTimeTs(cd.CurrentEpoch, cd.PeriodStart, head))
|
||||
fmt.Printf("Next Period Start: %s\n\n", cliutil.EpochTimeTs(cd.CurrentEpoch, cd.PeriodStart+cd.WPoStProvingPeriod, head))
|
||||
|
||||
fmt.Printf("Faults: %d (%.2f%%)\n", faults, faultPerc)
|
||||
fmt.Printf("Recovering: %d\n", recovering)
|
||||
|
||||
fmt.Printf("Deadline Index: %d\n", cd.Index)
|
||||
fmt.Printf("Deadline Sectors: %d\n", curDeadlineSectors)
|
||||
fmt.Printf("Deadline Open: %s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.Open))
|
||||
fmt.Printf("Deadline Close: %s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.Close))
|
||||
fmt.Printf("Deadline Challenge: %s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.Challenge))
|
||||
fmt.Printf("Deadline FaultCutoff: %s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.FaultCutoff))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ProvingDeadlinesCmd(getActorAddress ActorAddressGetter) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "deadlines",
|
||||
Usage: "View the current proving period deadlines information",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "all",
|
||||
Usage: "Count all sectors (only live sectors are counted by default)",
|
||||
Aliases: []string{"a"},
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, acloser, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer acloser()
|
||||
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
maddr, err := getActorAddress(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
head, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Miner: %s\n", color.BlueString("%s", maddr))
|
||||
|
||||
tw := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
|
||||
_, _ = fmt.Fprintln(tw, "deadline\topen\tpartitions\tsectors (faults)\tproven partitions")
|
||||
|
||||
for dlIdx, deadline := range deadlines {
|
||||
partitions, err := api.StateMinerPartitions(ctx, maddr, uint64(dlIdx), types.EmptyTSK)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting partitions for deadline %d: %w", dlIdx, err)
|
||||
}
|
||||
|
||||
provenPartitions, err := deadline.PostSubmissions.Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sectors := uint64(0)
|
||||
faults := uint64(0)
|
||||
var partitionCount int
|
||||
|
||||
for _, partition := range partitions {
|
||||
if !cctx.Bool("all") {
|
||||
sc, err := partition.LiveSectors.Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sc > 0 {
|
||||
partitionCount++
|
||||
}
|
||||
|
||||
sectors += sc
|
||||
} else {
|
||||
sc, err := partition.AllSectors.Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
partitionCount++
|
||||
sectors += sc
|
||||
}
|
||||
|
||||
fc, err := partition.FaultySectors.Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
faults += fc
|
||||
}
|
||||
|
||||
var cur string
|
||||
if di.Index == uint64(dlIdx) {
|
||||
cur += "\t(current)"
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(tw, "%d\t%s\t%d\t%d (%d)\t%d%s\n", dlIdx, deadlineOpenTime(head, uint64(dlIdx), di),
|
||||
partitionCount, sectors, faults, provenPartitions, cur)
|
||||
}
|
||||
|
||||
return tw.Flush()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func deadlineOpenTime(ts *types.TipSet, dlIdx uint64, di *dline.Info) string {
|
||||
gapIdx := dlIdx - di.Index
|
||||
gapHeight := uint64(di.WPoStProvingPeriod) / di.WPoStPeriodDeadlines * gapIdx
|
||||
|
||||
openHeight := di.Open + abi.ChainEpoch(gapHeight)
|
||||
genesisBlockTimestamp := ts.MinTimestamp() - uint64(ts.Height())*build.BlockDelaySecs
|
||||
|
||||
return time.Unix(int64(genesisBlockTimestamp+build.BlockDelaySecs*uint64(openHeight)), 0).Format(time.TimeOnly)
|
||||
}
|
||||
|
||||
func ProvingDeadlineInfoCmd(getActorAddress ActorAddressGetter) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "deadline",
|
||||
Usage: "View the current proving period deadline information by its index",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "sector-nums",
|
||||
Aliases: []string{"n"},
|
||||
Usage: "Print sector/fault numbers belonging to this deadline",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "bitfield",
|
||||
Aliases: []string{"b"},
|
||||
Usage: "Print partition bitfield stats",
|
||||
},
|
||||
},
|
||||
ArgsUsage: "<deadlineIdx>",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
|
||||
if cctx.NArg() != 1 {
|
||||
return lcli.IncorrectNumArgs(cctx)
|
||||
}
|
||||
|
||||
dlIdx, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("could not parse deadline index: %w", err)
|
||||
}
|
||||
|
||||
api, acloser, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer acloser()
|
||||
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
maddr, err := getActorAddress(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
partitions, err := api.StateMinerPartitions(ctx, maddr, dlIdx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting partitions for deadline %d: %w", dlIdx, err)
|
||||
}
|
||||
|
||||
head, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
provenPartitions, err := deadlines[dlIdx].PostSubmissions.Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Deadline Index: %d\n", dlIdx)
|
||||
fmt.Printf("Deadline Open: %s\n", deadlineOpenTime(head, dlIdx, di))
|
||||
fmt.Printf("Partitions: %d\n", len(partitions))
|
||||
fmt.Printf("Proven Partitions: %d\n", provenPartitions)
|
||||
fmt.Printf("Current: %t\n\n", di.Index == dlIdx)
|
||||
|
||||
for pIdx, partition := range partitions {
|
||||
fmt.Printf("Partition Index: %d\n", pIdx)
|
||||
|
||||
printStats := func(bf bitfield.BitField, name string) error {
|
||||
count, err := bf.Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rit, err := bf.RunIterator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cctx.Bool("bitfield") {
|
||||
var ones, zeros, oneRuns, zeroRuns, invalid uint64
|
||||
for rit.HasNext() {
|
||||
r, err := rit.NextRun()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("next run: %w", err)
|
||||
}
|
||||
if !r.Valid() {
|
||||
invalid++
|
||||
}
|
||||
if r.Val {
|
||||
ones += r.Len
|
||||
oneRuns++
|
||||
} else {
|
||||
zeros += r.Len
|
||||
zeroRuns++
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := bf.MarshalCBOR(&buf); err != nil {
|
||||
return err
|
||||
}
|
||||
sz := len(buf.Bytes())
|
||||
szstr := types.SizeStr(types.NewInt(uint64(sz)))
|
||||
|
||||
fmt.Printf("\t%s Sectors:%s%d (bitfield - runs %d+%d=%d - %d 0s %d 1s - %d inv - %s %dB)\n", name, strings.Repeat(" ", 18-len(name)), count, zeroRuns, oneRuns, zeroRuns+oneRuns, zeros, ones, invalid, szstr, sz)
|
||||
} else {
|
||||
fmt.Printf("\t%s Sectors:%s%d\n", name, strings.Repeat(" ", 18-len(name)), count)
|
||||
}
|
||||
|
||||
if cctx.Bool("sector-nums") {
|
||||
nums, err := bf.All(count)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("\t%s Sector Numbers:%s%v\n", name, strings.Repeat(" ", 12-len(name)), nums)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := printStats(partition.AllSectors, "All"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := printStats(partition.LiveSectors, "Live"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := printStats(partition.ActiveSectors, "Active"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := printStats(partition.FaultySectors, "Faulty"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := printStats(partition.RecoveringSectors, "Recovering"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ProvingFaultsCmd(getActorAddress ActorAddressGetter) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "faults",
|
||||
Usage: "View the currently known proving faulty sectors information",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, acloser, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer acloser()
|
||||
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
stor := store.ActorStore(ctx, blockstore.NewAPIBlockstore(api))
|
||||
|
||||
maddr, err := getActorAddress(cctx)
|
||||
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)
|
||||
_, _ = fmt.Fprintln(tw, "deadline\tpartition\tsectors")
|
||||
err = mas.ForEachDeadline(func(dlIdx uint64, dl miner.Deadline) error {
|
||||
return dl.ForEachPartition(func(partIdx uint64, part miner.Partition) error {
|
||||
faults, err := part.FaultySectors()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return faults.ForEach(func(num uint64) error {
|
||||
_, _ = fmt.Fprintf(tw, "%d\t%d\t%d\n", dlIdx, partIdx, num)
|
||||
return nil
|
||||
})
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tw.Flush()
|
||||
},
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,95 @@
|
||||
package spcli
|
||||
|
||||
import (
|
||||
"github.com/fatih/color"
|
||||
|
||||
sealing "github.com/filecoin-project/lotus/storage/pipeline"
|
||||
)
|
||||
|
||||
type StateMeta struct {
|
||||
I int
|
||||
Col color.Attribute
|
||||
State sealing.SectorState
|
||||
}
|
||||
|
||||
var StateOrder = map[sealing.SectorState]StateMeta{}
|
||||
var StateList = []StateMeta{
|
||||
{Col: 39, State: "Total"},
|
||||
{Col: color.FgGreen, State: sealing.Proving},
|
||||
{Col: color.FgGreen, State: sealing.Available},
|
||||
{Col: color.FgGreen, State: sealing.UpdateActivating},
|
||||
|
||||
{Col: color.FgMagenta, State: sealing.ReceiveSector},
|
||||
|
||||
{Col: color.FgBlue, State: sealing.Empty},
|
||||
{Col: color.FgBlue, State: sealing.WaitDeals},
|
||||
{Col: color.FgBlue, State: sealing.AddPiece},
|
||||
{Col: color.FgBlue, State: sealing.SnapDealsWaitDeals},
|
||||
{Col: color.FgBlue, State: sealing.SnapDealsAddPiece},
|
||||
|
||||
{Col: color.FgRed, State: sealing.UndefinedSectorState},
|
||||
{Col: color.FgYellow, State: sealing.Packing},
|
||||
{Col: color.FgYellow, State: sealing.GetTicket},
|
||||
{Col: color.FgYellow, State: sealing.PreCommit1},
|
||||
{Col: color.FgYellow, State: sealing.PreCommit2},
|
||||
{Col: color.FgYellow, State: sealing.PreCommitting},
|
||||
{Col: color.FgYellow, State: sealing.PreCommitWait},
|
||||
{Col: color.FgYellow, State: sealing.SubmitPreCommitBatch},
|
||||
{Col: color.FgYellow, State: sealing.PreCommitBatchWait},
|
||||
{Col: color.FgYellow, State: sealing.WaitSeed},
|
||||
{Col: color.FgYellow, State: sealing.Committing},
|
||||
{Col: color.FgYellow, State: sealing.CommitFinalize},
|
||||
{Col: color.FgYellow, State: sealing.SubmitCommit},
|
||||
{Col: color.FgYellow, State: sealing.CommitWait},
|
||||
{Col: color.FgYellow, State: sealing.SubmitCommitAggregate},
|
||||
{Col: color.FgYellow, State: sealing.CommitAggregateWait},
|
||||
{Col: color.FgYellow, State: sealing.FinalizeSector},
|
||||
{Col: color.FgYellow, State: sealing.SnapDealsPacking},
|
||||
{Col: color.FgYellow, State: sealing.UpdateReplica},
|
||||
{Col: color.FgYellow, State: sealing.ProveReplicaUpdate},
|
||||
{Col: color.FgYellow, State: sealing.SubmitReplicaUpdate},
|
||||
{Col: color.FgYellow, State: sealing.ReplicaUpdateWait},
|
||||
{Col: color.FgYellow, State: sealing.WaitMutable},
|
||||
{Col: color.FgYellow, State: sealing.FinalizeReplicaUpdate},
|
||||
{Col: color.FgYellow, State: sealing.ReleaseSectorKey},
|
||||
|
||||
{Col: color.FgCyan, State: sealing.Terminating},
|
||||
{Col: color.FgCyan, State: sealing.TerminateWait},
|
||||
{Col: color.FgCyan, State: sealing.TerminateFinality},
|
||||
{Col: color.FgCyan, State: sealing.TerminateFailed},
|
||||
{Col: color.FgCyan, State: sealing.Removing},
|
||||
{Col: color.FgCyan, State: sealing.Removed},
|
||||
{Col: color.FgCyan, State: sealing.AbortUpgrade},
|
||||
|
||||
{Col: color.FgRed, State: sealing.FailedUnrecoverable},
|
||||
{Col: color.FgRed, State: sealing.AddPieceFailed},
|
||||
{Col: color.FgRed, State: sealing.SealPreCommit1Failed},
|
||||
{Col: color.FgRed, State: sealing.SealPreCommit2Failed},
|
||||
{Col: color.FgRed, State: sealing.PreCommitFailed},
|
||||
{Col: color.FgRed, State: sealing.ComputeProofFailed},
|
||||
{Col: color.FgRed, State: sealing.RemoteCommitFailed},
|
||||
{Col: color.FgRed, State: sealing.CommitFailed},
|
||||
{Col: color.FgRed, State: sealing.CommitFinalizeFailed},
|
||||
{Col: color.FgRed, State: sealing.PackingFailed},
|
||||
{Col: color.FgRed, State: sealing.FinalizeFailed},
|
||||
{Col: color.FgRed, State: sealing.Faulty},
|
||||
{Col: color.FgRed, State: sealing.FaultReported},
|
||||
{Col: color.FgRed, State: sealing.FaultedFinal},
|
||||
{Col: color.FgRed, State: sealing.RemoveFailed},
|
||||
{Col: color.FgRed, State: sealing.DealsExpired},
|
||||
{Col: color.FgRed, State: sealing.RecoverDealIDs},
|
||||
{Col: color.FgRed, State: sealing.SnapDealsAddPieceFailed},
|
||||
{Col: color.FgRed, State: sealing.SnapDealsDealsExpired},
|
||||
{Col: color.FgRed, State: sealing.ReplicaUpdateFailed},
|
||||
{Col: color.FgRed, State: sealing.ReleaseSectorKeyFailed},
|
||||
{Col: color.FgRed, State: sealing.FinalizeReplicaUpdateFailed},
|
||||
}
|
||||
|
||||
func init() {
|
||||
for i, state := range StateList {
|
||||
StateOrder[state.State] = StateMeta{
|
||||
I: i,
|
||||
Col: state.Col,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package spcli
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
)
|
||||
|
||||
type ActorAddressGetter func(cctx *cli.Context) (address address.Address, err error)
|
||||
Reference in New Issue
Block a user