2019-10-11 23:47:29 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2020-04-24 17:35:41 +00:00
|
|
|
"bytes"
|
2019-10-14 02:32:32 +00:00
|
|
|
"context"
|
2019-10-11 23:47:29 +00:00
|
|
|
"fmt"
|
2020-04-24 17:35:41 +00:00
|
|
|
"golang.org/x/xerrors"
|
2019-10-11 23:47:29 +00:00
|
|
|
|
|
|
|
"gopkg.in/urfave/cli.v2"
|
|
|
|
|
2020-04-24 17:35:41 +00:00
|
|
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
|
|
|
sealing "github.com/filecoin-project/storage-fsm"
|
|
|
|
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/api"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
lcli "github.com/filecoin-project/lotus/cli"
|
2019-10-11 23:47:29 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var infoCmd = &cli.Command{
|
|
|
|
Name: "info",
|
|
|
|
Usage: "Print storage miner info",
|
|
|
|
Action: func(cctx *cli.Context) error {
|
|
|
|
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer closer()
|
2019-10-14 02:32:32 +00:00
|
|
|
|
|
|
|
api, acloser, err := lcli.GetFullNodeAPI(cctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer acloser()
|
|
|
|
|
2019-10-11 23:47:29 +00:00
|
|
|
ctx := lcli.ReqContext(cctx)
|
|
|
|
|
2019-10-14 02:32:32 +00:00
|
|
|
maddr, err := nodeApi.ActorAddress(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-04-24 17:35:41 +00:00
|
|
|
mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
var mas miner.State
|
|
|
|
{
|
|
|
|
rmas, err := api.ChainReadObj(ctx, mact.Head)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := mas.UnmarshalCBOR(bytes.NewReader(rmas)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-14 02:32:32 +00:00
|
|
|
fmt.Printf("Miner: %s\n", maddr)
|
|
|
|
|
2019-11-07 10:46:11 +00:00
|
|
|
// Sector size
|
2020-04-16 17:36:36 +00:00
|
|
|
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
2019-11-07 10:46:11 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-11-07 12:05:03 +00:00
|
|
|
|
2020-04-16 17:36:36 +00:00
|
|
|
fmt.Printf("Sector Size: %s\n", types.SizeStr(types.NewInt(uint64(mi.SectorSize))))
|
2019-11-07 10:46:11 +00:00
|
|
|
|
2020-02-11 23:29:45 +00:00
|
|
|
pow, err := api.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
2019-10-14 02:32:32 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-04-17 22:02:04 +00:00
|
|
|
rpercI := types.BigDiv(types.BigMul(pow.MinerPower.RawBytePower, types.NewInt(1000000)), pow.TotalPower.RawBytePower)
|
|
|
|
qpercI := types.BigDiv(types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(1000000)), pow.TotalPower.QualityAdjPower)
|
2020-04-21 19:46:50 +00:00
|
|
|
fmt.Printf("Byte Power: %s / %s (%0.4f%%)\n", types.SizeStr(pow.MinerPower.RawBytePower), types.SizeStr(pow.TotalPower.RawBytePower), float64(rpercI.Int64())/10000)
|
|
|
|
fmt.Printf("Actual Power: %s / %s (%0.4f%%)\n", types.DecStr(pow.MinerPower.QualityAdjPower), types.DecStr(pow.TotalPower.QualityAdjPower), float64(qpercI.Int64())/10000)
|
2020-02-11 23:29:45 +00:00
|
|
|
secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK)
|
2019-12-12 12:02:20 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-02-11 23:29:45 +00:00
|
|
|
faults, err := api.StateMinerFaults(ctx, maddr, types.EmptyTSK)
|
2020-01-30 18:38:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-04-16 17:36:36 +00:00
|
|
|
fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Sset), types.NewInt(uint64(mi.SectorSize)))))
|
2020-01-30 18:38:03 +00:00
|
|
|
if len(faults) == 0 {
|
2020-04-16 17:36:36 +00:00
|
|
|
fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Pset), types.NewInt(uint64(mi.SectorSize)))))
|
2020-01-30 18:38:03 +00:00
|
|
|
} else {
|
|
|
|
fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n",
|
2020-04-16 17:36:36 +00:00
|
|
|
types.SizeStr(types.BigMul(types.NewInt(secCounts.Pset-uint64(len(faults))), types.NewInt(uint64(mi.SectorSize)))),
|
|
|
|
types.SizeStr(types.BigMul(types.NewInt(uint64(len(faults))), types.NewInt(uint64(mi.SectorSize)))),
|
2020-01-31 01:27:38 +00:00
|
|
|
float64(10000*uint64(len(faults))/secCounts.Pset)/100.)
|
2020-01-30 18:38:03 +00:00
|
|
|
}
|
2019-12-12 12:02:20 +00:00
|
|
|
|
2020-04-24 17:35:41 +00:00
|
|
|
fmt.Printf("Miner Balance: %s\n", types.FIL(mact.Balance))
|
|
|
|
fmt.Printf("\tPreCommit: %s\n", types.FIL(mas.PreCommitDeposits))
|
|
|
|
fmt.Printf("\tLocked: %s\n", types.FIL(mas.LockedFunds))
|
|
|
|
fmt.Printf("\tAvailable: %s\n", types.FIL(types.BigSub(mact.Balance, types.BigAdd(mas.LockedFunds, mas.PreCommitDeposits))))
|
|
|
|
wb, err := api.WalletBalance(ctx, mi.Worker)
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("getting worker balance: %w", err)
|
|
|
|
}
|
|
|
|
fmt.Printf("Worker Balance: %s\n", types.FIL(wb))
|
|
|
|
|
|
|
|
mb, err := api.StateMarketBalance(ctx, maddr, types.EmptyTSK)
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("getting market balance: %w", err)
|
|
|
|
}
|
|
|
|
fmt.Printf("Market (Escrow): %s\n", types.FIL(mb.Escrow))
|
|
|
|
fmt.Printf("Market (Locked): %s\n", types.FIL(mb.Locked))
|
|
|
|
|
2020-03-03 22:19:22 +00:00
|
|
|
/*// TODO: indicate whether the post worker is in use
|
2019-11-08 18:15:13 +00:00
|
|
|
wstat, err := nodeApi.WorkerStats(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-11-21 16:23:42 +00:00
|
|
|
|
|
|
|
fmt.Printf("Worker use:\n")
|
2019-11-21 18:38:43 +00:00
|
|
|
fmt.Printf("\tLocal: %d / %d (+%d reserved)\n", wstat.LocalTotal-wstat.LocalReserved-wstat.LocalFree, wstat.LocalTotal-wstat.LocalReserved, wstat.LocalReserved)
|
|
|
|
fmt.Printf("\tRemote: %d / %d\n", wstat.RemotesTotal-wstat.RemotesFree, wstat.RemotesTotal)
|
2019-11-08 18:15:13 +00:00
|
|
|
|
2019-12-06 00:27:32 +00:00
|
|
|
fmt.Printf("Queues:\n")
|
|
|
|
fmt.Printf("\tAddPiece: %d\n", wstat.AddPieceWait)
|
|
|
|
fmt.Printf("\tPreCommit: %d\n", wstat.PreCommitWait)
|
|
|
|
fmt.Printf("\tCommit: %d\n", wstat.CommitWait)
|
2020-03-03 22:19:22 +00:00
|
|
|
fmt.Printf("\tUnseal: %d\n", wstat.UnsealWait)*/
|
2019-12-06 00:27:32 +00:00
|
|
|
|
2020-04-15 22:16:24 +00:00
|
|
|
/*ps, err := api.StateMinerPostState(ctx, maddr, types.EmptyTSK)
|
2019-11-09 09:49:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-02-21 18:20:22 +00:00
|
|
|
if ps.ProvingPeriodStart != 0 {
|
2019-11-09 12:11:46 +00:00
|
|
|
head, err := api.ChainHead(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-12-02 16:47:09 +00:00
|
|
|
|
2020-03-08 08:07:58 +00:00
|
|
|
fallback := ps.ProvingPeriodStart - head.Height()
|
2019-12-03 01:46:29 +00:00
|
|
|
fallbackS := fallback * build.BlockDelay
|
|
|
|
|
2020-03-08 08:07:58 +00:00
|
|
|
next := fallback + power.WindowedPostChallengeDuration
|
2019-12-02 16:47:09 +00:00
|
|
|
nextS := next * build.BlockDelay
|
|
|
|
|
|
|
|
fmt.Printf("PoSt Submissions:\n")
|
2020-03-08 08:07:58 +00:00
|
|
|
fmt.Printf("\tFallback: Epoch %d (in %d blocks, ~%dm %ds)\n", ps.ProvingPeriodStart, fallback, fallbackS/60, fallbackS%60)
|
2020-02-21 18:20:22 +00:00
|
|
|
fmt.Printf("\tDeadline: Epoch %d (in %d blocks, ~%dm %ds)\n", ps.ProvingPeriodStart+build.SlashablePowerDelay, next, nextS/60, nextS%60)
|
|
|
|
fmt.Printf("\tConsecutive Failures: %d\n", ps.NumConsecutiveFailures)
|
2019-11-09 12:11:46 +00:00
|
|
|
} else {
|
|
|
|
fmt.Printf("Proving Period: Not Proving\n")
|
2020-04-15 22:16:24 +00:00
|
|
|
}*/
|
2019-11-09 12:11:46 +00:00
|
|
|
|
2019-10-14 02:32:32 +00:00
|
|
|
sinfo, err := sectorsInfo(ctx, nodeApi)
|
2019-10-11 23:47:29 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-11-09 09:49:43 +00:00
|
|
|
fmt.Println("Sectors: ", sinfo)
|
2019-10-14 02:32:32 +00:00
|
|
|
|
2019-10-11 23:47:29 +00:00
|
|
|
// TODO: grab actr state / info
|
|
|
|
// * Sealed sectors (count / bytes)
|
|
|
|
// * Power
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
2019-10-14 02:32:32 +00:00
|
|
|
|
2020-04-06 20:23:37 +00:00
|
|
|
func sectorsInfo(ctx context.Context, napi api.StorageMiner) (map[sealing.SectorState]int, error) {
|
2019-10-14 02:32:32 +00:00
|
|
|
sectors, err := napi.SectorsList(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-04-06 20:23:37 +00:00
|
|
|
out := map[sealing.SectorState]int{
|
2019-11-01 03:57:10 +00:00
|
|
|
"Total": len(sectors),
|
2019-10-14 02:32:32 +00:00
|
|
|
}
|
|
|
|
for _, s := range sectors {
|
|
|
|
st, err := napi.SectorsStatus(ctx, s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-04-23 22:33:59 +00:00
|
|
|
out[sealing.SectorState(st.State)]++
|
2019-10-14 02:32:32 +00:00
|
|
|
}
|
|
|
|
|
2019-11-01 03:57:10 +00:00
|
|
|
return out, nil
|
2019-10-14 02:32:32 +00:00
|
|
|
}
|