diff --git a/CHANGELOG.md b/CHANGELOG.md index 854166c4c..a4fca397d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Lotus changelog +# 1.6.0 / 2021-04-05 + +This is a mandatory release of Lotus that upgrades the network to version 11, which implements [FIP-0014](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0014.md). The network will upgrade at height 665280, which is 2021-04-12T22:00:00Z. + +## v1 sector extension CLI + +This release also expands the `lotus-miner sectors extend` CLI, with a new option that automatically extends all extensible v1 sectors. The option can be run using `lotus-miner sectors extend --v1-sectors`. + +- The `tolerance` flag can be passed to indicate what durations aren't "worth" extending. It defaults to one week, which means that sectors whose current lifetime's are within one week of the maximum possible lifetime will not be extended. + +- The `expiration-cutoff` flag can be passed to skip sectors whose expiration is past a certain point from the current head. It defaults to infinity (no cutoff), but if, say, 28800 was specified, then only sectors expiring in the next 10 days would be extended (2880 epochs in 1 day). + +## Changes + +- Util for miners to extend all v1 sectors (https://github.com/filecoin-project/lotus/pull/5924) +- Upgrade the butterfly network (https://github.com/filecoin-project/lotus/pull/5929) +- Introduce the v11 network upgrade (https://github.com/filecoin-project/lotus/pull/5904) +- Debug mode: Make upgrade heights controllable by an envvar (https://github.com/filecoin-project/lotus/pull/5919) + # 1.5.3 / 2021-03-24 This is a patch release of Lotus that introduces small fixes to the Storage FSM. diff --git a/build/bootstrap/butterflynet.pi b/build/bootstrap/butterflynet.pi index dc49bdf0e..0de3043a3 100644 --- a/build/bootstrap/butterflynet.pi +++ b/build/bootstrap/butterflynet.pi @@ -1,2 +1,2 @@ -/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWQafkXgEWDgcVhZvF6KMhiC8ktdxjvmdQN8RarRXe9jCc -/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWE7UmZ4DLk9WBdEJUSwuSCPiSqjoCv3wPeoe8Tq3yMa77 +/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWRkaF18SR3E6qL6dkGrozT8QJUV5VbhE9E7BZtPmHqdWJ +/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWJcJUc23WJjJHGSboGcU3t76z9Lb7CghrH2tiBiDCY4ux diff --git a/build/genesis/butterflynet.car b/build/genesis/butterflynet.car index 1f5185c1a..6654d7195 100644 Binary files a/build/genesis/butterflynet.car and b/build/genesis/butterflynet.car differ diff --git a/build/params_2k.go b/build/params_2k.go index 308db3bd8..103dc7802 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -3,6 +3,9 @@ package build import ( + "os" + "strconv" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/chain/actors/policy" ) @@ -10,24 +13,27 @@ import ( const BootstrappersFile = "" const GenesisFile = "" -const UpgradeBreezeHeight = -1 +var UpgradeBreezeHeight = abi.ChainEpoch(-1) + const BreezeGasTampingDuration = 0 -const UpgradeSmokeHeight = -1 -const UpgradeIgnitionHeight = -2 -const UpgradeRefuelHeight = -3 -const UpgradeTapeHeight = -4 +var UpgradeSmokeHeight = abi.ChainEpoch(-1) +var UpgradeIgnitionHeight = abi.ChainEpoch(-2) +var UpgradeRefuelHeight = abi.ChainEpoch(-3) +var UpgradeTapeHeight = abi.ChainEpoch(-4) -const UpgradeActorsV2Height = 10 -const UpgradeLiftoffHeight = -5 +var UpgradeActorsV2Height = abi.ChainEpoch(10) +var UpgradeLiftoffHeight = abi.ChainEpoch(-5) -const UpgradeKumquatHeight = 15 -const UpgradeCalicoHeight = 20 -const UpgradePersianHeight = 25 -const UpgradeOrangeHeight = 27 -const UpgradeClausHeight = 30 +var UpgradeKumquatHeight = abi.ChainEpoch(15) +var UpgradeCalicoHeight = abi.ChainEpoch(20) +var UpgradePersianHeight = abi.ChainEpoch(25) +var UpgradeOrangeHeight = abi.ChainEpoch(27) +var UpgradeClausHeight = abi.ChainEpoch(30) -const UpgradeActorsV3Height = 35 +var UpgradeActorsV3Height = abi.ChainEpoch(35) + +var UpgradeNorwegianHeight = abi.ChainEpoch(40) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, @@ -39,6 +45,35 @@ func init() { policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) policy.SetPreCommitChallengeDelay(abi.ChainEpoch(10)) + getUpgradeHeight := func(ev string, def abi.ChainEpoch) abi.ChainEpoch { + hs, found := os.LookupEnv(ev) + if found { + h, err := strconv.Atoi(hs) + if err != nil { + log.Panicf("failed to parse %s env var", ev) + } + + return abi.ChainEpoch(h) + } + + return def + } + + UpgradeBreezeHeight = getUpgradeHeight("LOTUS_BREEZE_HEIGHT", UpgradeBreezeHeight) + UpgradeSmokeHeight = getUpgradeHeight("LOTUS_SMOKE_HEIGHT", UpgradeSmokeHeight) + UpgradeIgnitionHeight = getUpgradeHeight("LOTUS_IGNITION_HEIGHT", UpgradeIgnitionHeight) + UpgradeRefuelHeight = getUpgradeHeight("LOTUS_REFUEL_HEIGHT", UpgradeRefuelHeight) + UpgradeTapeHeight = getUpgradeHeight("LOTUS_TAPE_HEIGHT", UpgradeTapeHeight) + UpgradeActorsV2Height = getUpgradeHeight("LOTUS_ACTORSV2_HEIGHT", UpgradeActorsV2Height) + UpgradeLiftoffHeight = getUpgradeHeight("LOTUS_LIFTOFF_HEIGHT", UpgradeLiftoffHeight) + UpgradeKumquatHeight = getUpgradeHeight("LOTUS_KUMQUAT_HEIGHT", UpgradeKumquatHeight) + UpgradeCalicoHeight = getUpgradeHeight("LOTUS_CALICO_HEIGHT", UpgradeCalicoHeight) + UpgradePersianHeight = getUpgradeHeight("LOTUS_PERSIAN_HEIGHT", UpgradePersianHeight) + UpgradeOrangeHeight = getUpgradeHeight("LOTUS_ORANGE_HEIGHT", UpgradeOrangeHeight) + UpgradeClausHeight = getUpgradeHeight("LOTUS_CLAUS_HEIGHT", UpgradeClausHeight) + UpgradeActorsV3Height = getUpgradeHeight("LOTUS_ACTORSV3_HEIGHT", UpgradeActorsV3Height) + UpgradeNorwegianHeight = getUpgradeHeight("LOTUS_NORWEGIAN_HEIGHT", UpgradeNorwegianHeight) + BuildType |= Build2k } diff --git a/build/params_butterfly.go b/build/params_butterfly.go index f7bf8aa10..579e019b1 100644 --- a/build/params_butterfly.go +++ b/build/params_butterfly.go @@ -32,6 +32,7 @@ const UpgradePersianHeight = 150 const UpgradeClausHeight = 180 const UpgradeOrangeHeight = 210 const UpgradeActorsV3Height = 240 +const UpgradeNorwegianHeight = UpgradeActorsV3Height + (builtin2.EpochsInHour * 12) func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(2 << 30)) diff --git a/build/params_calibnet.go b/build/params_calibnet.go index 976cffd22..83cf10856 100644 --- a/build/params_calibnet.go +++ b/build/params_calibnet.go @@ -40,6 +40,7 @@ const UpgradeClausHeight = 250 const UpgradeOrangeHeight = 300 const UpgradeActorsV3Height = 600 +const UpgradeNorwegianHeight = 114000 func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(32 << 30)) diff --git a/build/params_mainnet.go b/build/params_mainnet.go index cc929978b..635bbc679 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -56,6 +56,9 @@ const UpgradeClausHeight = 343200 // 2021-03-04T00:00:30Z var UpgradeActorsV3Height = abi.ChainEpoch(550321) +// 2021-04-12T22:00:00Z +const UpgradeNorwegianHeight = 665280 + func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40)) diff --git a/build/params_nerpanet.go b/build/params_nerpanet.go index 20ecab4e2..1d051a908 100644 --- a/build/params_nerpanet.go +++ b/build/params_nerpanet.go @@ -39,6 +39,7 @@ const UpgradeClausHeight = 250 const UpgradeOrangeHeight = 300 const UpgradeActorsV3Height = 600 +const UpgradeNorwegianHeight = 999999 func init() { // Minimum block production power is set to 4 TiB diff --git a/build/params_testground.go b/build/params_testground.go index 5e9bc2672..e7c428368 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -81,18 +81,19 @@ var ( UpgradeBreezeHeight abi.ChainEpoch = -1 BreezeGasTampingDuration abi.ChainEpoch = 0 - UpgradeSmokeHeight abi.ChainEpoch = -1 - UpgradeIgnitionHeight abi.ChainEpoch = -2 - UpgradeRefuelHeight abi.ChainEpoch = -3 - UpgradeTapeHeight abi.ChainEpoch = -4 - UpgradeActorsV2Height abi.ChainEpoch = 10 - UpgradeLiftoffHeight abi.ChainEpoch = -5 - UpgradeKumquatHeight abi.ChainEpoch = -6 - UpgradeCalicoHeight abi.ChainEpoch = -7 - UpgradePersianHeight abi.ChainEpoch = -8 - UpgradeOrangeHeight abi.ChainEpoch = -9 - UpgradeClausHeight abi.ChainEpoch = -10 - UpgradeActorsV3Height abi.ChainEpoch = -11 + UpgradeSmokeHeight abi.ChainEpoch = -1 + UpgradeIgnitionHeight abi.ChainEpoch = -2 + UpgradeRefuelHeight abi.ChainEpoch = -3 + UpgradeTapeHeight abi.ChainEpoch = -4 + UpgradeActorsV2Height abi.ChainEpoch = 10 + UpgradeLiftoffHeight abi.ChainEpoch = -5 + UpgradeKumquatHeight abi.ChainEpoch = -6 + UpgradeCalicoHeight abi.ChainEpoch = -7 + UpgradePersianHeight abi.ChainEpoch = -8 + UpgradeOrangeHeight abi.ChainEpoch = -9 + UpgradeClausHeight abi.ChainEpoch = -10 + UpgradeActorsV3Height abi.ChainEpoch = -11 + UpgradeNorwegianHeight abi.ChainEpoch = -12 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 49a468efb..5bae8dea6 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 75badf36d..6b27238da 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -133,7 +133,7 @@ func DealProviderCollateralBounds( case actors.Version3: return market3.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) default: - panic("unsupported network version") + panic("unsupported actors version") } } @@ -196,3 +196,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/chain/actors/version.go b/chain/actors/version.go index 763c5a42c..d62fd0d17 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -21,7 +21,7 @@ func VersionForNetwork(version network.Version) Version { return Version0 case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8, network.Version9: return Version2 - case network.Version10: + case network.Version10, network.Version11: return Version3 default: panic(fmt.Sprintf("unsupported network version %d", version)) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index cb6cb2261..ce140868e 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -186,6 +186,10 @@ func DefaultUpgradeSchedule() UpgradeSchedule { StopWithin: 5, }}, Expensive: true, + }, { + Height: build.UpgradeNorwegianHeight, + Network: network.Version11, + Migration: nil, }} for _, u := range updates { diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index cf39e5516..7650de035 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -90,7 +90,7 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index 84654d789..f5ff25177 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -106,15 +106,21 @@ func main() { lcli.RunApp(app) } -func getActorAddress(ctx context.Context, nodeAPI api.StorageMiner, overrideMaddr string) (maddr address.Address, err error) { - if overrideMaddr != "" { - maddr, err = address.NewFromString(overrideMaddr) +func getActorAddress(ctx context.Context, cctx *cli.Context) (maddr address.Address, err error) { + if cctx.IsSet("actor") { + maddr, err = address.NewFromString(cctx.String("actor")) if err != nil { return maddr, err } return } + nodeAPI, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return address.Undef, err + } + defer closer() + maddr, err = nodeAPI.ActorAddress(ctx) if err != nil { return maddr, xerrors.Errorf("getting actor address: %w", err) diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index f6bc74318..66007b63d 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -38,12 +38,6 @@ var provingFaultsCmd = &cli.Command{ Action: func(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 @@ -54,7 +48,7 @@ var provingFaultsCmd = &cli.Command{ stor := store.ActorStore(ctx, blockstore.NewAPIBlockstore(api)) - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } @@ -98,12 +92,6 @@ var provingInfoCmd = &cli.Command{ Action: func(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 @@ -112,7 +100,7 @@ var provingInfoCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } @@ -211,12 +199,6 @@ var provingDeadlinesCmd = &cli.Command{ Action: func(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 @@ -225,7 +207,7 @@ var provingDeadlinesCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } @@ -301,12 +283,6 @@ var provingDeadlineInfoCmd = &cli.Command{ return xerrors.Errorf("could not parse deadline index: %w", err) } - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() - api, acloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -315,7 +291,7 @@ var provingDeadlineInfoCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index 8f6fd374f..3791dbf07 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -16,7 +16,7 @@ import ( "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" @@ -422,16 +422,27 @@ var sectorsExtendCmd = &cli.Command{ &cli.Int64Flag{ Name: "new-expiration", Usage: "new expiration epoch", - Required: true, + Required: false, + }, + &cli.BoolFlag{ + Name: "v1-sectors", + Usage: "renews all v1 sectors up to the maximum possible lifetime", + Required: false, + }, + &cli.Int64Flag{ + Name: "tolerance", + Value: 20160, + Usage: "when extending v1 sectors, don't try to extend sectors by fewer than this number of epochs", + 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 { - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() api, nCloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { @@ -440,49 +451,160 @@ var sectorsExtendCmd = &cli.Command{ defer nCloser() ctx := lcli.ReqContext(cctx) - if !cctx.Args().Present() { - return xerrors.Errorf("must pass at least one sector number") - } - maddr, err := nodeApi.ActorAddress(ctx) + maddr, err := getActorAddress(ctx, cctx) if err != nil { - return xerrors.Errorf("getting miner actor address: %w", err) + return err } - sectors := map[miner.SectorLocation][]uint64{} + var params []miner3.ExtendSectorExpirationParams - for i, s := range cctx.Args().Slice() { - id, err := strconv.ParseUint(s, 10, 64) + if cctx.Bool("v1-sectors") { + + head, err := api.ChainHead(ctx) if err != nil { - return xerrors.Errorf("could not parse sector %d: %w", i, err) + return err } - p, err := api.StateSectorPartition(ctx, maddr, abi.SectorNumber(id), types.EmptyTSK) + nv, err := api.StateNetworkVersion(ctx, types.EmptyTSK) if err != nil { - return xerrors.Errorf("getting sector location for sector %d: %w", id, err) + return err } - if p == nil { - return xerrors.Errorf("sector %d not found in any partition", id) + extensions := map[miner.SectorLocation]map[abi.ChainEpoch][]uint64{} + + // are given durations within tolerance epochs + withinTolerance := func(a, b abi.ChainEpoch) bool { + diff := a - b + if diff < 0 { + diff = b - a + } + + return diff <= abi.ChainEpoch(cctx.Int64("tolerance")) } - sectors[*p] = append(sectors[*p], id) + sis, err := api.StateMinerActiveSectors(ctx, maddr, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting miner sector infos: %w", err) + } + + for _, si := range sis { + if si.SealProof >= abi.RegisteredSealProof_StackedDrg2KiBV1_1 { + continue + } + + if cctx.IsSet("expiration-cutoff") { + if si.Expiration > (head.Height() + abi.ChainEpoch(cctx.Int64("expiration-cutoff"))) { + continue + } + } + + ml := policy.GetSectorMaxLifetime(si.SealProof, nv) + // if the sector's missing less than "tolerance" of its maximum possible lifetime, don't bother extending it + if withinTolerance(si.Expiration-si.Activation, ml) { + continue + } + + // 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) + } + + if p == nil { + return xerrors.Errorf("sector %d not found in any partition", 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 withinTolerance(exp, newExp) { + es[exp] = append(es[exp], uint64(si.SectorNumber)) + added = true + break + } + } + + if !added { + es[newExp] = []uint64{uint64(si.SectorNumber)} + } + } + } + + p := miner3.ExtendSectorExpirationParams{} + scount := 0 + + for l, exts := range extensions { + for newExp, numbers := range exts { + scount += len(numbers) + if scount > policy.GetAddressedSectorsMax(nv) || len(p.Extensions) == policy.GetDeclarationsMax(nv) { + params = append(params, p) + p = miner3.ExtendSectorExpirationParams{} + scount = len(numbers) + } + + p.Extensions = append(p.Extensions, miner3.ExpirationExtension{ + Deadline: l.Deadline, + Partition: l.Partition, + Sectors: bitfield.NewFromSet(numbers), + NewExpiration: newExp, + }) + } + } + + // if we have any sectors, then one last append is needed here + if scount != 0 { + params = append(params, p) + } + + } else { + if !cctx.Args().Present() || !cctx.IsSet("new-expiration") { + return xerrors.Errorf("must pass at least one sector number and new expiration") + } + sectors := map[miner.SectorLocation][]uint64{} + + for i, s := range cctx.Args().Slice() { + id, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return xerrors.Errorf("could not parse sector %d: %w", i, err) + } + + p, err := api.StateSectorPartition(ctx, maddr, abi.SectorNumber(id), types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting sector location for sector %d: %w", id, err) + } + + if p == nil { + return xerrors.Errorf("sector %d not found in any partition", id) + } + + sectors[*p] = append(sectors[*p], id) + } + + 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, + Sectors: bitfield.NewFromSet(numbers), + NewExpiration: abi.ChainEpoch(cctx.Int64("new-expiration")), + }) + } + + params = append(params, p) } - params := &miner0.ExtendSectorExpirationParams{} - for l, numbers := range sectors { - - params.Extensions = append(params.Extensions, miner0.ExpirationExtension{ - Deadline: l.Deadline, - Partition: l.Partition, - Sectors: bitfield.NewFromSet(numbers), - NewExpiration: abi.ChainEpoch(cctx.Int64("new-expiration")), - }) - } - - sp, err := actors.SerializeParams(params) - if err != nil { - return xerrors.Errorf("serializing params: %w", err) + if len(params) == 0 { + fmt.Println("nothing to extend") + return nil } mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) @@ -490,20 +612,27 @@ var sectorsExtendCmd = &cli.Command{ return xerrors.Errorf("getting miner info: %w", err) } - smsg, err := api.MpoolPushMessage(ctx, &types.Message{ - From: mi.Worker, - To: maddr, - Method: miner.Methods.ExtendSectorExpiration, + for i := range params { + sp, aerr := actors.SerializeParams(¶ms[i]) + if aerr != nil { + return xerrors.Errorf("serializing params: %w", err) + } - Value: big.Zero(), - Params: sp, - }, nil) - if err != nil { - return xerrors.Errorf("mpool push message: %w", err) + smsg, err := api.MpoolPushMessage(ctx, &types.Message{ + From: mi.Worker, + To: maddr, + Method: miner.Methods.ExtendSectorExpiration, + + Value: big.Zero(), + Params: sp, + }, nil) + if err != nil { + return xerrors.Errorf("mpool push message: %w", err) + } + + fmt.Println(smsg.Cid()) } - fmt.Println(smsg.Cid()) - return nil }, } @@ -741,12 +870,6 @@ var sectorsCapacityCollateralCmd = &cli.Command{ }, Action: func(cctx *cli.Context) error { - mApi, mCloser, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer mCloser() - nApi, nCloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -755,7 +878,7 @@ var sectorsCapacityCollateralCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) - maddr, err := mApi.ActorAddress(ctx) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } diff --git a/go.mod b/go.mod index fa564df80..f2d4b6a86 100644 --- a/go.mod +++ b/go.mod @@ -44,8 +44,8 @@ require ( github.com/filecoin-project/go-statestore v0.1.1 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.13 - github.com/filecoin-project/specs-actors/v2 v2.3.4 - github.com/filecoin-project/specs-actors/v3 v3.0.3 + github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb + github.com/filecoin-project/specs-actors/v3 v3.1.0 github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 github.com/filecoin-project/test-vectors/schema v0.0.5 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index fe0050b73..746875334 100644 --- a/go.sum +++ b/go.sum @@ -308,10 +308,10 @@ github.com/filecoin-project/specs-actors v0.9.13 h1:rUEOQouefi9fuVY/2HOroROJlZbO github.com/filecoin-project/specs-actors v0.9.13/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= github.com/filecoin-project/specs-actors/v2 v2.0.1/go.mod h1:v2NZVYinNIKA9acEMBm5wWXxqv5+frFEbekBFemYghY= github.com/filecoin-project/specs-actors/v2 v2.3.2/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= -github.com/filecoin-project/specs-actors/v2 v2.3.4 h1:NZK2oMCcA71wNsUzDBmLQyRMzcCnX9tDGvwZ53G67j8= -github.com/filecoin-project/specs-actors/v2 v2.3.4/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= -github.com/filecoin-project/specs-actors/v3 v3.0.3 h1:bq9B1Jnq+Z0A+Yj3KnYhN3kcTpUyP6Umo3MZgai0BRE= -github.com/filecoin-project/specs-actors/v3 v3.0.3/go.mod h1:oMcmEed6B7H/wHabM3RQphTIhq0ibAKsbpYs+bQ/uxQ= +github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb h1:orr/sMzrDZUPAveRE+paBdu1kScIUO5zm+HYeh+VlhA= +github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb/go.mod h1:LljnY2Mn2homxZsmokJZCpRuhOPxfXhvcek5gWkmqAc= +github.com/filecoin-project/specs-actors/v3 v3.1.0 h1:s4qiPw8pgypqBGAy853u/zdZJ7K9cTZdM1rTiSonHrg= +github.com/filecoin-project/specs-actors/v3 v3.1.0/go.mod h1:mpynccOLlIRy0QnR008BwYBwT9fen+sPR13MA1VmMww= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=