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  }