Merge pull request #7018 from filecoin-project/asr/sector-exp-alignment

PreCommitPolicy: Don't try to align expirations on proving period boundaries
This commit is contained in:
Aayush Rajasekaran 2021-08-11 13:05:27 -04:00 committed by GitHub
commit 07c636bf86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 35 deletions

View File

@ -38,7 +38,7 @@ func init() {
var Methods = builtin{{.latestVersion}}.MethodsMiner 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 WPoStProvingPeriod = miner0.WPoStProvingPeriod
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
var WPoStChallengeWindow = miner0.WPoStChallengeWindow var WPoStChallengeWindow = miner0.WPoStChallengeWindow

View File

@ -61,7 +61,7 @@ func init() {
var Methods = builtin5.MethodsMiner 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 WPoStProvingPeriod = miner0.WPoStProvingPeriod
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
var WPoStChallengeWindow = miner0.WPoStChallengeWindow var WPoStChallengeWindow = miner0.WPoStChallengeWindow

View File

@ -315,6 +315,10 @@ func GetMaxSectorExpirationExtension() abi.ChainEpoch {
return miner5.MaxSectorExpirationExtension return miner5.MaxSectorExpirationExtension
} }
func GetMinSectorExpiration() abi.ChainEpoch {
return miner5.MinSectorExpiration
}
func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) { func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) {
sectorsPerPart, err := builtin5.PoStProofWindowPoStPartitionSectors(p) sectorsPerPart, err := builtin5.PoStProofWindowPoStPartitionSectors(p)
if err != nil { if err != nil {

View File

@ -203,6 +203,10 @@ func GetMaxSectorExpirationExtension() abi.ChainEpoch {
return miner{{.latestVersion}}.MaxSectorExpirationExtension return miner{{.latestVersion}}.MaxSectorExpirationExtension
} }
func GetMinSectorExpiration() abi.ChainEpoch {
return miner{{.latestVersion}}.MinSectorExpiration
}
func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) { func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) {
sectorsPerPart, err := builtin{{.latestVersion}}.PoStProofWindowPoStPartitionSectors(p) sectorsPerPart, err := builtin{{.latestVersion}}.PoStProofWindowPoStPartitionSectors(p)
if err != nil { if err != nil {

View File

@ -39,19 +39,17 @@ type BasicPreCommitPolicy struct {
api Chain api Chain
getSealingConfig GetSealingConfigFunc getSealingConfig GetSealingConfigFunc
provingBoundary abi.ChainEpoch provingBuffer abi.ChainEpoch
provingBuffer abi.ChainEpoch
} }
// NewBasicPreCommitPolicy produces a BasicPreCommitPolicy. // NewBasicPreCommitPolicy produces a BasicPreCommitPolicy.
// //
// The provided duration is used as the default sector expiry when the sector // 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. // 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{ return BasicPreCommitPolicy{
api: api, api: api,
getSealingConfig: cfgGetter, getSealingConfig: cfgGetter,
provingBoundary: provingBoundary,
provingBuffer: provingBuffer, provingBuffer: provingBuffer,
} }
} }
@ -93,7 +91,12 @@ func (p *BasicPreCommitPolicy) Expiration(ctx context.Context, ps ...Piece) (abi
end = &tmp 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 return *end, nil
} }
@ -119,5 +122,5 @@ func (p *BasicPreCommitPolicy) getCCSectorLifetime() (abi.ChainEpoch, error) {
return maxExpiration, nil return maxExpiration, nil
} }
return (ccLifetimeEpochs - p.provingBuffer), nil return ccLifetimeEpochs - p.provingBuffer, nil
} }

View File

@ -9,7 +9,6 @@ import (
api "github.com/filecoin-project/lotus/api" api "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/builtin" "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/actors/policy"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing" sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" "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) { func TestBasicPolicyEmptySector(t *testing.T) {
cfg := fakeConfigGetter(nil) cfg := fakeConfigGetter(nil)
h := abi.ChainEpoch(55) h := abi.ChainEpoch(55)
pBoundary := abi.ChainEpoch(0)
pBuffer := abi.ChainEpoch(2) 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()) exp, err := pcp.Expiration(context.Background())
require.NoError(t, err) require.NoError(t, err)
// as set when there are no deal pieces // as set when there are no deal pieces
expected := h + policy.GetMaxSectorExpirationExtension() - (pBuffer * 2) expected := h + policy.GetMaxSectorExpirationExtension() - pBuffer
// as set just before returning within Expiration()
expected += miner.WPoStProvingPeriod - (expected % miner.WPoStProvingPeriod) + pBoundary - 1
assert.Equal(t, int(expected), int(exp)) assert.Equal(t, int(expected), int(exp))
} }
@ -80,27 +76,23 @@ func TestCustomCCSectorConfig(t *testing.T) {
cfgStub := fakeConfigStub{CCSectorLifetime: customLifetime} cfgStub := fakeConfigStub{CCSectorLifetime: customLifetime}
cfg := fakeConfigGetter(&cfgStub) cfg := fakeConfigGetter(&cfgStub)
h := abi.ChainEpoch(55) h := abi.ChainEpoch(55)
pBoundary := abi.ChainEpoch(0)
pBuffer := abi.ChainEpoch(2) 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()) exp, err := pcp.Expiration(context.Background())
require.NoError(t, err) require.NoError(t, err)
// as set when there are no deal pieces // as set when there are no deal pieces
expected := h + customLifetimeEpochs - (pBuffer * 2) expected := h + customLifetimeEpochs - pBuffer
// as set just before returning within Expiration()
expected += miner.WPoStProvingPeriod - (expected % miner.WPoStProvingPeriod) + pBoundary - 1
assert.Equal(t, int(expected), int(exp)) assert.Equal(t, int(expected), int(exp))
} }
func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) { func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) {
cfg := fakeConfigGetter(nil) cfg := fakeConfigGetter(nil)
pPeriod := abi.ChainEpoch(11)
policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ policy := sealing.NewBasicPreCommitPolicy(&fakeChain{
h: abi.ChainEpoch(55), h: abi.ChainEpoch(55),
}, cfg, pPeriod, 2) }, cfg, 2)
longestDealEpochEnd := abi.ChainEpoch(100) longestDealEpochEnd := abi.ChainEpoch(547300)
pieces := []sealing.Piece{ pieces := []sealing.Piece{
{ {
Piece: abi.PieceInfo{ Piece: abi.PieceInfo{
@ -111,7 +103,7 @@ func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) {
DealID: abi.DealID(42), DealID: abi.DealID(42),
DealSchedule: api.DealSchedule{ DealSchedule: api.DealSchedule{
StartEpoch: abi.ChainEpoch(70), 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...) exp, err := policy.Expiration(context.Background(), pieces...)
require.NoError(t, err) require.NoError(t, err)
expected := longestDealEpochEnd + miner.WPoStProvingPeriod - (longestDealEpochEnd % miner.WPoStProvingPeriod) + pPeriod - 1 assert.Equal(t, int(longestDealEpochEnd), int(exp))
assert.Equal(t, int(expected), int(exp))
} }
func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) { func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) {
cfg := fakeConfigGetter(nil) cfg := fakeConfigGetter(nil)
policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ policy := sealing.NewBasicPreCommitPolicy(&fakeChain{
h: abi.ChainEpoch(55), h: abi.ChainEpoch(55),
}, cfg, 0, 0) }, cfg, 0)
pieces := []sealing.Piece{ pieces := []sealing.Piece{
{ {
@ -162,14 +153,15 @@ func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) {
exp, err := policy.Expiration(context.Background(), pieces...) exp, err := policy.Expiration(context.Background(), pieces...)
require.NoError(t, err) 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) { func TestMissingDealIsIgnored(t *testing.T) {
cfg := fakeConfigGetter(nil) cfg := fakeConfigGetter(nil)
policy := sealing.NewBasicPreCommitPolicy(&fakeChain{ policy := sealing.NewBasicPreCommitPolicy(&fakeChain{
h: abi.ChainEpoch(55), h: abi.ChainEpoch(55),
}, cfg, 11, 0) }, cfg, 0)
pieces := []sealing.Piece{ pieces := []sealing.Piece{
{ {
@ -181,7 +173,7 @@ func TestMissingDealIsIgnored(t *testing.T) {
DealID: abi.DealID(44), DealID: abi.DealID(44),
DealSchedule: api.DealSchedule{ DealSchedule: api.DealSchedule{
StartEpoch: abi.ChainEpoch(1), 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...) exp, err := policy.Expiration(context.Background(), pieces...)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, 1558090, int(exp)) assert.Equal(t, 547300, int(exp))
} }

View File

@ -179,12 +179,10 @@ func (m *Miner) Run(ctx context.Context) error {
adaptedAPI = NewSealingAPIAdapter(m.api) adaptedAPI = NewSealingAPIAdapter(m.api)
// Instantiate a precommit policy. // Instantiate a precommit policy.
cfg = sealing.GetSealingConfigFunc(m.getSealConfig) cfg = sealing.GetSealingConfigFunc(m.getSealConfig)
provingBoundary = md.PeriodStart % md.WPoStProvingPeriod provingBuffer = md.WPoStProvingPeriod * 2
provingBuffer = md.WPoStProvingPeriod * 2
// TODO: Maybe we update this policy after actor upgrades? pcp = sealing.NewBasicPreCommitPolicy(adaptedAPI, cfg, provingBuffer)
pcp = sealing.NewBasicPreCommitPolicy(adaptedAPI, cfg, provingBoundary, provingBuffer)
// address selector. // address selector.
as = func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { as = func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) {