From 2855ec2ab80cd93cb3453dd9db0a7f55b114c649 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Sat, 3 Apr 2021 22:02:06 -0400 Subject: [PATCH] Address review on v1 sector extension tool --- chain/actors/builtin/miner/miner.go | 1 + chain/actors/policy/policy.go | 37 ++++++++- cmd/lotus-storage-miner/sectors.go | 112 ++++++++++++++++++---------- 3 files changed, 108 insertions(+), 42 deletions(-) diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 49a468efbf6..5bae8dea67c 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -50,6 +50,7 @@ var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff const MinSectorExpiration = miner0.MinSectorExpiration // Not used / checked in v0 +// TODO: Abstract over network versions var DeclarationsMax = miner2.DeclarationsMax var AddressedSectorsMax = miner2.AddressedSectorsMax diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index e32b3674310..aff746df13e 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -132,7 +132,7 @@ func DealProviderCollateralBounds( case actors.Version3: return market3.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) default: - panic("unsupported network version") + panic("unsupported actors version") } } @@ -191,3 +191,38 @@ func GetDefaultSectorSize() abi.SectorSize { return szs[0] } + +func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) abi.ChainEpoch { + if nwVer <= network.Version10 { + return builtin3.SealProofPoliciesV0[proof].SectorMaxLifetime + } + + return builtin3.SealProofPoliciesV11[proof].SectorMaxLifetime +} + +func GetAddressedSectorsMax(nwVer network.Version) int { + switch actors.VersionForNetwork(nwVer) { + case actors.Version0: + return miner0.AddressedSectorsMax + case actors.Version2: + return miner2.AddressedSectorsMax + case actors.Version3: + return miner3.AddressedSectorsMax + default: + panic("unsupported network version") + } +} + +func GetDeclarationsMax(nwVer network.Version) int { + switch actors.VersionForNetwork(nwVer) { + case actors.Version0: + // TODO: Should we instead panic here since the concept doesn't exist yet? + return miner0.AddressedPartitionsMax + case actors.Version2: + return miner2.DeclarationsMax + case actors.Version3: + return miner3.DeclarationsMax + default: + panic("unsupported network version") + } +} diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index a3978b5082e..9458990bcd9 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -8,10 +8,6 @@ import ( "strings" "time" - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" - - "github.com/filecoin-project/lotus/chain/actors/builtin" - "github.com/docker/go-units" "github.com/fatih/color" "github.com/urfave/cli/v2" @@ -433,6 +429,17 @@ var sectorsExtendCmd = &cli.Command{ Usage: "renews all v1 sectors up to the maximum possible lifetime", Required: false, }, + &cli.Int64Flag{ + Name: "tolerance", + Value: 20160, + Usage: "when extending v1 sectors, extensions less than this number of epochs will be ignored", + Required: false, + }, + &cli.Int64Flag{ + Name: "expiration-cutoff", + Usage: "when extending v1 sectors, skip sectors whose current expiration is more than epochs from now (infinity if unspecified)", + Required: false, + }, &cli.StringFlag{}, }, Action: func(cctx *cli.Context) error { @@ -453,15 +460,27 @@ var sectorsExtendCmd = &cli.Command{ var params []miner3.ExtendSectorExpirationParams if cctx.Bool("v1-sectors") { + + head, err := api.ChainHead(ctx) + if err != nil { + return err + } + + nv, err := api.StateNetworkVersion(ctx, types.EmptyTSK) + if err != nil { + return err + } + extensions := map[miner.SectorLocation]map[abi.ChainEpoch][]uint64{} - // are given durations within a week? + + // are given durations within tolerance epochs closeEnough := func(a, b abi.ChainEpoch) bool { diff := a - b if diff < 0 { diff = b - a } - return diff <= 7*builtin.EpochsInDay + return diff <= abi.ChainEpoch(cctx.Int64("tolerance")) } sis, err := api.StateMinerActiveSectors(ctx, maddr, types.EmptyTSK) @@ -470,53 +489,63 @@ var sectorsExtendCmd = &cli.Command{ } for _, si := range sis { - if si.SealProof < abi.RegisteredSealProof_StackedDrg2KiBV1_1 { + if si.SealProof >= abi.RegisteredSealProof_StackedDrg2KiBV1_1 { + continue + } - ml := builtin3.SealProofPoliciesV11[si.SealProof].SectorMaxLifetime - // if the sector's missing less than a week of its maximum possible lifetime, don't bother extending it - if closeEnough(si.Expiration-si.Activation, ml) { + if cctx.IsSet("expiration-cutoff") { + if si.Expiration > (head.Height() + abi.ChainEpoch(cctx.Int64("expiration-cutoff"))) { continue } + } - newExp := ml - (miner3.WPoStProvingPeriod * 2) + si.Activation - p, err := api.StateSectorPartition(ctx, maddr, si.SectorNumber, types.EmptyTSK) - if err != nil { - return xerrors.Errorf("getting sector location for sector %d: %w", si.SectorNumber, err) - } + ml := policy.GetSectorMaxLifetime(si.SealProof, nv) + // if the sector's missing less than a week of its maximum possible lifetime, don't bother extending it + if closeEnough(si.Expiration-si.Activation, ml) { + continue + } - if p == nil { - return xerrors.Errorf("sector %d not found in any partition", si.SectorNumber) - } + // Set the new expiration to 48 hours less than the theoretical maximum lifetime + newExp := ml - (miner3.WPoStProvingPeriod * 2) + si.Activation + p, err := api.StateSectorPartition(ctx, maddr, si.SectorNumber, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting sector location for sector %d: %w", si.SectorNumber, err) + } - es, found := extensions[*p] - if !found { - ne := make(map[abi.ChainEpoch][]uint64) - ne[newExp] = []uint64{uint64(si.SectorNumber)} - extensions[*p] = ne - } else { - added := false - for exp := range es { - if closeEnough(exp, newExp) { - es[exp] = append(es[exp], uint64(si.SectorNumber)) - added = true - break - } - } + if p == nil { + return xerrors.Errorf("sector %d not found in any partition", si.SectorNumber) + } - if !added { - es[newExp] = []uint64{uint64(si.SectorNumber)} + es, found := extensions[*p] + if !found { + ne := make(map[abi.ChainEpoch][]uint64) + ne[newExp] = []uint64{uint64(si.SectorNumber)} + extensions[*p] = ne + } else { + added := false + for exp := range es { + if closeEnough(exp, newExp) { + es[exp] = append(es[exp], uint64(si.SectorNumber)) + added = true + break } } + + if !added { + es[newExp] = []uint64{uint64(si.SectorNumber)} + } } } - p := &miner3.ExtendSectorExpirationParams{} + + p := miner3.ExtendSectorExpirationParams{} scount := 0 + for l, exts := range extensions { for newExp, numbers := range exts { scount += len(numbers) - if scount > miner.AddressedSectorsMax || len(p.Extensions) == miner3.DeclarationsMax { - params = append(params, *p) - p = &miner3.ExtendSectorExpirationParams{} + if scount > policy.GetAddressedSectorsMax(nv) || len(p.Extensions) == policy.GetDeclarationsMax(nv) { + params = append(params, p) + p = miner3.ExtendSectorExpirationParams{} scount = len(numbers) } @@ -528,7 +557,7 @@ var sectorsExtendCmd = &cli.Command{ }) } } - params = append(params, *p) + params = append(params, p) } else { if !cctx.Args().Present() || !cctx.IsSet("new-expiration") { @@ -554,9 +583,10 @@ var sectorsExtendCmd = &cli.Command{ sectors[*p] = append(sectors[*p], id) } - p := &miner3.ExtendSectorExpirationParams{} + p := miner3.ExtendSectorExpirationParams{} for l, numbers := range sectors { + // TODO: Dedup with above loop p.Extensions = append(p.Extensions, miner3.ExpirationExtension{ Deadline: l.Deadline, Partition: l.Partition, @@ -565,7 +595,7 @@ var sectorsExtendCmd = &cli.Command{ }) } - params = append(params, *p) + params = append(params, p) } mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)