diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index d680def37..d927f369f 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -560,8 +560,53 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return ChainFinality } -func GetMaxSectorExpirationExtension() abi.ChainEpoch { - return miner12.MaxSectorExpirationExtension +func GetMaxSectorExpirationExtension(nv network.Version) (abi.ChainEpoch, error) { + v, err := actorstypes.VersionForNetwork(nv) + if err != nil { + return 0, xerrors.Errorf("failed to get actors version: %w", err) + } + switch v { + + case actorstypes.Version0: + return miner0.MaxSectorExpirationExtension, nil + + case actorstypes.Version2: + return miner2.MaxSectorExpirationExtension, nil + + case actorstypes.Version3: + return miner3.MaxSectorExpirationExtension, nil + + case actorstypes.Version4: + return miner4.MaxSectorExpirationExtension, nil + + case actorstypes.Version5: + return miner5.MaxSectorExpirationExtension, nil + + case actorstypes.Version6: + return miner6.MaxSectorExpirationExtension, nil + + case actorstypes.Version7: + return miner7.MaxSectorExpirationExtension, nil + + case actorstypes.Version8: + return miner8.MaxSectorExpirationExtension, nil + + case actorstypes.Version9: + return miner9.MaxSectorExpirationExtension, nil + + case actorstypes.Version10: + return miner10.MaxSectorExpirationExtension, nil + + case actorstypes.Version11: + return miner11.MaxSectorExpirationExtension, nil + + case actorstypes.Version12: + return miner12.MaxSectorExpirationExtension, nil + + default: + return 0, xerrors.Errorf("unsupported network version") + } + } func GetMinSectorExpiration() abi.ChainEpoch { diff --git a/chain/actors/policy/policy.go.template b/chain/actors/policy/policy.go.template index 3eb39836a..c3ce4a9d9 100644 --- a/chain/actors/policy/policy.go.template +++ b/chain/actors/policy/policy.go.template @@ -223,8 +223,20 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return ChainFinality } -func GetMaxSectorExpirationExtension() abi.ChainEpoch { - return miner{{.latestVersion}}.MaxSectorExpirationExtension +func GetMaxSectorExpirationExtension(nv network.Version) (abi.ChainEpoch, error) { + v, err := actorstypes.VersionForNetwork(nv) + if err != nil { + return 0, xerrors.Errorf("failed to get actors version: %w", err) + } + switch v { + {{range .versions}} + case actorstypes.Version{{.}}: + return miner{{.}}.MaxSectorExpirationExtension, nil + {{end}} + default: + return 0, xerrors.Errorf("unsupported network version") + } + } func GetMinSectorExpiration() abi.ChainEpoch { diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 7905fd253..0bac282d2 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -125,7 +125,11 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal sectorWeight []abi.StoragePower }, len(miners)) - maxPeriods := policy.GetMaxSectorExpirationExtension() / minertypes.WPoStProvingPeriod + maxLifetime, err := policy.GetMaxSectorExpirationExtension(nv) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to get max extension: %w", err) + } + maxPeriods := maxLifetime / minertypes.WPoStProvingPeriod rawPow, qaPow := big.NewInt(0), big.NewInt(0) for i, m := range miners { // Create miner through power actor diff --git a/cmd/lotus-miner/sectors.go b/cmd/lotus-miner/sectors.go index 5c8cf6b87..6fd0fd709 100644 --- a/cmd/lotus-miner/sectors.go +++ b/cmd/lotus-miner/sectors.go @@ -846,7 +846,12 @@ var sectorsCheckExpireCmd = &cli.Command{ for _, sector := range sectors { MaxExpiration := sector.Activation + policy.GetSectorMaxLifetime(sector.SealProof, nv) - MaxExtendNow := currEpoch + policy.GetMaxSectorExpirationExtension() + maxExtension, err := policy.GetMaxSectorExpirationExtension(nv) + if err != nil { + return xerrors.Errorf("failed to get max extension: %w", err) + } + + MaxExtendNow := currEpoch + maxExtension if MaxExtendNow > MaxExpiration { MaxExtendNow = MaxExpiration @@ -1185,7 +1190,12 @@ var sectorsExtendCmd = &cli.Command{ newExp = abi.ChainEpoch(cctx.Int64("new-expiration")) } - maxExtendNow := currEpoch + policy.GetMaxSectorExpirationExtension() + maxExtension, err := policy.GetMaxSectorExpirationExtension(nv) + if err != nil { + return xerrors.Errorf("failed to get max extension: %w", err) + } + + maxExtendNow := currEpoch + maxExtension if newExp > maxExtendNow { newExp = maxExtendNow } @@ -1755,7 +1765,12 @@ var sectorsCapacityCollateralCmd = &cli.Command{ return err } - pci.Expiration = policy.GetMaxSectorExpirationExtension() + h.Height() + maxExtension, err := policy.GetMaxSectorExpirationExtension(nv) + if err != nil { + return xerrors.Errorf("failed to get max extension: %w", err) + } + + pci.Expiration = maxExtension + h.Height() } pc, err := nApi.StateMinerInitialPledgeCollateral(ctx, maddr, pci, types.EmptyTSK) diff --git a/cmd/lotus-sim/simulation/stages/precommit_stage.go b/cmd/lotus-sim/simulation/stages/precommit_stage.go index 5373ebe54..1a89413d7 100644 --- a/cmd/lotus-sim/simulation/stages/precommit_stage.go +++ b/cmd/lotus-sim/simulation/stages/precommit_stage.go @@ -176,7 +176,12 @@ func (stage *PreCommitStage) packMiner( return 0, false, err } - expiration := epoch + policy.GetMaxSectorExpirationExtension() + maxExtension, err := policy.GetMaxSectorExpirationExtension(nv) + if err != nil { + return 0, false, xerrors.Errorf("failed to get max extension: %w", err) + } + + expiration := epoch + maxExtension infos := make([]minertypes.PreCommitSectorParams, len(sectorNos)) for i, sno := range sectorNos { infos[i] = minertypes.PreCommitSectorParams{ diff --git a/node/config/def.go b/node/config/def.go index 4be902455..dd36803a0 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -10,6 +10,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/network" miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -122,6 +123,8 @@ func DefaultFullNode() *FullNode { } func DefaultStorageMiner() *StorageMiner { + // TODO: Should we increase this to nv21, which would push it to 3.5 years? + maxSectorExtentsion, _ := policy.GetMaxSectorExpirationExtension(network.Version20) cfg := &StorageMiner{ Common: defCommon(), @@ -143,7 +146,7 @@ func DefaultStorageMiner() *StorageMiner { // XXX snap deals wait deals slack if first 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 * uint64(policy.GetMaxSectorExpirationExtension()) * uint64(time.Second)), + CommittedCapacitySectorLifetime: Duration(builtin.EpochDurationSeconds * uint64(maxSectorExtentsion) * uint64(time.Second)), 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 diff --git a/storage/pipeline/precommit_policy.go b/storage/pipeline/precommit_policy.go index e1b6e6be7..6e234f930 100644 --- a/storage/pipeline/precommit_policy.go +++ b/storage/pipeline/precommit_policy.go @@ -85,10 +85,15 @@ func (p *BasicPreCommitPolicy) Expiration(ctx context.Context, ps ...api.SectorP } if end == nil { - // no deal pieces, get expiration for committed capacity sector - expirationDuration, err := p.getCCSectorLifetime() + nv, err := p.api.StateNetworkVersion(ctx, types.EmptyTSK) if err != nil { - return 0, err + return 0, xerrors.Errorf("failed to get network version: %w", err) + } + + // no deal pieces, get expiration for committed capacity sector + expirationDuration, err := p.getCCSectorLifetime(nv) + if err != nil { + return 0, xerrors.Errorf("failed to get cc sector lifetime: %w", err) } tmp := ts.Height() + expirationDuration @@ -105,25 +110,30 @@ func (p *BasicPreCommitPolicy) Expiration(ctx context.Context, ps ...api.SectorP return *end, nil } -func (p *BasicPreCommitPolicy) getCCSectorLifetime() (abi.ChainEpoch, error) { +func (p *BasicPreCommitPolicy) getCCSectorLifetime(nv network.Version) (abi.ChainEpoch, error) { c, err := p.getSealingConfig() if err != nil { return 0, xerrors.Errorf("sealing config load error: %w", err) } + maxCommitment, err := policy.GetMaxSectorExpirationExtension(nv) + if err != nil { + return 0, xerrors.Errorf("failed to get max extension: %w", err) + } + var ccLifetimeEpochs = abi.ChainEpoch(uint64(c.CommittedCapacitySectorLifetime.Seconds()) / builtin.EpochDurationSeconds) // if zero value in config, assume default sector extension if ccLifetimeEpochs == 0 { - ccLifetimeEpochs = policy.GetMaxSectorExpirationExtension() + ccLifetimeEpochs = maxCommitment } 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 } - if maxExpiration := policy.GetMaxSectorExpirationExtension(); ccLifetimeEpochs > maxExpiration { - log.Warnf("value for CommittedCapacitySectorLiftime is too long, using default maximum (%d epochs)", maxExpiration) - return maxExpiration, nil + if ccLifetimeEpochs > maxCommitment { + log.Warnf("value for CommittedCapacitySectorLiftime is too long, using default maximum (%d epochs)", maxCommitment) + return maxCommitment, nil } return ccLifetimeEpochs - p.provingBuffer, nil diff --git a/storage/pipeline/precommit_policy_test.go b/storage/pipeline/precommit_policy_test.go index 9f23e58d6..7865560de 100644 --- a/storage/pipeline/precommit_policy_test.go +++ b/storage/pipeline/precommit_policy_test.go @@ -68,7 +68,9 @@ func TestBasicPolicyEmptySector(t *testing.T) { require.NoError(t, err) // as set when there are no deal pieces - expected := h + policy.GetMaxSectorExpirationExtension() - pBuffer + maxExtension, err := policy.GetMaxSectorExpirationExtension(build.TestNetworkVersion) + assert.NoError(t, err) + expected := h + maxExtension - pBuffer assert.Equal(t, int(expected), int(exp)) } @@ -132,7 +134,7 @@ func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) { cfg := fakeConfigGetter(nil) - policy := pipeline.NewBasicPreCommitPolicy(&fakeChain{ + pcp := pipeline.NewBasicPreCommitPolicy(&fakeChain{ h: abi.ChainEpoch(55), }, cfg, 0) @@ -152,11 +154,14 @@ func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) { }, } - exp, err := policy.Expiration(context.Background(), pieces...) + exp, err := pcp.Expiration(context.Background(), pieces...) + require.NoError(t, err) + + maxLifetime, err := policy.GetMaxSectorExpirationExtension(build.TestNetworkVersion) require.NoError(t, err) // Treated as a CC sector, so expiration becomes currEpoch + maxLifetime = 55 + 1555200 - assert.Equal(t, 1555255, int(exp)) + assert.Equal(t, 55+maxLifetime, exp) } func TestMissingDealIsIgnored(t *testing.T) { diff --git a/storage/pipeline/states_sealing.go b/storage/pipeline/states_sealing.go index 8221b3968..3210109cc 100644 --- a/storage/pipeline/states_sealing.go +++ b/storage/pipeline/states_sealing.go @@ -353,7 +353,12 @@ func (m *Sealing) preCommitInfo(ctx statemachine.Context, sector SectorInfo) (*m } // Assume: both precommit msg & commit msg land on chain as early as possible - maxExpiration := ts.Height() + policy.GetPreCommitChallengeDelay() + policy.GetMaxSectorExpirationExtension() + maxExtension, err := policy.GetMaxSectorExpirationExtension(nv) + if err != nil { + return nil, big.Zero(), types.EmptyTSK, ctx.Send(SectorSealPreCommit1Failed{xerrors.Errorf("failed to get max extension: %w", err)}) + } + + maxExpiration := ts.Height() + policy.GetPreCommitChallengeDelay() + maxExtension if expiration > maxExpiration { expiration = maxExpiration }