github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/builtin/miner/policy.go (about) 1 package miner 2 3 import ( 4 "fmt" 5 6 "github.com/filecoin-project/go-state-types/abi" 7 "github.com/filecoin-project/go-state-types/big" 8 "github.com/filecoin-project/go-state-types/network" 9 "github.com/ipfs/go-cid" 10 mh "github.com/multiformats/go-multihash" 11 12 "github.com/filecoin-project/specs-actors/v4/actors/builtin" 13 ) 14 15 // The period over which a miner's active sectors are expected to be proven via WindowPoSt. 16 // This guarantees that (1) user data is proven daily, (2) user data is stored for 24h by a rational miner 17 // (due to Window PoSt cost assumption). 18 var WPoStProvingPeriod = abi.ChainEpoch(builtin.EpochsInDay) // 24 hours PARAM_SPEC 19 20 // The period between the opening and the closing of a WindowPoSt deadline in which the miner is expected to 21 // provide a Window PoSt proof. 22 // This provides a miner enough time to compute and propagate a Window PoSt proof. 23 var WPoStChallengeWindow = abi.ChainEpoch(30 * 60 / builtin.EpochDurationSeconds) // 30 minutes (48 per day) PARAM_SPEC 24 25 // WPoStDisputeWindow is the period after a challenge window ends during which 26 // PoSts submitted during that period may be disputed. 27 var WPoStDisputeWindow = 2 * ChainFinality // PARAM_SPEC 28 29 // The number of non-overlapping PoSt deadlines in a proving period. 30 // This spreads a miner's Window PoSt work across a proving period. 31 const WPoStPeriodDeadlines = uint64(48) // PARAM_SPEC 32 33 // MaxPartitionsPerDeadline is the maximum number of partitions that will be assigned to a deadline. 34 // For a minimum storage of upto 1Eib, we need 300 partitions per deadline. 35 // 48 * 32GiB * 2349 * 300 = 1.00808144 EiB 36 // So, to support upto 10Eib storage, we set this to 3000. 37 const MaxPartitionsPerDeadline = 3000 38 39 func init() { 40 // Check that the challenge windows divide the proving period evenly. 41 if WPoStProvingPeriod%WPoStChallengeWindow != 0 { 42 panic(fmt.Sprintf("incompatible proving period %d and challenge window %d", WPoStProvingPeriod, WPoStChallengeWindow)) 43 } 44 // Check that WPoStPeriodDeadlines is consistent with the proving period and challenge window. 45 if abi.ChainEpoch(WPoStPeriodDeadlines)*WPoStChallengeWindow != WPoStProvingPeriod { 46 panic(fmt.Sprintf("incompatible proving period %d and challenge window %d", WPoStProvingPeriod, WPoStChallengeWindow)) 47 } 48 49 // Check to make sure the dispute window is longer than finality so there's always some time to dispute bad proofs. 50 if WPoStDisputeWindow <= ChainFinality { 51 panic(fmt.Sprintf("the proof dispute period %d must exceed finality %d", WPoStDisputeWindow, ChainFinality)) 52 } 53 54 // A deadline becomes immutable one challenge window before it's challenge window opens. 55 // The challenge lookback must fall within this immutability period. 56 if WPoStChallengeLookback > WPoStChallengeWindow { 57 panic("the challenge lookback cannot exceed one challenge window") 58 } 59 60 // Deadlines are immutable when the challenge window is open, and during 61 // the previous challenge window. 62 immutableWindow := 2 * WPoStChallengeWindow 63 64 // We want to reserve at least one deadline's worth of time to compact a 65 // deadline. 66 minCompactionWindow := WPoStChallengeWindow 67 68 // Make sure we have enough time in the proving period to do everything we need. 69 if (minCompactionWindow + immutableWindow + WPoStDisputeWindow) > WPoStProvingPeriod { 70 panic(fmt.Sprintf("together, the minimum compaction window (%d) immutability window (%d) and the dispute window (%d) exceed the proving period (%d)", 71 minCompactionWindow, immutableWindow, WPoStDisputeWindow, WPoStProvingPeriod)) 72 } 73 } 74 75 // The maximum number of partitions that can be loaded in a single invocation. 76 // This limits the number of simultaneous fault, recovery, or sector-extension declarations. 77 // We set this to same as MaxPartitionsPerDeadline so we can process that many partitions every deadline. 78 const AddressedPartitionsMax = MaxPartitionsPerDeadline 79 80 // Maximum number of unique "declarations" in batch operations. 81 const DeclarationsMax = AddressedPartitionsMax 82 83 // The maximum number of sector infos that can be loaded in a single invocation. 84 // This limits the amount of state to be read in a single message execution. 85 const AddressedSectorsMax = 10_000 // PARAM_SPEC 86 87 // Libp2p peer info limits. 88 const ( 89 // MaxPeerIDLength is the maximum length allowed for any on-chain peer ID. 90 // Most Peer IDs are expected to be less than 50 bytes. 91 MaxPeerIDLength = 128 // PARAM_SPEC 92 93 // MaxMultiaddrData is the maximum amount of data that can be stored in multiaddrs. 94 MaxMultiaddrData = 1024 // PARAM_SPEC 95 ) 96 97 // Maximum number of control addresses a miner may register. 98 const MaxControlAddresses = 10 99 100 // The maximum number of partitions that may be required to be loaded in a single invocation, 101 // when all the sector infos for the partitions will be loaded. 102 func loadPartitionsSectorsMax(partitionSectorCount uint64) uint64 { 103 return min64(AddressedSectorsMax/partitionSectorCount, AddressedPartitionsMax) 104 } 105 106 // Epochs after which chain state is final with overwhelming probability (hence the likelihood of two fork of this size is negligible) 107 // This is a conservative value that is chosen via simulations of all known attacks. 108 const ChainFinality = abi.ChainEpoch(900) // PARAM_SPEC 109 110 // Prefix for sealed sector CIDs (CommR). 111 var SealedCIDPrefix = cid.Prefix{ 112 Version: 1, 113 Codec: cid.FilCommitmentSealed, 114 MhType: mh.POSEIDON_BLS12_381_A1_FC1, 115 MhLength: 32, 116 } 117 118 // List of proof types which may be used when creating a new miner actor or pre-committing a new sector. 119 // This is mutable to allow configuration of testing and development networks. 120 var PreCommitSealProofTypesV0 = map[abi.RegisteredSealProof]struct{}{ 121 abi.RegisteredSealProof_StackedDrg32GiBV1: {}, 122 abi.RegisteredSealProof_StackedDrg64GiBV1: {}, 123 } 124 var PreCommitSealProofTypesV7 = map[abi.RegisteredSealProof]struct{}{ 125 abi.RegisteredSealProof_StackedDrg32GiBV1: {}, 126 abi.RegisteredSealProof_StackedDrg64GiBV1: {}, 127 abi.RegisteredSealProof_StackedDrg32GiBV1_1: {}, 128 abi.RegisteredSealProof_StackedDrg64GiBV1_1: {}, 129 } 130 131 // From network version 8, sectors sealed with the V1 seal proof types cannot be committed. 132 var PreCommitSealProofTypesV8 = map[abi.RegisteredSealProof]struct{}{ 133 abi.RegisteredSealProof_StackedDrg32GiBV1_1: {}, 134 abi.RegisteredSealProof_StackedDrg64GiBV1_1: {}, 135 } 136 137 // Checks whether a seal proof type is supported for new miners and sectors. 138 func CanPreCommitSealProof(s abi.RegisteredSealProof, nv network.Version) bool { 139 _, ok := PreCommitSealProofTypesV0[s] 140 if nv >= network.Version7 { 141 _, ok = PreCommitSealProofTypesV7[s] 142 } 143 if nv >= network.Version8 { 144 _, ok = PreCommitSealProofTypesV8[s] 145 } 146 return ok 147 } 148 149 // List of proof types for which sector lifetime may be extended. 150 // From network version 7 to version 10, sectors sealed with the V1 seal proof types cannot be extended. 151 var ExtensibleProofTypes = map[abi.RegisteredSealProof]struct{}{ 152 abi.RegisteredSealProof_StackedDrg32GiBV1_1: {}, 153 abi.RegisteredSealProof_StackedDrg64GiBV1_1: {}, 154 } 155 156 // Checks whether a seal proof type is supported for new miners and sectors. 157 func CanExtendSealProofType(s abi.RegisteredSealProof, nv network.Version) bool { 158 if nv >= network.Version7 && nv <= network.Version10 { 159 _, ok := ExtensibleProofTypes[s] 160 return ok 161 } 162 return true 163 } 164 165 // Maximum delay to allow between sector pre-commit and subsequent proof. 166 // The allowable delay depends on seal proof algorithm. 167 var MaxProveCommitDuration = map[abi.RegisteredSealProof]abi.ChainEpoch{ 168 abi.RegisteredSealProof_StackedDrg32GiBV1: builtin.EpochsInDay + PreCommitChallengeDelay, // PARAM_SPEC 169 abi.RegisteredSealProof_StackedDrg2KiBV1: builtin.EpochsInDay + PreCommitChallengeDelay, 170 abi.RegisteredSealProof_StackedDrg8MiBV1: builtin.EpochsInDay + PreCommitChallengeDelay, 171 abi.RegisteredSealProof_StackedDrg512MiBV1: builtin.EpochsInDay + PreCommitChallengeDelay, 172 abi.RegisteredSealProof_StackedDrg64GiBV1: builtin.EpochsInDay + PreCommitChallengeDelay, 173 174 abi.RegisteredSealProof_StackedDrg32GiBV1_1: builtin.EpochsInDay + PreCommitChallengeDelay, // PARAM_SPEC 175 abi.RegisteredSealProof_StackedDrg2KiBV1_1: builtin.EpochsInDay + PreCommitChallengeDelay, 176 abi.RegisteredSealProof_StackedDrg8MiBV1_1: builtin.EpochsInDay + PreCommitChallengeDelay, 177 abi.RegisteredSealProof_StackedDrg512MiBV1_1: builtin.EpochsInDay + PreCommitChallengeDelay, 178 abi.RegisteredSealProof_StackedDrg64GiBV1_1: builtin.EpochsInDay + PreCommitChallengeDelay, 179 } 180 181 // Maximum delay between challenge and pre-commitment. 182 // This prevents a miner sealing sectors far in advance of committing them to the chain, thus committing to a 183 // particular chain. 184 var MaxPreCommitRandomnessLookback = builtin.EpochsInDay + ChainFinality // PARAM_SPEC 185 186 // Number of epochs between publishing a sector pre-commitment and when the challenge for interactive PoRep is drawn. 187 // This (1) prevents a miner predicting a challenge before staking their pre-commit deposit, and 188 // (2) prevents a miner attempting a long fork in the past to insert a pre-commitment after seeing the challenge. 189 var PreCommitChallengeDelay = abi.ChainEpoch(150) // PARAM_SPEC 190 191 // Lookback from the deadline's challenge window opening from which to sample chain randomness for the WindowPoSt challenge seed. 192 // This means that deadline windows can be non-overlapping (which make the programming simpler) without requiring a 193 // miner to wait for chain stability during the challenge window. 194 // This value cannot be too large lest it compromise the rationality of honest storage (from Window PoSt cost assumptions). 195 const WPoStChallengeLookback = abi.ChainEpoch(20) // PARAM_SPEC 196 197 // Minimum period between fault declaration and the next deadline opening. 198 // If the number of epochs between fault declaration and deadline's challenge window opening is lower than FaultDeclarationCutoff, 199 // the fault declaration is considered invalid for that deadline. 200 // This guarantees that a miner is not likely to successfully fork the chain and declare a fault after seeing the challenges. 201 const FaultDeclarationCutoff = WPoStChallengeLookback + 50 // PARAM_SPEC 202 203 // The maximum age of a fault before the sector is terminated. 204 // This bounds the time a miner can lose client's data before sacrificing pledge and deal collateral. 205 var FaultMaxAge = WPoStProvingPeriod * 14 // PARAM_SPEC 206 207 // Staging period for a miner worker key change. 208 // This delay prevents a miner choosing a more favorable worker key that wins leader elections. 209 const WorkerKeyChangeDelay = ChainFinality // PARAM_SPEC 210 211 // Minimum number of epochs past the current epoch a sector may be set to expire. 212 const MinSectorExpiration = 180 * builtin.EpochsInDay // PARAM_SPEC 213 214 // The maximum number of epochs past the current epoch that sector lifetime may be extended. 215 // A sector may be extended multiple times, however, the total maximum lifetime is also bounded by 216 // the associated seal proof's maximum lifetime. 217 const MaxSectorExpirationExtension = 540 * builtin.EpochsInDay // PARAM_SPEC 218 219 // Ratio of sector size to maximum number of deals per sector. 220 // The maximum number of deals is the sector size divided by this number (2^27) 221 // which limits 32GiB sectors to 256 deals and 64GiB sectors to 512 222 const DealLimitDenominator = 134217728 // PARAM_SPEC 223 224 // Number of epochs after a consensus fault for which a miner is ineligible 225 // for permissioned actor methods and winning block elections. 226 const ConsensusFaultIneligibilityDuration = ChainFinality 227 228 // DealWeight and VerifiedDealWeight are spacetime occupied by regular deals and verified deals in a sector. 229 // Sum of DealWeight and VerifiedDealWeight should be less than or equal to total SpaceTime of a sector. 230 // Sectors full of VerifiedDeals will have a SectorQuality of VerifiedDealWeightMultiplier/QualityBaseMultiplier. 231 // Sectors full of Deals will have a SectorQuality of DealWeightMultiplier/QualityBaseMultiplier. 232 // Sectors with neither will have a SectorQuality of QualityBaseMultiplier/QualityBaseMultiplier. 233 // SectorQuality of a sector is a weighted average of multipliers based on their proportions. 234 func QualityForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.SectorQuality { 235 // sectorSpaceTime = size * duration 236 sectorSpaceTime := big.Mul(big.NewIntUnsigned(uint64(size)), big.NewInt(int64(duration))) 237 // totalDealSpaceTime = dealWeight + verifiedWeight 238 totalDealSpaceTime := big.Add(dealWeight, verifiedWeight) 239 240 // Base - all size * duration of non-deals 241 // weightedBaseSpaceTime = (sectorSpaceTime - totalDealSpaceTime) * QualityBaseMultiplier 242 weightedBaseSpaceTime := big.Mul(big.Sub(sectorSpaceTime, totalDealSpaceTime), builtin.QualityBaseMultiplier) 243 // Deal - all deal size * deal duration * 10 244 // weightedDealSpaceTime = dealWeight * DealWeightMultiplier 245 weightedDealSpaceTime := big.Mul(dealWeight, builtin.DealWeightMultiplier) 246 // Verified - all verified deal size * verified deal duration * 100 247 // weightedVerifiedSpaceTime = verifiedWeight * VerifiedDealWeightMultiplier 248 weightedVerifiedSpaceTime := big.Mul(verifiedWeight, builtin.VerifiedDealWeightMultiplier) 249 // Sum - sum of all spacetime 250 // weightedSumSpaceTime = weightedBaseSpaceTime + weightedDealSpaceTime + weightedVerifiedSpaceTime 251 weightedSumSpaceTime := big.Sum(weightedBaseSpaceTime, weightedDealSpaceTime, weightedVerifiedSpaceTime) 252 // scaledUpWeightedSumSpaceTime = weightedSumSpaceTime * 2^20 253 scaledUpWeightedSumSpaceTime := big.Lsh(weightedSumSpaceTime, builtin.SectorQualityPrecision) 254 255 // Average of weighted space time: (scaledUpWeightedSumSpaceTime / sectorSpaceTime * 10) 256 return big.Div(big.Div(scaledUpWeightedSumSpaceTime, sectorSpaceTime), builtin.QualityBaseMultiplier) 257 } 258 259 // The power for a sector size, committed duration, and weight. 260 func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower { 261 quality := QualityForWeight(size, duration, dealWeight, verifiedWeight) 262 return big.Rsh(big.Mul(big.NewIntUnsigned(uint64(size)), quality), builtin.SectorQualityPrecision) 263 } 264 265 // The quality-adjusted power for a sector. 266 func QAPowerForSector(size abi.SectorSize, sector *SectorOnChainInfo) abi.StoragePower { 267 duration := sector.Expiration - sector.Activation 268 return QAPowerForWeight(size, duration, sector.DealWeight, sector.VerifiedDealWeight) 269 } 270 271 // Determine maximum number of deal miner's sector can hold 272 func SectorDealsMax(size abi.SectorSize) uint64 { 273 return max64(256, uint64(size/DealLimitDenominator)) 274 } 275 276 // Initial share of consensus fault penalty allocated as reward to the reporter. 277 var consensusFaultReporterInitialShare = builtin.BigFrac{ 278 Numerator: big.NewInt(1), // PARAM_SPEC 279 Denominator: big.NewInt(1000), 280 } 281 282 // Per-epoch growth rate of the consensus fault reporter reward. 283 // consensusFaultReporterInitialShare*consensusFaultReporterShareGrowthRate^consensusFaultGrowthDuration ~= consensusFaultReporterMaxShare 284 // consensusFaultGrowthDuration = 500 epochs 285 var consensusFaultReporterShareGrowthRate = builtin.BigFrac{ 286 Numerator: big.NewInt(100785473384), // PARAM_SPEC 287 Denominator: big.NewInt(100000000000), 288 } 289 290 // Maximum share of consensus fault penalty allocated as reporter reward. 291 var consensusFaultMaxReporterShare = builtin.BigFrac{ 292 Numerator: big.NewInt(1), // PARAM_SPEC 293 Denominator: big.NewInt(20), 294 } 295 296 // Specification for a linear vesting schedule. 297 type VestSpec struct { 298 InitialDelay abi.ChainEpoch // Delay before any amount starts vesting. 299 VestPeriod abi.ChainEpoch // Period over which the total should vest, after the initial delay. 300 StepDuration abi.ChainEpoch // Duration between successive incremental vests (independent of vesting period). 301 Quantization abi.ChainEpoch // Maximum precision of vesting table (limits cardinality of table). 302 } 303 304 // The vesting schedule for total rewards (block reward + gas reward) earned by a block producer. 305 var RewardVestingSpec = VestSpec{ // PARAM_SPEC 306 InitialDelay: abi.ChainEpoch(0), 307 VestPeriod: abi.ChainEpoch(180 * builtin.EpochsInDay), 308 StepDuration: abi.ChainEpoch(1 * builtin.EpochsInDay), 309 Quantization: 12 * builtin.EpochsInHour, 310 } 311 312 // When an actor reports a consensus fault, they earn a share of the penalty paid by the miner. 313 // This amount is: Min(initialShare * growthRate^elapsed, maxReporterShare) * collateral 314 // The reward grows over time until a maximum, forming an auction for the report. 315 func RewardForConsensusSlashReport(elapsedEpoch abi.ChainEpoch, collateral abi.TokenAmount) abi.TokenAmount { 316 // High level description 317 // var growthRate = SLASHER_SHARE_GROWTH_RATE_NUM / SLASHER_SHARE_GROWTH_RATE_DENOM 318 // var multiplier = growthRate^elapsedEpoch 319 // var slasherProportion = min(INITIAL_SLASHER_SHARE * multiplier, 0.05) 320 // return collateral * slasherProportion 321 322 // BigInt Operation 323 // NUM = SLASHER_SHARE_GROWTH_RATE_NUM^elapsedEpoch * INITIAL_SLASHER_SHARE_NUM * collateral 324 // DENOM = SLASHER_SHARE_GROWTH_RATE_DENOM^elapsedEpoch * INITIAL_SLASHER_SHARE_DENOM 325 // slasher_amount = min(NUM/DENOM, collateral) 326 elapsed := big.NewInt(int64(elapsedEpoch)) 327 328 // The following is equivalent to: slasherShare = growthRate^elapsed 329 // slasherShareNumerator = growthRateNumerator^elapsed 330 slasherShareNumerator := big.Exp(consensusFaultReporterShareGrowthRate.Numerator, elapsed) 331 // slasherShareDenominator = growthRateDenominator^elapsed 332 slasherShareDenominator := big.Exp(consensusFaultReporterShareGrowthRate.Denominator, elapsed) 333 334 // The following is equivalent to: reward = slasherShare * initialShare * collateral 335 // num = slasherShareNumerator * initialShareNumerator * collateral 336 num := big.Mul(big.Mul(slasherShareNumerator, consensusFaultReporterInitialShare.Numerator), collateral) 337 // denom = slasherShareDenominator * initialShareDenominator 338 denom := big.Mul(slasherShareDenominator, consensusFaultReporterInitialShare.Denominator) 339 340 // The following is equivalent to: Min(reward, collateral * maxReporterShare) 341 // Min(rewardNum/rewardDenom, maxReporterShareNum/maxReporterShareDen*collateral) 342 return big.Min(big.Div(num, denom), big.Div(big.Mul(collateral, consensusFaultMaxReporterShare.Numerator), 343 consensusFaultMaxReporterShare.Denominator)) 344 } 345 346 // The reward given for successfully disputing a window post. 347 func RewardForDisputedWindowPoSt(proofType abi.RegisteredPoStProof, disputedPower PowerPair) abi.TokenAmount { 348 // This is currently just the base. In the future, the fee may scale based on the disputed power. 349 return BaseRewardForDisputedWindowPoSt 350 }