diff --git a/documentation/en/default-lotus-miner-config.toml b/documentation/en/default-lotus-miner-config.toml index 47ac9f1e7ed..d8c774c7589 100644 --- a/documentation/en/default-lotus-miner-config.toml +++ b/documentation/en/default-lotus-miner-config.toml @@ -167,6 +167,14 @@ # env var: LOTUS_DEALMAKING_EXPECTEDSEALDURATION #ExpectedSealDuration = "24h0m0s" + # Whether new sectors are created to pack incoming deals + # When this is set to false no new sectors will be created for sealing incoming deals + # This is useful for forcing all deals to be assigned as snap deals to sectors marked for upgrade + # + # type: bool + # env var: LOTUS_DEALMAKING_MAKENEWSECTORFORDEALS + #MakeNewSectorForDeals = true + # Maximum amount of time proposed deal StartEpoch can be in future # # type: Duration diff --git a/extern/storage-sealing/input.go b/extern/storage-sealing/input.go index f3259f0cced..199892ca8f1 100644 --- a/extern/storage-sealing/input.go +++ b/extern/storage-sealing/input.go @@ -16,6 +16,7 @@ import ( "github.com/filecoin-project/specs-storage/storage" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" @@ -117,9 +118,25 @@ func (m *Sealing) maybeStartSealing(ctx statemachine.Context, sector SectorInfo, return false, xerrors.Errorf("getting storage config: %w", err) } - // todo check deal age, start sealing if any deal has less than X (configurable) to start deadline sealTime := time.Unix(sector.CreationTime, 0).Add(cfg.WaitDealsDelay) + // check deal age, start sealing when the deal closest to starting is within slack time + _, current, err := m.Api.ChainHead(ctx.Context()) + blockTime := time.Second * time.Duration(build.BlockDelaySecs) + if err != nil { + return false, xerrors.Errorf("API error getting head: %w", err) + } + for _, piece := range sector.Pieces { + if piece.DealInfo == nil { + continue + } + dealSafeSealEpoch := piece.DealInfo.DealProposal.StartEpoch - cfg.StartEpochSealingBuffer + dealSafeSealTime := time.Now().Add(time.Duration(dealSafeSealEpoch-current) * blockTime) + if dealSafeSealTime.Before(sealTime) { + sealTime = dealSafeSealTime + } + } + if now.After(sealTime) { log.Infow("starting to seal deal sector", "sector", sector.SectorNumber, "trigger", "wait-timeout") return true, ctx.Send(SectorStartPacking{}) @@ -475,6 +492,10 @@ func (m *Sealing) tryCreateDealSector(ctx context.Context, sp abi.RegisteredSeal return xerrors.Errorf("getting storage config: %w", err) } + if !cfg.MakeNewSectorForDeals { + return nil + } + if cfg.MaxSealingSectorsForDeals > 0 && m.stats.curSealing() >= cfg.MaxSealingSectorsForDeals { return nil } diff --git a/extern/storage-sealing/sealiface/config.go b/extern/storage-sealing/sealiface/config.go index d8a12283cdc..852034aa7fb 100644 --- a/extern/storage-sealing/sealiface/config.go +++ b/extern/storage-sealing/sealiface/config.go @@ -18,6 +18,8 @@ type Config struct { // includes failed, 0 = no limit MaxSealingSectorsForDeals uint64 + MakeNewSectorForDeals bool + WaitDealsDelay time.Duration CommittedCapacitySectorLifetime time.Duration diff --git a/node/config/def.go b/node/config/def.go index 644c28bea69..eded665fff8 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -156,6 +156,7 @@ func DefaultStorageMiner() *StorageMiner { ConsiderVerifiedStorageDeals: true, ConsiderUnverifiedStorageDeals: true, PieceCidBlocklist: []cid.Cid{}, + MakeNewSectorForDeals: true, // TODO: It'd be nice to set this based on sector size MaxDealStartDelay: Duration(time.Hour * 24 * 14), ExpectedSealDuration: Duration(time.Hour * 24), diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index c3730cbace6..79fcf7e43c6 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -239,6 +239,14 @@ Default value: 1 minute.`, Comment: `Maximum expected amount of time getting the deal into a sealed sector will take This includes the time the deal will need to get transferred and published before being assigned to a sector`, + }, + { + Name: "MakeNewSectorForDeals", + Type: "bool", + + Comment: `Whether new sectors are created to pack incoming deals +When this is set to false no new sectors will be created for sealing incoming deals +This is useful for forcing all deals to be assigned as snap deals to sectors marked for upgrade`, }, { Name: "MaxDealStartDelay", diff --git a/node/config/types.go b/node/config/types.go index 715f4824861..a03e3d3eade 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -120,6 +120,10 @@ type DealmakingConfig struct { // This includes the time the deal will need to get transferred and published // before being assigned to a sector ExpectedSealDuration Duration + // Whether new sectors are created to pack incoming deals + // When this is set to false no new sectors will be created for sealing incoming deals + // This is useful for forcing all deals to be assigned as snap deals to sectors marked for upgrade + MakeNewSectorForDeals bool // Maximum amount of time proposed deal StartEpoch can be in future MaxDealStartDelay Duration // When a deal is ready to publish, the amount of time to wait for more diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index da1a016f77e..f4a2364fd56 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -925,6 +925,8 @@ func ToSealingConfig(cfg *config.StorageMiner) sealiface.Config { MaxWaitDealsSectors: cfg.Sealing.MaxWaitDealsSectors, MaxSealingSectors: cfg.Sealing.MaxSealingSectors, MaxSealingSectorsForDeals: cfg.Sealing.MaxSealingSectorsForDeals, + StartEpochSealingBuffer: abi.ChainEpoch(cfg.Dealmaking.StartEpochSealingBuffer), + MakeNewSectorForDeals: cfg.Dealmaking.MakeNewSectorForDeals, CommittedCapacitySectorLifetime: time.Duration(cfg.Sealing.CommittedCapacitySectorLifetime), WaitDealsDelay: time.Duration(cfg.Sealing.WaitDealsDelay), AlwaysKeepUnsealedCopy: cfg.Sealing.AlwaysKeepUnsealedCopy, @@ -950,8 +952,6 @@ func ToSealingConfig(cfg *config.StorageMiner) sealiface.Config { TerminateBatchMax: cfg.Sealing.TerminateBatchMax, TerminateBatchMin: cfg.Sealing.TerminateBatchMin, TerminateBatchWait: time.Duration(cfg.Sealing.TerminateBatchWait), - - StartEpochSealingBuffer: abi.ChainEpoch(cfg.Dealmaking.StartEpochSealingBuffer), } }