From 9e34cce1f2f3984573b33f2fef839e81c34ca1ee Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Tue, 20 Jul 2021 17:19:28 -0400 Subject: [PATCH 1/7] feat(config): support configurable CC sector expiration --- extern/storage-sealing/sealiface/config.go | 2 ++ node/config/def.go | 6 ++++++ storage/miner.go | 18 ++++++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/extern/storage-sealing/sealiface/config.go b/extern/storage-sealing/sealiface/config.go index e33b36263..59c3d8c4f 100644 --- a/extern/storage-sealing/sealiface/config.go +++ b/extern/storage-sealing/sealiface/config.go @@ -20,6 +20,8 @@ type Config struct { WaitDealsDelay time.Duration + CommittedCapacityDefaultLifetime time.Duration + AlwaysKeepUnsealedCopy bool FinalizeEarly bool diff --git a/node/config/def.go b/node/config/def.go index 7042cf644..bf6526e4d 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -131,6 +131,12 @@ type SealingConfig struct { WaitDealsDelay Duration + // CommittedCapacityDefaultLifetime is the default duration a Committed Capacity (CC) + // sector will live before it must be extended or converted into sector containing deals + // before it is terminated. + // Value must be between 180-540 days inclusive. + CommittedCapacityDefaultLifetime Duration + AlwaysKeepUnsealedCopy bool // Run sector finalization before submitting sector proof to the chain diff --git a/storage/miner.go b/storage/miner.go index cdacc2734..06ee874a1 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -178,8 +178,11 @@ func (m *Miner) Run(ctx context.Context) error { // provides extra methods. adaptedAPI = NewSealingAPIAdapter(m.api) + // sealing configuration. + cfg = sealing.GetSealingConfigFunc(m.getSealConfig) + // Instantiate a precommit policy. - defaultDuration = policy.GetMaxSectorExpirationExtension() - (md.WPoStProvingPeriod * 2) + defaultDuration = getDefaultSectorExpirationExtension(cfg) - (md.WPoStProvingPeriod * 2) provingBoundary = md.PeriodStart % md.WPoStProvingPeriod // TODO: Maybe we update this policy after actor upgrades? @@ -189,9 +192,6 @@ func (m *Miner) Run(ctx context.Context) error { as = func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { return m.addrSel.AddressFor(ctx, m.api, mi, use, goodFunds, minFunds) } - - // sealing configuration. - cfg = sealing.GetSealingConfigFunc(m.getSealConfig) ) // Instantiate the sealing FSM. @@ -203,6 +203,16 @@ func (m *Miner) Run(ctx context.Context) error { return nil } +func getDefaultSectorExpirationExtension(cfg sealing.GetSealingConfigFunc) abi.ChainEpoch { + c, err := cfg() + if err != nil { + log.Warnf("failed to load sealing config, using default sector extension expiration") + log.Errorf("sealing config load error: %s", err.Error()) + return policy.GetMaxSectorExpirationExtension() + } + return abi.ChainEpoch(c.CommittedCapacityDefaultLifetime.Truncate(builtin.EpochDurationSeconds)) +} + func (m *Miner) handleSealingNotifications(before, after sealing.SectorInfo) { m.journal.RecordEvent(m.sealingEvtType, func() interface{} { return SealingStateEvt{ From adb62a3fff61d74aa07bd450ea4daa6044366546 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Thu, 22 Jul 2021 08:37:35 -0400 Subject: [PATCH 2/7] chore: Move cfg getter into PCPolicy; Clamp values on get --- chain/actors/policy/policy.go | 4 ++ extern/storage-sealing/precommit_policy.go | 48 +++++++++++++++++----- extern/storage-sealing/sealiface/config.go | 2 +- node/config/def.go | 13 +++--- storage/miner.go | 18 +------- 5 files changed, 53 insertions(+), 32 deletions(-) diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index c06c85d38..06db09ea8 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -301,6 +301,10 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return ChainFinality } +func GetMinSectorExpiration() abi.ChainEpoch { + return miner5.MinSectorExpiration +} + func GetMaxSectorExpirationExtension() abi.ChainEpoch { return miner5.MaxSectorExpirationExtension } diff --git a/extern/storage-sealing/precommit_policy.go b/extern/storage-sealing/precommit_policy.go index a6add5693..bc5a0a530 100644 --- a/extern/storage-sealing/precommit_policy.go +++ b/extern/storage-sealing/precommit_policy.go @@ -3,11 +3,13 @@ package sealing import ( "context" - "github.com/filecoin-project/lotus/chain/actors/builtin/miner" - - "github.com/filecoin-project/go-state-types/network" + "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/network" + "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" ) type PreCommitPolicy interface { @@ -34,21 +36,21 @@ type Chain interface { // If we're in Mode 2: The pre-commit expiration epoch will be set to the // current epoch + the provided default duration. type BasicPreCommitPolicy struct { - api Chain + api Chain + getSealingConfig GetSealingConfigFunc provingBoundary abi.ChainEpoch - duration 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, duration abi.ChainEpoch, provingBoundary abi.ChainEpoch) BasicPreCommitPolicy { +func NewBasicPreCommitPolicy(api Chain, cfgGetter GetSealingConfigFunc, provingBoundary abi.ChainEpoch) BasicPreCommitPolicy { return BasicPreCommitPolicy{ - api: api, - provingBoundary: provingBoundary, - duration: duration, + api: api, + getSealingConfig: cfgGetter, + provingBoundary: provingBoundary, } } @@ -79,7 +81,13 @@ func (p *BasicPreCommitPolicy) Expiration(ctx context.Context, ps ...Piece) (abi } if end == nil { - tmp := epoch + p.duration + // no deal pieces, get expiration for committed capacity sector + expirationDuration, err := p.getCCSectorLifetime() + if err != nil { + return 0, err + } + + tmp := epoch + expirationDuration end = &tmp } @@ -87,3 +95,23 @@ func (p *BasicPreCommitPolicy) Expiration(ctx context.Context, ps ...Piece) (abi return *end, nil } + +func (p *BasicPreCommitPolicy) getCCSectorLifetime() (abi.ChainEpoch, error) { + c, err := p.getSealingConfig() + if err != nil { + return 0, xerrors.Errorf("sealing config load error: %w", err) + } + + sectorExpiration := abi.ChainEpoch(c.CommittedCapacitySectorLifetime.Truncate(builtin.EpochDurationSeconds) / builtin.EpochDurationSeconds) + + if minExpiration := policy.GetMinSectorExpiration(); sectorExpiration < minExpiration { + log.Warnf("value for CommittedCapacitySectorLiftime is too short, using default minimum (%d epochs)", minExpiration) + return minExpiration, nil + } + if maxExpiration := policy.GetMaxSectorExpirationExtension(); sectorExpiration > maxExpiration { + log.Warnf("value for CommittedCapacitySectorLiftime is too long, using default maximum (%d epochs)", maxExpiration) + return maxExpiration, nil + } + + return sectorExpiration, nil +} diff --git a/extern/storage-sealing/sealiface/config.go b/extern/storage-sealing/sealiface/config.go index 59c3d8c4f..95b851609 100644 --- a/extern/storage-sealing/sealiface/config.go +++ b/extern/storage-sealing/sealiface/config.go @@ -20,7 +20,7 @@ type Config struct { WaitDealsDelay time.Duration - CommittedCapacityDefaultLifetime time.Duration + CommittedCapacitySectorLifetime time.Duration AlwaysKeepUnsealedCopy bool diff --git a/node/config/def.go b/node/config/def.go index bf6526e4d..17f43ffc3 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -10,6 +10,8 @@ import ( "github.com/filecoin-project/go-state-types/big" miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/types" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" ) @@ -131,11 +133,10 @@ type SealingConfig struct { WaitDealsDelay Duration - // CommittedCapacityDefaultLifetime is the default duration a Committed Capacity (CC) - // sector will live before it must be extended or converted into sector containing deals - // before it is terminated. - // Value must be between 180-540 days inclusive. - CommittedCapacityDefaultLifetime Duration + // CommittedCapacitySectorLifetime is the duration a Committed Capacity (CC) sector will + // live before it must be extended or converted into sector containing deals before it is + // terminated. Value must be between 180-540 days inclusive. + CommittedCapacitySectorLifetime Duration AlwaysKeepUnsealedCopy bool @@ -358,6 +359,8 @@ func DefaultStorageMiner() *StorageMiner { PreCommitBatchWait: Duration(24 * time.Hour), // this should be less than 31.5 hours, which is the expiration of a precommit ticket PreCommitBatchSlack: Duration(3 * time.Hour), // time buffer for forceful batch submission before sectors/deals in batch would start expiring, higher value will lower the chances for message fail due to expiration + CommittedCapacitySectorLifetime: Duration(builtin.EpochDurationSeconds * policy.GetMaxSectorExpirationExtension()), + AggregateCommits: true, MinCommitBatch: miner5.MinAggregatedSectors, // per FIP13, we must have at least four proofs to aggregate, where 4 is the cross over point where aggregation wins out on single provecommit gas costs MaxCommitBatch: miner5.MaxAggregatedSectors, // maximum 819 sectors, this is the maximum aggregation per FIP13 diff --git a/storage/miner.go b/storage/miner.go index 06ee874a1..c38671c8c 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -27,7 +27,6 @@ import ( "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" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" @@ -178,15 +177,12 @@ func (m *Miner) Run(ctx context.Context) error { // provides extra methods. adaptedAPI = NewSealingAPIAdapter(m.api) - // sealing configuration. - cfg = sealing.GetSealingConfigFunc(m.getSealConfig) - // Instantiate a precommit policy. - defaultDuration = getDefaultSectorExpirationExtension(cfg) - (md.WPoStProvingPeriod * 2) + cfg = sealing.GetSealingConfigFunc(m.getSealConfig) provingBoundary = md.PeriodStart % md.WPoStProvingPeriod // TODO: Maybe we update this policy after actor upgrades? - pcp = sealing.NewBasicPreCommitPolicy(adaptedAPI, defaultDuration, provingBoundary) + pcp = sealing.NewBasicPreCommitPolicy(adaptedAPI, cfg, provingBoundary) // address selector. as = func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { @@ -203,16 +199,6 @@ func (m *Miner) Run(ctx context.Context) error { return nil } -func getDefaultSectorExpirationExtension(cfg sealing.GetSealingConfigFunc) abi.ChainEpoch { - c, err := cfg() - if err != nil { - log.Warnf("failed to load sealing config, using default sector extension expiration") - log.Errorf("sealing config load error: %s", err.Error()) - return policy.GetMaxSectorExpirationExtension() - } - return abi.ChainEpoch(c.CommittedCapacityDefaultLifetime.Truncate(builtin.EpochDurationSeconds)) -} - func (m *Miner) handleSealingNotifications(before, after sealing.SectorInfo) { m.journal.RecordEvent(m.sealingEvtType, func() interface{} { return SealingStateEvt{ From 7ee46ad4e0638822c7dfcdf6fb4aa306ec3f9f40 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Thu, 22 Jul 2021 14:44:39 -0400 Subject: [PATCH 3/7] fix: PreCommitPolicy unit tests --- extern/storage-sealing/precommit_policy.go | 16 +++-- .../storage-sealing/precommit_policy_test.go | 63 ++++++++++++++----- storage/miner.go | 3 +- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/extern/storage-sealing/precommit_policy.go b/extern/storage-sealing/precommit_policy.go index bc5a0a530..6d1fddc47 100644 --- a/extern/storage-sealing/precommit_policy.go +++ b/extern/storage-sealing/precommit_policy.go @@ -40,17 +40,19 @@ type BasicPreCommitPolicy struct { getSealingConfig GetSealingConfigFunc provingBoundary 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) BasicPreCommitPolicy { +func NewBasicPreCommitPolicy(api Chain, cfgGetter GetSealingConfigFunc, provingBoundary abi.ChainEpoch, provingBuffer abi.ChainEpoch) BasicPreCommitPolicy { return BasicPreCommitPolicy{ api: api, getSealingConfig: cfgGetter, provingBoundary: provingBoundary, + provingBuffer: provingBuffer, } } @@ -102,16 +104,20 @@ func (p *BasicPreCommitPolicy) getCCSectorLifetime() (abi.ChainEpoch, error) { return 0, xerrors.Errorf("sealing config load error: %w", err) } - sectorExpiration := abi.ChainEpoch(c.CommittedCapacitySectorLifetime.Truncate(builtin.EpochDurationSeconds) / builtin.EpochDurationSeconds) + var ccLifetimeEpochs = abi.ChainEpoch(uint64(c.CommittedCapacitySectorLifetime.Truncate(builtin.EpochDurationSeconds).Seconds()) / builtin.EpochDurationSeconds) + // if zero value in config, assume maximum sector extension + if ccLifetimeEpochs == 0 { + ccLifetimeEpochs = policy.GetMaxSectorExpirationExtension() + } - if minExpiration := policy.GetMinSectorExpiration(); sectorExpiration < minExpiration { + if minExpiration := policy.GetMinSectorExpiration(); ccLifetimeEpochs < minExpiration { log.Warnf("value for CommittedCapacitySectorLiftime is too short, using default minimum (%d epochs)", minExpiration) return minExpiration, nil } - if maxExpiration := policy.GetMaxSectorExpirationExtension(); sectorExpiration > maxExpiration { + if maxExpiration := policy.GetMaxSectorExpirationExtension(); ccLifetimeEpochs > maxExpiration { log.Warnf("value for CommittedCapacitySectorLiftime is too long, using default maximum (%d epochs)", maxExpiration) return maxExpiration, nil } - return sectorExpiration, 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 a6c17d3fd..aa56f1e6f 100644 --- a/extern/storage-sealing/precommit_policy_test.go +++ b/extern/storage-sealing/precommit_policy_test.go @@ -3,10 +3,15 @@ package sealing_test import ( "context" "testing" + "time" "github.com/filecoin-project/go-state-types/network" api "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "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" "github.com/ipfs/go-cid" "github.com/stretchr/testify/assert" @@ -14,14 +19,31 @@ import ( commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/go-state-types/abi" - - sealing "github.com/filecoin-project/lotus/extern/storage-sealing" ) type fakeChain struct { h abi.ChainEpoch } +func fakeConfigGetter(stub interface{}, t *testing.T) sealing.GetSealingConfigFunc { + return func() (sealiface.Config, error) { + if stub == nil { + return sealiface.Config{}, nil + } + + castStub, ok := stub.(struct { + CCSectorLifetime time.Duration + }) + if !ok { + t.Fatal("failed to cast fakeConfig") + } + + return sealiface.Config{ + CommittedCapacitySectorLifetime: castStub.CCSectorLifetime, + }, nil + } +} + func (f *fakeChain) StateNetworkVersion(ctx context.Context, tok sealing.TipSetToken) (network.Version, error) { return build.NewestNetworkVersion, nil } @@ -38,21 +60,29 @@ func fakePieceCid(t *testing.T) cid.Cid { } func TestBasicPolicyEmptySector(t *testing.T) { - policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ - h: abi.ChainEpoch(55), - }, 10, 0) + cfg := fakeConfigGetter(nil, t) + h := abi.ChainEpoch(55) + pBoundary := abi.ChainEpoch(0) + pBuffer := abi.ChainEpoch(2) + pcp := sealing.NewBasicPreCommitPolicy(&fakeChain{h: h}, cfg, pBoundary, pBuffer) + exp, err := pcp.Expiration(context.Background()) - exp, err := policy.Expiration(context.Background()) require.NoError(t, err) - assert.Equal(t, 2879, int(exp)) + // 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 + assert.Equal(t, int(expected), int(exp)) } func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { + cfg := fakeConfigGetter(nil, t) + pPeriod := abi.ChainEpoch(11) policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), - }, 100, 11) - + }, cfg, pPeriod, 2) + longestDealEpochEnd := abi.ChainEpoch(100) pieces := []sealing.Piece{ { Piece: abi.PieceInfo{ @@ -76,7 +106,7 @@ func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { DealID: abi.DealID(43), DealSchedule: api.DealSchedule{ StartEpoch: abi.ChainEpoch(80), - EndEpoch: abi.ChainEpoch(100), + EndEpoch: longestDealEpochEnd, }, }, }, @@ -85,13 +115,15 @@ func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { exp, err := policy.Expiration(context.Background(), pieces...) require.NoError(t, err) - assert.Equal(t, 2890, int(exp)) + expected := longestDealEpochEnd + miner.WPoStProvingPeriod - (longestDealEpochEnd % miner.WPoStProvingPeriod) + pPeriod - 1 + assert.Equal(t, int(expected), int(exp)) } func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) { + cfg := fakeConfigGetter(nil, t) policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), - }, 100, 0) + }, cfg, 0, 0) pieces := []sealing.Piece{ { @@ -112,13 +144,14 @@ func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) { exp, err := policy.Expiration(context.Background(), pieces...) require.NoError(t, err) - assert.Equal(t, 2879, int(exp)) + assert.Equal(t, 1558079, int(exp)) } func TestMissingDealIsIgnored(t *testing.T) { + cfg := fakeConfigGetter(nil, t) policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), - }, 100, 11) + }, cfg, 11, 0) pieces := []sealing.Piece{ { @@ -146,5 +179,5 @@ func TestMissingDealIsIgnored(t *testing.T) { exp, err := policy.Expiration(context.Background(), pieces...) require.NoError(t, err) - assert.Equal(t, 2890, int(exp)) + assert.Equal(t, 1558090, int(exp)) } diff --git a/storage/miner.go b/storage/miner.go index c38671c8c..59c64eb41 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -180,9 +180,10 @@ func (m *Miner) Run(ctx context.Context) error { // Instantiate a precommit policy. cfg = sealing.GetSealingConfigFunc(m.getSealConfig) provingBoundary = md.PeriodStart % md.WPoStProvingPeriod + provingBuffer = md.WPoStProvingPeriod * 2 // TODO: Maybe we update this policy after actor upgrades? - pcp = sealing.NewBasicPreCommitPolicy(adaptedAPI, cfg, provingBoundary) + pcp = sealing.NewBasicPreCommitPolicy(adaptedAPI, cfg, provingBoundary, provingBuffer) // address selector. as = func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { From 123a976f6247ec84e3bb3ab0ddaa9fe7d1a6532a Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Thu, 22 Jul 2021 14:54:52 -0400 Subject: [PATCH 4/7] chore: Add unit test for custom CC lifetime value expiration --- .../storage-sealing/precommit_policy_test.go | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/extern/storage-sealing/precommit_policy_test.go b/extern/storage-sealing/precommit_policy_test.go index aa56f1e6f..7c92cd061 100644 --- a/extern/storage-sealing/precommit_policy_test.go +++ b/extern/storage-sealing/precommit_policy_test.go @@ -8,6 +8,7 @@ import ( "github.com/filecoin-project/go-state-types/network" 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" @@ -25,21 +26,18 @@ type fakeChain struct { h abi.ChainEpoch } -func fakeConfigGetter(stub interface{}, t *testing.T) sealing.GetSealingConfigFunc { +type fakeConfigStub struct { + CCSectorLifetime time.Duration +} + +func fakeConfigGetter(stub *fakeConfigStub) sealing.GetSealingConfigFunc { return func() (sealiface.Config, error) { if stub == nil { return sealiface.Config{}, nil } - castStub, ok := stub.(struct { - CCSectorLifetime time.Duration - }) - if !ok { - t.Fatal("failed to cast fakeConfig") - } - return sealiface.Config{ - CommittedCapacitySectorLifetime: castStub.CCSectorLifetime, + CommittedCapacitySectorLifetime: stub.CCSectorLifetime, }, nil } } @@ -60,7 +58,7 @@ func fakePieceCid(t *testing.T) cid.Cid { } func TestBasicPolicyEmptySector(t *testing.T) { - cfg := fakeConfigGetter(nil, t) + cfg := fakeConfigGetter(nil) h := abi.ChainEpoch(55) pBoundary := abi.ChainEpoch(0) pBuffer := abi.ChainEpoch(2) @@ -76,8 +74,28 @@ func TestBasicPolicyEmptySector(t *testing.T) { assert.Equal(t, int(expected), int(exp)) } +func TestCustomCCSectorConfig(t *testing.T) { + customLifetime := 200 * 24 * time.Hour + customLifetimeEpochs := abi.ChainEpoch(int64(customLifetime.Truncate(builtin.EpochDurationSeconds).Seconds()) / builtin.EpochDurationSeconds) + 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) + 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 + assert.Equal(t, int(expected), int(exp)) +} + func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { - cfg := fakeConfigGetter(nil, t) + cfg := fakeConfigGetter(nil) pPeriod := abi.ChainEpoch(11) policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), @@ -120,7 +138,7 @@ func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { } func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) { - cfg := fakeConfigGetter(nil, t) + cfg := fakeConfigGetter(nil) policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), }, cfg, 0, 0) @@ -148,7 +166,7 @@ func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) { } func TestMissingDealIsIgnored(t *testing.T) { - cfg := fakeConfigGetter(nil, t) + cfg := fakeConfigGetter(nil) policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), }, cfg, 11, 0) From 3829d6bd9adb22e8ac42f15b7c54e4440308c793 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Thu, 22 Jul 2021 15:05:03 -0400 Subject: [PATCH 5/7] fix: Remove actor method from autogen source; Move inline to pkg --- chain/actors/policy/policy.go | 4 ---- extern/storage-sealing/precommit_policy.go | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index 06db09ea8..c06c85d38 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -301,10 +301,6 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return ChainFinality } -func GetMinSectorExpiration() abi.ChainEpoch { - return miner5.MinSectorExpiration -} - func GetMaxSectorExpirationExtension() abi.ChainEpoch { return miner5.MaxSectorExpirationExtension } diff --git a/extern/storage-sealing/precommit_policy.go b/extern/storage-sealing/precommit_policy.go index 6d1fddc47..3856fd548 100644 --- a/extern/storage-sealing/precommit_policy.go +++ b/extern/storage-sealing/precommit_policy.go @@ -110,7 +110,7 @@ func (p *BasicPreCommitPolicy) getCCSectorLifetime() (abi.ChainEpoch, error) { ccLifetimeEpochs = policy.GetMaxSectorExpirationExtension() } - if minExpiration := policy.GetMinSectorExpiration(); ccLifetimeEpochs < minExpiration { + if minExpiration := abi.ChainEpoch(miner.MinSectorExpiration); ccLifetimeEpochs < minExpiration { log.Warnf("value for CommittedCapacitySectorLiftime is too short, using default minimum (%d epochs)", minExpiration) return minExpiration, nil } From 41bce7925a1852d2eba72b72357ec5d342402cb0 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Fri, 23 Jul 2021 20:12:30 -0400 Subject: [PATCH 6/7] fix: Remove unnecessary Truncate --- extern/storage-sealing/precommit_policy.go | 2 +- extern/storage-sealing/precommit_policy_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extern/storage-sealing/precommit_policy.go b/extern/storage-sealing/precommit_policy.go index 3856fd548..c911ccc8c 100644 --- a/extern/storage-sealing/precommit_policy.go +++ b/extern/storage-sealing/precommit_policy.go @@ -104,7 +104,7 @@ func (p *BasicPreCommitPolicy) getCCSectorLifetime() (abi.ChainEpoch, error) { return 0, xerrors.Errorf("sealing config load error: %w", err) } - var ccLifetimeEpochs = abi.ChainEpoch(uint64(c.CommittedCapacitySectorLifetime.Truncate(builtin.EpochDurationSeconds).Seconds()) / builtin.EpochDurationSeconds) + var ccLifetimeEpochs = abi.ChainEpoch(uint64(c.CommittedCapacitySectorLifetime.Seconds()) / builtin.EpochDurationSeconds) // if zero value in config, assume maximum sector extension if ccLifetimeEpochs == 0 { ccLifetimeEpochs = policy.GetMaxSectorExpirationExtension() diff --git a/extern/storage-sealing/precommit_policy_test.go b/extern/storage-sealing/precommit_policy_test.go index 7c92cd061..7f5aff0df 100644 --- a/extern/storage-sealing/precommit_policy_test.go +++ b/extern/storage-sealing/precommit_policy_test.go @@ -76,7 +76,7 @@ func TestBasicPolicyEmptySector(t *testing.T) { func TestCustomCCSectorConfig(t *testing.T) { customLifetime := 200 * 24 * time.Hour - customLifetimeEpochs := abi.ChainEpoch(int64(customLifetime.Truncate(builtin.EpochDurationSeconds).Seconds()) / builtin.EpochDurationSeconds) + customLifetimeEpochs := abi.ChainEpoch(int64(customLifetime.Seconds()) / builtin.EpochDurationSeconds) cfgStub := fakeConfigStub{CCSectorLifetime: customLifetime} cfg := fakeConfigGetter(&cfgStub) h := abi.ChainEpoch(55) From e68c59f984b67bacd234a3d27393c96894f7e8d8 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Fri, 23 Jul 2021 21:05:50 -0400 Subject: [PATCH 7/7] fix: Update node config docs --- node/config/doc_gen.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index ea68dc344..5163ac409 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -562,6 +562,14 @@ Note that setting this number too high in relation to deal ingestion rate may re Comment: `Upper bound on how many sectors can be sealing at the same time when creating new sectors with deals (0 = unlimited)`, }, + { + Name: "CommittedCapacitySectorLifetime", + Type: "Duration", + + Comment: `CommittedCapacitySectorLifetime is the duration a Committed Capacity (CC) sector will +live before it must be extended or converted into sector containing deals before it is +terminated. Value must be between 180-540 days inclusive`, + }, { Name: "WaitDealsDelay", Type: "Duration",