feat: miner cli: sectors list upgrade-bounds tool

This commit is contained in:
Łukasz Magiera 2023-05-26 12:21:06 +02:00
parent fdd013c103
commit 14f9770859
4 changed files with 199 additions and 4 deletions

View File

@ -61,6 +61,10 @@ const (
MaxPreCommitRandomnessLookback = builtin11.EpochsInDay + SealRandomnessLookback MaxPreCommitRandomnessLookback = builtin11.EpochsInDay + SealRandomnessLookback
) )
var (
MarketDefaultAllocationTermBuffer = market11.MarketDefaultAllocationTermBuffer
)
// SetSupportedProofTypes sets supported proof types, across all actor versions. // SetSupportedProofTypes sets supported proof types, across all actor versions.
// This should only be used for testing. // This should only be used for testing.
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {

View File

@ -39,6 +39,10 @@ const (
MaxPreCommitRandomnessLookback = builtin{{.latestVersion}}.EpochsInDay + SealRandomnessLookback MaxPreCommitRandomnessLookback = builtin{{.latestVersion}}.EpochsInDay + SealRandomnessLookback
) )
var (
MarketDefaultAllocationTermBuffer = market{{.latestVersion}}.MarketDefaultAllocationTermBuffer
)
// SetSupportedProofTypes sets supported proof types, across all actor versions. // SetSupportedProofTypes sets supported proof types, across all actor versions.
// This should only be used for testing. // This should only be used for testing.
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {

View File

@ -2,6 +2,7 @@ package main
import ( import (
"bufio" "bufio"
"encoding/csv"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -318,6 +319,9 @@ var sectorsListCmd = &cli.Command{
Value: parallelSectorChecks, Value: parallelSectorChecks,
}, },
}, },
Subcommands: []*cli.Command{
sectorsListUpgradeBoundsCmd,
},
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
// http mode allows for parallel json decoding/encoding, which was a bottleneck here // http mode allows for parallel json decoding/encoding, which was a bottleneck here
minerApi, closer, err := lcli.GetStorageMinerAPI(cctx, cliutil.StorageMinerUseHttp) minerApi, closer, err := lcli.GetStorageMinerAPI(cctx, cliutil.StorageMinerUseHttp)
@ -585,6 +589,169 @@ var sectorsListCmd = &cli.Command{
}, },
} }
var sectorsListUpgradeBoundsCmd = &cli.Command{
Name: "upgrade-bounds",
Usage: "Output upgrade bounds for available sectors",
Flags: []cli.Flag{
&cli.IntFlag{
Name: "buckets",
Value: 25,
},
&cli.BoolFlag{
Name: "csv",
Usage: "output machine-readable values",
},
&cli.BoolFlag{
Name: "deal-terms",
Usage: "bucket by how many deal-sectors can start at a given expiration",
},
},
Action: func(cctx *cli.Context) error {
minerApi, closer, err := lcli.GetStorageMinerAPI(cctx, cliutil.StorageMinerUseHttp)
if err != nil {
return err
}
defer closer()
fullApi, closer2, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer2()
ctx := lcli.ReqContext(cctx)
list, err := minerApi.SectorsListInStates(ctx, []api.SectorState{
api.SectorState(sealing.Available),
})
if err != nil {
return xerrors.Errorf("getting sector list: %w", err)
}
head, err := fullApi.ChainHead(ctx)
if err != nil {
return xerrors.Errorf("getting chain head: %w", err)
}
filter := bitfield.New()
for _, s := range list {
filter.Set(uint64(s))
}
maddr, err := minerApi.ActorAddress(ctx)
if err != nil {
return err
}
sset, err := fullApi.StateMinerSectors(ctx, maddr, &filter, head.Key())
if err != nil {
return err
}
if len(sset) == 0 {
return nil
}
var minExpiration, maxExpiration abi.ChainEpoch
for _, s := range sset {
if s.Expiration < minExpiration || minExpiration == 0 {
minExpiration = s.Expiration
}
if s.Expiration > maxExpiration {
maxExpiration = s.Expiration
}
}
buckets := cctx.Int("buckets")
bucketSize := (maxExpiration - minExpiration) / abi.ChainEpoch(buckets)
bucketCounts := make([]int, buckets+1)
for b := range bucketCounts {
bucketMin := minExpiration + abi.ChainEpoch(b)*bucketSize
bucketMax := minExpiration + abi.ChainEpoch(b+1)*bucketSize
if cctx.Bool("deal-terms") {
bucketMax = bucketMax + policy.MarketDefaultAllocationTermBuffer
}
for _, s := range sset {
isInBucket := s.Expiration >= bucketMin && s.Expiration < bucketMax
if isInBucket {
bucketCounts[b]++
}
}
}
// Creating CSV writer
writer := csv.NewWriter(os.Stdout)
// Writing CSV headers
err = writer.Write([]string{"Max Expiration in Bucket", "Sector Count"})
if err != nil {
return xerrors.Errorf("writing csv headers: %w", err)
}
// Writing bucket details
if cctx.Bool("csv") {
for i := 0; i < buckets; i++ {
maxExp := minExpiration + abi.ChainEpoch(i+1)*bucketSize
timeStr := strconv.FormatInt(int64(maxExp), 10)
err = writer.Write([]string{
timeStr,
strconv.Itoa(bucketCounts[i]),
})
if err != nil {
return xerrors.Errorf("writing csv row: %w", err)
}
}
// Flush to make sure all data is written to the underlying writer
writer.Flush()
if err := writer.Error(); err != nil {
return xerrors.Errorf("flushing csv writer: %w", err)
}
return nil
}
tw := tablewriter.New(
tablewriter.Col("Bucket Expiration"),
tablewriter.Col("Sector Count"),
tablewriter.Col("Bar"),
)
var barCols = 40
var maxCount int
for _, c := range bucketCounts {
if c > maxCount {
maxCount = c
}
}
for i := 0; i < buckets; i++ {
maxExp := minExpiration + abi.ChainEpoch(i+1)*bucketSize
timeStr := cliutil.EpochTime(head.Height(), maxExp)
tw.Write(map[string]interface{}{
"Bucket Expiration": timeStr,
"Sector Count": color.YellowString("%d", bucketCounts[i]),
"Bar": "[" + color.GreenString(strings.Repeat("|", bucketCounts[i]*barCols/maxCount)) + strings.Repeat(" ", barCols-bucketCounts[i]*barCols/maxCount) + "]",
})
}
return tw.Flush(os.Stdout)
},
}
var sectorsRefsCmd = &cli.Command{ var sectorsRefsCmd = &cli.Command{
Name: "refs", Name: "refs",
Usage: "List References to sectors", Usage: "List References to sectors",

View File

@ -654,17 +654,37 @@ NAME:
lotus-miner sectors list - List sectors lotus-miner sectors list - List sectors
USAGE: USAGE:
lotus-miner sectors list [command options] [arguments...] lotus-miner sectors list command [command options] [arguments...]
COMMANDS:
upgrade-bounds Output upgrade bounds for available sectors
help, h Shows a list of commands or help for one command
OPTIONS: OPTIONS:
--check-parallelism value number of parallel requests to make for checking sector states (default: 300) --show-removed, -r show removed sectors (default: false)
--events, -e display number of events the sector has received (default: false)
--fast, -f don't show on-chain info for better performance (default: false) --fast, -f don't show on-chain info for better performance (default: false)
--events, -e display number of events the sector has received (default: false)
--initial-pledge, -p display initial pledge (default: false) --initial-pledge, -p display initial pledge (default: false)
--seal-time, -t display how long it took for the sector to be sealed (default: false) --seal-time, -t display how long it took for the sector to be sealed (default: false)
--show-removed, -r show removed sectors (default: false)
--states value filter sectors by a comma-separated list of states --states value filter sectors by a comma-separated list of states
--unproven, -u only show sectors which aren't in the 'Proving' state (default: false) --unproven, -u only show sectors which aren't in the 'Proving' state (default: false)
--check-parallelism value number of parallel requests to make for checking sector states (default: 300)
--help, -h show help (default: false)
```
#### lotus-miner sectors list upgrade-bounds
```
NAME:
lotus-miner sectors list upgrade-bounds - Output upgrade bounds for available sectors
USAGE:
lotus-miner sectors list upgrade-bounds [command options] [arguments...]
OPTIONS:
--buckets value (default: 25)
--csv output machine-readable values (default: false)
--deal-terms bucket by how many deal-sectors can start at a given expiration (default: false)
``` ```