-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
precommit_policy.go
130 lines (108 loc) · 4.24 KB
/
precommit_policy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package sealing
import (
"context"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/builtin/v8/miner"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
type PreCommitPolicy interface {
Expiration(ctx context.Context, ps ...api.SectorPiece) (abi.ChainEpoch, error)
}
type Chain interface {
ChainHead(context.Context) (*types.TipSet, error)
StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (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
getSealingConfig dtypes.GetSealingConfigFunc
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 dtypes.GetSealingConfigFunc, provingBuffer abi.ChainEpoch) BasicPreCommitPolicy {
return BasicPreCommitPolicy{
api: api,
getSealingConfig: cfgGetter,
provingBuffer: provingBuffer,
}
}
// 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 ...api.SectorPiece) (abi.ChainEpoch, error) {
ts, 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 < ts.Height() {
log.Warnf("piece schedule %+v ended before current epoch %d", p, ts.Height())
continue
}
if end == nil || *end < p.DealInfo.DealSchedule.EndEpoch {
tmp := p.DealInfo.DealSchedule.EndEpoch
end = &tmp
}
}
if end == nil {
// no deal pieces, get expiration for committed capacity sector
expirationDuration, err := p.getCCSectorLifetime()
if err != nil {
return 0, err
}
tmp := ts.Height() + expirationDuration
end = &tmp
}
// 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 := ts.Height() + policy.GetMinSectorExpiration() + miner.WPoStProvingPeriod
if *end < minExp {
end = &minExp
}
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)
}
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()
}
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
}
return ccLifetimeEpochs - p.provingBuffer, nil
}