Merge pull request #2821 from filecoin-project/feat/miner-allinfo

miner: Command to dump all miner info
This commit is contained in:
Łukasz Magiera 2020-08-05 20:33:27 +02:00 committed by GitHub
commit 0073f10b62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 305 additions and 157 deletions

View File

@ -238,7 +238,7 @@ var CommonCommands = []*cli.Command{
logCmd, logCmd,
waitApiCmd, waitApiCmd,
fetchParamCmd, fetchParamCmd,
versionCmd, VersionCmd,
} }
var Commands = []*cli.Command{ var Commands = []*cli.Command{
@ -256,7 +256,7 @@ var Commands = []*cli.Command{
WithCategory("developer", fetchParamCmd), WithCategory("developer", fetchParamCmd),
WithCategory("network", netCmd), WithCategory("network", netCmd),
WithCategory("network", syncCmd), WithCategory("network", syncCmd),
versionCmd, VersionCmd,
} }
func WithCategory(cat string, cmd *cli.Command) *cli.Command { func WithCategory(cat string, cmd *cli.Command) *cli.Command {

View File

@ -18,16 +18,16 @@ var netCmd = &cli.Command{
Name: "net", Name: "net",
Usage: "Manage P2P Network", Usage: "Manage P2P Network",
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
netPeers, NetPeers,
netConnect, netConnect,
netListen, NetListen,
netId, NetId,
netFindPeer, netFindPeer,
netScores, netScores,
}, },
} }
var netPeers = &cli.Command{ var NetPeers = &cli.Command{
Name: "peers", Name: "peers",
Usage: "Print peers", Usage: "Print peers",
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
@ -93,7 +93,7 @@ var netScores = &cli.Command{
}, },
} }
var netListen = &cli.Command{ var NetListen = &cli.Command{
Name: "listen", Name: "listen",
Usage: "List listen addresses", Usage: "List listen addresses",
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
@ -147,7 +147,7 @@ var netConnect = &cli.Command{
}, },
} }
var netId = &cli.Command{ var NetId = &cli.Command{
Name: "id", Name: "id",
Usage: "Get node identity", Usage: "Get node identity",
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -6,7 +6,7 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
var versionCmd = &cli.Command{ var VersionCmd = &cli.Command{
Name: "version", Name: "version",
Usage: "Print version", Usage: "Print version",
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -24,154 +24,159 @@ import (
var infoCmd = &cli.Command{ var infoCmd = &cli.Command{
Name: "info", Name: "info",
Usage: "Print miner info", Usage: "Print miner info",
Action: func(cctx *cli.Context) error { Subcommands: []*cli.Command{
color.NoColor = !cctx.Bool("color") infoAllCmd,
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)
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
}
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
}
}
fmt.Printf("Miner: %s\n", color.BlueString("%s", maddr))
// Sector size
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
fmt.Printf("Sector Size: %s\n", types.SizeStr(types.NewInt(uint64(mi.SectorSize))))
pow, err := api.StateMinerPower(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
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)
fmt.Printf("Byte Power: %s / %s (%0.4f%%)\n",
color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)),
types.SizeStr(pow.TotalPower.RawBytePower),
float64(rpercI.Int64())/10000)
fmt.Printf("Actual Power: %s / %s (%0.4f%%)\n",
color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)),
types.DeciStr(pow.TotalPower.QualityAdjPower),
float64(qpercI.Int64())/10000)
secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
faults, err := api.StateMinerFaults(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
nfaults, err := faults.Count()
if err != nil {
return xerrors.Errorf("counting faults: %w", err)
}
fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Sectors), types.NewInt(uint64(mi.SectorSize)))))
if nfaults == 0 {
fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Active), types.NewInt(uint64(mi.SectorSize)))))
} else {
var faultyPercentage float64
if secCounts.Sectors != 0 {
faultyPercentage = float64(10000*nfaults/secCounts.Sectors) / 100.
}
fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n",
types.SizeStr(types.BigMul(types.NewInt(secCounts.Sectors), types.NewInt(uint64(mi.SectorSize)))),
types.SizeStr(types.BigMul(types.NewInt(nfaults), types.NewInt(uint64(mi.SectorSize)))),
faultyPercentage)
}
if pow.MinerPower.RawBytePower.LessThan(power.ConsensusMinerMinPower) {
fmt.Print("Below minimum power threshold, no blocks will be won")
} else {
expWinChance := float64(types.BigMul(qpercI, types.NewInt(build.BlocksPerEpoch)).Int64()) / 1000000
if expWinChance > 0 {
if expWinChance > 1 {
expWinChance = 1
}
winRate := time.Duration(float64(time.Second*time.Duration(build.BlockDelaySecs)) / expWinChance)
winPerDay := float64(time.Hour*24) / float64(winRate)
fmt.Print("Expected block win rate: ")
color.Blue("%.4f/day (every %s)", winPerDay, winRate.Truncate(time.Second))
}
}
fmt.Println()
fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance)))
fmt.Printf("\tPreCommit: %s\n", types.FIL(mas.PreCommitDeposits))
fmt.Printf("\tLocked: %s\n", types.FIL(mas.LockedFunds))
color.Green("\tAvailable: %s", 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)
}
color.Cyan("Worker Balance: %s", 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))
fmt.Println()
sealdur, err := nodeApi.SectorGetExpectedSealDuration(ctx)
if err != nil {
return err
}
fmt.Printf("Expected Seal Duration: %s\n\n", sealdur)
fmt.Println("Sectors:")
err = sectorsInfo(ctx, nodeApi)
if err != nil {
return err
}
// TODO: grab actr state / info
// * Sealed sectors (count / bytes)
// * Power
return nil
}, },
Action: infoCmdAct,
}
func infoCmdAct(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)
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
}
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
}
}
fmt.Printf("Miner: %s\n", color.BlueString("%s", maddr))
// Sector size
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
fmt.Printf("Sector Size: %s\n", types.SizeStr(types.NewInt(uint64(mi.SectorSize))))
pow, err := api.StateMinerPower(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
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)
fmt.Printf("Byte Power: %s / %s (%0.4f%%)\n",
color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)),
types.SizeStr(pow.TotalPower.RawBytePower),
float64(rpercI.Int64())/10000)
fmt.Printf("Actual Power: %s / %s (%0.4f%%)\n",
color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)),
types.DeciStr(pow.TotalPower.QualityAdjPower),
float64(qpercI.Int64())/10000)
secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
faults, err := api.StateMinerFaults(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
nfaults, err := faults.Count()
if err != nil {
return xerrors.Errorf("counting faults: %w", err)
}
fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Sectors), types.NewInt(uint64(mi.SectorSize)))))
if nfaults == 0 {
fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Active), types.NewInt(uint64(mi.SectorSize)))))
} else {
var faultyPercentage float64
if secCounts.Sectors != 0 {
faultyPercentage = float64(10000*nfaults/secCounts.Sectors) / 100.
}
fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n",
types.SizeStr(types.BigMul(types.NewInt(secCounts.Sectors), types.NewInt(uint64(mi.SectorSize)))),
types.SizeStr(types.BigMul(types.NewInt(nfaults), types.NewInt(uint64(mi.SectorSize)))),
faultyPercentage)
}
if pow.MinerPower.RawBytePower.LessThan(power.ConsensusMinerMinPower) {
fmt.Print("Below minimum power threshold, no blocks will be won")
} else {
expWinChance := float64(types.BigMul(qpercI, types.NewInt(build.BlocksPerEpoch)).Int64()) / 1000000
if expWinChance > 0 {
if expWinChance > 1 {
expWinChance = 1
}
winRate := time.Duration(float64(time.Second*time.Duration(build.BlockDelaySecs)) / expWinChance)
winPerDay := float64(time.Hour*24) / float64(winRate)
fmt.Print("Expected block win rate: ")
color.Blue("%.4f/day (every %s)", winPerDay, winRate.Truncate(time.Second))
}
}
fmt.Println()
fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance)))
fmt.Printf("\tPreCommit: %s\n", types.FIL(mas.PreCommitDeposits))
fmt.Printf("\tLocked: %s\n", types.FIL(mas.LockedFunds))
color.Green("\tAvailable: %s", 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)
}
color.Cyan("Worker Balance: %s", 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))
fmt.Println()
sealdur, err := nodeApi.SectorGetExpectedSealDuration(ctx)
if err != nil {
return err
}
fmt.Printf("Expected Seal Duration: %s\n\n", sealdur)
fmt.Println("Sectors:")
err = sectorsInfo(ctx, nodeApi)
if err != nil {
return err
}
// TODO: grab actr state / info
// * Sealed sectors (count / bytes)
// * Power
return nil
} }
type stateMeta struct { type stateMeta struct {

View File

@ -0,0 +1,143 @@
package main
import (
"flag"
"fmt"
"sort"
"github.com/urfave/cli/v2"
lcli "github.com/filecoin-project/lotus/cli"
)
var infoAllCmd = &cli.Command{
Name: "all",
Usage: "dump all related miner info",
Action: func(cctx *cli.Context) error {
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()
_ = api
ctx := lcli.ReqContext(cctx)
// Top-level info
fmt.Println("#: Version")
if err := lcli.VersionCmd.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: Miner Info")
if err := infoCmdAct(cctx); err != nil {
return err
}
// Verbose info
fmt.Println("\n#: Storage List")
if err := storageListCmd.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: Worker List")
if err := sealingWorkersCmd.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: PeerID")
if err := lcli.NetId.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: Listen Addresses")
if err := lcli.NetListen.Action(cctx); err != nil {
return err
}
// Very Verbose info
fmt.Println("\n#: Peers")
if err := lcli.NetPeers.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: Sealing Jobs")
if err := sealingJobsCmd.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: Sched Diag")
if err := sealingSchedDiagCmd.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: Storage Ask")
if err := getAskCmd.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: Storage Deals")
if err := dealsListCmd.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: Sector List")
if err := sectorsListCmd.Action(cctx); err != nil {
return err
}
fmt.Println("\n#: Sector Refs")
if err := sectorsRefsCmd.Action(cctx); err != nil {
return err
}
// Very Very Verbose info
fmt.Println("\n#: Per Sector Info")
list, err := nodeApi.SectorsList(ctx)
if err != nil {
return err
}
sort.Slice(list, func(i, j int) bool {
return list[i] < list[j]
})
for _, s := range list {
fmt.Printf("\n##: Sector %d Status\n", s)
fs := &flag.FlagSet{}
for _, f := range sectorsStatusCmd.Flags {
f.Apply(fs)
}
if err := fs.Parse([]string{"--log", "--on-chain-info", fmt.Sprint(s)}); err != nil {
return err
}
if err := sectorsStatusCmd.Action(cli.NewContext(cctx.App, fs, cctx)); err != nil {
return err
}
fmt.Printf("\n##: Sector %d Storage Location\n", s)
fs = &flag.FlagSet{}
if err := fs.Parse([]string{fmt.Sprint(s)}); err != nil {
return err
}
if err := storageFindCmd.Action(cli.NewContext(cctx.App, fs, cctx)); err != nil {
return err
}
}
return nil
},
}

View File

@ -266,7 +266,7 @@ var getAskCmd = &cli.Command{
} }
w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0) w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
fmt.Fprintf(w, "Price per GiB / Epoch\tMin. Piece Size (w/bit-padding)\tMax. Piece Size (w/bit-padding)\tExpiry (Epoch)\tExpiry (Appx. Rem. Time)\tSeq. No.\n") fmt.Fprintf(w, "Price per GiB/Epoch\tMin. Piece Size (padded)\tMax. Piece Size (padded)\tExpiry (Epoch)\tExpiry (Appx. Rem. Time)\tSeq. No.\n")
if ask == nil { if ask == nil {
fmt.Fprintf(w, "<miner does not have an ask>\n") fmt.Fprintf(w, "<miner does not have an ask>\n")