Merge pull request #5083 from filecoin-project/feat/miner-info-improvements

miner info cli improvements
This commit is contained in:
Łukasz Magiera 2020-12-01 22:46:50 +01:00 committed by GitHub
commit b6046924b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 154 additions and 29 deletions

View File

@ -23,6 +23,29 @@ func (f FIL) Unitless() string {
return strings.TrimRight(strings.TrimRight(r.FloatString(18), "0"), ".")
}
var unitPrefixes = []string{"a", "f", "p", "n", "μ", "m"}
func (f FIL) Short() string {
n := BigInt(f)
dn := uint64(1)
var prefix string
for _, p := range unitPrefixes {
if n.LessThan(NewInt(dn * 1000)) {
prefix = p
break
}
dn *= 1000
}
r := new(big.Rat).SetFrac(f.Int, big.NewInt(int64(dn)))
if r.Sign() == 0 {
return "0"
}
return strings.TrimRight(strings.TrimRight(r.FloatString(3), "0"), ".") + " " + prefix + "FIL"
}
func (f FIL) Format(s fmt.State, ch rune) {
switch ch {
case 's', 'v':

68
chain/types/fil_test.go Normal file
View File

@ -0,0 +1,68 @@
package types
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestFilShort(t *testing.T) {
for _, s := range []struct {
fil string
expect string
}{
{fil: "1", expect: "1 FIL"},
{fil: "1.1", expect: "1.1 FIL"},
{fil: "12", expect: "12 FIL"},
{fil: "123", expect: "123 FIL"},
{fil: "123456", expect: "123456 FIL"},
{fil: "123.23", expect: "123.23 FIL"},
{fil: "123456.234", expect: "123456.234 FIL"},
{fil: "123456.2341234", expect: "123456.234 FIL"},
{fil: "123456.234123445", expect: "123456.234 FIL"},
{fil: "0.1", expect: "100 mFIL"},
{fil: "0.01", expect: "10 mFIL"},
{fil: "0.001", expect: "1 mFIL"},
{fil: "0.0001", expect: "100 μFIL"},
{fil: "0.00001", expect: "10 μFIL"},
{fil: "0.000001", expect: "1 μFIL"},
{fil: "0.0000001", expect: "100 nFIL"},
{fil: "0.00000001", expect: "10 nFIL"},
{fil: "0.000000001", expect: "1 nFIL"},
{fil: "0.0000000001", expect: "100 pFIL"},
{fil: "0.00000000001", expect: "10 pFIL"},
{fil: "0.000000000001", expect: "1 pFIL"},
{fil: "0.0000000000001", expect: "100 fFIL"},
{fil: "0.00000000000001", expect: "10 fFIL"},
{fil: "0.000000000000001", expect: "1 fFIL"},
{fil: "0.0000000000000001", expect: "100 aFIL"},
{fil: "0.00000000000000001", expect: "10 aFIL"},
{fil: "0.000000000000000001", expect: "1 aFIL"},
{fil: "0.0000012", expect: "1.2 μFIL"},
{fil: "0.00000123", expect: "1.23 μFIL"},
{fil: "0.000001234", expect: "1.234 μFIL"},
{fil: "0.0000012344", expect: "1.234 μFIL"},
{fil: "0.00000123444", expect: "1.234 μFIL"},
{fil: "0.0002212", expect: "221.2 μFIL"},
{fil: "0.00022123", expect: "221.23 μFIL"},
{fil: "0.000221234", expect: "221.234 μFIL"},
{fil: "0.0002212344", expect: "221.234 μFIL"},
{fil: "0.00022123444", expect: "221.234 μFIL"},
} {
s := s
t.Run(s.fil, func(t *testing.T) {
f, err := ParseFIL(s.fil)
require.NoError(t, err)
require.Equal(t, s.expect, f.Short())
})
}
}

View File

@ -14,6 +14,7 @@ import (
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
"github.com/filecoin-project/lotus/api"
@ -59,7 +60,7 @@ func infoCmdAct(cctx *cli.Context) error {
ctx := lcli.ReqContext(cctx)
fmt.Print("Full node: ")
fmt.Print("Chain: ")
head, err := api.ChainHead(ctx)
if err != nil {
@ -75,6 +76,20 @@ func infoCmdAct(cctx *cli.Context) error {
fmt.Printf("[%s]", color.RedString("sync behind! (%s behind)", time.Now().Sub(time.Unix(int64(head.MinTimestamp()), 0)).Truncate(time.Second)))
}
basefee := head.MinTicketBlock().ParentBaseFee
gasCol := []color.Attribute{color.FgBlue}
switch {
case basefee.GreaterThan(big.NewInt(7000_000_000)): // 7 nFIL
gasCol = []color.Attribute{color.BgRed, color.FgBlack}
case basefee.GreaterThan(big.NewInt(3000_000_000)): // 3 nFIL
gasCol = []color.Attribute{color.FgRed}
case basefee.GreaterThan(big.NewInt(750_000_000)): // 750 uFIL
gasCol = []color.Attribute{color.FgYellow}
case basefee.GreaterThan(big.NewInt(100_000_000)): // 100 uFIL
gasCol = []color.Attribute{color.FgGreen}
}
fmt.Printf(" [basefee %s]", color.New(gasCol...).Sprint(types.FIL(basefee).Short()))
fmt.Println()
maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor"))
@ -93,15 +108,14 @@ func infoCmdAct(cctx *cli.Context) error {
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))))
ssize := types.SizeStr(types.NewInt(uint64(mi.SectorSize)))
fmt.Printf("Miner: %s (%s sectors)\n", color.BlueString("%s", maddr), ssize)
pow, err := api.StateMinerPower(ctx, maddr, types.EmptyTSK)
if err != nil {
@ -111,16 +125,16 @@ func infoCmdAct(cctx *cli.Context) error {
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",
fmt.Printf("Power: %s / %s (%0.4f%%)\n",
color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)),
types.DeciStr(pow.TotalPower.QualityAdjPower),
float64(qpercI.Int64())/10000)
fmt.Printf("\tRaw: %s / %s (%0.4f%%)\n",
color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)),
types.SizeStr(pow.TotalPower.RawBytePower),
float64(rpercI.Int64())/10000)
secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
@ -168,6 +182,10 @@ func infoCmdAct(cctx *cli.Context) error {
var nactiveDeals, nVerifDeals, ndeals uint64
var activeDealBytes, activeVerifDealBytes, dealBytes abi.PaddedPieceSize
for _, deal := range deals {
if deal.State == storagemarket.StorageDealError {
continue
}
ndeals++
dealBytes += deal.Proposal.PieceSize
@ -186,6 +204,8 @@ func infoCmdAct(cctx *cli.Context) error {
fmt.Printf("\tActive: %d, %s (Verified: %d, %s)\n", nactiveDeals, types.SizeStr(types.NewInt(uint64(activeDealBytes))), nVerifDeals, types.SizeStr(types.NewInt(uint64(activeVerifDealBytes))))
fmt.Println()
spendable := big.Zero()
// NOTE: there's no need to unlock anything here. Funds only
// vest on deadline boundaries, and they're unlocked by cron.
lockedFunds, err := mas.LockedFunds()
@ -196,33 +216,47 @@ func infoCmdAct(cctx *cli.Context) error {
if err != nil {
return xerrors.Errorf("getting available balance: %w", err)
}
fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance)))
fmt.Printf("\tPreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits))
fmt.Printf("\tPledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement))
fmt.Printf("\tVesting: %s\n", types.FIL(lockedFunds.VestingFunds))
color.Green("\tAvailable: %s", types.FIL(availBalance))
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))
spendable = big.Add(spendable, availBalance)
fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short()))
fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short())
fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short())
fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short())
color.Green(" Available: %s", types.FIL(availBalance).Short())
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))
spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked))
fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short())
fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short())
color.Green(" Available: %s\n", types.FIL(big.Sub(mb.Escrow, mb.Locked)).Short())
wb, err := api.WalletBalance(ctx, mi.Worker)
if err != nil {
return xerrors.Errorf("getting worker balance: %w", err)
}
spendable = big.Add(spendable, wb)
color.Cyan("Worker Balance: %s", types.FIL(wb).Short())
if len(mi.ControlAddresses) > 0 {
cbsum := big.Zero()
for _, ca := range mi.ControlAddresses {
b, err := api.WalletBalance(ctx, ca)
if err != nil {
return xerrors.Errorf("getting control address balance: %w", err)
}
cbsum = big.Add(cbsum, b)
}
spendable = big.Add(spendable, cbsum)
fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short())
}
fmt.Printf("Total Spendable: %s\n", color.YellowString(types.FIL(spendable).Short()))
fmt.Println()
sealdur, err := nodeApi.SectorGetExpectedSealDuration(ctx)
if err != nil {
return err
}
fmt.Printf("Expected Seal Duration: %s\n\n", sealdur)
if !cctx.Bool("hide-sectors-info") {
fmt.Println("Sectors:")
err = sectorsInfo(ctx, nodeApi)