package sealing import ( "context" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/go-state-types/abi" v0miner "github.com/filecoin-project/specs-actors/actors/builtin/miner" ) type PreCommitPolicy interface { Expiration(ctx context.Context, ps ...Piece) (abi.ChainEpoch, error) } type Chain interface { ChainHead(ctx context.Context) (TipSetToken, abi.ChainEpoch, error) StateNetworkVersion(ctx context.Context, tok TipSetToken) (network.Version, error) } // BasicPreCommitPolicy satisfies PreCommitPolicy. It has two modes: // // Mode 1: The sector contains a non-zero quantity of pieces with deal info // Mode 2: The sector contains no pieces with deal info // // The BasicPreCommitPolicy#Expiration method is given a slice of the pieces // which the miner has encoded into the sector, and from that slice picks either // the first or second mode. // // If we're in Mode 1: The pre-commit expiration epoch will be the maximum // deal end epoch of a piece in the sector. // // 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 provingBoundary abi.ChainEpoch duration abi.ChainEpoch } // NewBasicPreCommitPolicy produces a BasicPreCommitPolicy func NewBasicPreCommitPolicy(api Chain, duration abi.ChainEpoch, provingBoundary abi.ChainEpoch) BasicPreCommitPolicy { return BasicPreCommitPolicy{ api: api, provingBoundary: provingBoundary, duration: duration, } } // Expiration produces the pre-commit sector expiration epoch for an encoded // replica containing the provided enumeration of pieces and deals. func (p *BasicPreCommitPolicy) Expiration(ctx context.Context, ps ...Piece) (abi.ChainEpoch, error) { tok, epoch, err := p.api.ChainHead(ctx) if err != nil { return 0, err } var end *abi.ChainEpoch for _, p := range ps { if p.DealInfo == nil { continue } if p.DealInfo.DealSchedule.EndEpoch < epoch { log.Warnf("piece schedule %+v ended before current epoch %d", p, epoch) continue } if end == nil || *end < p.DealInfo.DealSchedule.EndEpoch { tmp := p.DealInfo.DealSchedule.EndEpoch end = &tmp } } if end == nil { tmp := epoch + p.duration end = &tmp } nv, err := p.api.StateNetworkVersion(ctx, tok) if err != nil { return 0, err } var wpp abi.ChainEpoch if nv < build.ActorUpgradeNetworkVersion { wpp = v0miner.WPoStProvingPeriod } else { // TODO: ActorUpgrade } *end += wpp - (*end % wpp) + p.provingBoundary - 1 return *end, nil }