diff --git a/chain/actors/builtin/miner/actor.go.template b/chain/actors/builtin/miner/actor.go.template index 12f418b37..edc298ca9 100644 --- a/chain/actors/builtin/miner/actor.go.template +++ b/chain/actors/builtin/miner/actor.go.template @@ -38,7 +38,7 @@ func init() { var Methods = builtin{{.latestVersion}}.MethodsMiner -// Unchanged between v0, v2, v3, and v4 actors +// Unchanged between v0, v2, v3, v4, and v5 actors var WPoStProvingPeriod = miner0.WPoStProvingPeriod var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines var WPoStChallengeWindow = miner0.WPoStChallengeWindow diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index fc1d60e71..43e3a0828 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -61,7 +61,7 @@ func init() { var Methods = builtin5.MethodsMiner -// Unchanged between v0, v2, v3, and v4 actors +// Unchanged between v0, v2, v3, v4, and v5 actors var WPoStProvingPeriod = miner0.WPoStProvingPeriod var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines var WPoStChallengeWindow = miner0.WPoStChallengeWindow diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index 492f76183..a67415726 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -315,6 +315,10 @@ func GetMaxSectorExpirationExtension() abi.ChainEpoch { return miner5.MaxSectorExpirationExtension } +func GetMinSectorExpiration() abi.ChainEpoch { + return miner5.MinSectorExpiration +} + func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) { sectorsPerPart, err := builtin5.PoStProofWindowPoStPartitionSectors(p) if err != nil { diff --git a/chain/actors/policy/policy.go.template b/chain/actors/policy/policy.go.template index 264d42992..9da91f73f 100644 --- a/chain/actors/policy/policy.go.template +++ b/chain/actors/policy/policy.go.template @@ -203,6 +203,10 @@ func GetMaxSectorExpirationExtension() abi.ChainEpoch { return miner{{.latestVersion}}.MaxSectorExpirationExtension } +func GetMinSectorExpiration() abi.ChainEpoch { + return miner{{.latestVersion}}.MinSectorExpiration +} + func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) { sectorsPerPart, err := builtin{{.latestVersion}}.PoStProofWindowPoStPartitionSectors(p) if err != nil { diff --git a/extern/storage-sealing/precommit_policy.go b/extern/storage-sealing/precommit_policy.go index c911ccc8c..398956f01 100644 --- a/extern/storage-sealing/precommit_policy.go +++ b/extern/storage-sealing/precommit_policy.go @@ -39,19 +39,17 @@ type BasicPreCommitPolicy struct { api Chain getSealingConfig GetSealingConfigFunc - provingBoundary abi.ChainEpoch - provingBuffer abi.ChainEpoch + provingBuffer abi.ChainEpoch } // NewBasicPreCommitPolicy produces a BasicPreCommitPolicy. // // The provided duration is used as the default sector expiry when the sector // contains no deals. The proving boundary is used to adjust/align the sector's expiration. -func NewBasicPreCommitPolicy(api Chain, cfgGetter GetSealingConfigFunc, provingBoundary abi.ChainEpoch, provingBuffer abi.ChainEpoch) BasicPreCommitPolicy { +func NewBasicPreCommitPolicy(api Chain, cfgGetter GetSealingConfigFunc, provingBuffer abi.ChainEpoch) BasicPreCommitPolicy { return BasicPreCommitPolicy{ api: api, getSealingConfig: cfgGetter, - provingBoundary: provingBoundary, provingBuffer: provingBuffer, } } @@ -93,7 +91,12 @@ func (p *BasicPreCommitPolicy) Expiration(ctx context.Context, ps ...Piece) (abi end = &tmp } - *end += miner.WPoStProvingPeriod - (*end % miner.WPoStProvingPeriod) + p.provingBoundary - 1 + // Ensure there is at least one day for the PC message to land without falling below min sector lifetime + // TODO: The "one day" should probably be a config, though it doesn't matter too much + minExp := epoch + policy.GetMinSectorExpiration() + miner.WPoStProvingPeriod + if *end < minExp { + end = &minExp + } return *end, nil } @@ -119,5 +122,5 @@ func (p *BasicPreCommitPolicy) getCCSectorLifetime() (abi.ChainEpoch, error) { return maxExpiration, nil } - return (ccLifetimeEpochs - p.provingBuffer), nil + return ccLifetimeEpochs - p.provingBuffer, nil } diff --git a/extern/storage-sealing/precommit_policy_test.go b/extern/storage-sealing/precommit_policy_test.go index 7f5aff0df..d4fa3eae4 100644 --- a/extern/storage-sealing/precommit_policy_test.go +++ b/extern/storage-sealing/precommit_policy_test.go @@ -9,7 +9,6 @@ import ( api "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin" - "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/policy" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" @@ -60,17 +59,14 @@ func fakePieceCid(t *testing.T) cid.Cid { func TestBasicPolicyEmptySector(t *testing.T) { cfg := fakeConfigGetter(nil) h := abi.ChainEpoch(55) - pBoundary := abi.ChainEpoch(0) pBuffer := abi.ChainEpoch(2) - pcp := sealing.NewBasicPreCommitPolicy(&fakeChain{h: h}, cfg, pBoundary, pBuffer) + pcp := sealing.NewBasicPreCommitPolicy(&fakeChain{h: h}, cfg, pBuffer) exp, err := pcp.Expiration(context.Background()) require.NoError(t, err) // as set when there are no deal pieces - expected := h + policy.GetMaxSectorExpirationExtension() - (pBuffer * 2) - // as set just before returning within Expiration() - expected += miner.WPoStProvingPeriod - (expected % miner.WPoStProvingPeriod) + pBoundary - 1 + expected := h + policy.GetMaxSectorExpirationExtension() - pBuffer assert.Equal(t, int(expected), int(exp)) } @@ -80,27 +76,23 @@ func TestCustomCCSectorConfig(t *testing.T) { cfgStub := fakeConfigStub{CCSectorLifetime: customLifetime} cfg := fakeConfigGetter(&cfgStub) h := abi.ChainEpoch(55) - pBoundary := abi.ChainEpoch(0) pBuffer := abi.ChainEpoch(2) - pcp := sealing.NewBasicPreCommitPolicy(&fakeChain{h: h}, cfg, pBoundary, pBuffer) + pcp := sealing.NewBasicPreCommitPolicy(&fakeChain{h: h}, cfg, pBuffer) exp, err := pcp.Expiration(context.Background()) require.NoError(t, err) // as set when there are no deal pieces - expected := h + customLifetimeEpochs - (pBuffer * 2) - // as set just before returning within Expiration() - expected += miner.WPoStProvingPeriod - (expected % miner.WPoStProvingPeriod) + pBoundary - 1 + expected := h + customLifetimeEpochs - pBuffer assert.Equal(t, int(expected), int(exp)) } func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { cfg := fakeConfigGetter(nil) - pPeriod := abi.ChainEpoch(11) policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), - }, cfg, pPeriod, 2) - longestDealEpochEnd := abi.ChainEpoch(100) + }, cfg, 2) + longestDealEpochEnd := abi.ChainEpoch(547300) pieces := []sealing.Piece{ { Piece: abi.PieceInfo{ @@ -111,7 +103,7 @@ func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { DealID: abi.DealID(42), DealSchedule: api.DealSchedule{ StartEpoch: abi.ChainEpoch(70), - EndEpoch: abi.ChainEpoch(75), + EndEpoch: abi.ChainEpoch(547275), }, }, }, @@ -133,15 +125,14 @@ func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { exp, err := policy.Expiration(context.Background(), pieces...) require.NoError(t, err) - expected := longestDealEpochEnd + miner.WPoStProvingPeriod - (longestDealEpochEnd % miner.WPoStProvingPeriod) + pPeriod - 1 - assert.Equal(t, int(expected), int(exp)) + assert.Equal(t, int(longestDealEpochEnd), int(exp)) } func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) { cfg := fakeConfigGetter(nil) policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), - }, cfg, 0, 0) + }, cfg, 0) pieces := []sealing.Piece{ { @@ -162,14 +153,15 @@ func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) { exp, err := policy.Expiration(context.Background(), pieces...) require.NoError(t, err) - assert.Equal(t, 1558079, int(exp)) + // Treated as a CC sector, so expiration becomes currEpoch + maxLifetime = 55 + 1555200 + assert.Equal(t, 1555255, int(exp)) } func TestMissingDealIsIgnored(t *testing.T) { cfg := fakeConfigGetter(nil) policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), - }, cfg, 11, 0) + }, cfg, 0) pieces := []sealing.Piece{ { @@ -181,7 +173,7 @@ func TestMissingDealIsIgnored(t *testing.T) { DealID: abi.DealID(44), DealSchedule: api.DealSchedule{ StartEpoch: abi.ChainEpoch(1), - EndEpoch: abi.ChainEpoch(10), + EndEpoch: abi.ChainEpoch(547300), }, }, }, @@ -197,5 +189,5 @@ func TestMissingDealIsIgnored(t *testing.T) { exp, err := policy.Expiration(context.Background(), pieces...) require.NoError(t, err) - assert.Equal(t, 1558090, int(exp)) + assert.Equal(t, 547300, int(exp)) } diff --git a/storage/miner.go b/storage/miner.go index 5308a3e3b..c4bf41c12 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -179,12 +179,10 @@ func (m *Miner) Run(ctx context.Context) error { adaptedAPI = NewSealingAPIAdapter(m.api) // Instantiate a precommit policy. - cfg = sealing.GetSealingConfigFunc(m.getSealConfig) - provingBoundary = md.PeriodStart % md.WPoStProvingPeriod - provingBuffer = md.WPoStProvingPeriod * 2 + cfg = sealing.GetSealingConfigFunc(m.getSealConfig) + provingBuffer = md.WPoStProvingPeriod * 2 - // TODO: Maybe we update this policy after actor upgrades? - pcp = sealing.NewBasicPreCommitPolicy(adaptedAPI, cfg, provingBoundary, provingBuffer) + pcp = sealing.NewBasicPreCommitPolicy(adaptedAPI, cfg, provingBuffer) // address selector. as = func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) {